libavutil: add utility functions to simplify allocation of audio buffers.
Based on code by Stefano Sabatini.
This commit is contained in:
		@@ -13,6 +13,10 @@ libavutil:   2011-04-18
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  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_MINOR 17
 | 
			
		||||
#define LIBAVUTIL_VERSION_MINOR 18
 | 
			
		||||
#define LIBAVUTIL_VERSION_MICRO  0
 | 
			
		||||
 | 
			
		||||
#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 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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user