1 #include "funcprotos.h"
6 #include "mpeg3private.h"
7 #include "mpeg3protos.h"
11 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
13 #define OUTPUT_ALLOCATION 0x100000
15 //static FILE *test = 0;
21 // Can't use same structure for header testing
22 mpeg3_layer_t
*mp3_header
;
23 unsigned char *packet_buffer
;
27 // Number of first sample in output relative to file
28 int64_t output_position
;
29 // Number of samples in output buffer
31 // Number of samples allocated in output buffer
32 long output_allocated
;
33 // Current reading position in file
35 int decode_initialized
;
41 lame_global_flags
*lame_global
;
42 // This calculates the number of samples per chunk
43 mpeg3_layer_t
*encoded_header
;
44 int encode_initialized
;
49 unsigned char *encoder_output
;
50 int encoder_output_size
;
51 int encoder_output_allocated
;
52 } quicktime_mp3_codec_t
;
58 static int delete_codec(quicktime_audio_map_t
*atrack
)
60 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
61 if(codec
->mp3
) mpeg3_delete_layer(codec
->mp3
);
62 if(codec
->mp3_header
) mpeg3_delete_layer(codec
->mp3_header
);
63 if(codec
->packet_buffer
) free(codec
->packet_buffer
);
67 for(i
= 0; i
< atrack
->channels
; i
++)
68 free(codec
->output
[i
]);
72 if(codec
->lame_global
)
74 lame_close(codec
->lame_global
);
80 for(i
= 0; i
< atrack
->channels
; i
++)
82 free(codec
->input
[i
]);
87 if(codec
->encoder_output
)
88 free(codec
->encoder_output
);
90 if(codec
->encoded_header
)
91 mpeg3_delete_layer(codec
->encoded_header
);
98 static int chunk_len(quicktime_t
*file
,
99 quicktime_mp3_codec_t
*codec
,
104 unsigned char header
[4];
107 while(offset
< next_chunk
)
109 quicktime_set_position(file
, offset
);
110 result
= !quicktime_read_data(file
, (unsigned char*)&header
, 4);
117 // Decode size of mp3 frame
118 result
= mpeg3_layer_header(codec
->mp3_header
,
129 quicktime_set_position(file
, offset
+ result
);
144 static int decode(quicktime_t
*file
,
152 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
153 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
154 quicktime_trak_t
*trak
= track_map
->track
;
155 long current_position
= track_map
->current_position
;
156 long end_position
= current_position
+ samples
;
167 if(samples
> OUTPUT_ALLOCATION
)
168 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION
);
171 //printf("decode 1\n");
172 if(output_i
) bzero(output_i
, sizeof(int16_t) * samples
);
173 if(output_f
) bzero(output_f
, sizeof(float) * samples
);
175 temp_output
= malloc(sizeof(float*) * track_map
->channels
);
177 // Seeked outside output buffer's range or not initialized: restart
178 if(current_position
< codec
->output_position
||
179 current_position
> codec
->output_position
+ codec
->output_size
||
180 !codec
->decode_initialized
)
182 quicktime_chunk_of_sample(&codec
->output_position
,
187 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
188 codec
->output_size
= 0;
189 //printf("decode 1 %lld %d\n", codec->output_position, quicktime_chunk_samples(trak, codec->chunk));
190 codec
->output_position
= quicktime_sample_of_chunk(trak
, codec
->chunk
);
191 //printf("decode 2 %lld\n", codec->output_position);
193 // Initialize and load initial buffer for decoding
194 if(!codec
->decode_initialized
)
197 codec
->decode_initialized
= 1;
198 codec
->output
= malloc(sizeof(float*) * track_map
->channels
);
199 for(i
= 0; i
< track_map
->channels
; i
++)
201 codec
->output
[i
] = malloc(sizeof(float) * OUTPUT_ALLOCATION
);
203 codec
->output_allocated
= OUTPUT_ALLOCATION
;
204 codec
->mp3
= mpeg3_new_layer();
205 codec
->mp3_header
= mpeg3_new_layer();
209 // Decode chunks until output is big enough
210 while(codec
->output_position
+ codec
->output_size
<
211 current_position
+ samples
&&
215 offset1
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
);
216 offset2
= quicktime_chunk_to_offset(file
, trak
, codec
->chunk
+ 1);
218 if(offset2
== offset1
) break;
220 chunk_size
= chunk_len(file
, codec
, offset1
, offset2
);
222 if(codec
->packet_allocated
< chunk_size
&&
223 codec
->packet_buffer
)
225 free(codec
->packet_buffer
);
226 codec
->packet_buffer
= 0;
229 if(!codec
->packet_buffer
)
231 codec
->packet_buffer
= calloc(1, chunk_size
);
232 codec
->packet_allocated
= chunk_size
;
235 quicktime_set_position(file
, offset1
);
236 result
= !quicktime_read_data(file
, codec
->packet_buffer
, chunk_size
);
239 for(i
= 0; i
< chunk_size
; )
241 // Allocate more output
242 new_size
= codec
->output_size
+ MAXFRAMESAMPLES
;
243 if(new_size
> codec
->output_allocated
)
245 for(j
= 0; j
< track_map
->channels
; j
++)
247 float *new_output
= calloc(sizeof(float), new_size
);
250 sizeof(float) * codec
->output_size
);
251 free(codec
->output
[j
]);
252 codec
->output
[j
] = new_output
;
254 codec
->output_allocated
= new_size
;
258 for(j
= 0; j
< track_map
->channels
; j
++)
259 temp_output
[j
] = codec
->output
[j
] + codec
->output_size
;
261 frame_size
= mpeg3_layer_header(codec
->mp3
,
262 codec
->packet_buffer
+ i
);
264 result
= mpeg3audio_dolayer3(codec
->mp3
,
265 codec
->packet_buffer
+ i
,
273 codec
->output_size
+= result
;
288 // Transfer region of output to argument
289 pcm
= codec
->output
[channel
];
292 for(i
= current_position
- codec
->output_position
, j
= 0;
293 j
< samples
&& i
< codec
->output_size
;
296 int sample
= pcm
[i
] * 32767;
297 CLAMP(sample
, -32768, 32767);
298 output_i
[j
] = sample
;
304 for(i
= current_position
- codec
->output_position
, j
= 0;
305 j
< samples
&& i
< codec
->output_size
;
308 output_f
[j
] = pcm
[i
];
312 // Delete excess output
313 if(codec
->output_size
> OUTPUT_ALLOCATION
)
315 int diff
= codec
->output_size
- OUTPUT_ALLOCATION
;
316 for(k
= 0; k
< track_map
->channels
; k
++)
318 pcm
= codec
->output
[k
];
319 for(i
= 0, j
= diff
; j
< codec
->output_size
; i
++, j
++)
324 codec
->output_size
-= diff
;
325 codec
->output_position
+= diff
;
329 //printf("decode 100\n");
336 static int allocate_output(quicktime_mp3_codec_t
*codec
,
339 int new_size
= codec
->encoder_output_size
+ samples
* 4;
340 if(codec
->encoder_output_allocated
< new_size
)
342 unsigned char *new_output
= calloc(1, new_size
);
344 if(codec
->encoder_output
)
347 codec
->encoder_output
,
348 codec
->encoder_output_size
);
349 free(codec
->encoder_output
);
351 codec
->encoder_output
= new_output
;
352 codec
->encoder_output_allocated
= new_size
;
359 // Empty the output buffer of frames
360 static int write_frames(quicktime_t
*file
,
361 quicktime_audio_map_t
*track_map
,
362 quicktime_trak_t
*trak
,
363 quicktime_mp3_codec_t
*codec
,
369 quicktime_atom_t chunk_atom
;
372 for(i
= 0; i
< codec
->encoder_output_size
- 4; )
374 unsigned char *header
= codec
->encoder_output
+ i
;
375 int frame_size
= mpeg3_layer_header(codec
->encoded_header
, header
);
379 // Frame is finished before end of buffer
380 if(i
+ frame_size
<= codec
->encoder_output_size
)
384 int frame_samples
= mpeg3audio_dolayer3(codec
->encoded_header
,
391 quicktime_write_vbr_frame(file
,
399 // quicktime_write_chunk_header(file, trak, &chunk_atom);
400 // result = !quicktime_write_data(file, header, frame_size);
401 // // Knows not to save the chunksizes for audio
402 // quicktime_write_chunk_footer(file,
404 // track_map->current_chunk,
407 track_map
->current_chunk
++;
415 // Frame isn't finished before end of buffer.
422 // Not the start of a frame. Skip it.
431 for(i
= frames_end
, j
= 0; i
< codec
->encoder_output_size
; i
++, j
++)
433 codec
->encoder_output
[j
] = codec
->encoder_output
[i
];
435 codec
->encoder_output_size
-= frames_end
;
445 static int encode(quicktime_t
*file
,
452 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
453 quicktime_trak_t
*trak
= track_map
->track
;
454 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
455 int new_size
= codec
->input_size
+ samples
;
459 if(!codec
->encode_initialized
)
461 codec
->encode_initialized
= 1;
462 codec
->lame_global
= lame_init();
463 lame_set_brate(codec
->lame_global
, codec
->bitrate
/ 1000);
464 lame_set_quality(codec
->lame_global
, 0);
465 lame_set_in_samplerate(codec
->lame_global
,
466 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
467 if((result
= lame_init_params(codec
->lame_global
)) < 0)
468 printf("encode: lame_init_params returned %d\n", result
);
469 codec
->encoded_header
= mpeg3_new_layer();
471 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
= 0;
475 // Stack input on end of buffer
476 if(new_size
> codec
->input_allocated
)
481 codec
->input
= calloc(sizeof(float*), track_map
->channels
);
483 for(i
= 0; i
< track_map
->channels
; i
++)
485 new_input
= calloc(sizeof(float), new_size
);
488 memcpy(new_input
, codec
->input
[i
], sizeof(float) * codec
->input_size
);
489 free(codec
->input
[i
]);
491 codec
->input
[i
] = new_input
;
493 codec
->input_allocated
= new_size
;
497 // Transfer to input buffers
500 for(i
= 0; i
< track_map
->channels
; i
++)
502 for(j
= 0; j
< samples
; j
++)
503 codec
->input
[i
][j
] = input_i
[i
][j
];
509 for(i
= 0; i
< track_map
->channels
; i
++)
511 for(j
= 0; j
< samples
; j
++)
512 codec
->input
[i
][j
] = input_f
[i
][j
] * 32767;
517 allocate_output(codec
, samples
);
519 result
= lame_encode_buffer_float(codec
->lame_global
,
521 (track_map
->channels
> 1) ? codec
->input
[1] : codec
->input
[0],
523 codec
->encoder_output
+ codec
->encoder_output_size
,
524 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
526 codec
->encoder_output_size
+= result
;
528 result
= write_frames(file
,
539 static int set_parameter(quicktime_t
*file
,
544 quicktime_audio_map_t
*atrack
= &(file
->atracks
[track
]);
545 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
547 if(!strcasecmp(key
, "mp3_bitrate"))
548 codec
->bitrate
= *(int*)value
;
555 static void flush(quicktime_t
*file
, int track
)
558 int64_t offset
= quicktime_position(file
);
559 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
560 quicktime_trak_t
*trak
= track_map
->track
;
561 quicktime_mp3_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
563 if(codec
->encode_initialized
)
565 result
= lame_encode_flush(codec
->lame_global
,
566 codec
->encoder_output
+ codec
->encoder_output_size
,
567 codec
->encoder_output_allocated
- codec
->encoder_output_size
);
568 codec
->encoder_output_size
+= result
;
569 result
= write_frames(file
,
578 void quicktime_init_codec_mp3(quicktime_audio_map_t
*atrack
)
580 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
581 quicktime_mp3_codec_t
*codec
;
583 /* Init public items */
584 codec_base
->priv
= calloc(1, sizeof(quicktime_mp3_codec_t
));
585 codec_base
->delete_acodec
= delete_codec
;
586 codec_base
->decode_audio
= decode
;
587 codec_base
->encode_audio
= encode
;
588 codec_base
->set_parameter
= set_parameter
;
589 codec_base
->flush
= flush
;
590 codec_base
->fourcc
= QUICKTIME_MP3
;
591 codec_base
->title
= "MP3";
592 codec_base
->desc
= "MP3 for video";
593 codec_base
->wav_id
= 0x55;
595 codec
= codec_base
->priv
;
596 codec
->bitrate
= 256000;