[Libav-user] Transcoding frame rate mismatch

James Crisafulli james2048 at gmail.com
Tue Nov 5 15:03:39 EET 2019


Glad it helped!
Ah yes, I just checked the git trunk examples and it is as you describe, so
maybe it was changed at some point, and I was basing on an older version of
transcoding.c.

- James

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

> Well that did the trick! I can't thank you enough James and also second
> your comment that this should be updated in the transcoding.c example.
> Is there anything we can do about this?
>
> As for the GLOBAL_HEADER if I am not mistaken it is done indeed as you
> suggest, maybe this has been updated, here is the relevant code:
>
>             if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
>                 enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
>
>             /* Third parameter can be used to pass settings to encoder */
>             ret = avcodec_open2(enc_ctx, encoder, NULL);
>
> Thanks again!
>
> On Tue, Nov 5, 2019 at 2:03 PM James Crisafulli <james2048 at gmail.com>
> wrote:
>
>> 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".
>>
>> _______________________________________________
>> 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/3c2dc39d/attachment.html>


More information about the Libav-user mailing list