diff options
author | wm4 <wm4@nowhere> | 2014-11-10 22:01:23 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-10 22:02:05 +0100 |
commit | 5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1 (patch) | |
tree | a3a3ae0ac6ee87449ed780604e55da6dca2f34f2 /audio/decode/ad_spdif.c | |
parent | 46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1 (diff) | |
download | mpv-5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1.tar.bz2 mpv-5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1.tar.xz |
audio: make decoders output refcounted frames
This rewrites the audio decode loop to some degree. Audio filters don't
do refcounted frames yet, so af.c contains a hacky "emulation".
Remove some of the weird heuristic-heavy code in dec_audio.c. Instead of
estimating how much audio we need to filter, we always filter full
frames. Maybe this should be adjusted later: in case filtering increases
the volume of the audio data, we should try not to buffer too much
filter output by reducing the input that is fed at once.
For ad_spdif.c and ad_mpg123.c, we don't avoid extra copying yet - it
doesn't seem worth the trouble.
Diffstat (limited to 'audio/decode/ad_spdif.c')
-rw-r--r-- | audio/decode/ad_spdif.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index bb39298dd6..a0d6d4da99 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -40,6 +40,7 @@ struct spdifContext { int out_buffer_len; uint8_t out_buffer[OUTBUF_SIZE]; bool need_close; + struct mp_audio fmt; }; static int write_packet(void *p, uint8_t *buf, int buf_size) @@ -162,9 +163,9 @@ static int init(struct dec_audio *da, const char *decoder) default: abort(); } - mp_audio_set_num_channels(&da->decoded, num_channels); - mp_audio_set_format(&da->decoded, sample_format); - da->decoded.rate = samplerate; + mp_audio_set_num_channels(&spdif_ctx->fmt, num_channels); + mp_audio_set_format(&spdif_ctx->fmt, sample_format); + spdif_ctx->fmt.rate = samplerate; if (avformat_write_header(lavf_ctx, &format_opts) < 0) { MP_FATAL(da, "libavformat spdif initialization failed.\n"); @@ -182,13 +183,11 @@ fail: return 0; } -static int decode_packet(struct dec_audio *da) +static int decode_packet(struct dec_audio *da, struct mp_audio **out) { struct spdifContext *spdif_ctx = da->priv; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; - mp_audio_set_null_data(&da->decoded); - spdif_ctx->out_buffer_len = 0; struct demux_packet *mpkt; @@ -212,8 +211,12 @@ static int decode_packet(struct dec_audio *da) if (ret < 0) return AD_ERR; - da->decoded.planes[0] = spdif_ctx->out_buffer; - da->decoded.samples = spdif_ctx->out_buffer_len / da->decoded.sstride; + int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride; + *out = mp_audio_pool_get(da->pool, &spdif_ctx->fmt, samples); + if (!*out) + return AD_ERR; + + memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len); return 0; } |