[Ffmpeg-cvslog] r7121 - in trunk: libavcodec/vmdav.c libavformat/sierravmd.c

kostya subversion
Sun Nov 19 06:30:44 CET 2006


Author: kostya
Date: Sun Nov 19 06:30:43 2006
New Revision: 7121

Modified:
   trunk/libavcodec/vmdav.c
   trunk/libavformat/sierravmd.c

Log:
Divide first audio buffer chunk into atomary bufffers.
This slightly simplifies decoder and removes potential
audio buffer overrun.



Modified: trunk/libavcodec/vmdav.c
==============================================================================
--- trunk/libavcodec/vmdav.c	(original)
+++ trunk/libavcodec/vmdav.c	Sun Nov 19 06:30:43 2006
@@ -519,12 +519,10 @@
                                  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 @@
         /* 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);

Modified: trunk/libavformat/sierravmd.c
==============================================================================
--- trunk/libavformat/sierravmd.c	(original)
+++ trunk/libavformat/sierravmd.c	Sun Nov 19 06:30:43 2006
@@ -87,6 +87,7 @@
     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 @@
 
     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 @@
                 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;




More information about the ffmpeg-cvslog mailing list