>From 753f08447f3a7b5859366b9274cd07ed4cd23484 Mon Sep 17 00:00:00 2001
From: Mike Scheutzow <mjs973@optonline.net>
Date: Wed, 27 Jun 2012 11:28:07 -0400
Subject: [PATCH] Fix timestamp calculation when demuxing MP3 frames in a .avi container.
 The bad code was using the frame byte length to calculate a timestamp,
 which is completely broken. Also set AVPacket.duration, since demux is
 already calculating it. The existing avi muxer already properly handles
 the muxing and index creation for MP3 audio frames.  Fixes the sample
 file in trac 1432.


Signed-off-by: Mike Scheutzow <mjs973@optonline.net>
---
 libavformat/avidec.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index fea0694..4835750 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -116,6 +116,10 @@ static int guess_ni_flag(AVFormatContext *s);
            (tag >> 24) & 0xff,                          \
            size)
 
+/* calculate the duration of the current frame, in units of AVStream.time_base.
+ * For video, or audio frames with variable byte length, the output value
+ * is defined to be '1'.
+ */
 static inline int get_duration(AVIStream *ast, int len){
     if(ast->sample_size){
         return len;
@@ -655,7 +659,15 @@ static int avi_read_header(AVFormatContext *s)
                     ret = ff_get_wav_header(pb, st->codec, size);
                     if (ret < 0)
                         return ret;
-                    ast->dshow_block_align= st->codec->block_align;
+                    if (st->codec->codec_id == CODEC_ID_MP3) {
+                        /* this file assumes that a non-zero sample_size 
+                         * means constant frame byte length; mp3 frames have 
+                         * variable byte length */
+                        ast->sample_size = 0;
+                        // must keep ast->dshow_block_align = 0
+                    } else {
+                        ast->dshow_block_align= st->codec->block_align;
+                    }
                     if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
                         av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
                         ast->sample_size= st->codec->block_align;
@@ -1204,7 +1216,9 @@ resync:
             } else {
                 pkt->flags |= AV_PKT_FLAG_KEY;
             }
-            ast->frame_offset += get_duration(ast, pkt->size);
+            /* pkt may contain multiple frames */
+            pkt->duration = get_duration(ast, pkt->size);
+            ast->frame_offset += pkt->duration;
         }
         ast->remaining -= size;
         if(!ast->remaining){
-- 
1.7.4

