]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/commitdiff
Divide first audio buffer chunk into atomary bufffers.
authorkostya <kostya@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Sun, 19 Nov 2006 05:30:43 +0000 (05:30 +0000)
committerkostya <kostya@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Sun, 19 Nov 2006 05:30:43 +0000 (05:30 +0000)
This slightly simplifies decoder and removes potential
audio buffer overrun.

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@7121 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

libavcodec/vmdav.c
libavformat/sierravmd.c

index 394d6d50d859545acbe213e02a63dbef61a5f617..a9937144e41bfa3c69bdab09a38be5789b72c546 100644 (file)
@@ -519,12 +519,10 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
                                  uint8_t *buf, int buf_size)
 {
     VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
-    unsigned int sound_flags;
     unsigned char *output_samples = (unsigned char *)data;
 
     /* point to the start of the encoded data */
     unsigned char *p = buf + 16;
-    unsigned char *p_end = buf + buf_size;
 
     if (buf_size < 16)
         return buf_size;
@@ -533,24 +531,10 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
         /* the chunk contains audio */
         *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
     } else if (buf[6] == 2) {
-        /* the chunk contains audio and silence mixed together */
-        sound_flags = LE_32(p);
+        /* the chunk may contain audio */
         p += 4;
-
-        /* do something with extrabufs here? */
-
-        while (p < p_end) {
-            if (sound_flags & 0x01)
-                /* silence */
-                *data_size += vmdaudio_loadsound(s, output_samples, p, 1);
-            else {
-                /* audio */
-                *data_size += vmdaudio_loadsound(s, output_samples, p, 0);
-                p += s->block_align;
-            }
-            output_samples += (s->block_align * s->bits / 8);
-            sound_flags >>= 1;
-        }
+        *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
+        output_samples += (s->block_align * s->bits / 8);
     } else if (buf[6] == 3) {
         /* silent chunk */
         *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
index bdb18072f7715a24382b6a734892ad91e94614dd..a056d9fbf3f78a5825094406b26efd10cfbc1c9d 100644 (file)
@@ -87,6 +87,7 @@ static int vmd_read_header(AVFormatContext *s,
     int64_t current_video_pts = 0, current_audio_pts = 0;
     unsigned char chunk[BYTES_PER_FRAME_RECORD];
     int num, den;
+    int sound_buffers;
 
     /* fetch the main header, including the 2 header length bytes */
     url_fseek(pb, 0, SEEK_SET);
@@ -146,13 +147,14 @@ static int vmd_read_header(AVFormatContext *s,
 
     raw_frame_table = NULL;
     vmd->frame_table = NULL;
+    sound_buffers = LE_16(&vmd->vmd_header[808]);
     raw_frame_table_size = vmd->frame_count * 6;
     raw_frame_table = av_malloc(raw_frame_table_size);
     if(vmd->frame_count * vmd->frames_per_block  >= UINT_MAX / sizeof(vmd_frame_t)){
         av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n");
         return -1;
     }
-    vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t));
+    vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame_t));
     if (!raw_frame_table || !vmd->frame_table) {
         av_free(raw_frame_table);
         av_free(vmd->frame_table);
@@ -182,14 +184,43 @@ static int vmd_read_header(AVFormatContext *s,
                 continue;
             switch(type) {
             case 1: /* Audio Chunk */
+                /* first audio chunk contains several audio buffers */
+                if(current_audio_pts){
                 vmd->frame_table[total_frames].frame_offset = current_offset;
                 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
                 vmd->frame_table[total_frames].frame_size = size;
                 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
                 vmd->frame_table[total_frames].pts = current_audio_pts;
                 total_frames++;
-                /* first audio chunk contains several audio buffers */
-                current_audio_pts += (current_audio_pts == 0) ? LE_16(&vmd->vmd_header[808]) * pts_inc : pts_inc;
+                current_audio_pts += pts_inc;
+                }else{
+                    uint32_t flags;
+                    int k;
+                    int noff;
+                    int64_t pos;
+
+                    pos = url_ftell(pb);
+                    url_fseek(pb, current_offset, SEEK_SET);
+                    flags = get_le32(pb);
+                    noff = 4;
+                    url_fseek(pb, pos, SEEK_SET);
+                    av_log(s, AV_LOG_DEBUG, "Sound mapping = %08X (%i bufs)\n", flags, sound_buffers);
+                    for(k = 0; k < sound_buffers - 1; k++){
+                        if(flags & 1) { /* silent block */
+                            vmd->frame_table[total_frames].frame_size = 0;
+                        }else{
+                            vmd->frame_table[total_frames].frame_size = st->codec->block_align + (st->codec->block_align & 1);
+                        }
+                        noff += vmd->frame_table[total_frames].frame_size;
+                        vmd->frame_table[total_frames].frame_offset = current_offset + noff;
+                        vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
+                        memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
+                        vmd->frame_table[total_frames].pts = current_audio_pts;
+                        total_frames++;
+                        current_audio_pts += pts_inc;
+                        flags >>= 1;
+                    }
+                }
                 break;
             case 2: /* Video Chunk */
                 vmd->frame_table[total_frames].frame_offset = current_offset;