summaryrefslogtreecommitdiff
path: root/libavresample/audio_data.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2012-12-19 14:58:57 -0500
committerJustin Ruggles <justin.ruggles@gmail.com>2013-01-07 21:49:06 -0500
commit074a00d192c0e749d677b008b337da42597e780f (patch)
tree3f828927503dfef5df7eee5c974ffab75f2407be /libavresample/audio_data.c
parent4d68269d58ca4f6f71b4baa30e0cf9fbde52bbc3 (diff)
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.c32
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;