在libav中替换已弃用的AVStream编解码器参数

3
很久以前,我实现了一个C++类,用于从图像数组创建MP4视频文件。代码运行得很好,但是我发现了一个我想要消除的弃用警告。AVStream结构中的“codec”参数已被弃用,我想要替换它。
以下是我的当前工作代码:
AVOutputFormat *outputFormat = av_guess_format("ffh264", movieFile.toLocal8Bit().data(), nullptr);
if (!outputFormat)
    return false;

enum AVCodecID videoCodecID = outputFormat->video_codec;

AVCodec *videoCodec = avcodec_find_encoder(videoCodecID);
if (!videoCodec)
    return false;

AVStream *stream = avformat_new_stream(formatContext, videoCodec);
if (!stream)
    return false;

AVCodecContext *videoCodecContext = stream->codec; // <- codec is a deprecated parameter

videoCodecContext->width = videoW;
videoCodecContext->height = videoH;

现在,为了替换"codec"参数,libav开发团队建议使用AVStream结构中包含的"codecpar" (AVCodecParameters) 参数。他们分享的示例如下:

if (avcodec_parameters_to_context(videoCodecContext, stream->codecpar) < 0)
    return nullptr;

注意:codecpar(AVCodecParameters)本身就是一个数据结构。
不幸的是,当我尝试使用该代码时,出现了这个问题:通常,存储在codecpar参数中的所有信息都来自先前打开的视频文件的数据结构。换句话说,信息已经存在。在我的情况下,情况有所不同,因为我正在从头开始创建一个MP4文件,因此没有以前的codecpar记录可用,因此我必须自己创建一个新的AVCodecParameters结构实例,并手动设置每个变量。
到目前为止,我已经能够设置codecpar结构中的所有变量,除了两个变量:
uint8_t * extradata 
int       extradata_size

注意:目前我可以在不设置这些变量的情况下“成功”创建MP4文件,但是该文件不完整。当我试图使用“mplayer”播放它时,会出现以下错误消息:

[extract_extradata @ 0x55b5bb7e45c0] No start code is found.

我正在研究这两个领域,它们似乎存储与编解码器相关的某些信息,而在我的情况下是H264。
因此,我的具体问题是:如果我从头开始设置一个codecpar变量(AVCodecParameters),如何以正确的方式设置extradataextradata_size字段的值,以适用于H264编解码器?
1个回答

2

解决方案:

以下是我遵循的基本步骤列表,成功替换了已弃用的stream->codec数据结构:

  1. Initialize AVFormatContext, AVOutputFormat variables (using av_guess_format and avformat_alloc_output_context2)

  2. Open video codec (using avcodec_find_encoder)

  3. Add/Initialize AVStream variable (using avformat_new_stream)

  4. Initialize AVCodecContext variable (using avcodec_alloc_context3)

  5. Customize AVCodecContext parameters, only if you need to. (In example: width, height, bit_rate, etc)

  6. Add this piece of code:

    if (formatContext->oformat->flags & AVFMT_GLOBALHEADER)
        videoCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
    
  7. Open AVCodecContext variable (using avcodec_open2)

  8. Copy AVCodecContext codecpar structure into AVStream codecpar (using avcodec_parameters_from_context)

从这个点开始,您将能够创建和添加框架到您的输出文件中。
PS:我用来编写此实现的参考示例可在 doc/examples/muxing.c 上找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接