]> git.sesse.net Git - ffmpeg/blobdiff - libavresample/audio_data.c
configure: Drop test for fork()
[ffmpeg] / libavresample / audio_data.c
index 3f82c50ef0a213cd41bd10535bbbc0cd0e31115f..2d01b8cfaa4b74719b781f90c3b3e66b30b415c1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <stdint.h>
+#include <string.h>
 
 #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;