Browse code

libavutil: add utility functions to simplify allocation of audio buffers.

Based on code by Stefano Sabatini.

Justin Ruggles authored on 2011/11/13 05:43:43
Showing 4 changed files
... ...
@@ -13,6 +13,10 @@ libavutil:   2011-04-18
13 13
 
14 14
 API changes, most recent first:
15 15
 
16
+2011-xx-xx - xxxxxxx - lavu 51.18.0
17
+  Add av_samples_get_buffer_size(), av_samples_fill_arrays(), and
18
+  av_samples_alloc(), to samplefmt.h.
19
+
16 20
 2011-xx-xx - xxxxxxx - lavu 51.17.0
17 21
   Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h.
18 22
 
... ...
@@ -153,7 +153,7 @@
153 153
  */
154 154
 
155 155
 #define LIBAVUTIL_VERSION_MAJOR 51
156
-#define LIBAVUTIL_VERSION_MINOR 17
156
+#define LIBAVUTIL_VERSION_MINOR 18
157 157
 #define LIBAVUTIL_VERSION_MICRO  0
158 158
 
159 159
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
... ...
@@ -92,3 +92,68 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
92 92
          return 0;
93 93
      return sample_fmt_info[sample_fmt].planar;
94 94
 }
95
+
96
+int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
97
+                               enum AVSampleFormat sample_fmt, int align)
98
+{
99
+    int line_size;
100
+    int sample_size = av_get_bytes_per_sample(sample_fmt);
101
+    int planar      = av_sample_fmt_is_planar(sample_fmt);
102
+
103
+    /* validate parameter ranges */
104
+    if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
105
+        return AVERROR(EINVAL);
106
+
107
+    /* check for integer overflow */
108
+    if (nb_channels > INT_MAX / align ||
109
+        (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
110
+        return AVERROR(EINVAL);
111
+
112
+    line_size = planar ? FFALIGN(nb_samples * sample_size,               align) :
113
+                         FFALIGN(nb_samples * sample_size * nb_channels, align);
114
+    if (linesize)
115
+        *linesize = line_size;
116
+
117
+    return planar ? line_size * nb_channels : line_size;
118
+}
119
+
120
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
121
+                           uint8_t *buf, int nb_channels, int nb_samples,
122
+                           enum AVSampleFormat sample_fmt, int align)
123
+{
124
+    int ch, planar, buf_size;
125
+
126
+    planar   = av_sample_fmt_is_planar(sample_fmt);
127
+    buf_size = av_samples_get_buffer_size(linesize, nb_channels, nb_samples,
128
+                                          sample_fmt, align);
129
+    if (buf_size < 0)
130
+        return buf_size;
131
+
132
+    audio_data[0] = buf;
133
+    for (ch = 1; planar && ch < nb_channels; ch++)
134
+        audio_data[ch] = audio_data[ch-1] + *linesize;
135
+
136
+    return 0;
137
+}
138
+
139
+int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
140
+                     int nb_samples, enum AVSampleFormat sample_fmt, int align)
141
+{
142
+    uint8_t *buf;
143
+    int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
144
+                                          sample_fmt, align);
145
+    if (size < 0)
146
+        return size;
147
+
148
+    buf = av_mallocz(size);
149
+    if (!buf)
150
+        return AVERROR(ENOMEM);
151
+
152
+    size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
153
+                                  nb_samples, sample_fmt, align);
154
+    if (size < 0) {
155
+        av_free(buf);
156
+        return size;
157
+    }
158
+    return 0;
159
+}
... ...
@@ -92,4 +92,57 @@ int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
92 92
  */
93 93
 int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);
94 94
 
95
+/**
96
+ * Get the required buffer size for the given audio parameters.
97
+ *
98
+ * @param[out] linesize calculated linesize, may be NULL
99
+ * @param nb_channels   the number of channels
100
+ * @param nb_samples    the number of samples in a single channel
101
+ * @param sample_fmt    the sample format
102
+ * @return              required buffer size, or negative error code on failure
103
+ */
104
+int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
105
+                               enum AVSampleFormat sample_fmt, int align);
106
+
107
+/**
108
+ * Fill channel data pointers and linesize for samples with sample
109
+ * format sample_fmt.
110
+ *
111
+ * The pointers array is filled with the pointers to the samples data:
112
+ * for planar, set the start point of each channel's data within the buffer,
113
+ * for packed, set the start point of the entire buffer only.
114
+ *
115
+ * The linesize array is filled with the aligned size of each channel's data
116
+ * buffer for planar layout, or the aligned size of the buffer for all channels
117
+ * for packed layout.
118
+ *
119
+ * @param[out] audio_data  array to be filled with the pointer for each channel
120
+ * @param[out] linesize    calculated linesize
121
+ * @param buf              the pointer to a buffer containing the samples
122
+ * @param nb_channels      the number of channels
123
+ * @param nb_samples       the number of samples in a single channel
124
+ * @param sample_fmt       the sample format
125
+ * @param align            buffer size alignment (1 = no alignment required)
126
+ * @return                 0 on success or a negative error code on failure
127
+ */
128
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf,
129
+                           int nb_channels, int nb_samples,
130
+                           enum AVSampleFormat sample_fmt, int align);
131
+
132
+/**
133
+ * Allocate a samples buffer for nb_samples samples, and fill data pointers and
134
+ * linesize accordingly.
135
+ * The allocated samples buffer can be freed by using av_freep(&audio_data[0])
136
+ *
137
+ * @param[out] audio_data  array to be filled with the pointer for each channel
138
+ * @param[out] linesize    aligned size for audio buffer(s)
139
+ * @param nb_channels      number of audio channels
140
+ * @param nb_samples       number of samples per channel
141
+ * @param align            buffer size alignment (1 = no alignment required)
142
+ * @return                 0 on success or a negative error code on failure
143
+ * @see av_samples_fill_arrays()
144
+ */
145
+int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
146
+                     int nb_samples, enum AVSampleFormat sample_fmt, int align);
147
+
95 148
 #endif /* AVUTIL_SAMPLEFMT_H */