1 #include "funcprotos.h"
6 #include "mpeg3private.h"
7 #include "mpeg3protos.h"
14 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
16 #define OUTPUT_ALLOCATION 0x100000
18 //static FILE *test = 0;
24 // Can't use same structure for header testing
25 mpeg3_layer_t
*mp3_header
;
26 unsigned char *packet_buffer
;
30 // Number of first sample in output relative to file
31 int64_t output_position
;
32 // Number of samples in output buffer
34 // Number of samples allocated in output buffer
35 long output_allocated
;
36 // Current reading position in file
38 int decode_initialized
;
44 lame_global_flags
*lame_global
;
45 // This calculates the number of samples per chunk
46 mpeg3_layer_t
*encoded_header
;
47 int encode_initialized
;
52 unsigned char *encoder_output
;
53 int encoder_output_size
;
54 int encoder_output_allocated
;
55 } quicktime_mp3_codec_t
;
61 static int delete_codec(quicktime_audio_map_t
*atrack
)
63 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
64 if(codec
->mp3
) mpeg3_delete_layer(codec
->mp3
);
65 if(codec
->mp3_header
) mpeg3_delete_layer(codec
->mp3_header
);
66 if(codec
->packet_buffer
) free(codec
->packet_buffer
);
70 for(i
= 0; i
< atrack
->channels
; i
++)
71 free(codec
->output
[i
]);
75 if(codec
->lame_global
)
77 lame_close(codec
->lame_global
);
83 for(i
= 0; i
< atrack
->channels
; i
++)
85 free(codec
->input
[i
]);
90 if(codec
->encoder_output
)
91 free(codec
->encoder_output
);
93 if(codec
->encoded_header
)
94 mpeg3_delete_layer(codec
->encoded_header
);
101 static int chunk_len(quicktime_t
*file
,
102 quicktime_mp3_codec_t
*codec
,
107 unsigned char header
[4];
110 while(offset
< next_chunk
)
112 quicktime_set_position(file
, offset
);
113 result
= !quicktime_read_data(file
, (unsigned char*)&header
, 4);
120 // Decode size of mp3 frame
121 result
= mpeg3_layer_header(codec
->mp3_header
,
132 quicktime_set_position(file
, offset
+ result
);
147 static int decode(quicktime_t
*file
,
155 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
156 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
157 quicktime_trak_t
*trak
= track_map
->track
;
158 long current_position
= track_map
->current_position
;
159 long end_position
= current_position
+ samples
;
170 if(samples
> OUTPUT_ALLOCATION
)
171 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION
);
174 //printf("decode 1\n");
175 if(output_i
) bzero(output_i
, sizeof(int16_t) * samples
);
176 if(output_f
) bzero(output_f
, sizeof(float) * samples
);
178 temp_output
= malloc(sizeof(float*) * track_map
->channels
);
180 // Seeked outside output buffer's range or not initialized: restart
181 if(current_position
< codec
->output_position
||
182 current_position
> codec
->output_position
+ codec
->output_size
||
183 !codec
->decode_initialized
)
185 quicktime_chunk_of_sample(&codec
->output_position
,
190 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
191 codec
->output_size
= 0;
192 //printf("decode 1 %lld %d\n", codec->output_position, quicktime_chunk_samples(trak, codec->chunk));
193 codec
->output_position
= quicktime_sample_of_chunk(trak
, codec
->chunk
);
194 //printf("decode 2 %lld\n", codec->output_position);
196 // Initialize and load initial buffer for decoding
197 if(!codec
->decode_initialized
)
200 codec
->decode_initialized
= 1;
201 codec
->output
= malloc(sizeof(float*) * track_map
->channels
);
202 for(i
= 0; i
< track_map
->channels
; i
++)
204 codec
->output
[i
] = malloc(sizeof(float) * OUTPUT_ALLOCATION
);
206 codec
->output_allocated
= OUTPUT_ALLOCATION
;
207 codec
->mp3
= mpeg3_new_layer();
208 codec
->mp3_header
= mpeg3_new_layer();
212 // Decode chunks until output is big enough
213 while(codec
->output_position
+ codec
->output_size
<
214 current_position
+ samples
&&
218 offset1
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
);
219 offset2
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
+ 1);
221 if(offset2
== offset1
) break;
223 chunk_size
= chunk_len(file
, codec
, offset1
, offset2
);
225 if(codec
->packet_allocated
< chunk_size
&&
226 codec
->packet_buffer
)
228 free(codec
->packet_buffer
);
229 codec
->packet_buffer
= 0;
232 if(!codec
->packet_buffer
)
234 codec
->packet_buffer
= calloc(1, chunk_size
);
235 codec
->packet_allocated
= chunk_size
;
238 quicktime_set_position(file
, offset1
);
239 result
= !quicktime_read_data(file
, codec
->packet_buffer
, chunk_size
);
242 for(i
= 0; i
< chunk_size
; )
244 // Allocate more output
245 new_size
= codec
->output_size
+ MAXFRAMESAMPLES
;
246 if(new_size
> codec
->output_allocated
)
248 for(j
= 0; j
< track_map
->channels
; j
++)
250 float *new_output
= calloc(sizeof(float), new_size
);
253 sizeof(float) * codec
->output_size
);
254 free(codec
->output
[j
]);
255 codec
->output
[j
] = new_output
;
257 codec
->output_allocated
= new_size
;
261 for(j
= 0; j
< track_map
->channels
; j
++)
262 temp_output
[j
] = codec
->output
[j
] + codec
->output_size
;
264 frame_size
= mpeg3_layer_header(codec
->mp3
,
265 codec
->packet_buffer
+ i
);
267 result
= mpeg3audio_dolayer3(codec
->mp3
,
268 codec
->packet_buffer
+ i
,
276 codec
->output_size
+= result
;
291 // Transfer region of output to argument
292 pcm
= codec
->output
[channel
];
295 for(i
= current_position
- codec
->output_position
, j
= 0;
296 j
< samples
&& i
< codec
->output_size
;
299 int sample
= pcm
[i
] * 32767;
300 CLAMP(sample
, -32768, 32767);
301 output_i
[j
] = sample
;
307 for(i
= current_position
- codec
->output_position
, j
= 0;
308 j
< samples
&& i
< codec
->output_size
;
311 output_f
[j
] = pcm
[i
];
315 // Delete excess output
316 if(codec
->output_size
> OUTPUT_ALLOCATION
)
318 int diff
= codec
->output_size
- OUTPUT_ALLOCATION
;
319 for(k
= 0; k
< track_map
->channels
; k
++)
321 pcm
= codec
->output
[k
];
322 for(i
= 0, j
= diff
; j
< codec
->output_size
; i
++, j
++)
327 codec
->output_size
-= diff
;
328 codec
->output_position
+= diff
;
332 //printf("decode 100\n");
339 static int allocate_output(quicktime_mp3_codec_t
*codec
,
342 int new_size
= codec
->encoder_output_size
+ samples
* 4;
343 if(codec
->encoder_output_allocated
< new_size
)
345 unsigned char *new_output
= calloc(1, new_size
);
347 if(codec
->encoder_output
)
350 codec
->encoder_output
,
351 codec
->encoder_output_size
);
352 free(codec
->encoder_output
);
354 codec
->encoder_output
= new_output
;
355 codec
->encoder_output_allocated
= new_size
;
362 // Empty the output buffer of frames
363 static int write_frames(quicktime_t
*file
,
364 quicktime_audio_map_t
*track_map
,
365 quicktime_trak_t
*trak
,
366 quicktime_mp3_codec_t
*codec
,
372 quicktime_atom_t chunk_atom
;
375 for(i
= 0; i
< codec
->encoder_output_size
- 4; )
377 unsigned char *header
= codec
->encoder_output
+ i
;
378 int frame_size
= mpeg3_layer_header(codec
->encoded_header
, header
);
382 // Frame is finished before end of buffer
383 if(i
+ frame_size
<= codec
->encoder_output_size
)
387 int frame_samples
= mpeg3audio_dolayer3(codec
->encoded_header
,
394 quicktime_write_vbr_frame(file
,
402 // quicktime_write_chunk_header(file, trak, &chunk_atom);
403 // result = !quicktime_write_data(file, header, frame_size);
404 // // Knows not to save the chunksizes for audio
405 // quicktime_write_chunk_footer(file,
407 // track_map->current_chunk,
410 track_map
->current_chunk
++;
418 // Frame isn't finished before end of buffer.
425 // Not the start of a frame. Skip it.
434 for(i
= frames_end
, j
= 0; i
< codec
->encoder_output_size
; i
++, j
++)
436 codec
->encoder_output
[j
] = codec
->encoder_output
[i
];
438 codec
->encoder_output_size
-= frames_end
;
448 static int encode(quicktime_t
*file
,
455 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
456 quicktime_trak_t
*trak
= track_map
->track
;
457 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
458 int new_size
= codec
->input_size
+ samples
;
462 if(!codec
->encode_initialized
)
464 codec
->encode_initialized
= 1;
465 codec
->lame_global
= lame_init();
466 lame_set_brate(codec
->lame_global
, codec
->bitrate
/ 1000);
467 lame_set_quality(codec
->lame_global
, 0);
468 lame_set_in_samplerate(codec
->lame_global
,
469 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
470 if((result
= lame_init_params(codec
->lame_global
)) < 0)
471 printf("encode: lame_init_params returned %d\n", result
);
472 codec
->encoded_header
= mpeg3_new_layer();
474 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
= 0;
478 // Stack input on end of buffer
479 if(new_size
> codec
->input_allocated
)
484 codec
->input
= calloc(sizeof(float*), track_map
->channels
);
486 for(i
= 0; i
< track_map
->channels
; i
++)
488 new_input
= calloc(sizeof(float), new_size
);
491 memcpy(new_input
, codec
->input
[i
], sizeof(float) * codec
->input_size
);
492 free(codec
->input
[i
]);
494 codec
->input
[i
] = new_input
;
496 codec
->input_allocated
= new_size
;
500 // Transfer to input buffers
503 for(i
= 0; i
< track_map
->channels
; i
++)
505 for(j
= 0; j
< samples
; j
++)
506 codec
->input
[i
][j
] = input_i
[i
][j
];
512 for(i
= 0; i
< track_map
->channels
; i
++)
514 for(j
= 0; j
< samples
; j
++)
515 codec
->input
[i
][j
] = input_f
[i
][j
] * 32767;
520 allocate_output(codec
, samples
);
522 result
= lame_encode_buffer_float(codec
->lame_global
,
524 (track_map
->channels
> 1) ? codec
->input
[1] : codec
->input
[0],
526 codec
->encoder_output
+ codec
->encoder_output_size
,
527 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
529 codec
->encoder_output_size
+= result
;
531 result
= write_frames(file
,
542 static int set_parameter(quicktime_t
*file
,
547 quicktime_audio_map_t
*atrack
= &(file
->atracks
[track
]);
548 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
550 if(!strcasecmp(key
, "mp3_bitrate"))
551 codec
->bitrate
= *(int*)value
;
558 static void flush(quicktime_t
*file
, int track
)
561 int64_t offset
= quicktime_position(file
);
562 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
563 quicktime_trak_t
*trak
= track_map
->track
;
564 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
566 if(codec
->encode_initialized
)
568 result
= lame_encode_flush(codec
->lame_global
,
569 codec
->encoder_output
+ codec
->encoder_output_size
,
570 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
571 codec
->encoder_output_size
+= result
;
572 result
= write_frames(file
,
581 void quicktime_init_codec_mp3(quicktime_audio_map_t
*atrack
)
583 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
584 quicktime_mp3_codec_t
*codec
;
586 /* Init public items */
587 codec_base
->priv
= calloc(1, sizeof(quicktime_mp3_codec_t
));
588 codec_base
->delete_acodec
= delete_codec
;
589 codec_base
->decode_audio
= decode
;
590 codec_base
->encode_audio
= encode
;
591 codec_base
->set_parameter
= set_parameter
;
592 codec_base
->flush
= flush
;
593 codec_base
->fourcc
= QUICKTIME_MP3
;
594 codec_base
->title
= "MP3";
595 codec_base
->desc
= "MP3 for video";
596 codec_base
->wav_id
= 0x55;
598 codec
= codec_base
->priv
;
599 codec
->bitrate
= 256000;