[Ffmpeg-devel] [PATCH] ODML AVI Duration

Michael Niedermayer michaelni
Wed Aug 23 01:53:37 CEST 2006


Hi

On Tue, Aug 22, 2006 at 04:38:39PM -0500, Brian Brice wrote:
> Michael Niedermayer wrote:
> >Hi
> >
> >On Tue, Aug 22, 2006 at 03:21:23PM -0500, Brian Brice wrote:
> >>If I encoded an AVI that was over 2 GB (or 4m:43s DV), then video
> >>players would read the wrong duration, thus not being able to show the
> >>entire clip.  For example, encoding a DV clip that is about 5 minutes
> >>in duration:
> >>
> >>ffmpeg -i INPUT.mpg -f avi -vcodec dvvideo -acodec pcm_s16le -s ntsc
> >>-r ntsc -ar 48000 -pix_fmt yuv411p -t 00:05:00 OUTPUT.avi
> >>
> >>Windows Media Player and even ffmpeg would report the duration as 4:43.
> >>This patch is to write the proper lengths in the AVI and stream headers.
> >>If the file contains only 1 RIFF, then all will be the same.  If there
> >>is more than 1 RIFF, then in the write_trailer, it updates the odml's
> >>length along with the headers.
> >
> >quoting the odml spec
> >"The dwTotalFrames field indicates the size (number of frames) within the 
> >first RIFF
> >chunk."
> >
> >...
> >
> >"Extended AVI Header (dmlh)
> >typedef struct {
> >   DWORD dwTotalFrames;
> >} ODMLExtendedAVIHeader;
> >Total Frames
> >The dwTotalFrames field indicates the real size of the AVI file. Since the 
> >same field in the
> >Main AVI Header indicates the size within the first RIFF chunk.
> >"
> 
> OK.  This version updates ONLY the stream headers' length but leaves
> the avih's total frames referring to ONLY the first RIFF's.  Having ONLY
> the streams' headers updated reports the correct duration in both
> Windows Media Player and ffmpeg.

[...]

> +static int avi_write_counters(AVFormatContext* s)
> +{
> +    ByteIOContext *pb = &s->pb;
> +    AVIContext *avi = s->priv_data;
> +    int n, au_byterate, au_ssize, au_scale, nb_frames = 0;
> +    offset_t file_size;
> +    AVCodecContext* stream;
> +
> +    file_size = url_ftell(pb);
> +    for(n = 0; n < s->nb_streams; n++) {
> +        assert(avi->frames_hdr_strm[n]);
> +        stream = s->streams[n]->codec;
> +        url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET);
> +        ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
> +        if(au_ssize == 0) {
> +           put_le32(pb, avi->packet_count[n]);
> +        } else {
> +           put_le32(pb, avi->audio_strm_length[n] / au_ssize);
> +        }
> +        if(stream->codec_type == CODEC_TYPE_VIDEO)
> +           nb_frames = FFMAX(nb_frames, avi->packet_count[n]);
> +    }
> +	 if(avi->riff_id == 1) {

id prefer if this could be passed as argument to the function
and it contains tabs and consequently messed up indention


> +	    assert(avi->frames_hdr_all);
> +   	 url_fseek(pb, avi->frames_hdr_all, SEEK_SET);
> +	    put_le32(pb, nb_frames);
> +   	 url_fseek(pb, file_size, SEEK_SET);
> +	 }
> +
> +    return 0;

while it might not be needed id also prefer if the last url_fseek where
outside the if()

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is




More information about the ffmpeg-devel mailing list