[Libav-user] Transcoding frame rate mismatch
bpantazhs at gmail.com
Tue Nov 5 14:36:24 EET 2019
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);
On Tue, Nov 5, 2019 at 2:03 PM James Crisafulli <james2048 at gmail.com> wrote:
> 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
> // 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
>> 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
>> 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
>> 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
>> 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>
>>> 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
>>> 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
>>> 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
>> 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
> To unsubscribe, visit link above, or email
> libav-user-request at ffmpeg.org with subject "unsubscribe".
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Libav-user