diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-12-19 14:58:57 -0500 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2013-01-07 21:49:06 -0500 |
commit | 074a00d192c0e749d677b008b337da42597e780f (patch) | |
tree | 3f828927503dfef5df7eee5c974ffab75f2407be /libavresample/audio_data.c | |
parent | 4d68269d58ca4f6f71b4baa30e0cf9fbde52bbc3 (diff) | |
download | ffmpeg-074a00d192c0e749d677b008b337da42597e780f.tar.gz |
lavr: add a public function for setting a custom channel map
This allows reordering, duplication, and silencing of input channels.
Diffstat (limited to 'libavresample/audio_data.c')
-rw-r--r-- | libavresample/audio_data.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/libavresample/audio_data.c b/libavresample/audio_data.c index 199a68cb11..c52f518e9a 100644 --- a/libavresample/audio_data.c +++ b/libavresample/audio_data.c @@ -213,7 +213,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; @@ -221,6 +221,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; @@ -233,8 +238,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; |