Based on code by Stefano Sabatini.tags/n0.9
| @@ -13,6 +13,10 @@ libavutil: 2011-04-18 | |||||
| API changes, most recent first: | API changes, most recent first: | ||||
| 2011-xx-xx - xxxxxxx - lavu 51.18.0 | |||||
| Add av_samples_get_buffer_size(), av_samples_fill_arrays(), and | |||||
| av_samples_alloc(), to samplefmt.h. | |||||
| 2011-xx-xx - xxxxxxx - lavu 51.17.0 | 2011-xx-xx - xxxxxxx - lavu 51.17.0 | ||||
| Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h. | Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h. | ||||
| @@ -153,7 +153,7 @@ | |||||
| */ | */ | ||||
| #define LIBAVUTIL_VERSION_MAJOR 51 | #define LIBAVUTIL_VERSION_MAJOR 51 | ||||
| #define LIBAVUTIL_VERSION_MINOR 17 | |||||
| #define LIBAVUTIL_VERSION_MINOR 18 | |||||
| #define LIBAVUTIL_VERSION_MICRO 0 | #define LIBAVUTIL_VERSION_MICRO 0 | ||||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||
| @@ -92,3 +92,68 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) | |||||
| return 0; | return 0; | ||||
| return sample_fmt_info[sample_fmt].planar; | return sample_fmt_info[sample_fmt].planar; | ||||
| } | } | ||||
| int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, | |||||
| enum AVSampleFormat sample_fmt, int align) | |||||
| { | |||||
| int line_size; | |||||
| int sample_size = av_get_bytes_per_sample(sample_fmt); | |||||
| int planar = av_sample_fmt_is_planar(sample_fmt); | |||||
| /* validate parameter ranges */ | |||||
| if (!sample_size || nb_samples <= 0 || nb_channels <= 0) | |||||
| return AVERROR(EINVAL); | |||||
| /* check for integer overflow */ | |||||
| if (nb_channels > INT_MAX / align || | |||||
| (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size) | |||||
| return AVERROR(EINVAL); | |||||
| line_size = planar ? FFALIGN(nb_samples * sample_size, align) : | |||||
| FFALIGN(nb_samples * sample_size * nb_channels, align); | |||||
| if (linesize) | |||||
| *linesize = line_size; | |||||
| return planar ? line_size * nb_channels : line_size; | |||||
| } | |||||
| int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, | |||||
| uint8_t *buf, int nb_channels, int nb_samples, | |||||
| enum AVSampleFormat sample_fmt, int align) | |||||
| { | |||||
| int ch, planar, buf_size; | |||||
| planar = av_sample_fmt_is_planar(sample_fmt); | |||||
| buf_size = av_samples_get_buffer_size(linesize, nb_channels, nb_samples, | |||||
| sample_fmt, align); | |||||
| if (buf_size < 0) | |||||
| return buf_size; | |||||
| audio_data[0] = buf; | |||||
| for (ch = 1; planar && ch < nb_channels; ch++) | |||||
| audio_data[ch] = audio_data[ch-1] + *linesize; | |||||
| return 0; | |||||
| } | |||||
| int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, | |||||
| int nb_samples, enum AVSampleFormat sample_fmt, int align) | |||||
| { | |||||
| uint8_t *buf; | |||||
| int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples, | |||||
| sample_fmt, align); | |||||
| if (size < 0) | |||||
| return size; | |||||
| buf = av_mallocz(size); | |||||
| if (!buf) | |||||
| return AVERROR(ENOMEM); | |||||
| size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels, | |||||
| nb_samples, sample_fmt, align); | |||||
| if (size < 0) { | |||||
| av_free(buf); | |||||
| return size; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @@ -92,4 +92,57 @@ int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); | |||||
| */ | */ | ||||
| int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); | int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); | ||||
| /** | |||||
| * Get the required buffer size for the given audio parameters. | |||||
| * | |||||
| * @param[out] linesize calculated linesize, may be NULL | |||||
| * @param nb_channels the number of channels | |||||
| * @param nb_samples the number of samples in a single channel | |||||
| * @param sample_fmt the sample format | |||||
| * @return required buffer size, or negative error code on failure | |||||
| */ | |||||
| int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, | |||||
| enum AVSampleFormat sample_fmt, int align); | |||||
| /** | |||||
| * Fill channel data pointers and linesize for samples with sample | |||||
| * format sample_fmt. | |||||
| * | |||||
| * The pointers array is filled with the pointers to the samples data: | |||||
| * 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. | |||||
| * | |||||
| * The linesize array is filled with the aligned size of each channel's data | |||||
| * buffer for planar layout, or the aligned size of the buffer for all channels | |||||
| * for packed layout. | |||||
| * | |||||
| * @param[out] audio_data array to be filled with the pointer for each channel | |||||
| * @param[out] linesize calculated linesize | |||||
| * @param buf the pointer to a buffer containing the samples | |||||
| * @param nb_channels the number of channels | |||||
| * @param nb_samples the number of samples in a single channel | |||||
| * @param sample_fmt the sample format | |||||
| * @param align buffer size alignment (1 = no alignment required) | |||||
| * @return 0 on success or a negative error code on failure | |||||
| */ | |||||
| int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf, | |||||
| int nb_channels, int nb_samples, | |||||
| enum AVSampleFormat sample_fmt, int align); | |||||
| /** | |||||
| * Allocate a samples buffer for nb_samples samples, and fill data pointers and | |||||
| * linesize accordingly. | |||||
| * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) | |||||
| * | |||||
| * @param[out] audio_data array to be filled with the pointer for each channel | |||||
| * @param[out] linesize aligned size for audio buffer(s) | |||||
| * @param nb_channels number of audio channels | |||||
| * @param nb_samples number of samples per channel | |||||
| * @param align buffer size alignment (1 = no alignment required) | |||||
| * @return 0 on success or a negative error code on failure | |||||
| * @see av_samples_fill_arrays() | |||||
| */ | |||||
| int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, | |||||
| int nb_samples, enum AVSampleFormat sample_fmt, int align); | |||||
| #endif /* AVUTIL_SAMPLEFMT_H */ | #endif /* AVUTIL_SAMPLEFMT_H */ | ||||