mirror of https://github.com/mpv-player/mpv
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:
parent
0ffaf653a2
commit
48c2e9d67d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue