lavfi: add avfilter_get_audio_buffer_ref_from_arrays().
authorStefano Sabatini <stefano.sabatini-lala@poste.it>
Sun, 30 Jan 2011 23:07:41 +0000 (00:07 +0100)
committerAnton Khirnov <anton@khirnov.net>
Wed, 9 May 2012 15:51:13 +0000 (17:51 +0200)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
libavfilter/avfilter.c
libavfilter/avfilter.h

index 5973e6b..e535bda 100644 (file)
@@ -385,6 +385,74 @@ AVFilterBufferRef *avfilter_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)
+{
+    int planes;
+    AVFilterBuffer    *samples    = av_mallocz(sizeof(*samples));
+    AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
+
+    if (!samples || !samplesref)
+        goto fail;
+
+    samplesref->buf         = samples;
+    samplesref->buf->free   = ff_avfilter_default_free_buffer;
+    if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
+        goto fail;
+
+    samplesref->audio->nb_samples     = nb_samples;
+    samplesref->audio->channel_layout = channel_layout;
+    samplesref->audio->planar         = av_sample_fmt_is_planar(sample_fmt);
+
+    planes = samplesref->audio->planar ? av_get_channel_layout_nb_channels(channel_layout) : 1;
+
+    /* make sure the buffer gets read permission or it's useless for output */
+    samplesref->perms = perms | AV_PERM_READ;
+
+    samples->refcount  = 1;
+    samplesref->type   = AVMEDIA_TYPE_AUDIO;
+    samplesref->format = sample_fmt;
+
+    memcpy(samples->data, data,
+           FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
+    memcpy(samplesref->data, samples->data, sizeof(samples->data));
+
+    samples->linesize[0] = samplesref->linesize[0] = linesize;
+
+    if (planes > FF_ARRAY_ELEMS(samples->data)) {
+        samples->   extended_data = av_mallocz(sizeof(*samples->extended_data) *
+                                               planes);
+        samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) *
+                                               planes);
+
+        if (!samples->extended_data || !samplesref->extended_data)
+            goto fail;
+
+        memcpy(samples->   extended_data, data, sizeof(*data)*planes);
+        memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
+    } else {
+        samples->extended_data    = samples->data;
+        samplesref->extended_data = samplesref->data;
+    }
+
+    return samplesref;
+
+fail:
+    if (samples && samples->extended_data != samples->data)
+        av_freep(&samples->extended_data);
+    if (samplesref) {
+        av_freep(&samplesref->audio);
+        if (samplesref->extended_data != samplesref->data)
+            av_freep(&samplesref->extended_data);
+    }
+    av_freep(&samplesref);
+    av_freep(&samples);
+    return NULL;
+}
+
 int avfilter_request_frame(AVFilterLink *link)
 {
     FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
index 8965094..6555744 100644 (file)
@@ -701,6 +701,24 @@ AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
                                              uint64_t channel_layout, int planar);
 
 /**
+ * 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 channel_layout the channel layout of the buffer
+ */
+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);
+
+/**
  * Request an input frame from the filter at the other end of the link.
  *
  * @param link the input link