minimp3: Numerous buffering fixes, consolidation
Move minimp3 packet decoder state into the decoder_ex state structure, instead of using the redundant duplicate structure. Also reduce input buffer size for streams to 16KiB, and actually use the defined macro in the header file to declare the streaming buffer size. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
6e8538c7c9
commit
410395dded
2 changed files with 14 additions and 11 deletions
|
@ -15,12 +15,11 @@
|
|||
|
||||
#import "Plugin.h"
|
||||
|
||||
#define INPUT_BUFFER_SIZE 5 * 8192
|
||||
#define INPUT_BUFFER_SIZE 16 * 1024
|
||||
|
||||
@interface MP3Decoder : NSObject <CogDecoder> {
|
||||
BOOL seekable;
|
||||
mp3dec_t _decoder;
|
||||
unsigned char _decoder_buffer[32768];
|
||||
unsigned char _decoder_buffer[INPUT_BUFFER_SIZE];
|
||||
size_t _decoder_buffer_filled;
|
||||
|
||||
mp3dec_ex_t _decoder_ex;
|
||||
|
|
|
@ -38,6 +38,8 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
size_t id3_length = 0;
|
||||
|
||||
if(seekable) {
|
||||
// minimp3 already skips ID3v2, but we need to supplement it with support for
|
||||
// iTunes gapless info, which is stored in the ID3v2 tag
|
||||
uint8_t buffer[10];
|
||||
size_t buflen = [source read:&buffer[0] amount:10];
|
||||
|
||||
|
@ -137,12 +139,14 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
if(error)
|
||||
return NO;
|
||||
if(_foundiTunSMPB) {
|
||||
// start_delay is used for seeking, to_skip must be filled for the first packet decoded
|
||||
// and detected_samples will truncate the end padding
|
||||
_decoder_ex.start_delay = _decoder_ex.to_skip = _startPadding * _decoder_ex.info.channels;
|
||||
_decoder_ex.detected_samples = totalFrames * _decoder_ex.info.channels;
|
||||
_decoder_ex.samples = (totalFrames + _startPadding + _endPadding) * _decoder_ex.info.channels;
|
||||
}
|
||||
mp3d_sample_t *sample_ptr = NULL;
|
||||
size_t samples = mp3dec_ex_read_frame(&_decoder_ex, &sample_ptr, &_decoder_info, 1152 * 2);
|
||||
size_t samples = mp3dec_ex_read_frame(&_decoder_ex, &sample_ptr, &_decoder_info, MINIMP3_MAX_SAMPLES_PER_FRAME);
|
||||
if(samples && sample_ptr) {
|
||||
samples_filled = samples / _decoder_info.channels;
|
||||
memcpy(&_decoder_buffer_output[0], sample_ptr, sizeof(mp3d_sample_t) * samples);
|
||||
|
@ -157,10 +161,10 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
}
|
||||
bitrate = (double)((_fileSize - id3_length) * 8) / ((double)totalFrames / (double)_decoder_info.hz) / 1000.0;
|
||||
} else {
|
||||
_decoder_buffer_filled = [source read:_decoder_buffer amount:32768];
|
||||
inputEOF = _decoder_buffer_filled < 32768;
|
||||
mp3dec_init(&_decoder);
|
||||
int samples = mp3dec_decode_frame(&_decoder, _decoder_buffer, (int)_decoder_buffer_filled, &_decoder_buffer_output[0], &_decoder_info);
|
||||
_decoder_buffer_filled = [source read:_decoder_buffer amount:INPUT_BUFFER_SIZE];
|
||||
inputEOF = _decoder_buffer_filled < INPUT_BUFFER_SIZE;
|
||||
mp3dec_init(&_decoder_ex.mp3d);
|
||||
int samples = mp3dec_decode_frame(&_decoder_ex.mp3d, _decoder_buffer, (int)_decoder_buffer_filled, &_decoder_buffer_output[0], &_decoder_info);
|
||||
if(!samples)
|
||||
return NO;
|
||||
size_t bytes_read = _decoder_info.frame_bytes;
|
||||
|
@ -231,7 +235,7 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
|
||||
if(seekable) {
|
||||
mp3d_sample_t *sample_ptr = NULL;
|
||||
size_t samples = mp3dec_ex_read_frame(&_decoder_ex, &sample_ptr, &_decoder_info, 1152 * 2);
|
||||
size_t samples = mp3dec_ex_read_frame(&_decoder_ex, &sample_ptr, &_decoder_info, MINIMP3_MAX_SAMPLES_PER_FRAME);
|
||||
if(samples && sample_ptr) {
|
||||
samples_filled = samples / _decoder_info.channels;
|
||||
memcpy(&_decoder_buffer_output[0], sample_ptr, sizeof(mp3d_sample_t) * samples);
|
||||
|
@ -239,7 +243,7 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
inputEOF = YES;
|
||||
}
|
||||
} else {
|
||||
size_t bytesRemain = 32768 - _decoder_buffer_filled;
|
||||
size_t bytesRemain = INPUT_BUFFER_SIZE - _decoder_buffer_filled;
|
||||
ssize_t bytesRead = [_source read:&_decoder_buffer[_decoder_buffer_filled] amount:bytesRemain];
|
||||
if(bytesRead < 0 || bytesRead < bytesRemain) {
|
||||
inputEOF = YES;
|
||||
|
@ -247,7 +251,7 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
|
|||
if(bytesRead > 0) {
|
||||
_decoder_buffer_filled += bytesRead;
|
||||
}
|
||||
int samples = mp3dec_decode_frame(&_decoder, &_decoder_buffer[0], (int)_decoder_buffer_filled, &_decoder_buffer_output[0], &_decoder_info);
|
||||
int samples = mp3dec_decode_frame(&_decoder_ex.mp3d, &_decoder_buffer[0], (int)_decoder_buffer_filled, &_decoder_buffer_output[0], &_decoder_info);
|
||||
if(samples > 0) {
|
||||
samples_filled = samples;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue