summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-10-26 15:54:00 +0100
committerwm4 <wm4@nowhere>2015-10-26 15:54:00 +0100
commit48c2e9d67d36af8aff354b18ab2ddda26abca117 (patch)
tree09dd86519bbe9c557d19762bff508919086e79a4 /audio
parent0ffaf653a21d0c767abfcf1094f9e57a6c9b5ba4 (diff)
downloadmpv-48c2e9d67d36af8aff354b18ab2ddda26abca117.tar.bz2
mpv-48c2e9d67d36af8aff354b18ab2ddda26abca117.tar.xz
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.
Diffstat (limited to 'audio')
-rw-r--r--audio/audio.c12
-rw-r--r--audio/filter/af_lavfi.c8
-rw-r--r--audio/out/ao_lavc.c3
3 files changed, 15 insertions, 8 deletions
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;