Based on code by Stefano Sabatini.
Unified · Split
| @@ -13,6 +13,10 @@ libavutil: 2011-04-18 · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | API changes, most recent first: | 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 | 2011-xx-xx - xxxxxxx - lavu 51.17.0 | 20 | 2011-xx-xx - xxxxxxx - lavu 51.17.0 |
| 17 | Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h. | 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 | #define LIBAVUTIL_VERSION_MAJOR 51 | 155 | #define LIBAVUTIL_VERSION_MAJOR 51 |
| 156 | #define LIBAVUTIL_VERSION_MINOR 17 | 156 | #define LIBAVUTIL_VERSION_MINOR 18 |
| 157 | #define LIBAVUTIL_VERSION_MICRO 0 | 157 | #define LIBAVUTIL_VERSION_MICRO 0 |
| 158 | 158 | ||
| 159 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | 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 | return 0; | 92 | return 0; |
| 93 | return sample_fmt_info[sample_fmt].planar; | 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 | int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); | 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 | #endif /* AVUTIL_SAMPLEFMT_H */ | 148 | #endif /* AVUTIL_SAMPLEFMT_H */ |