From eb4654c8155adfd4a9a1c0dc206fbcdb678356e7 Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 23 Aug 2024 21:25:24 +0200 Subject: [PATCH] cleanup: mpeg decoder tweaks --- src/coding/mpeg_custom_utils_ealayer3.c | 10 ++- src/coding/mpeg_custom_utils_eamp3.c | 5 +- src/coding/mpeg_decoder.c | 87 ++++++++++++------------- src/coding/mpeg_decoder.h | 17 ++--- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/src/coding/mpeg_custom_utils_ealayer3.c b/src/coding/mpeg_custom_utils_ealayer3.c index e86cc55e..60d0af54 100644 --- a/src/coding/mpeg_custom_utils_ealayer3.c +++ b/src/coding/mpeg_custom_utils_ealayer3.c @@ -698,7 +698,7 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d bytes_filled = sizeof(sample_t) * ms->samples_filled * channels_per_frame; - if (bytes_filled + eaf->pcm_size > ms->output_buffer_size) { + if (bytes_filled + eaf->pcm_size > ms->sbuf_size) { VGM_LOG("EAL3: can't fill the sample buffer with 0x%x\n", eaf->pcm_size); goto fail; } @@ -709,10 +709,12 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d } if (eaf->v1_pcm_samples || eaf->v1_offset_samples) { - uint8_t* outbuf = ms->output_buffer + bytes_filled; + uint8_t* outbuf = ms->sbuf; off_t pcm_offset = stream->offset + eaf->pre_size + eaf->common_size; size_t decode_to_discard; + outbuf += bytes_filled; + VGM_ASSERT(eaf->v1_offset_samples > 576, "EAL3: big discard %i at 0x%x\n", eaf->v1_offset_samples, (uint32_t)stream->offset); VGM_ASSERT(eaf->v1_pcm_samples > 0x100, "EAL3: big samples %i at 0x%x\n", eaf->v1_pcm_samples, (uint32_t)stream->offset); VGM_ASSERT(eaf->v1_offset_samples > 0 && eaf->v1_pcm_samples == 0, "EAL3: offset_samples without pcm_samples\n"); /* not seen but could work */ @@ -742,10 +744,12 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d } if (eaf->v2_extended_flag) { - uint8_t* outbuf = ms->output_buffer + bytes_filled; + uint8_t* outbuf = ms->sbuf; off_t pcm_offset = stream->offset + eaf->pre_size + eaf->common_size; size_t usable_samples, decode_to_discard; + outbuf += bytes_filled; + /* V2P usually only copies big PCM, while V2S discards then copies few samples (similar to V1b). * Unlike V1b, both modes seem to use 'packed' PCM block */ ealayer3_copy_pcm_block(outbuf, pcm_offset, eaf->v2_pcm_samples, channels_per_frame, 1, stream->streamfile); diff --git a/src/coding/mpeg_custom_utils_eamp3.c b/src/coding/mpeg_custom_utils_eamp3.c index 6b59e1e4..1db0b224 100644 --- a/src/coding/mpeg_custom_utils_eamp3.c +++ b/src/coding/mpeg_custom_utils_eamp3.c @@ -131,7 +131,7 @@ static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data bytes_filled = sizeof(sample_t) * ms->samples_filled * data->channels_per_frame; - if (bytes_filled + eaf->pcm_size > ms->output_buffer_size) { + if (bytes_filled + eaf->pcm_size > ms->sbuf_size) { VGM_LOG("EAMP3: can't fill the sample buffer with 0x%x\n", eaf->pcm_size); goto fail; } @@ -143,7 +143,8 @@ static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data for (i = 0; i < eaf->pcm_number * data->channels_per_frame; i++) { off_t pcm_offset = stream->offset + eaf->pre_size + eaf->mpeg_size + sizeof(sample_t)*i; int16_t pcm_sample = read_s16le(pcm_offset,stream->streamfile); - put_s16le(ms->output_buffer + bytes_filled + sizeof(sample_t) * i, pcm_sample); + uint8_t* sbuf = ms->sbuf; + put_s16le(sbuf + bytes_filled + sizeof(sample_t) * i, pcm_sample); } ms->samples_filled += eaf->pcm_number; diff --git a/src/coding/mpeg_decoder.c b/src/coding/mpeg_decoder.c index 6363e258..6dbd9050 100644 --- a/src/coding/mpeg_decoder.c +++ b/src/coding/mpeg_decoder.c @@ -170,9 +170,9 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* if (!data->streams[i].handle) goto fail; /* size could be any value */ - data->streams[i].output_buffer_size = sizeof(sample_t) * data->channels_per_frame * data->samples_per_frame; - data->streams[i].output_buffer = calloc(data->streams[i].output_buffer_size, sizeof(uint8_t)); - if (!data->streams[i].output_buffer) goto fail; + data->streams[i].sbuf_size = sizeof(sample_t) * data->channels_per_frame * data->samples_per_frame; + data->streams[i].sbuf = calloc(data->streams[i].sbuf_size, sizeof(uint8_t)); + if (!data->streams[i].sbuf) goto fail; /* one per stream as sometimes mpg123 can't read the whole buffer in one pass */ data->streams[i].buffer_size = data->default_buffer_size; @@ -246,16 +246,15 @@ void decode_mpeg(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, * Feeds raw data and extracts decoded samples as needed. */ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels) { - int samples_done = 0; - unsigned char *outbytes = (unsigned char *)outbuf; + int samples_done = 0; while (samples_done < samples_to_do) { size_t bytes_done; int rc, bytes_to_do; /* read more raw data */ if (!data->buffer_full) { - data->bytes_in_buffer = read_streamfile(data->buffer,stream->offset,data->buffer_size,stream->streamfile); + data->bytes_in_buffer = read_streamfile(data->buffer, stream->offset, data->buffer_size, stream->streamfile); /* end of stream, fill rest with 0s */ if (data->bytes_in_buffer <= 0) { @@ -264,32 +263,32 @@ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data break; } - data->buffer_full = 1; - data->buffer_used = 0; + data->buffer_full = true; + data->buffer_used = false; stream->offset += data->bytes_in_buffer; } - bytes_to_do = (samples_to_do-samples_done)*sizeof(sample_t)*channels; + bytes_to_do = (samples_to_do-samples_done) * channels * sizeof(sample_t); /* feed new raw data to the decoder if needed, copy decoded results to output */ if (!data->buffer_used) { - rc = mpg123_decode(data->m, data->buffer,data->bytes_in_buffer, outbytes, bytes_to_do, &bytes_done); - data->buffer_used = 1; + rc = mpg123_decode(data->m, data->buffer, data->bytes_in_buffer, outbuf, bytes_to_do, &bytes_done); + data->buffer_used = true; } else { - rc = mpg123_decode(data->m, NULL,0, outbytes, bytes_to_do, &bytes_done); + rc = mpg123_decode(data->m, NULL,0, outbuf, bytes_to_do, &bytes_done); } /* not enough raw data, request more */ if (rc == MPG123_NEED_MORE) { - data->buffer_full = 0; + data->buffer_full = false; } VGM_ASSERT(rc != MPG123_NEED_MORE && rc != MPG123_OK, "MPEG: error %i\n", rc); /* update copied samples */ samples_done += bytes_done / sizeof(sample_t) / channels; - outbytes += bytes_done; + outbuf += bytes_done / sizeof(sample_t); } } @@ -301,14 +300,14 @@ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data . Depletes the stream's sample buffers before decoding more, so it doesn't run out of buffer space. */ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels) { - int i, samples_done = 0; + int samples_done = 0; while (samples_done < samples_to_do) { int samples_to_copy = -1; /* find max to copy from all streams (equal for all channels) */ - for (i = 0; i < data->streams_size; i++) { - size_t samples_in_stream = data->streams[i].samples_filled - data->streams[i].samples_used; + for (int i = 0; i < data->streams_size; i++) { + size_t samples_in_stream = data->streams[i].samples_filled - data->streams[i].samples_used; if (samples_to_copy < 0 || samples_in_stream < samples_to_copy) samples_to_copy = samples_in_stream; } @@ -320,7 +319,7 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp if (samples_to_discard > data->samples_to_discard) samples_to_discard = data->samples_to_discard; - for (i = 0; i < data->streams_size; i++) { + for (int i = 0; i < data->streams_size; i++) { data->streams[i].samples_used += samples_to_discard; } data->samples_to_discard -= samples_to_discard; @@ -329,24 +328,21 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp /* mux streams channels (1/2ch combos) to outbuf (Nch) */ if (samples_to_copy > 0) { - int ch, stream; - if (samples_to_copy > samples_to_do - samples_done) samples_to_copy = samples_to_do - samples_done; - ch = 0; - for (stream = 0; stream < data->streams_size; stream++) { + int ch = 0; + for (int stream = 0; stream < data->streams_size; stream++) { mpeg_custom_stream* ms = &data->streams[stream]; - sample_t* inbuf = (sample_t *)ms->output_buffer; + sample_t* sbuf = ms->sbuf; int stream_channels = ms->channels_per_frame; - int stream_ch, s; - for (stream_ch = 0; stream_ch < stream_channels; stream_ch++) { - for (s = 0; s < samples_to_copy; s++) { + for (int stream_ch = 0; stream_ch < stream_channels; stream_ch++) { + for (int s = 0; s < samples_to_copy; s++) { size_t stream_sample = (ms->samples_used+s)*stream_channels + stream_ch; size_t buffer_sample = (samples_done+s)*channels + ch; - outbuf[buffer_sample] = inbuf[stream_sample]; + outbuf[buffer_sample] = sbuf[stream_sample]; } ch++; } @@ -361,7 +357,7 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp /* Handle offsets depending on the data layout (may only use half VGMSTREAMCHANNELs with 2ch streams) * With multiple offsets they should already start in the first frame of each stream. */ - for (i=0; i < data->streams_size; i++) { + for (int i = 0; i < data->streams_size; i++) { switch(data->type) { //case MPEG_FSB: /* same offset: alternate frames between streams (maybe needed for weird layouts?) */ @@ -385,6 +381,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* int rc, ok; mpeg_custom_stream* ms = &data->streams[num_stream]; int channels_per_frame = ms->channels_per_frame; + uint8_t* sbuf = ms->sbuf; //;VGM_LOG("MPEG: decode stream%i @ 0x%08lx (filled=%i, used=%i, buffer_full=%i)\n", num_stream, stream->offset, ms->samples_filled, ms->samples_used, ms->buffer_full); @@ -424,8 +421,8 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* /* parse frame may not touch the buffer (only move offset, or fill the sample buffer) */ if (ms->bytes_in_buffer) { - ms->buffer_full = 1; - ms->buffer_used = 0; + ms->buffer_full = true; + ms->buffer_used = false; } } @@ -436,26 +433,25 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* //;VGM_LOG("MPEG: feed new data and get samples\n"); rc = mpg123_decode(ms->handle, ms->buffer, ms->bytes_in_buffer, - (unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled, + sbuf + bytes_filled, ms->sbuf_size - bytes_filled, &bytes_done); - ms->buffer_used = 1; + ms->buffer_used = true; } else { //;VGM_LOG("MPEG: get samples from old data\n"); rc = mpg123_decode(ms->handle, NULL, 0, - (unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled, + sbuf + bytes_filled, ms->sbuf_size - bytes_filled, &bytes_done); } - samples_filled = (bytes_done / sizeof(sample_t) / channels_per_frame); + samples_filled = bytes_done / channels_per_frame / sizeof(sample_t); /* discard for weird features (EALayer3 and PCM blocks, AWC and repeated frames) */ if (ms->decode_to_discard) { - size_t bytes_to_discard = 0; size_t decode_to_discard = ms->decode_to_discard; if (decode_to_discard > samples_filled) decode_to_discard = samples_filled; - bytes_to_discard = sizeof(sample_t) * decode_to_discard * channels_per_frame; + size_t bytes_to_discard = sizeof(sample_t) * decode_to_discard * channels_per_frame; bytes_done -= bytes_to_discard; ms->decode_to_discard -= decode_to_discard; @@ -469,7 +465,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* * (but only with empty mpg123 buffer, EA blocks wait for all samples decoded before advancing blocks) */ if (!bytes_done && rc == MPG123_NEED_MORE) { //;VGM_LOG("MPEG: need more raw data to get samples (bytes_done=%x)\n", bytes_done); - ms->buffer_full = 0; + ms->buffer_full = false; } @@ -479,8 +475,8 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* decode_fail: /* 0-fill but continue with other streams */ bytes_filled = ms->samples_filled * channels_per_frame * sizeof(sample_t); - memset(ms->output_buffer + bytes_filled, 0, ms->output_buffer_size - bytes_filled); - ms->samples_filled = (ms->output_buffer_size / channels_per_frame / sizeof(sample_t)); + memset(sbuf + bytes_filled, 0, ms->sbuf_size - bytes_filled); + ms->samples_filled = (ms->sbuf_size / channels_per_frame / sizeof(sample_t)); } @@ -503,7 +499,7 @@ void free_mpeg(mpeg_codec_data* data) { continue; mpg123_delete(data->streams[i].handle); free(data->streams[i].buffer); - free(data->streams[i].output_buffer); + free(data->streams[i].sbuf); } free(data->streams); } @@ -586,9 +582,8 @@ static void flush_mpeg(mpeg_codec_data* data, int is_loop) { mpg123_open_feed(data->m); /* mpg123_feedseek won't work */ } else { - int i; /* re-start from 0 */ - for (i=0; i < data->streams_size; i++) { + for (int i = 0; i < data->streams_size; i++) { if (!data->streams) continue; @@ -597,8 +592,8 @@ static void flush_mpeg(mpeg_codec_data* data, int is_loop) { if (is_loop && data->custom && !(data->type == MPEG_FSB)) mpg123_open_feed(data->streams[i].handle); data->streams[i].bytes_in_buffer = 0; - data->streams[i].buffer_full = 0; - data->streams[i].buffer_used = 0; + data->streams[i].buffer_full = false; + data->streams[i].buffer_used = false; data->streams[i].samples_filled = 0; data->streams[i].samples_used = 0; data->streams[i].current_size_count = 0; @@ -610,8 +605,8 @@ static void flush_mpeg(mpeg_codec_data* data, int is_loop) { } data->bytes_in_buffer = 0; - data->buffer_full = 0; - data->buffer_used = 0; + data->buffer_full = false; + data->buffer_used = false; } int mpeg_get_sample_rate(mpeg_codec_data* data) { diff --git a/src/coding/mpeg_decoder.h b/src/coding/mpeg_decoder.h index 83f4ca35..3278facc 100644 --- a/src/coding/mpeg_decoder.h +++ b/src/coding/mpeg_decoder.h @@ -12,16 +12,16 @@ /* represents a single MPEG stream */ typedef struct { /* per stream as sometimes mpg123 must be fed in passes if data is big enough (ex. EALayer3 multichannel) */ - uint8_t *buffer; /* raw data buffer */ + uint8_t* buffer; /* raw data buffer */ size_t buffer_size; size_t bytes_in_buffer; - int buffer_full; /* raw buffer has been filled */ - int buffer_used; /* raw buffer has been fed to the decoder */ + bool buffer_full; /* raw buffer has been filled */ + bool buffer_used; /* raw buffer has been fed to the decoder */ mpg123_handle* handle; /* MPEG decoder */ - uint8_t *output_buffer; /* decoded samples from this stream (in bytes for mpg123) */ - size_t output_buffer_size; + void* sbuf; /* decoded samples from this stream */ + size_t sbuf_size; /* in bytes for mpg123 */ size_t samples_filled; /* data in the buffer (in samples) */ size_t samples_used; /* data extracted from the buffer */ @@ -37,9 +37,10 @@ struct mpeg_codec_data { uint8_t* buffer; /* raw data buffer */ size_t buffer_size; size_t bytes_in_buffer; - int buffer_full; /* raw buffer has been filled */ - int buffer_used; /* raw buffer has been fed to the decoder */ - mpg123_handle *m; /* MPEG decoder */ + bool buffer_full; /* raw buffer has been filled */ + bool buffer_used; /* raw buffer has been fed to the decoder */ + + mpg123_handle* m; /* MPEG decoder */ struct mpg123_frameinfo mi; /* start info, so it's available even when resetting */ /* for internal use */