last frame problem in some mp4 files produced by avidemux in copy mode

Started by Elstar`, October 08, 2022, 10:42:08 PM

Previous topic - Next topic

Elstar`

When source is H.264/AVC 25 fps, B-frames (yt-dlp result for https://www.youtube.com/watch?v=Dkgwo-EJMyg format 137+140), cutting with Avidemux (on keyframe) and saving as mp4, results in inaccessible last frame in Virtualdub2. Doing stream copy (-codec copy) of Avidemux output with latest ffmpeg solves this problem.

There is no such problem when saving same file as mkv, but Virtualdub2 then detects keyframes at +40ms (next frame) after actual I-frame.

These problems do not appear when cutting 30fps video without B-frames (youtube live stream) and saving as mkv.

I have just checked another youtube video (https://www.youtube.com/watch?v=HLFn5EoV-W0) that has actually 24.975 (25000/1001) fps and Avidemux cuts it correctly (when saving as mp4). I wonder, why there are problems on exactly 25 fps...

This problem also happens when cutting variable frame rate youtube live stream (~30 or ~60 fps).

eumagga0x2a

Confirming the issue – libavformat MOV/MP4 demuxer drops the last picture due to video duration in the edit list being too short. Avidemux itself silently fixes the duration when it loads the resulting video, obfuscating the problem.

It seems, libavformat mp4 muxer expects frame duration to be set in the AVPacket struct we pass to av_write_frame() function, at least for the last packet, which is pretty bad because we don't know which packet will be the last. For other packets, the mp4 muxer in libavformat library calculates the duration as the difference between their DTS (decode timestamps) on its own.

Will try to fix the issue.

eumagga0x2a

This bug should be fixed by the changeset [muxerMp4] Set average frame rate to fix too short video track duration in the edit list.

Quote from: Elstar` on October 08, 2022, 10:42:08 PMI wonder, why there are problems on exactly 25 fps...

Please have a look at this location in FFmpeg code.

If the duration of the last picture is not explicitly set (i.e. it is zero) and the value returned by calc_samples_pts_duration() can be exactly represented in MOV_TIMESCALE units and no rounding happens, the PTS of the last picture is equal track duration, i.e. the last picture falls off the cliff when the video is played (the end point of a range doesn't belong to the range). Else the duration is minimally longer and the last picture (barely) fits in.

Thank you for your report.

Elstar`

Confirmed, at 25 fps, latest build 221015 now generates correct mp4 with accessible last frame.