X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavresample%2Faudio_data.c;h=2d01b8cfaa4b74719b781f90c3b3e66b30b415c1;hb=421c10ed4fb0475a2cb055dd130ba12a6adb9f70;hp=3f82c50ef0a213cd41bd10535bbbc0cd0e31115f;hpb=c8af852b97447491823ff9b91413e32415e2babf;p=ffmpeg diff --git a/libavresample/audio_data.c b/libavresample/audio_data.c index 3f82c50ef0a..2d01b8cfaa4 100644 --- a/libavresample/audio_data.c +++ b/libavresample/audio_data.c @@ -19,6 +19,7 @@ */ #include +#include #include "libavutil/mem.h" #include "audio_data.h" @@ -47,6 +48,14 @@ static void calc_ptr_alignment(AudioData *a) a->ptr_align = min_align; } +int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels) +{ + if (channels == 1) + return 1; + else + return av_sample_fmt_is_planar(sample_fmt); +} + int ff_audio_data_set_channels(AudioData *a, int channels) { if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS || @@ -61,9 +70,10 @@ int ff_audio_data_set_channels(AudioData *a, int channels) return 0; } -int ff_audio_data_init(AudioData *a, void **src, int plane_size, int channels, - int nb_samples, enum AVSampleFormat sample_fmt, - int read_only, const char *name) +int ff_audio_data_init(AudioData *a, uint8_t * const *src, int plane_size, + int channels, int nb_samples, + enum AVSampleFormat sample_fmt, int read_only, + const char *name) { int p; @@ -80,7 +90,7 @@ int ff_audio_data_init(AudioData *a, void **src, int plane_size, int channels, av_log(a, AV_LOG_ERROR, "invalid sample format\n"); return AVERROR(EINVAL); } - a->is_planar = av_sample_fmt_is_planar(sample_fmt); + a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels); a->planes = a->is_planar ? channels : 1; a->stride = a->sample_size * (a->is_planar ? 1 : channels); @@ -124,7 +134,7 @@ AudioData *ff_audio_data_alloc(int channels, int nb_samples, av_free(a); return NULL; } - a->is_planar = av_sample_fmt_is_planar(sample_fmt); + a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels); a->planes = a->is_planar ? channels : 1; a->stride = a->sample_size * (a->is_planar ? 1 : channels); @@ -212,7 +222,7 @@ void ff_audio_data_free(AudioData **a) av_freep(a); } -int ff_audio_data_copy(AudioData *dst, AudioData *src) +int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map) { int ret, p; @@ -220,6 +230,11 @@ int ff_audio_data_copy(AudioData *dst, AudioData *src) if (dst->sample_fmt != src->sample_fmt || dst->channels < src->channels) return AVERROR(EINVAL); + if (map && !src->is_planar) { + av_log(src, AV_LOG_ERROR, "cannot remap packed format during copy\n"); + return AVERROR(EINVAL); + } + /* if the input is empty, just empty the output */ if (!src->nb_samples) { dst->nb_samples = 0; @@ -232,8 +247,29 @@ int ff_audio_data_copy(AudioData *dst, AudioData *src) return ret; /* copy data */ - for (p = 0; p < src->planes; p++) - memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride); + if (map) { + if (map->do_remap) { + for (p = 0; p < src->planes; p++) { + if (map->channel_map[p] >= 0) + memcpy(dst->data[p], src->data[map->channel_map[p]], + src->nb_samples * src->stride); + } + } + if (map->do_copy || map->do_zero) { + for (p = 0; p < src->planes; p++) { + if (map->channel_copy[p]) + memcpy(dst->data[p], dst->data[map->channel_copy[p]], + src->nb_samples * src->stride); + else if (map->channel_zero[p]) + av_samples_set_silence(&dst->data[p], 0, src->nb_samples, + 1, dst->sample_fmt); + } + } + } else { + for (p = 0; p < src->planes; p++) + memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride); + } + dst->nb_samples = src->nb_samples; return 0;