2 #include "funcprotos.h"
7 /* McRowesoft media player audio */
14 // Number of first sample in output relative to file
15 int64_t output_position
;
16 // Number of samples in output buffer
18 // Number of samples allocated in output buffer
19 long output_allocated
;
22 // Current reading position in file
29 AVCodecContext
*decoder_context
;
30 int decode_initialized
;
31 } quicktime_wma_codec_t
;
35 // Default number of samples to allocate in work buffer
36 #define OUTPUT_ALLOCATION 0x100000
38 static int delete_codec(quicktime_audio_map_t
*atrack
)
40 quicktime_wma_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
42 if(codec
->decode_initialized
)
44 pthread_mutex_lock(&ffmpeg_lock
);
45 avcodec_close(codec
->decoder_context
);
46 free(codec
->decoder_context
);
47 pthread_mutex_unlock(&ffmpeg_lock
);
48 codec
->decode_initialized
= 0;
51 if(codec
->work_buffer
)
52 free(codec
->work_buffer
);
53 if(codec
->packet_buffer
)
54 free(codec
->packet_buffer
);
60 static int init_decode(quicktime_audio_map_t
*track_map
,
61 quicktime_wma_codec_t
*codec
)
63 if(!codec
->decode_initialized
)
65 quicktime_trak_t
*trak
= track_map
->track
;
66 pthread_mutex_lock(&ffmpeg_lock
);
67 if(!ffmpeg_initialized
)
69 ffmpeg_initialized
= 1;
71 avcodec_register_all();
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_context();
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_open(codec
->decoder_context
, codec
->decoder
) < 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
;
107 long end_position
= current_position
+ samples
;
111 int sample_size
= 2 * track_map
->channels
;
113 if(output_i
) bzero(output_i
, sizeof(int16_t) * samples
);
114 if(output_f
) bzero(output_f
, sizeof(float) * samples
);
116 if(samples
> OUTPUT_ALLOCATION
)
117 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION
);
119 result
= init_decode(track_map
, codec
);
122 // Seeked outside output buffer's range or not initialized: restart
123 if(current_position
< codec
->output_position
||
124 current_position
> codec
->output_position
+ codec
->output_size
||
125 !codec
->decode_initialized
)
127 quicktime_chunk_of_sample(&codec
->output_position
,
132 //printf("decode 1 %lld %d\n", codec->output_position, codec->chunk);
133 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
134 codec
->output_size
= 0;
135 codec
->decode_initialized
= 1;
138 // Decode chunks until output buffer covers requested range
139 while(codec
->output_position
+ codec
->output_size
<
140 current_position
+ samples
&&
143 // Load chunk into work buffer
144 int64_t chunk_offset
= 0;
145 int chunk_samples
= quicktime_chunk_samples(trak
, codec
->chunk
);
146 int chunk_size
= quicktime_chunk_bytes(file
,
150 // Getting invalid numbers for this
151 // int max_samples = chunk_samples * 2;
152 int max_samples
= 32768;
153 int max_bytes
= max_samples
* sample_size
;
154 int bytes_decoded
= 0;
155 printf("decode 2 %x %llx %llx\n", chunk_size
, chunk_offset
, chunk_offset
+ chunk_size
);
157 // Allocate packet buffer
158 if(codec
->packet_allocated
< chunk_size
&&
159 codec
->packet_buffer
)
161 free(codec
->packet_buffer
);
162 codec
->packet_buffer
= 0;
165 if(!codec
->packet_buffer
)
167 codec
->packet_buffer
= calloc(1, chunk_size
);
168 codec
->packet_allocated
= chunk_size
;
171 // Allocate work buffer
172 if(max_bytes
+ codec
->output_size
* sample_size
> codec
->output_allocated
* sample_size
)
174 char *new_output
= calloc(1, max_bytes
+ codec
->output_size
* sample_size
);
175 if(codec
->work_buffer
)
177 memcpy(new_output
, codec
->work_buffer
, codec
->output_size
* sample_size
);
178 free(codec
->work_buffer
);
180 codec
->work_buffer
= new_output
;
181 codec
->output_allocated
= max_bytes
+ codec
->output_size
* sample_size
;
184 quicktime_set_position(file
, chunk_offset
);
185 result
= !quicktime_read_data(file
, codec
->packet_buffer
, chunk_size
);
188 // Decode chunk into work buffer.
189 pthread_mutex_lock(&ffmpeg_lock
);
190 result
= avcodec_decode_audio(codec
->decoder_context
,
191 (int16_t*)(codec
->work_buffer
+ codec
->output_size
* sample_size
),
193 codec
->packet_buffer
,
195 pthread_mutex_unlock(&ffmpeg_lock
);
196 if(bytes_decoded
<= 0)
202 if(codec
->output_size
* sample_size
+ bytes_decoded
> codec
->output_allocated
* sample_size
)
203 printf("decode: FYI: bytes_decoded=%d is greater than output_allocated=%d\n",
204 codec
->output_size
* sample_size
+ bytes_decoded
,
205 codec
->output_allocated
);
206 codec
->output_size
+= bytes_decoded
/ sample_size
;
212 //printf("decode 15 %d %lld %d\n", try, codec->output_position, codec->output_size);
213 // Transfer to output
216 int16_t *pcm_ptr
= (int16_t*)codec
->work_buffer
+
217 (current_position
- codec
->output_position
) * track_map
->channels
+
219 for(i
= current_position
- codec
->output_position
, j
= 0;
220 j
< samples
&& i
< codec
->output_size
;
223 output_i
[j
] = *pcm_ptr
;
224 pcm_ptr
+= track_map
->channels
;
230 int16_t *pcm_ptr
= (int16_t*)codec
->work_buffer
+
231 (current_position
- codec
->output_position
) * track_map
->channels
+
233 for(i
= current_position
- codec
->output_position
, j
= 0;
234 j
< samples
&& i
< codec
->output_size
;
237 output_i
[j
] = (float)*pcm_ptr
/ (float)32767;
238 pcm_ptr
+= track_map
->channels
;
242 // Delete excess output
243 if(codec
->output_size
> OUTPUT_ALLOCATION
)
245 int sample_diff
= codec
->output_size
- OUTPUT_ALLOCATION
;
246 int byte_diff
= sample_diff
* sample_size
;
247 memcpy(codec
->work_buffer
,
248 codec
->work_buffer
+ byte_diff
,
249 OUTPUT_ALLOCATION
* sample_size
);
250 codec
->output_size
-= sample_diff
;
251 codec
->output_position
+= sample_diff
;
263 static void init_codec_common(quicktime_audio_map_t
*atrack
)
265 quicktime_wma_codec_t
*codec
;
266 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
268 /* Init public items */
269 codec_base
->delete_acodec
= delete_codec
;
270 codec_base
->decode_audio
= decode
;
273 /* Init private items */
274 codec
= codec_base
->priv
= calloc(1, sizeof(quicktime_wma_codec_t
));
278 void quicktime_init_codec_wmav1(quicktime_audio_map_t
*atrack
)
280 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
281 quicktime_wma_codec_t
*codec
;
282 init_codec_common(atrack
);
284 codec
= codec_base
->priv
;
285 codec_base
->fourcc
= QUICKTIME_WMA
;
286 codec_base
->title
= "Win Media Audio 1";
287 codec_base
->desc
= "Win Media Audio 1";
288 codec_base
->wav_id
= 0x160;
289 codec
->ffmpeg_id
= CODEC_ID_WMAV1
;
293 void quicktime_init_codec_wmav2(quicktime_audio_map_t
*atrack
)
295 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
296 quicktime_wma_codec_t
*codec
;
297 init_codec_common(atrack
);
299 codec
= codec_base
->priv
;
300 codec_base
->fourcc
= QUICKTIME_WMA
;
301 codec_base
->title
= "Win Media Audio 2";
302 codec_base
->desc
= "Win Media Audio 2";
303 codec_base
->wav_id
= 0x161;
304 codec
->ffmpeg_id
= CODEC_ID_WMAV2
;