lavfi: add avfilter_get_audio_buffer_ref_from_arrays_channels.
authorNicolas George <nicolas.george@normalesup.org>
Sun, 30 Dec 2012 14:15:50 +0000 (15:15 +0100)
committerNicolas George <nicolas.george@normalesup.org>
Tue, 1 Jan 2013 01:01:28 +0000 (02:01 +0100)
It is the same as avfilter_get_audio_buffer_ref_from_arrays
except it has a "channels" and the channel layout can be 0.

libavfilter/audio.c
libavfilter/avcodec.c
libavfilter/avfilter.h
libavfilter/src_buffer.c

index 3564896..74cf9a8 100644 (file)
@@ -58,9 +58,9 @@ AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
     if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
         goto fail;
 
-    samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, full_perms,
-                                                           nb_samples, link->format,
-                                                           link->channel_layout);
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
+        data, linesize, full_perms, nb_samples, link->format,
+        link->channels, link->channel_layout);
     if (!samplesref)
         goto fail;
 
@@ -92,13 +92,14 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
     return ret;
 }
 
-AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
-                                                             int linesize,int perms,
-                                                             int nb_samples,
-                                                             enum AVSampleFormat sample_fmt,
-                                                             uint64_t channel_layout)
+AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
+                                                                      int linesize,
+                                                                      int perms,
+                                                                      int nb_samples,
+                                                                      enum AVSampleFormat sample_fmt,
+                                                                      int channels,
+                                                                      uint64_t channel_layout)
 {
-    int channels = av_get_channel_layout_nb_channels(channel_layout);
     int planes;
     AVFilterBuffer    *samples    = av_mallocz(sizeof(*samples));
     AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
@@ -106,6 +107,10 @@ AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
     if (!samples || !samplesref)
         goto fail;
 
+    av_assert0(channels);
+    av_assert0(channel_layout == 0 ||
+               channels == av_get_channel_layout_nb_channels(channel_layout));
+
     samplesref->buf         = samples;
     samplesref->buf->free   = ff_avfilter_default_free_buffer;
     if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
@@ -163,6 +168,18 @@ fail:
     return NULL;
 }
 
+AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
+                                                             int linesize,int perms,
+                                                             int nb_samples,
+                                                             enum AVSampleFormat sample_fmt,
+                                                             uint64_t channel_layout)
+{
+    int channels = av_get_channel_layout_nb_channels(channel_layout);
+    return avfilter_get_audio_buffer_ref_from_arrays_channels(data, linesize, perms,
+                                                              nb_samples, sample_fmt,
+                                                              channels, channel_layout);
+}
+
 static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
 {
     return ff_filter_frame(link->dst->outputs[0], frame);
index 2533bd8..dcd6bb6 100644 (file)
@@ -93,6 +93,7 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame
                                                             int perms)
 {
     AVFilterBufferRef *samplesref;
+    int channels = av_frame_get_channels(frame);
     int64_t layout = av_frame_get_channel_layout(frame);
 
     if(av_frame_get_channels(frame) > 8) // libavfilter does not suport more than 8 channels FIXME, remove once libavfilter is fixed
@@ -103,9 +104,9 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame
         return NULL;
     }
 
-    samplesref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms,
-                                                  frame->nb_samples, frame->format,
-                                                  av_frame_get_channel_layout(frame));
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
+        (uint8_t **)frame->data, frame->linesize[0], perms,
+        frame->nb_samples, frame->format, channels, layout);
     if (!samplesref)
         return NULL;
     if (avfilter_copy_frame_props(samplesref, frame) < 0) {
index 3849c7b..900afbb 100644 (file)
@@ -765,6 +765,9 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int lin
  * Create an audio buffer reference wrapped around an already
  * allocated samples buffer.
  *
+ * See avfilter_get_audio_buffer_ref_from_arrays_channels() for a version
+ * that can handle unknown channel layouts.
+ *
  * @param data           pointers to the samples plane buffers
  * @param linesize       linesize for the samples plane buffers
  * @param perms          the required access permissions
@@ -778,6 +781,27 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
                                                              int nb_samples,
                                                              enum AVSampleFormat sample_fmt,
                                                              uint64_t channel_layout);
+/**
+ * Create an audio buffer reference wrapped around an already
+ * allocated samples buffer.
+ *
+ * @param data           pointers to the samples plane buffers
+ * @param linesize       linesize for the samples plane buffers
+ * @param perms          the required access permissions
+ * @param nb_samples     number of samples per channel
+ * @param sample_fmt     the format of each sample in the buffer to allocate
+ * @param channels       the number of channels of the buffer
+ * @param channel_layout the channel layout of the buffer,
+ *                       must be either 0 or consistent with channels
+ */
+AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
+                                                                      int linesize,
+                                                                      int perms,
+                                                                      int nb_samples,
+                                                                      enum AVSampleFormat sample_fmt,
+                                                                      int channels,
+                                                                      uint64_t channel_layout);
+
 
 
 #define AVFILTER_CMD_FLAG_ONE   1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically
index acd490b..a997034 100644 (file)
@@ -81,6 +81,8 @@ int av_asrc_buffer_add_samples(AVFilterContext *ctx,
 {
     AVFilterBufferRef *samplesref;
 
+    if (!channel_layout)
+        return AVERROR(EINVAL);
     samplesref = avfilter_get_audio_buffer_ref_from_arrays(
                      data, linesize[0], AV_PERM_WRITE,
                      nb_samples,