对不起,如果我的问题没有得到很好的表述,我现在才开始使用FFmpeg和Libav。我对媒体格式也不太了解,过去一个月我几乎了解了这个话题。我已经做了尽可能多的研究,而且已经走得很远了,但我现在才刚刚到达我几乎不确定我的问题实际上是什么的地步!这些更像是观察,但希望有些专家可以帮助我。
我尝试使用FFmpeg的库将Gif转码为MP4,但在使用H264 Codec时我遇到了一个奇怪的问题。在我的代码转换循环中,我保留了我写出的帧数(通过验证av_write_frame的返回值)。在特定的样本中,我总共计算出166帧。如果我使用FFprobe检查FFmpeg的转换文件(我希望使用我的程序模拟的功能,从Gif到MP4的转换),FFmpeg的输出文件似乎也有166帧,但是当我用FFprobe检查输出时,我似乎只有144帧。我觉得有点有趣的是,如果我只是将我的编解码器从H264改为MPEG4,我的输出似乎有166帧,匹配FFmpeg的输出和我的计数器。我得到了与不同Gif文件非常相似的结果,其中我写的帧计数器与FFmpeg的输出帧数相匹配,但我的输出似乎丢失了一些帧。
编码器设置:
ostream_codec_context->codec_id = CODEC_IN_USE; //CODEC_ID_H264 or CODEC_ID_MPEG4
ostream_codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
ostream_codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
ostream_codec_context->flags = CODEC_FLAG_GLOBAL_HEADER;
ostream_codec_context->profile = FF_PROFILE_MPEG4_SIMPLE;
ostream_codec_context->gop_size = istream_codec_context->gop_size;
ostream_codec_context->time_base = istream_codec_context->time_base;
ostream_codec_context->width = (istream_codec_context->width / 2) * 2;
ostream_codec_context->height = (istream_codec_context->height / 2) * 2;
转码循环:
我省略了一些错误检查代码和调试语句
avformat_write_header(oformat_context, NULL);
while (av_read_frame(iformat_context, &packet) == 0 )
{
if (packet.stream_index == istream_index)
{
avcodec_decode_video2(istream_codec_context, ipicture, &full_frame, &packet);
if (full_frame)
{
sws_scale(image_conversion_context,
(uint8_t const * const *) ipicture->data,
ipicture->linesize, 0, istream_codec_context->height,
opicture->data, opicture->linesize);
opicture->pts = av_rescale_q(packet.pts, istream_codec_context->time_base,
ostream->time_base);
ret = avcodec_encode_video2(ostream_codec_context, &packet,
opicture, &got_packet);
if (!ret)
{
ret = av_write_frame(oformat_context, &packet);
if (ret < 0)
num_frames_written++;
}
}
}
av_free_packet(&packet);
av_init_packet(&packet);
}
我的输出比特率也有问题。我可以尝试使用其余的编码器设置来设置它,但FFprobe显示的比特率不与我给编解码器上下文相同。我尝试将比特率设置为常数,只是为了看看它如何影响我的输出,虽然我的输出的比特率与我给它的相同,我发现我的输入肯定似乎影响输出的实际比特率。我发现了一篇似乎正在处理我的问题的帖子,但是那里列出的解决方案似乎没有解决我的问题。
http://ffmpeg.org/pipermail/libav-user/2012-July/002492.html
值得一提的另一件事是,我的各个时间基础似乎与FFmpeg的输出相匹配。值得注意的是,我输出的TBC似乎是输出编解码器上下文的时基的两倍。我不太确定这是否是Gif文件格式的问题,我的输出编解码器上下文似乎总是设置为1/100。
比特率计算和设置
int calculated_br = istream_codec_context->time_base.den *
avpicture_get_size(AV_PIX_FMT_YUV420P, ostream_codec_context->width,
ostream_codec_context->height);
ostream_codec_context->bit_rate = calculated_br;
ostream_codec_context->rc_min_rate = calculated_br;
ostream_codec_context->rc_max_rate = calculated_br;
ostream_codec_context->rc_buffer_size = calculated_br;
即使我的输出的pts / dts值与FFmpeg输出的值相匹配,我还是预感到所有这些问题都与我没有正确设置PTS / DTS有关。
我很感激一些帮助, 谢谢!