简体   繁体   English

Libav转码为H264:丢帧

[英]Libav Transcoding to H264: Frames being dropped

I'm sorry if my question isn't too well formulated, I'm only now getting started with FFmpeg and Libav. 抱歉,如果我的问题表达得不够好,那么我才开始使用FFmpeg和Libav。 I'm not too knowledgable about media formats either, I pretty much learned all I know about the topic this past month. 我对媒体格式也不太了解,在过去的一个月中,我几乎了解了有关该主题的所有知识。 I've been doing as much research as I can, and have gotten pretty far, but I've only now gotten to the point where I'm almost unsure what my question actually is! 我一直在做尽可能多的研究,并且已经走了很远,但是直到现在我几乎不确定我的问题到底是什么! These are more like observations, but hopefully some of the experts can help me out here. 这些更像是观察,但是希望一些专家可以在这里帮助我。

I'm trying to transcode Gifs into MP4s using FFmpeg's libraries, but I'm running into a strange issue when using the H264 Codec. 我正在尝试使用FFmpeg的库将Gifs转换为MP4,但是在使用H264编解码器时遇到了一个奇怪的问题。 In my transcoding loop, I keep a count of the number of frames that I write out (by verifying the return value of av_write_frame). 在我的代码转换循环中,我保留我写出的帧数(通过验证av_write_frame的返回值)。 In a particular sample, I count a total of 166 frames written out. 在一个特定的样本中,我算出总共写入了166帧。 If I examine FFmpeg's converted file using FFprobe (the functionality I'm wanting to emulate using my program, a conversion from Gif to MP4), FFmpeg's output file also seems to have 166 frames, but when I examine my output with FFprobe, I seem to only have 144 frames. 如果我使用FFprobe(我想用我的程序模拟的功能,从Gif到MP4的转换)检查FFmpeg的转换文件,则FFmpeg的输出文件似乎也有166帧,但是当我用FFprobe检查输出时,我似乎只有144帧。 What I find a bit interesting is that if I simply change my codec from H264 to MPEG4, my output appears to have the 166 frames, matching FFmpeg's output and my counter. 我发现有点有趣的是,如果我只是将编解码器从H264更改为MPEG4,则我的输出似乎具有166帧,与FFmpeg的输出和我的计数器匹配。 I get very similar results with different Gif files, where my counter of frames written matches FFmpeg's output's frame count, but my output seems to drop some frames. 在不同的Gif文件中,我得到的结果非常相似,其中我写入的帧计数器与FFmpeg输出的帧计数匹配,但是我的输出似乎丢失了一些帧。

Encoder settings: 编码器设置:

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;    

Transcoding loop: 转码循环:

I've omitted some error-checking code and debugging statements 我省略了一些错误检查代码和调试语句

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);
}

I'm also having issues with my output's bit-rate. 我的输出的比特率也有问题。 I can try setting it with the rest of my encoder settings, but the bit-rate that FFprobe shows is not the same as what I give the codec context. 我可以尝试用我的编码器设置,其余的设置,但比特率FFprobe显示是一样的。我拿什么编解码器上下文。 I tried setting the bit-rate to constant values just to see how it affected my output, and although my output's bit-rate isn't the same as what I give it, I found that my input definitely seems to influence the output's actual bit-rate. 我尝试将位速率设置为恒定值,只是为了查看它如何影响输出,尽管我的输出的位速率与给出的值不同,但是我发现我的输入确实会影响输出的实际位-率。 I found a post that seems to be dealing with my issue, but the solution listed there does not seem to fix my issue. 我发现有一篇帖子似乎在解决我的问题,但是那里列出的解决方案似乎无法解决我的问题。

http://ffmpeg.org/pipermail/libav-user/2012-July/002492.html http://ffmpeg.org/pipermail/libav-user/2012-July/002492.html

Another thing worth mentioning is that my various time bases don't seem to match up with those of FFmpeg's output. 值得一提的另一件事是,我的各种时基似乎与FFmpeg的输出不匹配。 Notably, my output's TBC seems to be twice the inverse of my output codec context's time base. 值得注意的是,我的输出的TBC似乎是我的输出编解码器上下文时基的两倍。 I'm not too sure if this is an issue with the Gif file format, my output codec context's always seems to be set to 1/100. 我不太确定这是否是Gif文件格式的问题,我的输出编解码器上下文似乎总是设置为1/100。

Bit-rate calculation and setting 比特率计算和设置

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;

I've got a hunch that all these issues could be related to me not setting my PTS/DTS correctly, even though my output's pts/dts values match those of FFmpeg's output. 我直觉所有这些问题可能与我没有正确设置PTS / DTS有关,即使我的输出的pts / dts值与FFmpeg的输出匹配。

I would appreciate some help, Thank you! 我将不胜感激,谢谢!

Using libx264 for output you may need to manually rescale the timestamps as I describe in this answer . 使用libx264进行输出时,您可能需要手动重新调整时间戳,如我在此答案中所述 This could explain your bitrate problem. 这可以解释您的比特率问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM