mirror of
https://github.com/mpv-player/mpv
synced 2025-04-01 00:07:33 +00:00
af_lavrresample: add support for non-interleaved audio
This commit is contained in:
parent
bf60281ffb
commit
45d1510e4e
@ -24,6 +24,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/audioconvert.h>
|
||||
#include <libavutil/common.h>
|
||||
@ -244,10 +246,8 @@ 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_NE);
|
||||
mp_audio_force_interleaved_format(in);
|
||||
if (af_to_avformat(out->format) == AV_SAMPLE_FMT_NONE)
|
||||
mp_audio_set_format(out, in->format);
|
||||
mp_audio_force_interleaved_format(out);
|
||||
|
||||
af->mul = (double) (out->rate * out->nch) / (in->rate * in->nch);
|
||||
af->delay = out->nch * s->opts.filter_size / FFMIN(af->mul, 1);
|
||||
@ -301,38 +301,51 @@ static bool needs_reorder(int *reorder, int num_ch)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reorder_planes(struct mp_audio *mpa, int *reorder)
|
||||
{
|
||||
struct mp_audio prev = *mpa;
|
||||
for (int n = 0; n < mpa->num_planes; n++) {
|
||||
assert(reorder[n] >= 0 && reorder[n] < mpa->num_planes);
|
||||
mpa->planes[n] = prev.planes[reorder[n]];
|
||||
}
|
||||
}
|
||||
|
||||
#if !USE_SET_CHANNEL_MAPPING
|
||||
static void do_reorder(struct mp_audio *mpa, int *reorder)
|
||||
{
|
||||
if (af_fmt_is_planar(mpa->format)) {
|
||||
reorder_planes(mpa, reorder);
|
||||
} else {
|
||||
reorder_channels(mpa->planes[0], reorder, mpa->bps, mpa->nch, mpa->samples);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
struct mp_audio *in = data;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
|
||||
int in_samples = data->samples;
|
||||
int in_size = data->samples * data->sstride;
|
||||
int out_samples = avresample_available(s->avrctx) +
|
||||
av_rescale_rnd(get_delay(s) + in_samples,
|
||||
out->samples = avresample_available(s->avrctx) +
|
||||
av_rescale_rnd(get_delay(s) + in->samples,
|
||||
s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
|
||||
int out_size = out_samples * out->sstride;
|
||||
|
||||
if (talloc_get_size(out->planes[0]) < out_size)
|
||||
out->planes[0] = talloc_realloc_size(out, out->planes[0], out_size);
|
||||
mp_audio_realloc_min(out, out->samples);
|
||||
|
||||
af->delay = out->bps * av_rescale_rnd(get_delay(s),
|
||||
s->ctx.out_rate, s->ctx.in_rate,
|
||||
AV_ROUND_UP);
|
||||
|
||||
#if USE_SET_CHANNEL_MAPPING
|
||||
(void)in_size;
|
||||
#else
|
||||
reorder_channels(data->planes[0], s->reorder_in, data->bps, data->nch, in_samples);
|
||||
#if !USE_SET_CHANNEL_MAPPING
|
||||
do_reorder(in, s->reorder_in);
|
||||
#endif
|
||||
|
||||
if (out_samples) {
|
||||
out_samples = avresample_convert(s->avrctx,
|
||||
(uint8_t **) out->planes, out_size, out_samples,
|
||||
(uint8_t **) in->planes, in_size, in_samples);
|
||||
if (out_samples < 0)
|
||||
if (out->samples) {
|
||||
out->samples = avresample_convert(s->avrctx,
|
||||
(uint8_t **) out->planes, out->samples * out->sstride, out->samples,
|
||||
(uint8_t **) in->planes, in->samples * in->sstride, in->samples);
|
||||
if (out->samples < 0)
|
||||
return NULL; // error
|
||||
}
|
||||
|
||||
@ -340,18 +353,23 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
|
||||
#if USE_SET_CHANNEL_MAPPING
|
||||
if (needs_reorder(s->reorder_out, out->nch)) {
|
||||
if (talloc_get_size(s->reorder_buffer) < out_size)
|
||||
s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size);
|
||||
data->planes[0] = s->reorder_buffer;
|
||||
out_samples = avresample_convert(s->avrctx_out,
|
||||
(uint8_t **) data->planes, out_size, out_samples,
|
||||
(uint8_t **) out->planes, out_size, out_samples);
|
||||
if (af_fmt_is_planar(out->format)) {
|
||||
reorder_planes(data, s->reorder_out);
|
||||
} else {
|
||||
int out_size = out->samples * out->sstride;
|
||||
if (talloc_get_size(s->reorder_buffer) < out_size)
|
||||
s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size);
|
||||
data->planes[0] = s->reorder_buffer;
|
||||
int out_samples = avresample_convert(s->avrctx_out,
|
||||
(uint8_t **) data->planes, out_size, out->samples,
|
||||
(uint8_t **) out->planes, out_size, out->samples);
|
||||
assert(out_samples == data->samples);
|
||||
}
|
||||
}
|
||||
#else
|
||||
reorder_channels(data->planes[0], s->reorder_out, out->bps, out->nch, out_samples);
|
||||
do_reorder(data, s->reorder_out);
|
||||
#endif
|
||||
|
||||
data->samples = out_samples;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user