FFmpeg
Loading...
Searching...
No Matches
samplefmt.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "error.h"
20#include "macros.h"
21#include "mem.h"
22#include "samplefmt.h"
23
24#include <limits.h>
25#include <stdio.h>
26#include <string.h>
27
28typedef struct SampleFmtInfo {
29 char name[8];
30 int bits;
31 int planar;
32 enum AVSampleFormat altform; ///< planar<->packed alternative form
34
35/** this table gives more information about formats */
37 [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P },
38 [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P },
39 [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P },
40 [AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P },
41 [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP },
42 [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP },
43 [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 },
44 [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 },
45 [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 },
46 [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 },
47 [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT },
48 [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL },
49 [AV_SAMPLE_FMT_DSD] = { .name = "dsd", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_DSD },
50};
51
52const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
53{
54 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
55 return NULL;
56 return sample_fmt_info[sample_fmt].name;
57}
58
60{
61 int i;
62
63 for (i = 0; i < AV_SAMPLE_FMT_NB; i++)
64 if (!strcmp(sample_fmt_info[i].name, name))
65 return i;
66 return AV_SAMPLE_FMT_NONE;
67}
68
69enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
70{
71 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
72 return AV_SAMPLE_FMT_NONE;
73 if (sample_fmt_info[sample_fmt].planar == planar)
74 return sample_fmt;
75 return sample_fmt_info[sample_fmt].altform;
76}
77
79{
80 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
81 return AV_SAMPLE_FMT_NONE;
82 if (sample_fmt_info[sample_fmt].planar)
83 return sample_fmt_info[sample_fmt].altform;
84 return sample_fmt;
85}
86
88{
89 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
90 return AV_SAMPLE_FMT_NONE;
91 if (sample_fmt_info[sample_fmt].planar)
92 return sample_fmt;
93 return sample_fmt_info[sample_fmt].altform;
94}
95
96char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt)
97{
98 /* print header */
99 if (sample_fmt < 0)
100 snprintf(buf, buf_size, "name " " depth");
101 else if (sample_fmt < AV_SAMPLE_FMT_NB) {
102 SampleFmtInfo info = sample_fmt_info[sample_fmt];
103 snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits);
104 }
105
106 return buf;
107}
108
110{
111 return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ?
112 0 : sample_fmt_info[sample_fmt].bits >> 3;
113}
114
116{
117 if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
118 return 0;
119 return sample_fmt_info[sample_fmt].planar;
120}
121
122int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
123 enum AVSampleFormat sample_fmt, int align)
124{
125 int line_size;
126 int sample_size = av_get_bytes_per_sample(sample_fmt);
127 int planar = av_sample_fmt_is_planar(sample_fmt);
128
129 /* validate parameter ranges */
130 if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
131 return AVERROR(EINVAL);
132
133 /* auto-select alignment if not specified */
134 if (!align) {
135 if (nb_samples > INT_MAX - 31)
136 return AVERROR(EINVAL);
137 align = 1;
138 nb_samples = FFALIGN(nb_samples, 32);
139 }
140
141 /* check for integer overflow */
142 if (nb_channels > INT_MAX / align ||
143 (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
144 return AVERROR(EINVAL);
145
146 line_size = planar ? FFALIGN(nb_samples * sample_size, align) :
147 FFALIGN(nb_samples * sample_size * nb_channels, align);
148 if (linesize)
149 *linesize = line_size;
150
151 return planar ? line_size * nb_channels : line_size;
152}
153
154int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
155 const uint8_t *buf, int nb_channels, int nb_samples,
156 enum AVSampleFormat sample_fmt, int align)
157{
158 int ch, planar, buf_size, line_size;
159
160 planar = av_sample_fmt_is_planar(sample_fmt);
161 buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples,
162 sample_fmt, align);
163 if (buf_size < 0)
164 return buf_size;
165
166 if (linesize)
167 *linesize = line_size;
168
169 memset(audio_data, 0, planar
170 ? sizeof(*audio_data) * nb_channels
171 : sizeof(*audio_data));
172
173 if (!buf)
174 return buf_size;
175
176 audio_data[0] = (uint8_t *)buf;
177 for (ch = 1; planar && ch < nb_channels; ch++)
178 audio_data[ch] = audio_data[ch-1] + line_size;
179
180 return buf_size;
181}
182
183int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
184 int nb_samples, enum AVSampleFormat sample_fmt, int align)
185{
186 uint8_t *buf;
187 int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
188 sample_fmt, align);
189 if (size < 0)
190 return size;
191
192 buf = av_malloc(size);
193 if (!buf)
194 return AVERROR(ENOMEM);
195
196 size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
197 nb_samples, sample_fmt, align);
198 if (size < 0) {
199 av_free(buf);
200 return size;
201 }
202
203 av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt);
204
205 return size;
206}
207
208int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels,
209 int nb_samples, enum AVSampleFormat sample_fmt, int align)
210{
211 int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
212
213 *audio_data = av_calloc(nb_planes, sizeof(**audio_data));
214 if (!*audio_data)
215 return AVERROR(ENOMEM);
216 ret = av_samples_alloc(*audio_data, linesize, nb_channels,
217 nb_samples, sample_fmt, align);
218 if (ret < 0)
219 av_freep(audio_data);
220 return ret;
221}
222
223int av_samples_copy(uint8_t * const *dst, uint8_t * const *src, int dst_offset,
224 int src_offset, int nb_samples, int nb_channels,
225 enum AVSampleFormat sample_fmt)
226{
227 int planar = av_sample_fmt_is_planar(sample_fmt);
228 int planes = planar ? nb_channels : 1;
229 int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
230 int data_size = nb_samples * block_align;
231 int i;
232
233 dst_offset *= block_align;
234 src_offset *= block_align;
235
236 if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) {
237 for (i = 0; i < planes; i++)
238 memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
239 } else {
240 for (i = 0; i < planes; i++)
241 memmove(dst[i] + dst_offset, src[i] + src_offset, data_size);
242 }
243
244 return 0;
245}
246
247int av_samples_set_silence(uint8_t * const *audio_data, int offset, int nb_samples,
248 int nb_channels, enum AVSampleFormat sample_fmt)
249{
250 int planar = av_sample_fmt_is_planar(sample_fmt);
251 int planes = planar ? nb_channels : 1;
252 int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
253 int data_size = nb_samples * block_align;
254 int fill_char, i;
255
256 if (sample_fmt == AV_SAMPLE_FMT_U8 || sample_fmt == AV_SAMPLE_FMT_U8P)
257 fill_char = 0x80;
258 else if (sample_fmt == AV_SAMPLE_FMT_DSD)
259 fill_char = 0x69; // only ultrasonic tones, filtered out on playback
260 else
261 fill_char = 0x00;
262
263 offset *= block_align;
264
265 for (i = 0; i < planes; i++)
266 memset(audio_data[i] + offset, fill_char, data_size);
267
268 return 0;
269}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static const uint8_t *BS_FUNC align(BSCTX *bc)
Skip bits to a byte boundary.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
error code definitions
#define AVERROR(e)
Definition error.h:45
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition samplefmt.c:115
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition samplefmt.c:109
enum AVSampleFormat av_get_sample_fmt(const char *name)
Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE on error.
Definition samplefmt.c:59
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition samplefmt.c:78
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
Definition samplefmt.c:87
enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
Return the planar<->packed alternative form of the given sample format, or AV_SAMPLE_FMT_NONE on erro...
Definition samplefmt.c:69
int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Get the required buffer size for the given audio parameters.
Definition samplefmt.c:122
char * av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt)
Generate a string corresponding to the sample format with sample_fmt, or a header if sample_fmt is ne...
Definition samplefmt.c:96
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition samplefmt.c:52
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition samplefmt.h:64
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
@ AV_SAMPLE_FMT_S64
signed 64 bits
Definition samplefmt.h:68
@ AV_SAMPLE_FMT_U8P
unsigned 8 bits, planar
Definition samplefmt.h:63
@ AV_SAMPLE_FMT_DSD
DSD (Direct Stream Digital) bitstream, interleaved.
Definition samplefmt.h:77
@ AV_SAMPLE_FMT_NB
Number of sample formats. DO NOT USE if linking dynamically.
Definition samplefmt.h:79
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition samplefmt.h:65
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition samplefmt.h:59
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition samplefmt.h:57
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition samplefmt.h:67
@ AV_SAMPLE_FMT_DBL
double
Definition samplefmt.h:61
@ AV_SAMPLE_FMT_S64P
signed 64 bits, planar
Definition samplefmt.h:69
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
int av_samples_alloc(uint8_t **audio_data, int *linesize, 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.
Definition samplefmt.c:183
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, const uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Fill plane data pointers and linesize for samples with sample format sample_fmt.
Definition samplefmt.c:154
int av_samples_set_silence(uint8_t *const *audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition samplefmt.c:247
int av_samples_copy(uint8_t *const *dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Copy samples from src to dst.
Definition samplefmt.c:223
int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Allocate a data pointers array, samples buffer for nb_samples samples, and fill data pointers and lin...
Definition samplefmt.c:208
unsigned offset
Definition libaomenc.c:763
static const struct @257111027162314367033347246032313251342043035002 planes[]
Utility Preprocessor macros.
#define FFALIGN(x, a)
Definition macros.h:78
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
#define av_malloc(s)
Definition ops_static.c:52
const char * name
Definition qsvenc.c:142
static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB]
this table gives more information about formats
Definition samplefmt.c:36
enum AVSampleFormat altform
planar<->packed alternative form
Definition samplefmt.c:32
char name[8]
Definition samplefmt.c:29
#define av_free(p)
#define av_freep(p)
#define src
Definition vp8dsp.c:248
int size