summaryrefslogtreecommitdiffstats
path: root/audio/decode/dec_audio.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-21 19:29:37 +0200
committerwm4 <wm4@nowhere>2014-07-21 19:29:58 +0200
commitb6af44d31e5c00b512e4c64b7075b771286e7c74 (patch)
tree0590b1095d13c61a538d622c1383f96554f27c85 /audio/decode/dec_audio.c
parent1f9e0a15a13f9b1efece10515c57e5ed4683e9f3 (diff)
downloadmpv-b6af44d31e5c00b512e4c64b7075b771286e7c74.tar.bz2
mpv-b6af44d31e5c00b512e4c64b7075b771286e7c74.tar.xz
audio: move initial decode to generic code
This commit mainly moves the initial decoding of data (done to probe the audio format) to generic code. This will make it easier to make audio decoding non-blocking in a later commit. This commit also changes how decoders return data: instead of having them write the data into a prepared buffer, they return a reference to an internal buffer (by setting dec_audio.decoded). This makes it significantly easier to handle audio format changes, since the decoders don't really need to care anymore.
Diffstat (limited to 'audio/decode/dec_audio.c')
-rw-r--r--audio/decode/dec_audio.c53
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