使用ffmpeg API的MPEG-2视频编码:比ffmpeg.exe更大的文件大小

时间:2011-05-26 12:22:11

标签: api encoding ffmpeg filesize

我正在尝试使用ffmpeg API将视频从原始YUV编码为MPEG-2。

我的问题是 API 生成的文件大约是。比 ffmpeg 生成的等效文件大1.7倍。

我使用量化参数(通过qminqmax)而不是比特率。

API -version基本上是:

//...
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
pCodecCtx->qmin = 3;
pCodecCtx->qmax = 3;
pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = 30;
avcodec_open(pCodecCtx, avcodec_find_encoder(CODEC_ID_MPEG2VIDEO));
//...
while(/*...*/) {
  avcodec_encode_video(pCodecCtx, pOutbuf, outbufSize, pPicture);
  //..
}
//...

对于 ffmpeg 本身,我使用命令:

ffmpeg -s 352x288 -r 30 -i foreman_352x288.yuv -f mpeg2video -vcodec mpeg2video -r 30 -pix_fmt yuv420p -qmin 3 -qmax 3 foreman.m2v

为什么 API 生成文件的比特率为5212 kb / s,而 ffmpeg 生成的文件的相同qp比特率为3047 kb / s的??

(更令人费解的是,较小的 ffmpeg 版本具有稍高的PSNR,40.49 dB与40.02 dB相比)。

我错过了其他相关参数吗? ffmpeg 实际上是否尊重量化参数?

1 个答案:

答案 0 :(得分:1)

使用ffmpeg API时,需要为每个帧手动设置图片类型(I帧,P帧等)。默认情况下,ffmpeg将使每个帧成为I帧。

解决方案是在编码帧之前设置图片类型(此处GOP大小为12):

//...
while(/*...*/) {
  if(pCodecCtx->frame_number % 12) 
    pPicture->pict_type = AV_PICTURE_TYPE_P;

  avcodec_encode_video(pCodecCtx, pOutbuf, outbufSize, pPicture);
  //...
}
//...

请注意,在编码之前设置pCodecCtx->gop_size无效。