On date Monday 2011-05-23 19:48:53 +0200, Stefano Sabatini encoded:
> On date Monday 2011-05-23 16:51:25 +0200, Stefano Sabatini encoded:
[...]
> Elaborating more: this patches is basically changing the layout of the
> samples buffer.
> 
> My objective is getting a layout as similiar as possible with that of
> the video buffer.
> 
> So this was my idea:
> pointers  -> contain pointers to each samples plane
> linesizes -> the linesize of each plane
> 
> This looks simpler and generally easier to manage.
> 
> Currently we have:
>  * data[c] points to the first sample of channel c.
>  * data[c] + linesize[0] points to the second sample of channel c
> 
> This has a slight advantage for accessing the samples for each channel
> but it has the disadvantage that:
> * misuse the term "linesize" (with a different semantics depending on
>   planar/packed mode)
> * creates an asymmetry between audio and video data layout

Updated patchset in attachment. This is the base of the audio-filters
changes, and will possibly affect also how audio in AVFrame is dealt
with.

I'm adding libav-devel to recipients in case they're interested in
discussing (av_samples_* functions were never integrated in libav).
-- 
FFmpeg = Friendly and Fierce Monstrous Pacific Efficient Goblin
>From 6443ffdcac7a2d6cb8e0266adb24c30155fb08f4 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <[email protected]>
Date: Tue, 22 Mar 2011 13:29:28 +0100
Subject: [PATCH] samplefmt: change layout for arrays created by av_samples_alloc() and _fill_arrays()

The new layout is consistent with that of the av_image_() API, and
simplifies understanding and copy operations, it also preserves
alignment information which was lost with the previous layout.

This breaks API/ABI, but since the function was never referenced in
the code (and it isn't unlikely already used by someone) then this
should not be a problem.
---
 libavutil/samplefmt.c |   22 ++++++++++++----------
 libavutil/samplefmt.h |    4 ++--
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index ea004d9..ca669da 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -76,28 +76,30 @@ int av_samples_fill_arrays(uint8_t *pointers[8], int linesizes[8],
                            uint8_t *buf, int nb_channels, int nb_samples,
                            enum AVSampleFormat sample_fmt, int planar, int align)
 {
-    int i, step_size = 0;
+    int i, linesize;
     int sample_size = av_get_bits_per_sample_fmt(sample_fmt) >> 3;
-    int channel_step = planar ? FFALIGN(nb_samples*sample_size, align) : sample_size;
 
-    if(nb_channels * (uint64_t)nb_samples * sample_size >= INT_MAX - align*(uint64_t)nb_channels)
+    if (nb_channels * (uint64_t)nb_samples * sample_size >= INT_MAX - align*(uint64_t)nb_channels)
         return AVERROR(EINVAL);
+    linesize = planar ? FFALIGN(nb_samples*sample_size,             align) :
+                        FFALIGN(nb_samples*sample_size*nb_channels, align);
 
     if (pointers) {
         pointers[0] = buf;
-        for (i = 0; i < nb_channels; i++) {
-            pointers[i] = buf + step_size;
-            step_size += channel_step;
+        for (i = 1; planar && i < nb_channels; i++) {
+            pointers[i] = pointers[i-1] + linesize;
         }
-        memset(&pointers[nb_channels], 0, (8-nb_channels) * sizeof(pointers[0]));
+        memset(&pointers[i], 0, (8-i) * sizeof(pointers[0]));
     }
 
     if (linesizes) {
-        linesizes[0] = planar ?  sample_size : nb_channels*sample_size;
-        memset(&linesizes[1], 0, (8-1) * sizeof(linesizes[0]));
+        linesizes[0] = linesize;
+        for (i = 1; planar && i < nb_channels; i++)
+            linesizes[i] = linesizes[0];
+        memset(&linesizes[i], 0, (8-i) * sizeof(linesizes[0]));
     }
 
-    return planar ? channel_step * nb_channels : FFALIGN(nb_channels*sample_size*nb_samples, align);
+    return planar ? linesize * nb_channels : linesize;
 }
 
 int av_samples_alloc(uint8_t *pointers[8], int linesizes[8],
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index 9b9c0d4..f1e66d0 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -74,8 +74,8 @@ int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
  * format sample_fmt.
  *
  * The pointers array is filled with the pointers to the samples data:
- * data[c] points to the first sample of channel c.
- * data[c] + linesize[0] points to the second sample of channel c
+ * for planar, set the start point of each plane's data within the buffer,
+ * for packed, set the start point of the entire buffer only.
  *
  * @param pointers array to be filled with the pointer for each plane, may be NULL
  * @param linesizes array to be filled with the linesize, may be NULL
-- 
1.7.2.3

>From 317651c4e15b36a9196ea6622c7456e78d299ab1 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <[email protected]>
Date: Thu, 2 Jun 2011 11:14:24 +0200
Subject: [PATCH] samplefmt: switch nb_channels/nb_samples params order in av_samples_alloc()

This is consistent with the order of parameters in
av_samples_fill_arrays().
---
 libavutil/samplefmt.c |    2 +-
 libavutil/samplefmt.h |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index ca669da..041aaea 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -103,7 +103,7 @@ int av_samples_fill_arrays(uint8_t *pointers[8], int linesizes[8],
 }
 
 int av_samples_alloc(uint8_t *pointers[8], int linesizes[8],
-                     int nb_samples, int nb_channels,
+                     int nb_channels, int nb_samples,
                      enum AVSampleFormat sample_fmt, int planar,
                      int align)
 {
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index f1e66d0..ed14802 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -96,6 +96,7 @@ int av_samples_fill_arrays(uint8_t *pointers[8], int linesizes[8],
  * The allocated samples buffer has to be freed by using
  * av_freep(&pointers[0]).
  *
+ * @param nb_channels number of audio channels
  * @param nb_samples number of samples per channel
  * @param planar 1 if the samples layout is planar, 0 if packed,
  * @param align the value to use for buffer size alignment
@@ -104,7 +105,7 @@ int av_samples_fill_arrays(uint8_t *pointers[8], int linesizes[8],
  * @see av_samples_fill_arrays()
  */
 int av_samples_alloc(uint8_t *pointers[8], int linesizes[8],
-                     int nb_samples, int nb_channels,
+                     int nb_channels, int nb_samples,
                      enum AVSampleFormat sample_fmt, int planar,
                      int align);
 
-- 
1.7.2.3

>From fa3b19c5c08374e3146cf6a4d17b6875a91bc117 Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <[email protected]>
Date: Tue, 1 Feb 2011 12:34:23 +0100
Subject: [PATCH] lavfi: prefer nb_samples over size in AVFilterBufferRefAudioProps

Remove AVFilterBufferRefAudioProps.size, and use nb_samples in
avfilter_get_audio_buffer() and avfilter_default_get_audio_buffer() in
place of size.

This is required as the size in the audio buffer may be aligned, so it
may not contain a well defined number of samples.
---
 libavfilter/avfilter.c |   15 ++++++++-------
 libavfilter/avfilter.h |   11 +++++------
 libavfilter/defaults.c |   11 +++++------
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 72e0a87..79326a0 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -280,10 +280,9 @@ static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
                 av_get_picture_type_char(ref->video->pict_type));
     }
     if (ref->audio) {
-        av_dlog(ctx, " cl:%"PRId64"d sn:%d s:%d sr:%d p:%d",
+        av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
                 ref->audio->channel_layout,
                 ref->audio->nb_samples,
-                ref->audio->size,
                 ref->audio->sample_rate,
                 ref->audio->planar);
     }
@@ -380,16 +379,16 @@ fail:
 }
 
 AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
-                                             enum AVSampleFormat sample_fmt, int size,
+                                             enum AVSampleFormat sample_fmt, int nb_samples,
                                              int64_t channel_layout, int planar)
 {
     AVFilterBufferRef *ret = NULL;
 
     if (link->dstpad->get_audio_buffer)
-        ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
+        ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, nb_samples, channel_layout, planar);
 
     if (!ret)
-        ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
+        ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, nb_samples, channel_layout, planar);
 
     if (ret)
         ret->type = AVMEDIA_TYPE_AUDIO;
@@ -520,6 +519,7 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
 {
     void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
     AVFilterPad *dst = link->dstpad;
+    int i;
 
     FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
 
@@ -536,14 +536,15 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
 
         link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
                                                           samplesref->format,
-                                                          samplesref->audio->size,
+                                                          samplesref->audio->nb_samples,
                                                           samplesref->audio->channel_layout,
                                                           samplesref->audio->planar);
         link->cur_buf->pts                = samplesref->pts;
         link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;
 
         /* Copy actual data into new samples buffer */
-        memcpy(link->cur_buf->data[0], samplesref->data[0], samplesref->audio->size);
+        for (i = 0; samplesref->data[i]; i++)
+            memcpy(link->cur_buf->data[i], samplesref->data[i], samplesref->linesize[0]);
 
         avfilter_unref_buffer(samplesref);
     } else
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 602b243..b7d82a5 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -98,8 +98,7 @@ typedef struct AVFilterBuffer {
  */
 typedef struct AVFilterBufferRefAudioProps {
     int64_t channel_layout;     ///< channel layout of audio buffer
-    int nb_samples;             ///< number of audio samples
-    int size;                   ///< audio buffer size
+    int nb_samples;             ///< number of audio samples per channel
     uint32_t sample_rate;       ///< audio buffer sample rate
     int planar;                 ///< audio buffer - planar or packed
 } AVFilterBufferRefAudioProps;
@@ -372,7 +371,7 @@ struct AVFilterPad {
      * Input audio pads only.
      */
     AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
-                                           enum AVSampleFormat sample_fmt, int size,
+                                           enum AVSampleFormat sample_fmt, int nb_samples,
                                            int64_t channel_layout, int planar);
 
     /**
@@ -461,7 +460,7 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link,
 
 /** default handler for get_audio_buffer() for audio inputs */
 AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
-                                                     enum AVSampleFormat sample_fmt, int size,
+                                                     enum AVSampleFormat sample_fmt, int nb_samples,
                                                      int64_t channel_layout, int planar);
 
 /**
@@ -679,14 +678,14 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
  *                       be requested
  * @param perms          the required access permissions
  * @param sample_fmt     the format of each sample in the buffer to allocate
- * @param size           the buffer size in bytes
+ * @param nb_samples     the number of samples per channel
  * @param channel_layout the number and type of channels per sample in the buffer to allocate
  * @param planar         audio data layout - planar or packed
  * @return               A reference to the samples. This must be unreferenced with
  *                       avfilter_unref_buffer when you are finished with it.
  */
 AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
-                                             enum AVSampleFormat sample_fmt, int size,
+                                             enum AVSampleFormat sample_fmt, int nb_samples,
                                              int64_t channel_layout, int planar);
 
 /**
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index 9ee23e5..854a105 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -79,7 +79,7 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
 }
 
 AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
-                                                     enum AVSampleFormat sample_fmt, int size,
+                                                     enum AVSampleFormat sample_fmt, int nb_samples,
                                                      int64_t channel_layout, int planar)
 {
     AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
@@ -98,7 +98,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
         goto fail;
 
     ref->audio->channel_layout = channel_layout;
-    ref->audio->size           = size;
+    ref->audio->nb_samples     = nb_samples;
     ref->audio->planar         = planar;
 
     /* make sure the buffer gets read permission or it's useless for output */
@@ -110,8 +110,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
     sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3;
     chans_nb = av_get_channel_layout_nb_channels(channel_layout);
 
-    per_channel_size = size/chans_nb;
-    ref->audio->nb_samples = per_channel_size/sample_size;
+    per_channel_size = nb_samples * sample_size;
 
     /* Set the number of bytes to traverse to reach next sample of a particular channel:
      * For planar, this is simply the sample size.
@@ -122,7 +121,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
     memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));
 
     /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
-    bufsize = (size + 15)&~15;
+    bufsize = (nb_samples * chans_nb * sample_size + 15)&~15;
     buf = av_malloc(bufsize);
     if (!buf)
         goto fail;
@@ -210,7 +209,7 @@ void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *sa
 
     if (outlink) {
         outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format,
-                                                             samplesref->audio->size,
+                                                             samplesref->audio->nb_samples,
                                                              samplesref->audio->channel_layout,
                                                              samplesref->audio->planar);
         outlink->out_buf->pts                = samplesref->pts;
-- 
1.7.2.3

>From 712e7f1158306637ca087691bc15d51c95d486aa Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <[email protected]>
Date: Sat, 15 Jan 2011 18:48:37 +0100
Subject: [PATCH] lavfi: use av_samples_alloc() in avfilter_default_get_audio_buffer()

---
 libavfilter/defaults.c |   38 ++++----------------------------------
 1 files changed, 4 insertions(+), 34 deletions(-)

diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index 854a105..0ef0d2f 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -84,8 +84,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
 {
     AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
     AVFilterBufferRef *ref = NULL;
-    int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;
-    char *buf;
+    int nb_channels = av_get_channel_layout_nb_channels(channel_layout);
 
     if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))
         goto fail;
@@ -107,41 +106,12 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
     samples->refcount   = 1;
     samples->free       = ff_avfilter_default_free_buffer;
 
-    sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3;
-    chans_nb = av_get_channel_layout_nb_channels(channel_layout);
-
-    per_channel_size = nb_samples * sample_size;
-
-    /* Set the number of bytes to traverse to reach next sample of a particular channel:
-     * For planar, this is simply the sample size.
-     * For packed, this is the number of samples * sample_size.
-     */
-    for (i = 0; i < chans_nb; i++)
-        samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;
-    memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));
-
     /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
-    bufsize = (nb_samples * chans_nb * sample_size + 15)&~15;
-    buf = av_malloc(bufsize);
-    if (!buf)
+    if (av_samples_alloc(samples->data, samples->linesize,
+                         nb_channels, nb_samples, sample_fmt,
+                         planar, 15) < 0)
         goto fail;
 
-    /* For planar, set the start point of each channel's data within the buffer
-     * For packed, set the start point of the entire buffer only
-     */
-    samples->data[0] = buf;
-    if (buf && planar) {
-        for (i = 1; i < chans_nb; i++) {
-            step_size += per_channel_size;
-            samples->data[i] = buf + step_size;
-        }
-    } else {
-        for (i = 1; i < chans_nb; i++)
-            samples->data[i] = buf;
-    }
-
-    memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));
-
     memcpy(ref->data,     samples->data,     sizeof(ref->data));
     memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));
 
-- 
1.7.2.3

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to