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.
This commit is contained in:
wm4 2015-10-26 15:54:00 +01:00
parent 0ffaf653a2
commit 48c2e9d67d
3 changed files with 15 additions and 8 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;