[Ffmpeg-devel] [PATCH] ODML AVI Duration

Brian Brice bbrice
Wed Aug 23 02:18:16 CEST 2006


Michael Niedermayer wrote:
> 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

Added.  Forgot to turn off tabs.. :-(

> 
> 
>> +	    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()

That's changed.


-- 
Brian Brice
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: avienc.c.patch
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20060822/ed13e854/attachment.asc>



More information about the ffmpeg-devel mailing list