00001 #include "funcprotos.h"
00002
00003 #include <lame/lame.h>
00004
00005
00006 #include "mpeg3private.h"
00007 #include "mpeg3protos.h"
00008 #include "quicktime.h"
00009 #include "qtmp3.h"
00010 #include <string.h>
00011
00012
00013
00014 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
00015
00016 #define OUTPUT_ALLOCATION 0x100000
00017
00018
00019
00020 typedef struct
00021 {
00022
00023 mpeg3_layer_t *mp3;
00024
00025 mpeg3_layer_t *mp3_header;
00026 unsigned char *packet_buffer;
00027 int packet_allocated;
00028
00029
00030
00031 int64_t output_position;
00032
00033 long output_size;
00034
00035 long output_allocated;
00036
00037 int64_t chunk;
00038 int decode_initialized;
00039 float **output;
00040
00041
00042
00043
00044 lame_global_flags *lame_global;
00045
00046 mpeg3_layer_t *encoded_header;
00047 int encode_initialized;
00048 float **input;
00049 int input_size;
00050 int input_allocated;
00051 int bitrate;
00052 unsigned char *encoder_output;
00053 int encoder_output_size;
00054 int encoder_output_allocated;
00055 } quicktime_mp3_codec_t;
00056
00057
00058
00059
00060
00061 static int delete_codec(quicktime_audio_map_t *atrack)
00062 {
00063 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00064 if(codec->mp3) mpeg3_delete_layer(codec->mp3);
00065 if(codec->mp3_header) mpeg3_delete_layer(codec->mp3_header);
00066 if(codec->packet_buffer) free(codec->packet_buffer);
00067 if(codec->output)
00068 {
00069 int i;
00070 for(i = 0; i < atrack->channels; i++)
00071 free(codec->output[i]);
00072 free(codec->output);
00073 }
00074
00075 if(codec->lame_global)
00076 {
00077 lame_close(codec->lame_global);
00078 }
00079
00080 if(codec->input)
00081 {
00082 int i;
00083 for(i = 0; i < atrack->channels; i++)
00084 {
00085 free(codec->input[i]);
00086 }
00087 free(codec->input);
00088 }
00089
00090 if(codec->encoder_output)
00091 free(codec->encoder_output);
00092
00093 if(codec->encoded_header)
00094 mpeg3_delete_layer(codec->encoded_header);
00095
00096 free(codec);
00097
00098 return 0;
00099 }
00100
00101 static int chunk_len(quicktime_t *file,
00102 quicktime_mp3_codec_t *codec,
00103 int64_t offset,
00104 int64_t next_chunk)
00105 {
00106 int result = 0;
00107 unsigned char header[4];
00108 int accum = 0;
00109
00110 while(offset < next_chunk)
00111 {
00112 quicktime_set_position(file, offset);
00113 result = !quicktime_read_data(file, (unsigned char*)&header, 4);
00114
00115 if(result)
00116 {
00117 return accum;
00118 }
00119
00120
00121 result = mpeg3_layer_header(codec->mp3_header,
00122 header);
00123
00124
00125 if(!result)
00126 return accum;
00127 else
00128
00129 {
00130 accum += result;
00131 offset += result;
00132 quicktime_set_position(file, offset + result);
00133 }
00134 }
00135 return accum;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static int decode(quicktime_t *file,
00148 int16_t *output_i,
00149 float *output_f,
00150 long samples,
00151 int track,
00152 int channel)
00153 {
00154 int result = 0;
00155 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00156 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00157 quicktime_trak_t *trak = track_map->track;
00158 long current_position = track_map->current_position;
00159 long end_position = current_position + samples;
00160 float *pcm;
00161 int i, j, k;
00162 int64_t offset1;
00163 int64_t offset2;
00164 int chunk_size;
00165 int new_size;
00166 int frame_size;
00167 int try = 0;
00168 float **temp_output;
00169
00170 if(samples > OUTPUT_ALLOCATION)
00171 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION);
00172
00173
00174
00175 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
00176 if(output_f) bzero(output_f, sizeof(float) * samples);
00177
00178 temp_output = malloc(sizeof(float*) * track_map->channels);
00179
00180
00181 if(current_position < codec->output_position ||
00182 current_position > codec->output_position + codec->output_size ||
00183 !codec->decode_initialized)
00184 {
00185 quicktime_chunk_of_sample(&codec->output_position,
00186 &codec->chunk,
00187 trak,
00188 current_position);
00189
00190
00191 codec->output_size = 0;
00192
00193 codec->output_position = quicktime_sample_of_chunk(trak, codec->chunk);
00194
00195
00196
00197 if(!codec->decode_initialized)
00198 {
00199 int i;
00200 codec->decode_initialized = 1;
00201 codec->output = malloc(sizeof(float*) * track_map->channels);
00202 for(i = 0; i < track_map->channels; i++)
00203 {
00204 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
00205 }
00206 codec->output_allocated = OUTPUT_ALLOCATION;
00207 codec->mp3 = mpeg3_new_layer();
00208 codec->mp3_header = mpeg3_new_layer();
00209 }
00210 }
00211
00212
00213 while(codec->output_position + codec->output_size <
00214 current_position + samples &&
00215 try < 6)
00216 {
00217
00218 offset1 = quicktime_chunk_to_offset(file, trak, codec->chunk);
00219 offset2 = quicktime_chunk_to_offset(file, trak, codec->chunk + 1);
00220
00221 if(offset2 == offset1) break;
00222
00223 chunk_size = chunk_len(file, codec, offset1, offset2);
00224
00225 if(codec->packet_allocated < chunk_size &&
00226 codec->packet_buffer)
00227 {
00228 free(codec->packet_buffer);
00229 codec->packet_buffer = 0;
00230 }
00231
00232 if(!codec->packet_buffer)
00233 {
00234 codec->packet_buffer = calloc(1, chunk_size);
00235 codec->packet_allocated = chunk_size;
00236 }
00237
00238 quicktime_set_position(file, offset1);
00239 result = !quicktime_read_data(file, codec->packet_buffer, chunk_size);
00240 if(result) break;
00241
00242 for(i = 0; i < chunk_size; )
00243 {
00244
00245 new_size = codec->output_size + MAXFRAMESAMPLES;
00246 if(new_size > codec->output_allocated)
00247 {
00248 for(j = 0; j < track_map->channels; j++)
00249 {
00250 float *new_output = calloc(sizeof(float), new_size);
00251 memcpy(new_output,
00252 codec->output[j],
00253 sizeof(float) * codec->output_size);
00254 free(codec->output[j]);
00255 codec->output[j] = new_output;
00256 }
00257 codec->output_allocated = new_size;
00258 }
00259
00260
00261 for(j = 0; j < track_map->channels; j++)
00262 temp_output[j] = codec->output[j] + codec->output_size;
00263
00264 frame_size = mpeg3_layer_header(codec->mp3,
00265 codec->packet_buffer + i);
00266
00267 result = mpeg3audio_dolayer3(codec->mp3,
00268 codec->packet_buffer + i,
00269 frame_size,
00270 temp_output,
00271 1);
00272
00273
00274 if(result)
00275 {
00276 codec->output_size += result;
00277 result = 0;
00278 try = 0;
00279 }
00280 else
00281 {
00282 try++;
00283 }
00284
00285 i += frame_size;
00286 }
00287
00288 codec->chunk++;
00289 }
00290
00291
00292 pcm = codec->output[channel];
00293 if(output_i)
00294 {
00295 for(i = current_position - codec->output_position, j = 0;
00296 j < samples && i < codec->output_size;
00297 j++, i++)
00298 {
00299 int sample = pcm[i] * 32767;
00300 CLAMP(sample, -32768, 32767);
00301 output_i[j] = sample;
00302 }
00303 }
00304 else
00305 if(output_f)
00306 {
00307 for(i = current_position - codec->output_position, j = 0;
00308 j < samples && i < codec->output_size;
00309 j++, i++)
00310 {
00311 output_f[j] = pcm[i];
00312 }
00313 }
00314
00315
00316 if(codec->output_size > OUTPUT_ALLOCATION)
00317 {
00318 int diff = codec->output_size - OUTPUT_ALLOCATION;
00319 for(k = 0; k < track_map->channels; k++)
00320 {
00321 pcm = codec->output[k];
00322 for(i = 0, j = diff; j < codec->output_size; i++, j++)
00323 {
00324 pcm[i] = pcm[j];
00325 }
00326 }
00327 codec->output_size -= diff;
00328 codec->output_position += diff;
00329 }
00330
00331 free(temp_output);
00332
00333 return 0;
00334 }
00335
00336
00337
00338
00339 static int allocate_output(quicktime_mp3_codec_t *codec,
00340 int samples)
00341 {
00342 int new_size = codec->encoder_output_size + samples * 4;
00343 if(codec->encoder_output_allocated < new_size)
00344 {
00345 unsigned char *new_output = calloc(1, new_size);
00346
00347 if(codec->encoder_output)
00348 {
00349 memcpy(new_output,
00350 codec->encoder_output,
00351 codec->encoder_output_size);
00352 free(codec->encoder_output);
00353 }
00354 codec->encoder_output = new_output;
00355 codec->encoder_output_allocated = new_size;
00356 }
00357
00358 }
00359
00360
00361
00362
00363 static int write_frames(quicktime_t *file,
00364 quicktime_audio_map_t *track_map,
00365 quicktime_trak_t *trak,
00366 quicktime_mp3_codec_t *codec,
00367 int track)
00368 {
00369 int result = 0;
00370 int i, j;
00371 int frames_end = 0;
00372 quicktime_atom_t chunk_atom;
00373
00374
00375 for(i = 0; i < codec->encoder_output_size - 4; )
00376 {
00377 unsigned char *header = codec->encoder_output + i;
00378 int frame_size = mpeg3_layer_header(codec->encoded_header, header);
00379
00380 if(frame_size)
00381 {
00382
00383 if(i + frame_size <= codec->encoder_output_size)
00384 {
00385
00386 int64_t offset;
00387 int frame_samples = mpeg3audio_dolayer3(codec->encoded_header,
00388 header,
00389 frame_size,
00390 0,
00391 0);
00392
00393
00394 quicktime_write_vbr_frame(file,
00395 track,
00396 header,
00397 frame_size,
00398 frame_samples);
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 track_map->current_chunk++;
00411
00412
00413
00414 i += frame_size;
00415 frames_end = i;
00416 }
00417 else
00418
00419 {
00420 frames_end = i;
00421 break;
00422 }
00423 }
00424 else
00425
00426 {
00427 i++;
00428 frames_end = i;
00429 }
00430 }
00431
00432 if(frames_end > 0)
00433 {
00434 for(i = frames_end, j = 0; i < codec->encoder_output_size; i++, j++)
00435 {
00436 codec->encoder_output[j] = codec->encoder_output[i];
00437 }
00438 codec->encoder_output_size -= frames_end;
00439 }
00440 return result;
00441 }
00442
00443
00444
00445
00446
00447
00448 static int encode(quicktime_t *file,
00449 int16_t **input_i,
00450 float **input_f,
00451 int track,
00452 long samples)
00453 {
00454 int result = 0;
00455 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00456 quicktime_trak_t *trak = track_map->track;
00457 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00458 int new_size = codec->input_size + samples;
00459 int i, j;
00460 int frames_end = 0;
00461
00462 if(!codec->encode_initialized)
00463 {
00464 codec->encode_initialized = 1;
00465 codec->lame_global = lame_init();
00466 lame_set_brate(codec->lame_global, codec->bitrate / 1000);
00467 lame_set_quality(codec->lame_global, 0);
00468 lame_set_in_samplerate(codec->lame_global,
00469 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
00470 if((result = lame_init_params(codec->lame_global)) < 0)
00471 printf("encode: lame_init_params returned %d\n", result);
00472 codec->encoded_header = mpeg3_new_layer();
00473 if(file->use_avi)
00474 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
00475 }
00476
00477
00478
00479 if(new_size > codec->input_allocated)
00480 {
00481 float *new_input;
00482
00483 if(!codec->input)
00484 codec->input = calloc(sizeof(float*), track_map->channels);
00485
00486 for(i = 0; i < track_map->channels; i++)
00487 {
00488 new_input = calloc(sizeof(float), new_size);
00489 if(codec->input[i])
00490 {
00491 memcpy(new_input, codec->input[i], sizeof(float) * codec->input_size);
00492 free(codec->input[i]);
00493 }
00494 codec->input[i] = new_input;
00495 }
00496 codec->input_allocated = new_size;
00497 }
00498
00499
00500
00501 if(input_i)
00502 {
00503 for(i = 0; i < track_map->channels; i++)
00504 {
00505 for(j = 0; j < samples; j++)
00506 codec->input[i][j] = input_i[i][j];
00507 }
00508 }
00509 else
00510 if(input_f)
00511 {
00512 for(i = 0; i < track_map->channels; i++)
00513 {
00514 for(j = 0; j < samples; j++)
00515 codec->input[i][j] = input_f[i][j] * 32767;
00516 }
00517 }
00518
00519
00520 allocate_output(codec, samples);
00521
00522 result = lame_encode_buffer_float(codec->lame_global,
00523 codec->input[0],
00524 (track_map->channels > 1) ? codec->input[1] : codec->input[0],
00525 samples,
00526 codec->encoder_output + codec->encoder_output_size,
00527 codec->encoder_output_allocated - codec->encoder_output_size);
00528
00529 codec->encoder_output_size += result;
00530
00531 result = write_frames(file,
00532 track_map,
00533 trak,
00534 codec,
00535 track);
00536
00537 return result;
00538 }
00539
00540
00541
00542 static int set_parameter(quicktime_t *file,
00543 int track,
00544 char *key,
00545 void *value)
00546 {
00547 quicktime_audio_map_t *atrack = &(file->atracks[track]);
00548 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00549
00550 if(!strcasecmp(key, "mp3_bitrate"))
00551 codec->bitrate = *(int*)value;
00552
00553 return 0;
00554 }
00555
00556
00557
00558 static void flush(quicktime_t *file, int track)
00559 {
00560 int result = 0;
00561 int64_t offset = quicktime_position(file);
00562 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00563 quicktime_trak_t *trak = track_map->track;
00564 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00565
00566 if(codec->encode_initialized)
00567 {
00568 result = lame_encode_flush(codec->lame_global,
00569 codec->encoder_output + codec->encoder_output_size,
00570 codec->encoder_output_allocated - codec->encoder_output_size);
00571 codec->encoder_output_size += result;
00572 result = write_frames(file,
00573 track_map,
00574 trak,
00575 codec,
00576 track);
00577 }
00578 }
00579
00580
00581 void quicktime_init_codec_mp3(quicktime_audio_map_t *atrack)
00582 {
00583 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
00584 quicktime_mp3_codec_t *codec;
00585
00586
00587 codec_base->priv = calloc(1, sizeof(quicktime_mp3_codec_t));
00588 codec_base->delete_acodec = delete_codec;
00589 codec_base->decode_audio = decode;
00590 codec_base->encode_audio = encode;
00591 codec_base->set_parameter = set_parameter;
00592 codec_base->flush = flush;
00593 codec_base->fourcc = QUICKTIME_MP3;
00594 codec_base->title = "MP3";
00595 codec_base->desc = "MP3 for video";
00596 codec_base->wav_id = 0x55;
00597
00598 codec = codec_base->priv;
00599 codec->bitrate = 256000;
00600 }
00601
00602
00603
00604