Based on code by Stefano Sabatini.
Unified · Split
| @@ -13,6 +13,10 @@ libavutil: 2011-04-18 · 12 unmodified lines | ||
| 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 @@ · 152 unmodified lines | ||
| 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) · 91 unmodified lines | ||
| 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); · 91 unmodified lines | ||
| 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 */ |