diff options
Diffstat (limited to 'audio/decode/dec_audio.c')
-rw-r--r-- | audio/decode/dec_audio.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 907b154bf8..c2857353fa 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -56,13 +56,6 @@ static const struct ad_functions * const ad_drivers[] = { NULL }; -// ad_mpg123 needs to be able to decode 1152 samples at once -// ad_spdif needs up to 8192 -#define DECODE_MAX_UNIT MPMAX(8192, 1152) - -// At least 8192 samples, plus hack for ad_mpg123 and ad_spdif -#define DECODE_BUFFER_SAMPLES (8192 + DECODE_MAX_UNIT) - // Drop audio buffer and reinit it (after format change) // Returns whether the format was valid at all. static bool reinit_audio_buffer(struct dec_audio *da) @@ -73,7 +66,6 @@ static bool reinit_audio_buffer(struct dec_audio *da) return false; } mp_audio_buffer_reinit(da->decode_buffer, &da->decoded); - mp_audio_buffer_preallocate_min(da->decode_buffer, DECODE_BUFFER_SAMPLES); return true; } @@ -97,6 +89,21 @@ static int init_audio_codec(struct dec_audio *d_audio, const char *decoder) return 0; } + // Decode enough until we know the audio format. + for (int tries = 1; ; tries++) { + if (mp_audio_config_valid(&d_audio->decoded)) { + MP_VERBOSE(d_audio, "Initial decode succeeded after %d packets.\n", + tries); + break; + } + if (tries >= 50) { + MP_ERR(d_audio, "initial decode failed\n"); + uninit_decoder(d_audio); + return 0; + } + d_audio->ad_driver->decode_packet(d_audio); + } + d_audio->decode_buffer = mp_audio_buffer_create(NULL); if (!reinit_audio_buffer(d_audio)) { uninit_decoder(d_audio); @@ -241,26 +248,28 @@ static int filter_n_bytes(struct dec_audio *da, struct mp_audio_buffer *outbuf, mp_audio_buffer_get_format(da->decode_buffer, &config); while (mp_audio_buffer_samples(da->decode_buffer) < len) { - int maxlen = mp_audio_buffer_get_write_available(da->decode_buffer); - if (maxlen < DECODE_MAX_UNIT) - break; - struct mp_audio buffer; - mp_audio_buffer_get_write_buffer(da->decode_buffer, maxlen, &buffer); - buffer.samples = 0; - error = da->ad_driver->decode_audio(da, &buffer, maxlen); - if (error < 0) - break; - // Commit the data just read as valid data - mp_audio_buffer_finish_write(da->decode_buffer, buffer.samples); // Format change if (!mp_audio_config_equals(&da->decoded, &config)) { // If there are still samples left in the buffer, let them drain // first, and don't signal a format change to the caller yet. - if (mp_audio_buffer_samples(da->decode_buffer) > 0) - break; - error = AD_NEW_FMT; + if (mp_audio_buffer_samples(da->decode_buffer) == 0) + error = AD_NEW_FMT; break; } + if (da->decoded.samples > 0) { + int copy = MPMIN(da->decoded.samples, len); + struct mp_audio append = da->decoded; + append.samples = copy; + mp_audio_buffer_append(da->decode_buffer, &append); + mp_audio_skip_samples(&da->decoded, copy); + continue; + } + error = da->ad_driver->decode_packet(da); + if (error < 0) + break; + // No progress means the decoder is buffering input data. + if (!da->decoded.samples) + break; } // Filter |