该函数用于初始化一个视音频编解码器的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. JAXB--@XmlType注解标注xml生成顺序

      默认情况下,Jaxb编组出来的xml中的字段顺序是随机的,你可以使用@XmlType的propOrder属性 来指定序列化的顺序.   第一步:定义java类时,使用@XmlType(propOrde ...

    2. 【Unity】12.2 导航网格寻路简单示例

      开发环境:Win10.Unity5.3.4.C#.VS2015 创建日期:2016-05-09 一.简介 本节通过一个简单例子,演示如何利用静态对象实现导航网格,并让某个动态物体利用导航网格自动寻路, ...

    3. RVM切换ruby版本号

      RVM是Ruby Version Manager的缩写,是一个命令行工具,它能够让你轻松地安装,管理和使用多个版本号的Ruby.不同的rails项目使用等ruby和rails版本号不一样的时候.能够使 ...

    4. ssh以密钥的方式登录服务器时,只要有密钥可以登服务器,如果有密钥和公钥同时存在(在公钥没问题的情况下可以),但如果公钥有问题,就不能登录成功

      在~/.ssh/下如果只有密钥或公私同时存在时,都可以成功登录服务器,但!!!!!!如果公钥有换成别的服务器的公钥时,是无法登录远程的服务器!!!!

    5. 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理

      之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...

    6. Flink KAFKA

      https://data-artisans.com/blog/kafka-flink-a-practical-how-to https://github.com/dataArtisans/kafka- ...

    7. numpy数组-标准化数据

      标准化数据的公式: (数据值 - 平均数) / 标准差 import numpy as np employment = np.array([ 55.70000076, 51.40000153, 50. ...

    8. 京东轮播图片的静态页面CSS3

      效果图: index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

    9. VS调试dll

      (ps:编译dll的工程最好配置一下预编译宏:“配置属性”/“C或C++”/“预处理器”/“预处理器定义”,选择编辑,在最下面加一行“_CRT_SECURE_NO_WARNINGS”) 1. 右键dl ...

    10. 【delphi】多线程同步之Semaphore

      另外两种多线程的同步方法 CriticalSection(临界区) 和 Mutex(互斥), 这两种同步方法差不多, 只是作用域不同; CriticalSection(临界区) 类似于只有一个蹲位的公 ...