该函数用于初始化一个视音频编解码器的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. wifiphisher 钓鱼工具的使用

      wifiphisher 钓鱼工具的使用一.简介 Wifiphisher是一个安全工具,具有安装快速.自动化搭建的优点,利用它搭建起来的网络钓鱼攻击WiFi可以轻松获得密码和其他凭证.与其它(网络钓鱼) ...

    2. 如何分析Java程序中的死锁

      使用下面方式:产生java的Thread Dump信息 windows平台上:ctrl+break 或者 ctrl+(fn+b)键 Linux平台上:kill -3 pid (查找程序进程id -&g ...

    3. 求最大连续和——dp

      输入一组整数,求出这组数字子序列和中最大值.也就是仅仅要求出最大子序列的和,不必求出最大的那个序列. 比如: 序列:-2 11 -4 13 -5 -2,则最大子序列和为20. 序列:-6 2 4 -7 ...

    4. vivado烧写bin文件到flash 中

      点击 bitstream setting ,将 bin_file 勾上,点击 OK. 2)点击 generate bitstream ,生成 bit 文件和 bin 文件 3)点击 open hard ...

    5. HTML5学习笔记(二十):JavaScript中的标准对象

      这里提到的标准对象指ECMAScript中定义的对象,无论JavaScript运行那种环境(浏览器.Node.js)下都存在的对象. typeof 在JavaScript的世界里,一切都是对象. 但是 ...

    6. VLAN,GRE,VXLAN

      https://www.cnblogs.com/charles1ee/p/6629009.html VLAN介绍 局域网LAN(多个机器连接一个Hub或者Switch),是一个广播域 VLAN:一台S ...

    7. OpenSUSE安装软件

      zypper se xxxxx 是搜索软件包 zypper in xxxxx 跟你的apt-get install xxxx等价 zypper rm xxxx 删除 zypper up xxxx 更新 ...

    8. Arrays.sort()的底层实现

      1.基本类型(以int为例) 源码中的快速排序,主要做了以下几个方面的优化: 1)当待排序的数组中的元素个数较少时,源码中的阀值为7,采用的是插入排序.尽管插入排序的时间复杂度为0(n^2),但是当数 ...

    9. 【转】MySQL查看表占用空间大小(转)

      //先进去MySQL自带管理库:information_schema //自己的数据库:rokid_cas_music_test //自己的表:data_song_thirdparty mysql&g ...

    10. LeetCode: Balanced Binary Tree 解题报告

      Balanced Binary Tree Given a binary tree, determine if it is height-balanced. For this problem, a he ...