1/* 2 * This file is part of Libav. 3 * 4 * Libav is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * Libav is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with Libav; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include "samplefmt.h" 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24 25typedef struct SampleFmtInfo { 26 const char *name; 27 int bits; 28 int planar; 29} SampleFmtInfo; 30 31/** this table gives more information about formats */ 32static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = { 33 [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0 }, 34 [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0 }, 35 [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0 }, 36 [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0 }, 37 [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0 }, 38 [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1 }, 39 [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1 }, 40 [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1 }, 41 [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1 }, 42 [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1 }, 43}; 44 45const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt) 46{ 47 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) 48 return NULL; 49 return sample_fmt_info[sample_fmt].name; 50} 51 52enum AVSampleFormat av_get_sample_fmt(const char *name) 53{ 54 int i; 55 56 for (i = 0; i < AV_SAMPLE_FMT_NB; i++) 57 if (!strcmp(sample_fmt_info[i].name, name)) 58 return i; 59 return AV_SAMPLE_FMT_NONE; 60} 61 62char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt) 63{ 64 /* print header */ 65 if (sample_fmt < 0) 66 snprintf(buf, buf_size, "name " " depth"); 67 else if (sample_fmt < AV_SAMPLE_FMT_NB) { 68 SampleFmtInfo info = sample_fmt_info[sample_fmt]; 69 snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits); 70 } 71 72 return buf; 73} 74 75int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt) 76{ 77 return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ? 78 0 : sample_fmt_info[sample_fmt].bits >> 3; 79} 80 81#if FF_API_GET_BITS_PER_SAMPLE_FMT 82int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt) 83{ 84 return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ? 85 0 : sample_fmt_info[sample_fmt].bits; 86} 87#endif 88 89int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) 90{ 91 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) 92 return 0; 93 return sample_fmt_info[sample_fmt].planar; 94} 95 96int 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 120int 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 139int 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} 160