1 #include "funcprotos.h"
14 #include "mpeg3private.h"
15 #include "mpeg3protos.h"
16 #include "quicktime.h"
19 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
21 #define OUTPUT_ALLOCATION 0x100000
23 //static FILE *test = 0;
29 // Can't use same structure for header testing
30 mpeg3_layer_t
*mp3_header
;
31 unsigned char *packet_buffer
;
35 // Number of first sample in output relative to file
36 int64_t output_position
;
37 // Number of samples in output buffer
39 // Number of samples allocated in output buffer
40 long output_allocated
;
41 // Current reading position in file
43 int decode_initialized
;
49 lame_global_flags
*lame_global
;
50 // This calculates the number of samples per chunk
51 mpeg3_layer_t
*encoded_header
;
52 int encode_initialized
;
57 unsigned char *encoder_output
;
58 int encoder_output_size
;
59 int encoder_output_allocated
;
60 } quicktime_mp3_codec_t
;
66 static int delete_codec(quicktime_audio_map_t
*atrack
)
68 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
69 if(codec
->mp3
) mpeg3_delete_layer(codec
->mp3
);
70 if(codec
->mp3_header
) mpeg3_delete_layer(codec
->mp3_header
);
71 if(codec
->packet_buffer
) free(codec
->packet_buffer
);
75 for(i
= 0; i
< atrack
->channels
; i
++)
76 free(codec
->output
[i
]);
80 if(codec
->lame_global
)
82 lame_close(codec
->lame_global
);
88 for(i
= 0; i
< atrack
->channels
; i
++)
90 free(codec
->input
[i
]);
95 if(codec
->encoder_output
)
96 free(codec
->encoder_output
);
98 if(codec
->encoded_header
)
99 mpeg3_delete_layer(codec
->encoded_header
);
106 static int chunk_len(quicktime_t
*file
,
107 quicktime_mp3_codec_t
*codec
,
112 unsigned char header
[4];
115 while(offset
< next_chunk
)
117 quicktime_set_position(file
, offset
);
118 result
= !quicktime_read_data(file
, (unsigned char*)&header
, 4);
125 // Decode size of mp3 frame
126 result
= mpeg3_layer_header(codec
->mp3_header
,
137 quicktime_set_position(file
, offset
+ result
);
152 static int decode(quicktime_t
*file
,
160 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
161 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
162 quicktime_trak_t
*trak
= track_map
->track
;
163 long current_position
= track_map
->current_position
;
164 long end_position
= current_position
+ samples
;
175 if(samples
> OUTPUT_ALLOCATION
)
176 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION
);
179 //printf("decode 1\n");
180 if(output_i
) bzero(output_i
, sizeof(int16_t) * samples
);
181 if(output_f
) bzero(output_f
, sizeof(float) * samples
);
183 temp_output
= malloc(sizeof(float*) * track_map
->channels
);
185 // Seeked outside output buffer's range or not initialized: restart
186 if(current_position
< codec
->output_position
||
187 current_position
> codec
->output_position
+ codec
->output_size
||
188 !codec
->decode_initialized
)
190 quicktime_chunk_of_sample(&codec
->output_position
,
195 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
196 codec
->output_size
= 0;
197 //printf("decode 1 %lld %d\n", codec->output_position, quicktime_chunk_samples(trak, codec->chunk));
198 codec
->output_position
= quicktime_sample_of_chunk(trak
, codec
->chunk
);
199 //printf("decode 2 %lld\n", codec->output_position);
201 // Initialize and load initial buffer for decoding
202 if(!codec
->decode_initialized
)
205 codec
->decode_initialized
= 1;
206 codec
->output
= malloc(sizeof(float*) * track_map
->channels
);
207 for(i
= 0; i
< track_map
->channels
; i
++)
209 codec
->output
[i
] = malloc(sizeof(float) * OUTPUT_ALLOCATION
);
211 codec
->output_allocated
= OUTPUT_ALLOCATION
;
212 codec
->mp3
= mpeg3_new_layer();
213 codec
->mp3_header
= mpeg3_new_layer();
217 // Decode chunks until output is big enough
218 while(codec
->output_position
+ codec
->output_size
<
219 current_position
+ samples
&&
223 offset1
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
);
224 offset2
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
+ 1);
226 if(offset2
== offset1
) break;
228 chunk_size
= chunk_len(file
, codec
, offset1
, offset2
);
230 if(codec
->packet_allocated
< chunk_size
&&
231 codec
->packet_buffer
)
233 free(codec
->packet_buffer
);
234 codec
->packet_buffer
= 0;
237 if(!codec
->packet_buffer
)
239 codec
->packet_buffer
= calloc(1, chunk_size
);
240 codec
->packet_allocated
= chunk_size
;
243 quicktime_set_position(file
, offset1
);
244 result
= !quicktime_read_data(file
, codec
->packet_buffer
, chunk_size
);
247 for(i
= 0; i
< chunk_size
; )
249 // Allocate more output
250 new_size
= codec
->output_size
+ MAXFRAMESAMPLES
;
251 if(new_size
> codec
->output_allocated
)
253 for(j
= 0; j
< track_map
->channels
; j
++)
255 float *new_output
= calloc(sizeof(float), new_size
);
258 sizeof(float) * codec
->output_size
);
259 free(codec
->output
[j
]);
260 codec
->output
[j
] = new_output
;
262 codec
->output_allocated
= new_size
;
266 for(j
= 0; j
< track_map
->channels
; j
++)
267 temp_output
[j
] = codec
->output
[j
] + codec
->output_size
;
269 frame_size
= mpeg3_layer_header(codec
->mp3
,
270 codec
->packet_buffer
+ i
);
272 result
= mpeg3audio_dolayer3(codec
->mp3
,
273 codec
->packet_buffer
+ i
,
281 codec
->output_size
+= result
;
296 // Transfer region of output to argument
297 pcm
= codec
->output
[channel
];
300 for(i
= current_position
- codec
->output_position
, j
= 0;
301 j
< samples
&& i
< codec
->output_size
;
304 int sample
= pcm
[i
] * 32767;
305 CLAMP(sample
, -32768, 32767);
306 output_i
[j
] = sample
;
312 for(i
= current_position
- codec
->output_position
, j
= 0;
313 j
< samples
&& i
< codec
->output_size
;
316 output_f
[j
] = pcm
[i
];
320 // Delete excess output
321 if(codec
->output_size
> OUTPUT_ALLOCATION
)
323 int diff
= codec
->output_size
- OUTPUT_ALLOCATION
;
324 for(k
= 0; k
< track_map
->channels
; k
++)
326 pcm
= codec
->output
[k
];
327 for(i
= 0, j
= diff
; j
< codec
->output_size
; i
++, j
++)
332 codec
->output_size
-= diff
;
333 codec
->output_position
+= diff
;
337 //printf("decode 100\n");
344 static int allocate_output(quicktime_mp3_codec_t
*codec
,
347 int new_size
= codec
->encoder_output_size
+ samples
* 4;
348 if(codec
->encoder_output_allocated
< new_size
)
350 unsigned char *new_output
= calloc(1, new_size
);
352 if(codec
->encoder_output
)
355 codec
->encoder_output
,
356 codec
->encoder_output_size
);
357 free(codec
->encoder_output
);
359 codec
->encoder_output
= new_output
;
360 codec
->encoder_output_allocated
= new_size
;
367 // Empty the output buffer of frames
368 static int write_frames(quicktime_t
*file
,
369 quicktime_audio_map_t
*track_map
,
370 quicktime_trak_t
*trak
,
371 quicktime_mp3_codec_t
*codec
)
376 quicktime_atom_t chunk_atom
;
379 for(i
= 0; i
< codec
->encoder_output_size
- 4; )
381 unsigned char *header
= codec
->encoder_output
+ i
;
382 int frame_size
= mpeg3_layer_header(codec
->encoded_header
, header
);
386 // Frame is finished before end of buffer
387 if(i
+ frame_size
<= codec
->encoder_output_size
)
391 int frame_samples
= mpeg3audio_dolayer3(codec
->encoded_header
,
397 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
398 result
= !quicktime_write_data(file
, header
, frame_size
);
399 // Knows not to save the chunksizes for audio
400 quicktime_write_chunk_footer(file
,
402 track_map
->current_chunk
,
406 track_map
->current_chunk
++;
411 // Frame isn't finished before end of buffer.
418 // Not the start of a frame. Skip it.
427 for(i
= frames_end
, j
= 0; i
< codec
->encoder_output_size
; i
++, j
++)
429 codec
->encoder_output
[j
] = codec
->encoder_output
[i
];
431 codec
->encoder_output_size
-= frames_end
;
441 static int encode(quicktime_t
*file
,
448 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
449 quicktime_trak_t
*trak
= track_map
->track
;
450 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
451 int new_size
= codec
->input_size
+ samples
;
455 if(!codec
->encode_initialized
)
457 codec
->encode_initialized
= 1;
458 codec
->lame_global
= lame_init();
459 lame_set_brate(codec
->lame_global
, codec
->bitrate
/ 1000);
460 lame_set_quality(codec
->lame_global
, 0);
461 lame_set_in_samplerate(codec
->lame_global
,
462 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
463 if((result
= lame_init_params(codec
->lame_global
)) < 0)
464 printf("encode: lame_init_params returned %d\n", result
);
465 codec
->encoded_header
= mpeg3_new_layer();
467 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
= 0;
471 // Stack input on end of buffer
472 if(new_size
> codec
->input_allocated
)
477 codec
->input
= calloc(sizeof(float*), track_map
->channels
);
479 for(i
= 0; i
< track_map
->channels
; i
++)
481 new_input
= calloc(sizeof(float), new_size
);
484 memcpy(new_input
, codec
->input
[i
], sizeof(float) * codec
->input_size
);
485 free(codec
->input
[i
]);
487 codec
->input
[i
] = new_input
;
489 codec
->input_allocated
= new_size
;
493 // Transfer to input buffers
496 for(i
= 0; i
< track_map
->channels
; i
++)
498 for(j
= 0; j
< samples
; j
++)
499 codec
->input
[i
][j
] = input_i
[i
][j
];
505 for(i
= 0; i
< track_map
->channels
; i
++)
507 for(j
= 0; j
< samples
; j
++)
508 codec
->input
[i
][j
] = input_f
[i
][j
] * 32767;
513 allocate_output(codec
, samples
);
515 result
= lame_encode_buffer_float(codec
->lame_global
,
517 (track_map
->channels
> 1) ? codec
->input
[1] : codec
->input
[0],
519 codec
->encoder_output
+ codec
->encoder_output_size
,
520 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
522 codec
->encoder_output_size
+= result
;
524 result
= write_frames(file
,
534 static int set_parameter(quicktime_t
*file
,
539 quicktime_audio_map_t
*atrack
= &(file
->atracks
[track
]);
540 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
542 if(!strcasecmp(key
, "mp3_bitrate"))
543 codec
->bitrate
= *(int*)value
;
550 static void flush(quicktime_t
*file
, int track
)
553 int64_t offset
= quicktime_position(file
);
554 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
555 quicktime_trak_t
*trak
= track_map
->track
;
556 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
558 if(codec
->encode_initialized
)
560 result
= lame_encode_flush(codec
->lame_global
,
561 codec
->encoder_output
+ codec
->encoder_output_size
,
562 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
563 codec
->encoder_output_size
+= result
;
564 result
= write_frames(file
,
572 void quicktime_init_codec_mp3(quicktime_audio_map_t
*atrack
)
574 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
575 quicktime_mp3_codec_t
*codec
;
577 /* Init public items */
578 codec_base
->priv
= calloc(1, sizeof(quicktime_mp3_codec_t
));
579 codec_base
->delete_acodec
= delete_codec
;
580 codec_base
->decode_audio
= decode
;
581 codec_base
->encode_audio
= encode
;
582 codec_base
->set_parameter
= set_parameter
;
583 codec_base
->flush
= flush
;
584 codec_base
->fourcc
= QUICKTIME_MP3
;
585 codec_base
->title
= "MP3";
586 codec_base
->desc
= "MP3 for video";
587 codec_base
->wav_id
= 0x55;
589 codec
= codec_base
->priv
;
590 codec
->bitrate
= 256000;