From 48c2e9d67d36af8aff354b18ab2ddda26abca117 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 26 Oct 2015 15:54:00 +0100 Subject: audio: use AVFrames with more than 8 channels correctly Requires messy dealing with the extended_ fields. Don't bother with af_lavfi and ao_lavc for now. There are probably no valid use-cases for these. --- audio/audio.c | 12 +++++++----- audio/filter/af_lavfi.c | 8 +++++--- audio/out/ao_lavc.c | 3 +++ 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'audio') diff --git a/audio/audio.c b/audio/audio.c index 4b12992879..c4ad4021b5 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -323,21 +323,23 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe) } // If we can't handle the format (e.g. too many channels), bail out. - if (!mp_audio_config_valid(new) || avframe->nb_extended_buf) + if (!mp_audio_config_valid(new)) goto fail; - for (int n = 0; n < AV_NUM_DATA_POINTERS; n++) { - if (!avframe->buf[n]) + for (int n = 0; n < AV_NUM_DATA_POINTERS + avframe->nb_extended_buf; n++) { + AVBufferRef *buf = n < AV_NUM_DATA_POINTERS ? avframe->buf[n] + : avframe->extended_buf[n - AV_NUM_DATA_POINTERS]; + if (!buf) break; if (n >= MP_NUM_CHANNELS) goto fail; - new->allocated[n] = av_buffer_ref(avframe->buf[n]); + new->allocated[n] = av_buffer_ref(buf); if (!new->allocated[n]) goto fail; } for (int n = 0; n < new->num_planes; n++) - new->planes[n] = avframe->data[n]; + new->planes[n] = avframe->extended_data[n]; new->samples = avframe->nb_samples; return new; diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c index a40904aa78..af521abd9c 100644 --- a/audio/filter/af_lavfi.c +++ b/audio/filter/af_lavfi.c @@ -195,6 +195,10 @@ static int control(struct af_instance *af, int cmd, void *arg) if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(in, AF_FORMAT_FLOAT); + // Removing this requires fixing AVFrame.data vs. AVFrame.extended_data + if (in->channels.num > AV_NUM_DATA_POINTERS) + return AF_ERROR; + if (!mp_chmap_is_lavc(&in->channels)) mp_chmap_reorder_to_lavc(&in->channels); // will always work @@ -211,7 +215,7 @@ static int control(struct af_instance *af, int cmd, void *arg) mp_chmap_from_lavc(&out_cm, l_out->channel_layout); mp_audio_set_channels(out, &out_cm); - if (!mp_audio_config_valid(out)) + if (!mp_audio_config_valid(out) || out->channels.num > AV_NUM_DATA_POINTERS) return AF_ERROR; p->timebase_out = l_out->time_base; @@ -349,8 +353,6 @@ static int af_open(struct af_instance *af) af->uninit = uninit; af->filter_frame = filter_frame; af->filter_out = filter_out; - // Removing this requires fixing AVFrame.data vs. AVFrame.extended_data - assert(MP_NUM_CHANNELS <= AV_NUM_DATA_POINTERS); return AF_OK; } diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c index 09bf8717a6..332350fd17 100644 --- a/audio/out/ao_lavc.c +++ b/audio/out/ao_lavc.c @@ -164,6 +164,9 @@ static int init(struct ao *ao) ao->untimed = true; + if (ao->channels.num > AV_NUM_DATA_POINTERS) + goto fail; + pthread_mutex_unlock(&ao->encode_lavc_ctx->lock); return 0; -- cgit v1.2.3