*/
#include <stdint.h>
+#include <string.h>
#include "libavutil/mem.h"
#include "audio_data.h"
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 ||
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;
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);
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);
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;
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;
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;