[Libav-user] Transcoding frame rate mismatch

James Crisafulli james2048 at gmail.com
Tue Nov 5 13:34:24 EET 2019


Hi,

I used to have the same issue with my application, which I based on
transcoding.c (not transcoding but anyways, writing H264 to MP4 file).
You need to set the AVPacket duration field, for some reason it shows this
issue if you let it automatically set it (set to -1).
I had to do this both using libx264 and mpeg4 encoders.

Example in my code from the muxing section:

av_packet_rescale_ts(&packet, codecCtx->time_base, stream->time_base);
packet.stream_index = 0;
// probably best to write this as av_rescale_* functions, but this is old
code
// for example, if 25 FPS, and time_base is 12800, then packet.duration =
12800 / 25 = 512
packet.duration = stream->time_base.den / stream->time_base.num /
stream->avg_frame_rate.num * stream->avg_frame_rate.den;
// now you can mux
ret = av_interleaved_write_frame(formatCtx, &packet);

I am not sure why this is needed, I found this in another codebase with a
similar comment, and it fixed my issue.

Might as well mention that in transcoding.c, it also doesn't set the
GLOBAL_HEADER flag at the right time, and as such you get a malformed file
if writing MP4 format. I noticed it wouldn't open in Adobe Premiere, and
Windows 10 Films & TV player, and ffprobe had warnings about it as well but
did manage to read it.

// TOO LATE! has to be done before avcodec open!! In transcoding.c, it does
this after the call and as such the flags are ignored.
if (formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

To fix that, I have hard coded the flag early when I know I am writing MP4,
before avcodec_open():

codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
AVDictionary *encoderOpts = nullptr;
ret = avcodec_open2(codecCtx, codecCtx->codec, &encoderOpts);

And now everything works well for me. Hopefully it fixed the issues for you
as well.
Would be nice to see transcoding.c updated to fix these small issues as it
is used as a base by so many people looking into libav* development.

- James

On Tue, 5 Nov 2019 at 11:07, Vassilis <bpantazhs at gmail.com> wrote:

> This can not be reproduced with the ffmpeg cli, conversion works fine
> there.
> However it can be reproduced with transcoding.c for all input files.
> Additionally to what I mentioned, 29.96 fps test files result in 29.98 and
> 30 to 30.11.
> Another 24 fps file resulted in 24.03. The changes seem to be related with
> the duration of the file: the longer the file the shorter the marginal fps
> difference.
> The output frame rate can be determined with both fffmpeg -i as well as
> with
> QuickTime 7 and VLC. Like I mentioned, I have spent some time with
> investigating this
> and it looks like an issue with the correct conversion of the last frame;
> I was able
> to get different framerate values when tampering with the pts of the last
> frame
> but this looked like a nasty hack that I shouldn't be doing, plus it fails
> again when re-encoding the file.  Here is the info from an input/output
> test file
> that has the frame rate changed from 24 fps to 24.03:
>
>  Duration: 00:00:36.08, start: 0.000000, bitrate: 178309 kb/s
>     Stream #0:0(eng): Video: dnxhd (DNXHD) (AVdn / 0x6E645641),
> yuv422p10le(tv, bt709/unknown/unknown), 1920x1080, 176160 kb/s, SAR 1:1 DAR
> 16:9, 24 fps, 24 tbr, 23976 tbn, 23976 tbc (default)
>
>   Duration: 00:00:36.10, start: 0.000000, bitrate: 116072 kb/s
>     Stream #0:0: Video: dnxhd (DNXHD) (AVdn / 0x6E645641), yuv422p(tv,
> bt709/unknown/unknown), 1920x1080, 116526 kb/s, SAR 1:1 DAR 16:9, 24.03
> fps, 24 tbr, 12288 tbn, 12288 tbc (default)
>
> You'll notice that there is a slight change in the duration as well, but
> this happens with the ffmpeg conversion with the cli as well.
>
> Let me know if you need more information and thanks for the help!
>
>
> On Tue, Nov 5, 2019 at 3:42 AM Carl Eugen Hoyos <ceffmpeg at gmail.com>
> wrote:
>
>> Am Di., 5. Nov. 2019 um 00:16 Uhr schrieb Vassilis <bpantazhs at gmail.com>:
>> > I am trying simply to perform a transcoding process using the
>> transcoding.c example from doc/examples. However I am seeing a very strange
>> result (even when the example is not modified at all, ie not even changing
>> codecs); the transcoded file has a marginally different frame rate than the
>> original file. For example for a frame rate of 24 fps I get 24.14 fps. I
>> also implemented this with the newer av_send/receive packet/frame functions
>> to no avail. I would be most grateful for any insights, I've spent quite
>> some time trying to troubleshoot this.
>>
>> Can you reproduce the issue with the ffmpeg cli or only with
>> transcoding.c?
>>
>> Why do you think that the output frame rate is 24.14? What does ffmpeg
>> -i show for your input file?
>>
>> Carl Eugen
>> _______________________________________________
>> Libav-user mailing list
>> Libav-user at ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/libav-user
>>
>> To unsubscribe, visit link above, or email
>> libav-user-request at ffmpeg.org with subject "unsubscribe".
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> libav-user-request at ffmpeg.org with subject "unsubscribe".
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20191105/8cb92c52/attachment.html>


More information about the Libav-user mailing list