该函数用于初始化一个视音频编解码器的AVCodecContext。
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
];
  • snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt);
  • av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid or not supported\n",
  • (char *)av_x_if_null(av_get_pix_fmt_name(avctx->pix_fmt), buf));
  • ret = AVERROR(EINVAL);
  • goto free_and_end;
  • }
  • if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
  • avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
  • avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
  • avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
  • avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
  • avctx->color_range = AVCOL_RANGE_JPEG;
  • }
  • 可以看出,该代码首先进入了一个for()循环,将AVCodecContext中设定的pix_fmt与编码器AVCodec中的pix_fmts数组中的元素逐一比较。
    先简单介绍一下AVCodec中的pix_fmts数组。AVCodec中的pix_fmts数组存储了该种编码器支持的像素格式,并且规定以AV_PIX_FMT_NONE(AV_PIX_FMT_NONE取值为-1)为结尾。例如,libx264的pix_fmts数组的定义位于libavcodec\libx264.c,如下所示。
    1. staticconstenum AVPixelFormat pix_fmts_8bit[] = {
    2. AV_PIX_FMT_YUV420P,
    3. AV_PIX_FMT_YUVJ420P,
    4. AV_PIX_FMT_YUV422P,
    5. AV_PIX_FMT_YUVJ422P,
    6. AV_PIX_FMT_YUV444P,
    7. AV_PIX_FMT_YUVJ444P,
    8. AV_PIX_FMT_NV12,
    9. AV_PIX_FMT_NV16,
    10. AV_PIX_FMT_NONE
    11. };
    从pix_fmts_8bit的定义可以看出libx264主要支持的是以YUV为主的像素格式。
    现在回到“检查输入pix_fmt是否符合编码器的要求”的那段代码。如果for()循环从AVCodec->pix_fmts数组中找到了符合AVCodecContext->pix_fmt的像素格式,或者完成了AVCodec->pix_fmts数组的遍历,都会跳出循环。如果发现AVCodec->pix_fmts数组中索引为i的元素是AV_PIX_FMT_NONE(即最后一个元素,取值为-1)的时候,就认为没有找到合适的像素格式,并且最终提示错误信息。
    AVCodec->init()
    avcodec_open2()中最关键的一步就是调用AVCodec的init()方法初始化具体的编码器。AVCodec的init()是一个函数指针,指向具体编解码器中的初始化函数。这里我们以libx264为例,看一下它对应的AVCodec的定义。libx264对应的AVCodec的定义位于libavcodec\libx264.c,如下所示。
    1. AVCodec ff_libx264_encoder = {
    2. .name = "libx264",
    3. .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    4. .type = AVMEDIA_TYPE_VIDEO,
    5. .id = AV_CODEC_ID_H264,
    6. .priv_data_size = sizeof(X264Context),
    7. .init = X264_init,
    8. .encode2 = X264_frame,
    9. .close = X264_close,
    10. .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
    11. .priv_class = &x264_class,
    12. .defaults = x264_defaults,
    13. .init_static_data = X264_init_static,
    14. };
    可以看出在ff_libx264_encoder中init()指向X264_init()。X264_init()的定义同样位于libavcodec\libx264.c,
    X264_init()的代码以后研究X264的时候再进行细节的分析,在这里简单记录一下它做的两项工作:
    (1)设置X264Context的参数。X264Context主要完成了libx264和FFmpeg对接的功能。可以看出代码主要在设置一个params结构体变量,该变量的类型即是x264中存储参数的结构体x264_param_t。
    (2)调用libx264的API进行编码器的初始化工作。例如调用x264_param_default()设置默认参数,调用x264_param_apply_profile()设置profile,调用x264_encoder_open()打开编码器等等。
    X264Context的定义,位于libavcodec\libx264.c,

    avcodec_open2()分析的更多相关文章

    1. FFmpeg 学习(四):FFmpeg API 介绍与通用 API 分析

      一.FFmpeg 相关术语 1. 容器/文件(Container/File):即特定格式的多媒体文件,比如MP4,flv,mov等. 2. 媒体流(Stream):表示在时间轴上的一段连续的数据,比如 ...

    2. FFmpeg源代码简单分析:avcodec_open2()

      ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

    3. 转:LAV Filter 源代码分析

      1: 总体结构 LAV Filter 是一款视频分离和解码软件,他的分离器封装了FFMPEG中的libavformat,解码器则封装了FFMPEG中的libavcodec.它支持十分广泛的视音频格式. ...

    4. 转:XBMC源代码分析

      1:整体结构以及编译方法 XBMC(全称是XBOX Media Center)是一个开源的媒体中心软件.XBMC最初为Xbox而开发,可以运行在Linux.OSX.Windows.Android4.0 ...

    5. 转:ffdshow 源代码分析

      ffdshow神奇的功能:视频播放时显示运动矢量和QP FFDShow可以称得上是全能的解码.编码器.最初FFDShow只是mpeg视频解码器,不过现在他能做到的远不止于此.它能够解码的视频格式已经远 ...

    6. 最新版ffmpeg源码分析

      最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...

    7. FFmpeg资料来源简单分析:libswscale的sws_getContext()

      ===================================================== FFmpeg库函数的源代码的分析文章: [骨架] FFmpeg源码结构图 - 解码 FFmp ...

    8. FFmpeg源码简单分析:libswscale的sws_scale()

      ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

    9. FFmpeg源代码简单分析:libavdevice的gdigrab

      ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

    随机推荐

    1. linux经常使用命令-帮助命令-授之以渔

      原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc 我的虚拟机系统是CentOS.版本号较老,谅解 一.为什么要学习帮助命令?   授人以鱼不如授人以渔.学会了 ...

    2. 批处理脚本一键重置mysql的root密码

      一键重置mysql的root密码的实现脚本. @echo off title mysql ::从注册表找到Mysql的安装路径写入文件mysql.txt reg query HKLM\SYSTEM\C ...

    3. [svc]tomcat目录结构/虚拟主机/nginx反向代理cache配置

      tomcat目录文件 /usr/local/tomcat/bin/catalina.sh stop sleep 3 /usr/local/tomcat/bin/catalina.sh start to ...

    4. Java 格式化数字

      ; ){ DecimalFormat df = "); String xs = df.format(x); System.out.println(xs); x++; } 将 1 格式化为 0 ...

    5. XCode 7 运行 cocos2dx 2.2.6问题小节

      终于磕磕绊绊的在模拟器上,成功运行了已有项目. 公司提供的Mac系统,版本炒鸡低.向同事拷贝了OS,和XCode. 安装完成后,将已有的可以在Windows上成功运行Android版本的项目,拷贝到了 ...

    6. Docker 入门(Mac环境)- part 5 stacks

      part-5 stacks 简介 stack就是栈,栈的结构是什么样的呢?一层一层是紧挨着的,然后互相依赖,不能说中间少了一个.这样说就很明白了,栈实际上在docker中就相当于多个互相依赖的组件,共 ...

    7. Context.startActivity出现AndroidRuntimeException

      转:http://hi.baidu.com/huaxinchang/item/e1a771cf4d424312b77a2416 昨天做了一个Activity的启动动画,效果是点击桌面图标先出现动画后启 ...

    8. Java获取此次请求URL以及服务器根路径的方法

      http://www.jb51.net/article/71693.htm ********************************************** 本文介绍了Java获取此次请求 ...

    9. stm32keilIDE遇到的bug

      最进项目中遇到keil中使用sscanf时,采取类正则表达 %*[^/]/%[^@]时不能正确得到的结果,同样的代码在gcc中运行通过.然后又遇到stm32 keil编译器printf带多个参数就卡死 ...

    10. EntityFramework Model有外键时,Json提示循环引用 解决方法

      正文之前先说两句,距离上篇博客已将近两个月,这方面的学习和探索并没有停止,而是前进道路上遇上了各种各样的问题,需要不断的整理.反思和优化,这段时间的成果,将在最近陆续整理发出来. 个人感觉国内心态太浮 ...