使用步骤:
1.option_table.h中添加字段,avformat.h文件的AVFormatContext结构体中增加字段
avformat.h
typedef struct AVFormatContext {
int _mp4_drm_head_key; // 增加头部的字段
}
options_table.h android\contrib\ffmpeg-armv7a\libavformat
static const AVOption avformat_options[] = {
{"_mp4_drm_head_key", "����mp4�ӽ��ܵ�head key", OFFSET(_mp4_drm_head_key), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D},
}
2.应用层调用setOption相应的字符串的key
应用层调用:
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "_mp4_drm_head_key", mSDKSettings.getMp4DrmHeadKey());
底层设置过程:
IjkMediaPlayer_setOption
ijkmp_set_option
void ffp_set_option(FFPlayer *ffp, int opt_category, const char *name, const char *value)
{
if (!ffp)
return;
AVDictionary **dict = ffp_get_opt_dict(ffp, opt_category);
av_dict_set(dict, name, value, 0);
}
static AVDictionary **ffp_get_opt_dict(FFPlayer *ffp, int opt_category)
{
switch (opt_category) {
case FFP_OPT_CATEGORY_FORMAT: return &ffp->format_opts; // 设置到FFPlayer的字典中
case FFP_OPT_CATEGORY_CODEC: return &ffp->codec_opts;
case FFP_OPT_CATEGORY_SWS: return &ffp->sws_dict;
case FFP_OPT_CATEGORY_PLAYER: return &ffp->player_opts;
case FFP_OPT_CATEGORY_SWR: return &ffp->swr_opts;
}
}
3.底层初始化的时候自动赋值:设置字典中的数据到AVFormatContext结构中对应的 成员变量中
IjkMediaPlayer_prepareAsync 10 ijkplayer_jni.c (ijkmedia\ijkplayer\android)
ijkmp_prepare_async ijkplayer.h (ijkmedia\ijkplayer)
ijkmp_prepare_async_l 25 ijkplayer.c (ijkmedia\ijkplayer)
ffp_prepare_async_l 12 ff_ffplay.c (ijkmedia\ijkplayer)
stream_open 42 ff_ffplay.c (ijkmedia\ijkplayer)
avformat_open_input 77 utils.c (android\ffmpeg-armv7a\libavformat)
stream_open中调用:avformat_open_input(&ic, is->filename, is->iformat, &ffp->format_opts);
// 打开输入
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
{
AVFormatContext *s = *ps;
int ret = 0;
AVDictionary *tmp = NULL;
if (!s && !(s = avformat_alloc_context()))
return AVERROR(ENOMEM);
if (fmt)
s->iformat = fmt;
// 将所有option拷贝到临时的options中
if (options)
av_dict_copy(&tmp, *options, 0);
// 将先前的option设置到AVFormatContext的相应的成员变量中
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
// 初始化输入
if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
}
4.底层可使用应用层设置进来的数据
AVFormatContext结构中对应的成员变量值已经由字典的值设置进来了
总结下:
1.底层需要应用层设置数据(初始化)
底层的AVFormatContext结构增加对应的成员变量并将相应的成员变量的说明设置到table中
2.应用层调用setOption设置相应的数据(设置)
3.应用层设置数据到底层,底层走“## 3.底层初始化的时候自动赋值”流程,自动赋值给AVFormatContext结构(自动赋值)
4.底层相应的代码可以使用到设置进来的数据(使用数据)