3 #include "funcprotos.h"
8 /* McRowesoft media player audio */
15 // Number of first sample in output relative to file
16 int64_t output_position;
17 // Number of samples in output buffer
19 // Number of samples allocated in output buffer
20 long output_allocated;
23 // Current reading position in file
30 AVCodecContext *decoder_context;
31 int decode_initialized;
32 } quicktime_wma_codec_t;
36 // Default number of samples to allocate in work buffer
37 #define OUTPUT_ALLOCATION 0x100000
39 static void delete_codec(quicktime_audio_map_t *atrack)
41 quicktime_wma_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
43 if(codec->decode_initialized)
45 pthread_mutex_lock(&ffmpeg_lock);
46 avcodec_close(codec->decoder_context);
47 free(codec->decoder_context);
48 pthread_mutex_unlock(&ffmpeg_lock);
49 codec->decode_initialized = 0;
52 if(codec->work_buffer)
53 free(codec->work_buffer);
54 if(codec->packet_buffer)
55 free(codec->packet_buffer);
61 static int init_decode(quicktime_audio_map_t *track_map,
62 quicktime_wma_codec_t *codec)
64 if(!codec->decode_initialized)
66 quicktime_trak_t *trak = track_map->track;
67 pthread_mutex_lock(&ffmpeg_lock);
68 if(!ffmpeg_initialized)
70 ffmpeg_initialized = 1;
74 codec->decoder = avcodec_find_decoder(codec->ffmpeg_id);
77 printf("init_decode: avcodec_find_decoder returned NULL.\n");
80 codec->decoder_context = avcodec_alloc_context3(codec->decoder);
81 codec->decoder_context->sample_rate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
82 codec->decoder_context->channels = track_map->channels;
83 if(avcodec_open2(codec->decoder_context, codec->decoder, 0) < 0)
85 printf("init_decode: avcodec_open failed.\n");
88 pthread_mutex_unlock(&ffmpeg_lock);
90 codec->work_buffer = malloc(2 * track_map->channels * OUTPUT_ALLOCATION);
91 codec->output_allocated = OUTPUT_ALLOCATION;
96 static int decode(quicktime_t *file,
103 quicktime_audio_map_t *track_map = &(file->atracks[track]);
104 quicktime_wma_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
105 quicktime_trak_t *trak = track_map->track;
106 long current_position = track_map->current_position;
110 int sample_size = 2 * track_map->channels;
112 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
113 if(output_f) bzero(output_f, sizeof(float) * samples);
115 if(samples > OUTPUT_ALLOCATION)
116 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION);
118 result = init_decode(track_map, codec);
121 // Seeked outside output buffer's range or not initialized: restart
122 if(current_position < codec->output_position ||
123 current_position > codec->output_position + codec->output_size ||
124 !codec->decode_initialized)
126 quicktime_chunk_of_sample(&codec->output_position,
131 //printf("decode 1 %lld %d\n", codec->output_position, codec->chunk);
132 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
133 codec->output_size = 0;
134 codec->decode_initialized = 1;
137 // Decode chunks until output buffer covers requested range
138 while(codec->output_position + codec->output_size <
139 current_position + samples &&
142 // Load chunk into work buffer
143 int64_t chunk_offset = 0;
144 // int chunk_samples = quicktime_chunk_samples(trak, codec->chunk);
145 int chunk_size = quicktime_chunk_bytes(file,
149 // Getting invalid numbers for this
150 // int max_samples = chunk_samples * 2;
151 int max_samples = 32768;
152 int max_bytes = max_samples * sample_size;
153 int bytes_decoded = 0;
154 //printf("decode 2 %x %jx %jx\n", chunk_size, chunk_offset, chunk_offset + chunk_size);
156 // Allocate packet buffer
157 if(codec->packet_allocated < chunk_size &&
158 codec->packet_buffer)
160 free(codec->packet_buffer);
161 codec->packet_buffer = 0;
164 if(!codec->packet_buffer)
166 codec->packet_buffer = calloc(1, chunk_size);
167 codec->packet_allocated = chunk_size;
170 // Allocate work buffer
171 if(max_bytes + codec->output_size * sample_size > codec->output_allocated * sample_size)
173 char *new_output = calloc(1, max_bytes + codec->output_size * sample_size);
174 if(codec->work_buffer)
176 memcpy(new_output, codec->work_buffer, codec->output_size * sample_size);
177 free(codec->work_buffer);
179 codec->work_buffer = new_output;
180 codec->output_allocated = max_bytes + codec->output_size * sample_size;
183 quicktime_set_position(file, chunk_offset);
184 result = !quicktime_read_data(file, codec->packet_buffer, chunk_size);
187 // Decode chunk into work buffer.
188 pthread_mutex_lock(&ffmpeg_lock);
190 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
191 result = avcodec_decode_audio(codec->decoder_context,
192 (int16_t*)(codec->work_buffer + codec->output_size * sample_size),
194 codec->packet_buffer,
197 bytes_decoded = OUTPUT_ALLOCATION;
198 result = avcodec_decode_audio2(codec->decoder_context,
199 (int16_t*)(codec->work_buffer + codec->output_size * sample_size),
200 &bytes_decoded, codec->packet_buffer, chunk_size);
204 av_init_packet(&avpkt);
205 avpkt.data = (unsigned char *)codec->packet_buffer;
206 avpkt.size = chunk_size;
207 bytes_decoded = OUTPUT_ALLOCATION;
208 result = quicktime_decode_audio3(codec->decoder_context,
209 (int16_t*)(codec->work_buffer + codec->output_size * sample_size),
210 &bytes_decoded, &avpkt);
213 pthread_mutex_unlock(&ffmpeg_lock);
214 if(bytes_decoded <= 0)
220 if(codec->output_size * sample_size + bytes_decoded > codec->output_allocated * sample_size)
221 printf("decode: FYI: bytes_decoded=%ld is greater than output_allocated=%ld\n",
222 codec->output_size * sample_size + bytes_decoded,
223 codec->output_allocated);
224 codec->output_size += bytes_decoded / sample_size;
230 //printf("decode 15 %d %lld %d\n", try, codec->output_position, codec->output_size);
231 // Transfer to output
234 int16_t *pcm_ptr = (int16_t*)codec->work_buffer +
235 (current_position - codec->output_position) * track_map->channels +
237 for(i = current_position - codec->output_position, j = 0;
238 j < samples && i < codec->output_size;
241 output_i[j] = *pcm_ptr;
242 pcm_ptr += track_map->channels;
248 int16_t *pcm_ptr = (int16_t*)codec->work_buffer +
249 (current_position - codec->output_position) * track_map->channels +
251 for(i = current_position - codec->output_position, j = 0;
252 j < samples && i < codec->output_size;
255 output_i[j] = (float)*pcm_ptr / (float)32767;
256 pcm_ptr += track_map->channels;
260 // Delete excess output
261 if(codec->output_size > OUTPUT_ALLOCATION)
263 int sample_diff = codec->output_size - OUTPUT_ALLOCATION;
264 int byte_diff = sample_diff * sample_size;
265 memcpy(codec->work_buffer,
266 codec->work_buffer + byte_diff,
267 OUTPUT_ALLOCATION * sample_size);
268 codec->output_size -= sample_diff;
269 codec->output_position += sample_diff;
281 static void init_codec_common(quicktime_audio_map_t *atrack)
283 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
285 /* Init public items */
286 codec_base->delete_acodec = delete_codec;
287 codec_base->decode_audio = decode;
290 /* Init private items */
291 // quicktime_wma_codec_t *codec =
292 codec_base->priv = calloc(1, sizeof(quicktime_wma_codec_t));
296 void quicktime_init_codec_wmav1(quicktime_audio_map_t *atrack)
298 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
299 quicktime_wma_codec_t *codec;
300 init_codec_common(atrack);
302 codec = codec_base->priv;
303 codec_base->fourcc = QUICKTIME_WMA;
304 codec_base->title = "Win Media Audio 1";
305 codec_base->desc = "Win Media Audio 1";
306 codec_base->wav_id = 0x160;
307 codec->ffmpeg_id = CODEC_ID_WMAV1;
311 void quicktime_init_codec_wmav2(quicktime_audio_map_t *atrack)
313 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
314 quicktime_wma_codec_t *codec;
315 init_codec_common(atrack);
317 codec = codec_base->priv;
318 codec_base->fourcc = QUICKTIME_WMA;
319 codec_base->title = "Win Media Audio 2";
320 codec_base->desc = "Win Media Audio 2";
321 codec_base->wav_id = 0x161;
322 codec->ffmpeg_id = CODEC_ID_WMAV2;