FFmpeg
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 "common.h"
20 #include "samplefmt.h"
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 typedef struct SampleFmtInfo {
27  char name[8];
28  int bits;
29  int planar;
30  enum AVSampleFormat altform; ///< planar<->packed alternative form
32 
33 /** this table gives more information about formats */
35  [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P },
36  [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P },
37  [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P },
38  [AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P },
39  [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP },
40  [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP },
41  [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 },
42  [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 },
43  [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 },
44  [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 },
45  [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT },
46  [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL },
47 };
48 
49 const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
50 {
51  if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
52  return NULL;
53  return sample_fmt_info[sample_fmt].name;
54 }
55 
57 {
58  int i;
59 
60  for (i = 0; i < AV_SAMPLE_FMT_NB; i++)
61  if (!strcmp(sample_fmt_info[i].name, name))
62  return i;
63  return AV_SAMPLE_FMT_NONE;
64 }
65 
67 {
68  if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
69  return AV_SAMPLE_FMT_NONE;
70  if (sample_fmt_info[sample_fmt].planar == planar)
71  return sample_fmt;
72  return sample_fmt_info[sample_fmt].altform;
73 }
74 
76 {
77  if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
78  return AV_SAMPLE_FMT_NONE;
79  if (sample_fmt_info[sample_fmt].planar)
80  return sample_fmt_info[sample_fmt].altform;
81  return sample_fmt;
82 }
83 
85 {
86  if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
87  return AV_SAMPLE_FMT_NONE;
88  if (sample_fmt_info[sample_fmt].planar)
89  return sample_fmt;
90  return sample_fmt_info[sample_fmt].altform;
91 }
92 
93 char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt)
94 {
95  /* print header */
96  if (sample_fmt < 0)
97  snprintf(buf, buf_size, "name " " depth");
98  else if (sample_fmt < AV_SAMPLE_FMT_NB) {
99  SampleFmtInfo info = sample_fmt_info[sample_fmt];
100  snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits);
101  }
102 
103  return buf;
104 }
105 
107 {
108  return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ?
109  0 : sample_fmt_info[sample_fmt].bits >> 3;
110 }
111 
113 {
114  if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
115  return 0;
116  return sample_fmt_info[sample_fmt].planar;
117 }
118 
119 int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
120  enum AVSampleFormat sample_fmt, int align)
121 {
122  int line_size;
123  int sample_size = av_get_bytes_per_sample(sample_fmt);
124  int planar = av_sample_fmt_is_planar(sample_fmt);
125 
126  /* validate parameter ranges */
127  if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
128  return AVERROR(EINVAL);
129 
130  /* auto-select alignment if not specified */
131  if (!align) {
132  if (nb_samples > INT_MAX - 31)
133  return AVERROR(EINVAL);
134  align = 1;
135  nb_samples = FFALIGN(nb_samples, 32);
136  }
137 
138  /* check for integer overflow */
139  if (nb_channels > INT_MAX / align ||
140  (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
141  return AVERROR(EINVAL);
142 
143  line_size = planar ? FFALIGN(nb_samples * sample_size, align) :
144  FFALIGN(nb_samples * sample_size * nb_channels, align);
145  if (linesize)
146  *linesize = line_size;
147 
148  return planar ? line_size * nb_channels : line_size;
149 }
150 
151 int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
152  const uint8_t *buf, int nb_channels, int nb_samples,
153  enum AVSampleFormat sample_fmt, int align)
154 {
155  int ch, planar, buf_size, line_size;
156 
157  planar = av_sample_fmt_is_planar(sample_fmt);
158  buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples,
159  sample_fmt, align);
160  if (buf_size < 0)
161  return buf_size;
162 
163  audio_data[0] = (uint8_t *)buf;
164  for (ch = 1; planar && ch < nb_channels; ch++)
165  audio_data[ch] = audio_data[ch-1] + line_size;
166 
167  if (linesize)
168  *linesize = line_size;
169 
170  return buf_size;
171 }
172 
173 int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
174  int nb_samples, enum AVSampleFormat sample_fmt, int align)
175 {
176  uint8_t *buf;
177  int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
178  sample_fmt, align);
179  if (size < 0)
180  return size;
181 
182  buf = av_malloc(size);
183  if (!buf)
184  return AVERROR(ENOMEM);
185 
186  size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
187  nb_samples, sample_fmt, align);
188  if (size < 0) {
189  av_free(buf);
190  return size;
191  }
192 
193  av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt);
194 
195  return size;
196 }
197 
198 int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels,
199  int nb_samples, enum AVSampleFormat sample_fmt, int align)
200 {
201  int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
202 
203  *audio_data = av_calloc(nb_planes, sizeof(**audio_data));
204  if (!*audio_data)
205  return AVERROR(ENOMEM);
206  ret = av_samples_alloc(*audio_data, linesize, nb_channels,
207  nb_samples, sample_fmt, align);
208  if (ret < 0)
209  av_freep(audio_data);
210  return ret;
211 }
212 
213 int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
214  int src_offset, int nb_samples, int nb_channels,
215  enum AVSampleFormat sample_fmt)
216 {
217  int planar = av_sample_fmt_is_planar(sample_fmt);
218  int planes = planar ? nb_channels : 1;
219  int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
220  int data_size = nb_samples * block_align;
221  int i;
222 
223  dst_offset *= block_align;
224  src_offset *= block_align;
225 
226  if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) {
227  for (i = 0; i < planes; i++)
228  memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
229  } else {
230  for (i = 0; i < planes; i++)
231  memmove(dst[i] + dst_offset, src[i] + src_offset, data_size);
232  }
233 
234  return 0;
235 }
236 
237 int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
238  int nb_channels, enum AVSampleFormat sample_fmt)
239 {
240  int planar = av_sample_fmt_is_planar(sample_fmt);
241  int planes = planar ? nb_channels : 1;
242  int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
243  int data_size = nb_samples * block_align;
244  int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 ||
245  sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00;
246  int i;
247 
248  offset *= block_align;
249 
250  for (i = 0; i < planes; i++)
251  memset(audio_data[i] + offset, fill_char, data_size);
252 
253  return 0;
254 }
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
av_get_sample_fmt_string
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:93
av_samples_fill_arrays
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:151
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
SampleFmtInfo
Definition: samplefmt.c:26
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
samplefmt.h
av_samples_alloc
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:173
AV_SAMPLE_FMT_S64P
@ AV_SAMPLE_FMT_S64P
signed 64 bits, planar
Definition: samplefmt.h:72
av_get_planar_sample_fmt
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
Definition: samplefmt.c:84
info
MIPS optimizations info
Definition: mips.txt:2
av_sample_fmt_is_planar
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
av_get_sample_fmt_name
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:49
NULL
#define NULL
Definition: coverity.c:32
src
#define src
Definition: vp8dsp.c:255
AV_SAMPLE_FMT_U8
AV_SAMPLE_FMT_U8
Definition: audio_convert.c:194
SampleFmtInfo::planar
int planar
Definition: samplefmt.c:29
AV_SAMPLE_FMT_NB
@ AV_SAMPLE_FMT_NB
Number of sample formats. DO NOT USE if linking dynamically.
Definition: samplefmt.h:74
AV_SAMPLE_FMT_U8P
@ AV_SAMPLE_FMT_U8P
unsigned 8 bits, planar
Definition: samplefmt.h:66
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:10344
SampleFmtInfo::name
char name[8]
Definition: samplefmt.c:27
sample_fmt_info
static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB]
this table gives more information about formats
Definition: samplefmt.c:34
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
av_samples_copy
int av_samples_copy(uint8_t **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:213
i
int i
Definition: input.c:407
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
av_get_sample_fmt
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:56
SampleFmtInfo::bits
int bits
Definition: samplefmt.c:28
common.h
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
av_samples_get_buffer_size
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:119
av_samples_set_silence
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:237
ret
ret
Definition: filter_design.txt:187
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
SampleFmtInfo::altform
enum AVSampleFormat altform
planar<->packed alternative form
Definition: samplefmt.c:30
av_get_packed_sample_fmt
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:75
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
planes
static const struct @322 planes[]
av_get_alt_sample_fmt
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:66
av_samples_alloc_array_and_samples
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:198
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
planar
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out->ch+ch,(const uint8_t **) in->ch+ch, off *(out-> planar
Definition: audioconvert.c:56
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
snprintf
#define snprintf
Definition: snprintf.h:34
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
AV_SAMPLE_FMT_S64
@ AV_SAMPLE_FMT_S64
signed 64 bits
Definition: samplefmt.h:71
nb_channels
int nb_channels
Definition: channel_layout.c:81