2 #include "funcprotos.h"
6 /* McRowesoft media player audio */
13 // Number of first sample in output relative to file
14 int64_t output_position
;
15 // Number of samples in output buffer
17 // Number of samples allocated in output buffer
18 long output_allocated
;
21 // Current reading position in file
28 AVCodecContext
*decoder_context
;
29 int decode_initialized
;
30 } quicktime_wma_codec_t
;
34 // Default number of samples to allocate in work buffer
35 #define OUTPUT_ALLOCATION 0x100000
37 static int delete_codec(quicktime_audio_map_t
*atrack
)
39 quicktime_wma_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
41 if(codec
->decode_initialized
)
43 pthread_mutex_lock(&ffmpeg_lock
);
44 avcodec_close(codec
->decoder_context
);
45 free(codec
->decoder_context
);
46 pthread_mutex_unlock(&ffmpeg_lock
);
47 codec
->decode_initialized
= 0;
50 if(codec
->work_buffer
)
51 free(codec
->work_buffer
);
52 if(codec
->packet_buffer
)
53 free(codec
->packet_buffer
);
59 static int init_decode(quicktime_audio_map_t
*track_map
,
60 quicktime_wma_codec_t
*codec
)
62 if(!codec
->decode_initialized
)
64 quicktime_trak_t
*trak
= track_map
->track
;
65 pthread_mutex_lock(&ffmpeg_lock
);
66 if(!ffmpeg_initialized
)
68 ffmpeg_initialized
= 1;
70 avcodec_register_all();
73 codec
->decoder
= avcodec_find_decoder(codec
->ffmpeg_id
);
76 printf("init_decode: avcodec_find_decoder returned NULL.\n");
79 codec
->decoder_context
= avcodec_alloc_context();
80 codec
->decoder_context
->sample_rate
= trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
;
81 codec
->decoder_context
->channels
= track_map
->channels
;
82 if(avcodec_open(codec
->decoder_context
, codec
->decoder
) < 0)
84 printf("init_decode: avcodec_open failed.\n");
87 pthread_mutex_unlock(&ffmpeg_lock
);
89 codec
->work_buffer
= malloc(2 * track_map
->channels
* OUTPUT_ALLOCATION
);
90 codec
->output_allocated
= OUTPUT_ALLOCATION
;
95 static int decode(quicktime_t
*file
,
102 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
103 quicktime_wma_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
104 quicktime_trak_t
*trak
= track_map
->track
;
105 long current_position
= track_map
->current_position
;
106 long end_position
= current_position
+ samples
;
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 %llx %llx\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
);
189 result
= avcodec_decode_audio(codec
->decoder_context
,
190 (int16_t*)(codec
->work_buffer
+ codec
->output_size
* sample_size
),
192 codec
->packet_buffer
,
194 pthread_mutex_unlock(&ffmpeg_lock
);
195 if(bytes_decoded
<= 0)
201 if(codec
->output_size
* sample_size
+ bytes_decoded
> codec
->output_allocated
* sample_size
)
202 printf("decode: FYI: bytes_decoded=%d is greater than output_allocated=%d\n",
203 codec
->output_size
* sample_size
+ bytes_decoded
,
204 codec
->output_allocated
);
205 codec
->output_size
+= bytes_decoded
/ sample_size
;
211 //printf("decode 15 %d %lld %d\n", try, codec->output_position, codec->output_size);
212 // Transfer to output
215 int16_t *pcm_ptr
= (int16_t*)codec
->work_buffer
+
216 (current_position
- codec
->output_position
) * track_map
->channels
+
218 for(i
= current_position
- codec
->output_position
, j
= 0;
219 j
< samples
&& i
< codec
->output_size
;
222 output_i
[j
] = *pcm_ptr
;
223 pcm_ptr
+= track_map
->channels
;
229 int16_t *pcm_ptr
= (int16_t*)codec
->work_buffer
+
230 (current_position
- codec
->output_position
) * track_map
->channels
+
232 for(i
= current_position
- codec
->output_position
, j
= 0;
233 j
< samples
&& i
< codec
->output_size
;
236 output_i
[j
] = (float)*pcm_ptr
/ (float)32767;
237 pcm_ptr
+= track_map
->channels
;
241 // Delete excess output
242 if(codec
->output_size
> OUTPUT_ALLOCATION
)
244 int sample_diff
= codec
->output_size
- OUTPUT_ALLOCATION
;
245 int byte_diff
= sample_diff
* sample_size
;
246 memcpy(codec
->work_buffer
,
247 codec
->work_buffer
+ byte_diff
,
248 OUTPUT_ALLOCATION
* sample_size
);
249 codec
->output_size
-= sample_diff
;
250 codec
->output_position
+= sample_diff
;
262 static void init_codec_common(quicktime_audio_map_t
*atrack
)
264 quicktime_wma_codec_t
*codec
;
265 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
267 /* Init public items */
268 codec_base
->delete_acodec
= delete_codec
;
269 codec_base
->decode_audio
= decode
;
272 /* Init private items */
273 codec
= codec_base
->priv
= calloc(1, sizeof(quicktime_wma_codec_t
));
277 void quicktime_init_codec_wmav1(quicktime_audio_map_t
*atrack
)
279 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
280 quicktime_wma_codec_t
*codec
;
281 init_codec_common(atrack
);
283 codec
= codec_base
->priv
;
284 codec_base
->fourcc
= QUICKTIME_WMA
;
285 codec_base
->title
= "Win Media Audio 1";
286 codec_base
->desc
= "Win Media Audio 1";
287 codec_base
->wav_id
= 0x160;
288 codec
->ffmpeg_id
= CODEC_ID_WMAV1
;
292 void quicktime_init_codec_wmav2(quicktime_audio_map_t
*atrack
)
294 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
295 quicktime_wma_codec_t
*codec
;
296 init_codec_common(atrack
);
298 codec
= codec_base
->priv
;
299 codec_base
->fourcc
= QUICKTIME_WMA
;
300 codec_base
->title
= "Win Media Audio 2";
301 codec_base
->desc
= "Win Media Audio 2";
302 codec_base
->wav_id
= 0x161;
303 codec
->ffmpeg_id
= CODEC_ID_WMAV2
;