[gstreamer-bugs] [Bug 371939] New: mov/mp4/m4a/3gp/3g2 muxers create wrong durations

GStreamer (bugzilla.gnome.org) bugzilla-daemon at bugzilla.gnome.org
Tue Nov 7 02:41:25 PST 2006


Do not reply to this via email (we are currently unable to handle email
responses and they get discarded).  You can add comments to this bug at
http://bugzilla.gnome.org/show_bug.cgi?id=371939

  GStreamer | gst-ffmpeg | Ver: HEAD CVS

           Summary: mov/mp4/m4a/3gp/3g2 muxers create wrong durations
           Product: GStreamer
           Version: HEAD CVS
          Platform: Other
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: gst-ffmpeg
        AssignedTo: gstreamer-bugs at lists.sourceforge.net
        ReportedBy: bilboed at bilboed.com
         QAContact: gstreamer-bugs at lists.sourceforge.net
     GNOME version: Unspecified
   GNOME milestone: Unspecified


Copied from question/answer mail on gst-devel:

Hi,

On 11/4/06, Deeptendu Bikash <dbikash at 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


-- 
Configure bugmail: http://bugzilla.gnome.org/userprefs.cgi?tab=email




More information about the Gstreamer-bugs mailing list