comparison sierravmd.c @ 1528:32d49970f01a libavformat

Divide first audio buffer chunk into atomary bufffers. This slightly simplifies decoder and removes potential audio buffer overrun.
author kostya
date Sun, 19 Nov 2006 05:30:43 +0000
parents deaec052eec4
children 07898e88c5b9
comparison
equal deleted inserted replaced
1527:185cafb49ae8 1528:32d49970f01a
85 unsigned int total_frames; 85 unsigned int total_frames;
86 int64_t pts_inc = 1; 86 int64_t pts_inc = 1;
87 int64_t current_video_pts = 0, current_audio_pts = 0; 87 int64_t current_video_pts = 0, current_audio_pts = 0;
88 unsigned char chunk[BYTES_PER_FRAME_RECORD]; 88 unsigned char chunk[BYTES_PER_FRAME_RECORD];
89 int num, den; 89 int num, den;
90 int sound_buffers;
90 91
91 /* fetch the main header, including the 2 header length bytes */ 92 /* fetch the main header, including the 2 header length bytes */
92 url_fseek(pb, 0, SEEK_SET); 93 url_fseek(pb, 0, SEEK_SET);
93 if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE) 94 if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
94 return AVERROR_IO; 95 return AVERROR_IO;
144 vmd->frames_per_block = LE_16(&vmd->vmd_header[18]); 145 vmd->frames_per_block = LE_16(&vmd->vmd_header[18]);
145 url_fseek(pb, toc_offset, SEEK_SET); 146 url_fseek(pb, toc_offset, SEEK_SET);
146 147
147 raw_frame_table = NULL; 148 raw_frame_table = NULL;
148 vmd->frame_table = NULL; 149 vmd->frame_table = NULL;
150 sound_buffers = LE_16(&vmd->vmd_header[808]);
149 raw_frame_table_size = vmd->frame_count * 6; 151 raw_frame_table_size = vmd->frame_count * 6;
150 raw_frame_table = av_malloc(raw_frame_table_size); 152 raw_frame_table = av_malloc(raw_frame_table_size);
151 if(vmd->frame_count * vmd->frames_per_block >= UINT_MAX / sizeof(vmd_frame_t)){ 153 if(vmd->frame_count * vmd->frames_per_block >= UINT_MAX / sizeof(vmd_frame_t)){
152 av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n"); 154 av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n");
153 return -1; 155 return -1;
154 } 156 }
155 vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t)); 157 vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame_t));
156 if (!raw_frame_table || !vmd->frame_table) { 158 if (!raw_frame_table || !vmd->frame_table) {
157 av_free(raw_frame_table); 159 av_free(raw_frame_table);
158 av_free(vmd->frame_table); 160 av_free(vmd->frame_table);
159 return AVERROR_NOMEM; 161 return AVERROR_NOMEM;
160 } 162 }
180 size = LE_32(&chunk[2]); 182 size = LE_32(&chunk[2]);
181 if(!size) 183 if(!size)
182 continue; 184 continue;
183 switch(type) { 185 switch(type) {
184 case 1: /* Audio Chunk */ 186 case 1: /* Audio Chunk */
187 /* first audio chunk contains several audio buffers */
188 if(current_audio_pts){
185 vmd->frame_table[total_frames].frame_offset = current_offset; 189 vmd->frame_table[total_frames].frame_offset = current_offset;
186 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index; 190 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
187 vmd->frame_table[total_frames].frame_size = size; 191 vmd->frame_table[total_frames].frame_size = size;
188 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD); 192 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
189 vmd->frame_table[total_frames].pts = current_audio_pts; 193 vmd->frame_table[total_frames].pts = current_audio_pts;
190 total_frames++; 194 total_frames++;
191 /* first audio chunk contains several audio buffers */ 195 current_audio_pts += pts_inc;
192 current_audio_pts += (current_audio_pts == 0) ? LE_16(&vmd->vmd_header[808]) * pts_inc : pts_inc; 196 }else{
197 uint32_t flags;
198 int k;
199 int noff;
200 int64_t pos;
201
202 pos = url_ftell(pb);
203 url_fseek(pb, current_offset, SEEK_SET);
204 flags = get_le32(pb);
205 noff = 4;
206 url_fseek(pb, pos, SEEK_SET);
207 av_log(s, AV_LOG_DEBUG, "Sound mapping = %08X (%i bufs)\n", flags, sound_buffers);
208 for(k = 0; k < sound_buffers - 1; k++){
209 if(flags & 1) { /* silent block */
210 vmd->frame_table[total_frames].frame_size = 0;
211 }else{
212 vmd->frame_table[total_frames].frame_size = st->codec->block_align + (st->codec->block_align & 1);
213 }
214 noff += vmd->frame_table[total_frames].frame_size;
215 vmd->frame_table[total_frames].frame_offset = current_offset + noff;
216 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
217 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
218 vmd->frame_table[total_frames].pts = current_audio_pts;
219 total_frames++;
220 current_audio_pts += pts_inc;
221 flags >>= 1;
222 }
223 }
193 break; 224 break;
194 case 2: /* Video Chunk */ 225 case 2: /* Video Chunk */
195 vmd->frame_table[total_frames].frame_offset = current_offset; 226 vmd->frame_table[total_frames].frame_offset = current_offset;
196 vmd->frame_table[total_frames].stream_index = vmd->video_stream_index; 227 vmd->frame_table[total_frames].stream_index = vmd->video_stream_index;
197 vmd->frame_table[total_frames].frame_size = size; 228 vmd->frame_table[total_frames].frame_size = size;