Mercurial > libavformat.hg
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; |