Based on code by Stefano Sabatini.
| ... | ... |
@@ -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 |
|
| ... | ... |
@@ -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 */ |