After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 371939 - mov/mp4/m4a/3gp/3g2 muxers create wrong durations
mov/mp4/m4a/3gp/3g2 muxers create wrong durations
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-libav
git master
Other Linux
: Normal normal
: 0.10.5
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 541408 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2006-11-07 10:40 UTC by Edward Hervey
Modified: 2008-07-06 21:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Edward Hervey 2006-11-07 10:40:18 UTC
Copied from question/answer mail on gst-devel:

Hi,

On 11/4/06, Deeptendu Bikash <dbikash@gmail.com> wrote:
> Hello, 
>   
> I am using the latest CVS version of gst-ffmpeg to mux raw AAC files into
> MP4 format, but there seems to be some problem with the duration. 
>   
> gst-launch filesrc location=... ! audio/mpeg, rate=\(int\)8000,
> channels=\(int\)2, mpegversion=\(int\)4 ! ffmux_mp4 ! filesink location=... 
>   
> The resulting file has the MP4 file format but has a huge duration (8000
> hours etc) and a zero bitrate. And of course, no player, including VLC,
> could play it. Any suggestions on how to fix this? 

  There are several issues at hand. What ffmpeg does, for a start, is utterly wrong:
  in libavformat/movenc.c (the code used by quicktime/mp4/iso muxing), the duration for a track is calculated using:
   mov->tracks[i].trackDuration = 	 
	             (int64_t)mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration;
  The sampleCount is the number of samples for that track, and sampleDuration is computed using:
  track->sampleDuration = st->codec->frame_size;
  All of this is done when writing the headers of the file, after having received EOS. The problem is that the value of st->codec->frame_size is only calculated when receiving the first buffer (code you pasted below).... which doesn't mean anything (nothing guarantees that all the following buffers will have the same duration). In fact there's a VERY good chance that the first buffer will last longer than the following ones. Resulting in a computed duration which is way too big.

  The main problem, therefore, is that we need to give ffmpeg a combination of st->codec->frame_size and st->codec->sample_rate in such a way that:
  total_duration = frame_size * sample_rate * GST_SECOND.

  The fix I'm thinking about implementing is to, when we receive EOS and before writing the headers, compute the proper frame_size according to the real duration (which we know in GStreamer) as such :
  frame_size = RealDuration / (sample_rate * GST_SECOND).

  Unfortunately I currently don't have time to implement it right now (apart from creating a crude hack, doing it properly requires implementing GstSegment support in GstFFMpegMux so we get the REAL duration). Anyone up to the job can follow these ideas if I still haven't implmented it.

  Looking back on previous versions of both the ffmpeg and gst-ffmpeg code, this has always been broken (resulting in completely broken durations). The funniest part is that it plays fine in mplayer (using ffmpeg of course). In fact all the files I tried to create using the ffmpeg mov/mp4/iso muxers have broken duration with gstreamer qtdemux and Quicktime Player... but give correct duration with... ffmpeg :( 

>   
> Looking at the code (gstffmpegmux.c), the portion that sets the framerate
> for audio, looks to incomplete/incorrect. There is a comment saying that
> this might not work for any kind of audio. 
>   
>     buffer=gst_collect_pads_peek(ffmpegmux->collect,
> (GstCollectData *)collect_pad); 
>     if(buffer){ 
>         st->codec->frame_size = st->codec->sample_rate *
> GST_BUFFER_DURATION(buffer)/GST_SECOND; 
>         gst_buffer_unref(buffer); 
>     } 
>   
> When I print the values of st->codec->frame_size, st->codec->sample_rate and
> GST_BUFFER_DURATION(buffer)/GST_SECOND, I get the values
> 1266874889, 8000 and 1266874889. Evidently, the buffer duration is wrong.
> How can I correct it? 
>   
> Can anybody help with this much of info? 
>   
> Regards, 
> Deeptendu
Comment 1 Laurent Glayal 2008-01-17 15:51:03 UTC
Hi, this bug is present in the latest CVS code of gst-ffmpeg (in date of 01/17/2008), is there any plan to correct it for the next revision of gst-ffmpeg ?
Regards.
Comment 2 Mark Nauwelaerts 2008-07-06 20:57:01 UTC
*** Bug 541408 has been marked as a duplicate of this bug. ***
Comment 3 Mark Nauwelaerts 2008-07-06 21:07:19 UTC
If I read things right, duration has become more reasonable in movenc.c now:
trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration;

However, it appears there was also a problem with the pkt->duration that it was being fed; see above duplicate bug for background.


2008-07-06  Mark Nauwelaerts  <mark.nauwelaerts@collabora.co.uk>

	Based on a patch by: Aurelien Grimaud <gstelzz at yahoo dot fr>

	* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_collected):
	Properly convert buffer duration to an ffmpeg packet duration.
	Fixes #371939.