如何使用libavcodec设置输出帧时间?

问题描述 投票:0回答:1

我正在使用 libavcodec 来编码一些 mp4 (视频格式为 AV_CODEC_ID_MPEG4).下面的代码运行得很好,没有异常警告,但输出文件却以90000 FPS的速度编码。

// Please note averror(...) is a simple utility
// function which throws on errors...
const char  *outfile = "output.mp4";
AVFormatContext *octx_ = 0;
averror(avformat_alloc_output_context2(&octx_, 0, 0, outfile));
std::unique_ptr<AVFormatContext, void(*)(AVFormatContext*)> octx(octx_, [](AVFormatContext* p){ if(p) avformat_close_input(&p); });
AVStream    *strm = avformat_new_stream(octx.get(), 0);
if(!strm)
    throw std::runtime_error("avformat_new_stream");
auto        *penc = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
if(!penc)
    throw std::runtime_error("avcodec_find_encoder");
auto        *pc = avcodec_alloc_context3(penc);
std::unique_ptr<AVCodecContext, void(*)(AVCodecContext*)>   ocodec(pc, [](AVCodecContext* p){ if(p) avcodec_free_context(&p); });
// setup additinal info about codec
ocodec->pix_fmt  = AV_PIX_FMT_YUV420P;
//ocodec->bit_rate = 400000;
ocodec->width = 3440;
ocodec->height = 1440;
ocodec->time_base = (AVRational){1, 60}; // this doesn't work...
ocodec->framerate = (AVRational){60, 1}; // nor this...
// fix about global headers
if(octx->oformat->flags & AVFMT_GLOBALHEADER)
    octx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
// bind context codec
averror(avcodec_open2(ocodec.get(), penc, 0));
// fill in the context parameters
averror(avcodec_parameters_from_context(strm->codecpar, ocodec.get()));

我怎样才能设置为60 FPS呢,上面的代码似乎没有任何效果。

我设法让它工作的唯一方法是使用过时的代码,而不是分配我自己的编解码器结构并将其关联起来,只需修改上下文中的一个(类似于上面的片段,中间部分)。

if(!penc)
   throw std::runtime_error("avcodec_find_encoder");
//auto      *pc = avcodec_alloc_context3(penc);
//std::unique_ptr<AVCodecContext, void(*)(AVCodecContext*)> ocodec(pc, [](AVCodecContext* p){ if(p) {avcodec_free_context(&p);} });
// setup additinal info about codec
AVCodecContext  *ocodec = strm->codec; // this is deprecated!
ocodec->codec_id = AV_CODEC_ID_MPEG4;
ocodec->codec_type = AVMEDIA_TYPE_VIDEO;
ocodec->pix_fmt  = AV_PIX_FMT_YUV420P;
ocodec->bit_rate = 400000;
ocodec->width = 3440;
ocodec->height = 1440;
ocodec->gop_size = 3;
ocodec->max_b_frames = 2;
ocodec->time_base.num = 1;
ocodec->time_base.den = 60;

不知道下一步该怎么做,上面的代码有一个废弃的方式来关联编解码器和容器... ...

c++ mp4 frame-rate libav libavcodec
1个回答
1
投票

你需要将时间戳设置在...上。AVPacket 呼叫前 av_write_frame()av_interleaved_write_frame()

© www.soinside.com 2019 - 2024. All rights reserved.