当前位置: 首页 > news >正文

网站设计与建设的公司欧洲站fba

网站设计与建设的公司,欧洲站fba,wordpress 动作,懂装修公司怎么样引言 在使用 ijkplayer 时我们可以对其做一些参数配置,用以开启或关闭某些功能模块,或选择使用某种方式。比如通过参数配置使用硬解码还是软解码,Android 音频播放使用 AudioTrack 还是 OpenSL,是否启用 SoundTouch 等等。那 ijk…

引言

在使用 ijkplayer 时我们可以对其做一些参数配置,用以开启或关闭某些功能模块,或选择使用某种方式。比如通过参数配置使用硬解码还是软解码,Android 音频播放使用 AudioTrack 还是 OpenSL,是否启用 SoundTouch 等等。那 ijkplayer 有哪些参数配置?各个参数有什么作用?有哪些常用的参数配置呢?

本文是基于 A4ijkplayer 项目进行 ijkplayer 源码分析,该项目是将 ijkplayer 改成基于 CMake 编译,可导入 Android Studio 编译运行,方便代码查找、函数跳转、单步调试、调用栈跟踪等。

本文主要内容结构:

  • 一、ijkplayer 常用参数设置
  • 二、ijkplayer 参数设置流程
  • 三、ijkplayer 的五类参数设置及各参数作用

一、ijkplayer 常用参数设置

// OPT_CATEGORY_PLAYER 类的参数设置// 是否开启 Mediacodec 硬解,1 为开启,0 为关闭
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
// 关闭 Mediacodec 硬解,使用 FFmpeg 软解
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);// 音频播放是否使用 openSL,1:使用 openSL,0:使用 AudioTrack
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1);// 当 CPU 处理不过来的时候的丢帧帧数,默认为 0,参数范围是 [-1, 120],详情见:ff_ffplay_options.h
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 5);// 在资源准备好后是否自动播放,1:自动播放,0:准备好后不自动播放
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1);// 使用 mediacodec 时是否根据 meta 信息自动旋转视频
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);// 使用 mediacodec 时是否处理分辨率改变
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0);// 设置视频显示格式
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);// 是否开启精准 seek,默认关闭
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1)// 是否启用 soundtouch,配合 setSpeed 实现变速播放
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1)
ijkMediaPlayer.setSpeed(0.5f);// OPT_CATEGORY_CODEC 类的参数设置// 是否开启跳过 loop filter,0 为开启,画面质量高,但解码开销大,48 为关闭,画面质量稍差,但解码开销小
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 0);// OPT_CATEGORY_FORMAT 类的参数设置// 设置探测输入的分析时长,单位:微秒,详情见:libavformat/options_table.h,通常设置 1 达到首屏秒开效果
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);// 在每个数据包之后启用 I/O 上下文的刷新
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1);

二、ijkplayer 参数设置流程

先看 Java 层 IjkMediaPlayer.java 中参数设置接口的定义:

    public void setOption(int category, String name, String value) {_setOption(category, name, value);}public void setOption(int category, String name, long value) {_setOption(category, name, value);}private native void _setOption(int category, String name, String value);private native void _setOption(int category, String name, long value);

上面两个接口类似,都是 category、key、value 的形式,区别在于 value 是 String 型还是 long 型。可以看出它有三个参数:

  • category:要设置的参数的大的分类,ijkplayer 中一共定义了五类,后文会详细介绍:
    • format: FFP_OPT_CATEGORY_FORMAT 1
    • codec: FFP_OPT_CATEGORY_CODEC 2
    • sws: FFP_OPT_CATEGORY_SWS 3
    • player: FFP_OPT_CATEGORY_PLAYER 4
    • swr: FFP_OPT_CATEGORY_SWR 5
  • key:大类下要设置的参数的 key
  • value:大类下要设置的参数的 value

2.1 保存上层设置的参数

Java 层调用 _setOption 后会调到 ijkmedia/ijkplayer/android/ijkplayer_jni.c 中的 IjkMediaPlayer_setOption() 方法,如下:

static void
IjkMediaPlayer_setOption(JNIEnv *env, jobject thiz, jint category, jobject name, jobject value)
{// ...c_name = (*env)->GetStringUTFChars(env, name, NULL );c_value = (*env)->GetStringUTFChars(env, value, NULL );// ...ijkmp_set_option(mp, category, c_name, c_value);// ...
}static void
IjkMediaPlayer_setOptionLong(JNIEnv *env, jobject thiz, jint category, jobject name, jlong value)
{// ...c_name = (*env)->GetStringUTFChars(env, name, NULL );// ...ijkmp_set_option_int(mp, category, c_name, value);
}

接着会调到 ijkmedia/ijkplayer/ijkplayer.cijkmp_set_option() 方法:

void ijkmp_set_option(IjkMediaPlayer *mp, int opt_category, const char *name, const char *value)
{pthread_mutex_lock(&mp->mutex);ffp_set_option(mp->ffplayer, opt_category, name, value);pthread_mutex_unlock(&mp->mutex);
}void ijkmp_set_option_int(IjkMediaPlayer *mp, int opt_category, const char *name, int64_t value)
{pthread_mutex_lock(&mp->mutex);ffp_set_option_int(mp->ffplayer, opt_category, name, value);pthread_mutex_unlock(&mp->mutex);
}

再调到 ijkmedia/ijkplayer/ff_ffplay.cffp_set_option() 方法,实际是调用 ijkmedia/ijkplayer/ff_ffplay.c 中的 ffp_get_opt_dict() 获取 FFPlayer 中对应大类的字典然后把参数按照分类保存起来:

void ffp_set_option(FFPlayer *ffp, int opt_category, const char *name, const char *value)
{AVDictionary **dict = ffp_get_opt_dict(ffp, opt_category);av_dict_set(dict, name, value, 0);
}void ffp_set_option_int(FFPlayer *ffp, int opt_category, const char *name, int64_t value)
{AVDictionary **dict = ffp_get_opt_dict(ffp, opt_category);av_dict_set_int(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;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;default:av_log(ffp, AV_LOG_ERROR, "unknown option category %d\n", opt_category);return NULL;}
}

2.2 应用设置的参数

setOption() 执行完后只是将参数保存了,那在什么地方用,怎么用呢?

1 FFP_OPT_CATEGORY_FORMAT 参数的应用

从上一节可以看出 format 相关参数是保存在 ffp->format_opts 中,其应用是在 prepareAsync() 准备资源,调用 FFmpeg 的 avformat_open_input() 打开输入流时设置给 FFmpeg 内部用。

static int read_thread(void *arg)
{// ...err = avformat_open_input(&ic, is->filename, is->iformat, &ffp->format_opts);// ...
}

2 FFP_OPT_CATEGORY_CODEC 参数的应用

从上一节可以看出 codec 相关参数是保存在 ffp->codec_opts 中,其应用是在 prepareAsync() 准备资源,调用 FFmpeg 打开解码器以及获取流信息时使用。

static int stream_component_open(FFPlayer *ffp, int stream_index)
{// ...opts = filter_codec_opts(ffp->codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);// ...if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {goto fail;}
}
static int read_thread(void *arg)
{// ...if (ffp->find_stream_info) {AVDictionary **opts = setup_find_stream_info_opts(ic, ffp->codec_opts);// ...do {// ...err = avformat_find_stream_info(ic, opts);} while(0);}// ...
}

3 FFP_OPT_CATEGORY_SWS 参数的应用

从上一节可以看出 sws 相关参数是保存在 ffp->sws_dict 中,该类参数在 ijkplayer 中并没有真正使用,只在 prepareAsync() 准备资源时做了参数打印输出。

int ffp_prepare_async_l(FFPlayer *ffp, const char *file_name)
{// ...av_log(NULL, AV_LOG_INFO, "===== options =====\n");ffp_show_dict(ffp, "player-opts", ffp->player_opts);ffp_show_dict(ffp, "format-opts", ffp->format_opts);ffp_show_dict(ffp, "codec-opts ", ffp->codec_opts);ffp_show_dict(ffp, "sws-opts   ", ffp->sws_dict);ffp_show_dict(ffp, "swr-opts   ", ffp->swr_opts);// ...
}

4 FFP_OPT_CATEGORY_PLAYER 参数的应用

从上一节可以看出 player 相关参数是保存在 ffp->player_opts 中,其应用是在 prepareAsync() 准备资源时保存到 FFplayer 对应的成员变量中:

int ffp_prepare_async_l(FFPlayer *ffp, const char *file_name)
{// ...av_log(NULL, AV_LOG_INFO, "===== options =====\n");ffp_show_dict(ffp, "player-opts", ffp->player_opts);// ...av_opt_set_dict(ffp, &ffp->player_opts);// ...
}/*** Set all the options from a given dictionary on an object.** @param obj a struct whose first element is a pointer to AVClass* @param options options to process. This dictionary will be freed and replaced*                by a new one containing all options not found in obj.*                Of course this new dictionary needs to be freed by caller*                with av_dict_free().** @return 0 on success, a negative AVERROR if some option was found in obj,*         but could not be set.** @see av_dict_copy()*/
int av_opt_set_dict(void *obj, struct AVDictionary **options);

av_opt_set_dict() 是 FFmpeg 的 libavutil/opt.h 中定义的函数,从其函数说明可以看到,它是把字典中的所有 options 设置到传入的对象中,这里也就是 FFPlayer ,其他模块的 options 实际上也是通过该函数保存到各自的对象中的。那它们是怎么保存的呢?

可以看该函数第一个参数的说明,通过传入对象结构的第一个元素 AVClass

@param obj a struct whose first element is a pointer to AVClass

那我们看下 FFPlayer 结构体,在 ijkmedia/ijkplayer/ff_ffplay_def.h 中定义:

typedef struct FFPlayer {const AVClass *av_class;// ...
} FFPlayer;

在看 av_class 的使用,在 ijkmedia/ijkplayer/ff_ffplay.c 文件中:

FFPlayer *ffp_create()
{// ...ffp->av_class = &ffp_context_class;// ...
}const AVClass ffp_context_class = {.class_name       = "FFPlayer",.item_name        = ffp_context_to_name,.option           = ffp_context_options,.version          = LIBAVUTIL_VERSION_INT,.child_next       = ffp_context_child_next,.child_class_next = ffp_context_child_class_next,
};

这里终于看到了 option 的使用:

.option           = ffp_context_options,

接着看 ffp_context_options ,在 ijkmedia/ijkplayer/ff_ffplay_options.h 中定义,可以看到我们常用的参数的定义和说明(完整参数请看后文内容):

static const AVOption ffp_context_options[] = {// original options in ffplay.c{ "an",                             "disable audio", OPTION_OFFSET(audio_disable),   OPTION_INT(0, 0, 1) },{ "vn",                             "disable video", OPTION_OFFSET(video_disable),   OPTION_INT(0, 0, 1) },// ...{ "framedrop",                      "drop frames when cpu is too slow", OPTION_OFFSET(framedrop),       OPTION_INT(0, -1, 120) },// ...{ "start-on-prepared",                  "automatically start playing on prepared", OPTION_OFFSET(start_on_prepared),   OPTION_INT(1, 0, 1) },// ...{ "enable-accurate-seek",                      "enable accurate seek", OPTION_OFFSET(enable_accurate_seek),       OPTION_INT(0, 0, 1) },// ...{ "mediacodec",                             "MediaCodec: enable H264 (deprecated by 'mediacodec-avc')", OPTION_OFFSET(mediacodec_avc),          OPTION_INT(0, 0, 1) },// ...{ "opensles",                           "OpenSL ES: enable", OPTION_OFFSET(opensles),            OPTION_INT(0, 0, 1) },{ "soundtouch",                           "SoundTouch: enable", OPTION_OFFSET(soundtouch_enable),OPTION_INT(0, 0, 1) },// ...
}

其中每一行的结构如下:
{name, help, offset, type, default_val, min, max, …}

  • name:就是要设置的参数的 key
  • help:该参数的帮助说明
  • offset:当前参数对应的成员变量在结构体中的偏移,这样就可以在调用 av_opt_set_dict() 时把字典中 key 对应的参数值存入到结构体对象对应的成员变量中。比如,如果外面设置了 “opensles” 的 option,那么就可以根据偏移 OPTION_OFFSET(opensles) 映射到 FFplayer 结构体中的 opensles 成员变量,FFmpeg 中参数设置都是这种模式。
    typedef struct FFPlayer {const AVClass *av_class;// ...int opensles;int soundtouch_enable;// ...
    } FFPlayer;
    
  • type:参数的数据类型
  • default_val:参数的默认值
  • min:参数最小值
  • max:参数最大值

5 FFP_OPT_CATEGORY_SWR 参数的应用

从上一节可以看出 sws 相关参数是保存在 ffp->swr_opts 中,该类参数在 ijkplayer 中并没有真正使用,而且 Java 上层的 IjkMediaPlayer 中并没有定义该类型。

三、ijkplayer 的五类参数设置及各参数作用

FFP_OPT_CATEGORY_FORMATFFP_OPT_CATEGORY_CODECFFP_OPT_CATEGORY_SWSFFP_OPT_CATEGORY_PLAYERFFP_OPT_CATEGORY_SWR 这五类其实只有 FFP_OPT_CATEGORY_PLAYER 是 ijkplayer 自己参考 FFmpeg 参数结构设计的,其他四个都是 FFmpeg 原有的参数。

1 FFP_OPT_CATEGORY_FORMAT 完整参数

是 FFmpeg libavformat 模块相关参数,其完整参数见 FFmpeg 源码中的:libavformat/options_table.h

https://github.com/bilibili/FFmpeg/blob/ff4.0--ijk0.8.8--20210426--001/libavformat/options_table.hstatic const AVOption avformat_options[] = {
{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
{"formatprobesize", "number of bytes to probe file format", OFFSET(format_probesize), AV_OPT_TYPE_INT, {.i64 = PROBE_BUF_MAX}, 0, INT_MAX-1, D},
{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, E},
// ...
}

2 FFP_OPT_CATEGORY_CODEC 完整参数

是 FFmpeg libavcodec 模块相关参数,其完整参数见 FFmpeg 源码中的:libavcodec/options_table.h

https://github.com/bilibili/FFmpeg/blob/ff4.0--ijk0.8.8--20210426--001/libavcodec/options_table.hstatic const AVOption avcodec_options[] = {
{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
// ...
{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
{"skip_idct"       , "skip IDCT/dequantization for the selected frames",    OFFSET(skip_idct),        AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
{"skip_frame"      , "skip decoding for the selected frames",               OFFSET(skip_frame),       AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},// ...
}

3 FFP_OPT_CATEGORY_SWS 完整参数

是 FFmpeg libswscale 模块相关参数,其完整参数见 FFmpeg 源码中的:libswscale/options.c

https://github.com/bilibili/FFmpeg/blob/ff4.0--ijk0.8.8--20210426--001/libswscale/options.c
static const AVOption swscale_options[] = {{ "sws_flags",       "scaler flags",                  OFFSET(flags),     AV_OPT_TYPE_FLAGS,  { .i64  = SWS_BICUBIC        }, 0,      UINT_MAX,        VE, "sws_flags" },{ "fast_bilinear",   "fast bilinear",                 0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_FAST_BILINEAR  }, INT_MIN, INT_MAX,        VE, "sws_flags" },{ "bilinear",        "bilinear",                      0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_BILINEAR       }, INT_MIN, INT_MAX,        VE, "sws_flags" },// ...
}

4 FFP_OPT_CATEGORY_PLAYER 完整参数

是 ijkplayer 自身配置的相关参数,其完整参数见 ijkplayer 源码中的:ijkmedia/ijkplayer/ff_ffplay_options.h

https://github.com/Bilibili/ijkplayer/blob/k0.8.8/ijkmedia/ijkplayer/ff_ffplay_options.h
static const AVOption ffp_context_options[] = {// original options in ffplay.c{ "an",                             "disable audio", OPTION_OFFSET(audio_disable),   OPTION_INT(0, 0, 1) },{ "vn",                             "disable video", OPTION_OFFSET(video_disable),   OPTION_INT(0, 0, 1) },// ...{ "framedrop",                      "drop frames when cpu is too slow", OPTION_OFFSET(framedrop),       OPTION_INT(0, -1, 120) },// ...{ "start-on-prepared",                  "automatically start playing on prepared", OPTION_OFFSET(start_on_prepared),   OPTION_INT(1, 0, 1) },// ...{ "enable-accurate-seek",                      "enable accurate seek", OPTION_OFFSET(enable_accurate_seek),       OPTION_INT(0, 0, 1) },// ...{ "mediacodec",                             "MediaCodec: enable H264 (deprecated by 'mediacodec-avc')", OPTION_OFFSET(mediacodec_avc),          OPTION_INT(0, 0, 1) },// ...{ "opensles",                           "OpenSL ES: enable", OPTION_OFFSET(opensles),            OPTION_INT(0, 0, 1) },{ "soundtouch",                           "SoundTouch: enable", OPTION_OFFSET(soundtouch_enable),OPTION_INT(0, 0, 1) },// ...
}

5 FFP_OPT_CATEGORY_SWR 完整参数

是 FFmpeg libswresample 模块相关参数,其完整参数见 FFmpeg 源码中的:libswresample/options.c

https://github.com/bilibili/FFmpeg/blob/ff4.0--ijk0.8.8--20210426--001/libswresample/options.c
static const AVOption options[]={
{"ich"                  , "set input channel count"     , OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0                    }, 0      , SWR_CH_MAX, PARAM},
{"in_channel_count"     , "set input channel count"     , OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0                    }, 0      , SWR_CH_MAX, PARAM},
{"och"                  , "set output channel count"    , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0                    }, 0      , SWR_CH_MAX, PARAM},
{"out_channel_count"    , "set output channel count"    , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0                    }, 0      , SWR_CH_MAX, PARAM},
// ...
}
http://www.lbrq.cn/news/2703943.html

相关文章:

  • 成都定制网站建设营销qq下载
  • 网站建设计划书查网站权重
  • 做基网站外贸seo
  • 个人网站设计风格杭州龙席网络seo
  • 网站的标题可以改吗b站引流推广网站
  • 烟台网站建设的方法有哪些百度授权代理商
  • 职业病院网站建设线上销售水果营销方案
  • 拖拽网站关键词挖掘长尾词工具
  • 孙俪做的网站广告买卖交易平台
  • 彩票网站的表格是如何做的百度竞价推广怎么样才有效果
  • 湘潭做网站公司互联网广告代理
  • 廊坊做网站哪家好色盲悖论
  • asp.net做电商网站页面设计seo岗位培训
  • 茂名放心营销网站开发海南百度推广运营中心
  • 哪里找需要网站建设的网站建设的技术支持
  • 如何加强精神文明网站建设内容凡科网
  • 使用flash做网站seo北京公司
  • 网站建设重要新拉新推广怎么做代理
  • 网站建设管理员角色设置营销网站建设的因素
  • 宿迁明远建设有限公司网站河北百度推广客服电话
  • 专门做推广的网站家居seo整站优化方案
  • 定制手机微网站地推接单平台
  • h5响应式集团网站推荐域名ip查询入口
  • 工程建设标准网官方网站经营管理培训课程
  • wordpress s3插件南宁网站seo
  • 源码怎么做成网站商业软文代写
  • 泉州建设网站公司乔拓云智能建站
  • 经典网站案例制作一个网站的全过程
  • wordpress导航页面样式长春做网络优化的公司
  • 没有域名可以先做网站吗sem是什么设备
  • C++中的`auto`与`std::any`:功能、区别与选择建议
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day3
  • 西门子S7-200与S7-1200通过PPI以太网模块通讯,赋能汽车制造行业发展
  • Git 常用命令速查表
  • 【代码随想录day 17】 力扣 98.验证二叉搜索树
  • 【13-向量化-高效计算】