FFmpeg
audio_data.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include "libavutil/mem.h"
25 #include "audio_data.h"
26 
27 static const AVClass audio_data_class = {
28  .class_name = "AudioData",
29  .item_name = av_default_item_name,
30  .version = LIBAVUTIL_VERSION_INT,
31 };
32 
33 /*
34  * Calculate alignment for data pointers.
35  */
37 {
38  int p;
39  int min_align = 128;
40 
41  for (p = 0; p < a->planes; p++) {
42  int cur_align = 128;
43  while ((intptr_t)a->data[p] % cur_align)
44  cur_align >>= 1;
45  if (cur_align < min_align)
46  min_align = cur_align;
47  }
48  a->ptr_align = min_align;
49 }
50 
52 {
53  if (channels == 1)
54  return 1;
55  else
56  return av_sample_fmt_is_planar(sample_fmt);
57 }
58 
60 {
62  channels > a->allocated_channels)
63  return AVERROR(EINVAL);
64 
65  a->channels = channels;
66  a->planes = a->is_planar ? channels : 1;
67 
69 
70  return 0;
71 }
72 
73 int ff_audio_data_init(AudioData *a, uint8_t * const *src, int plane_size,
74  int channels, int nb_samples,
75  enum AVSampleFormat sample_fmt, int read_only,
76  const char *name)
77 {
78  int p;
79 
80  memset(a, 0, sizeof(*a));
81  a->class = &audio_data_class;
82 
84  av_log(a, AV_LOG_ERROR, "invalid channel count: %d\n", channels);
85  return AVERROR(EINVAL);
86  }
87 
88  a->sample_size = av_get_bytes_per_sample(sample_fmt);
89  if (!a->sample_size) {
90  av_log(a, AV_LOG_ERROR, "invalid sample format\n");
91  return AVERROR(EINVAL);
92  }
93  a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels);
94  a->planes = a->is_planar ? channels : 1;
95  a->stride = a->sample_size * (a->is_planar ? 1 : channels);
96 
97  for (p = 0; p < (a->is_planar ? channels : 1); p++) {
98  if (!src[p]) {
99  av_log(a, AV_LOG_ERROR, "invalid NULL pointer for src[%d]\n", p);
100  return AVERROR(EINVAL);
101  }
102  a->data[p] = src[p];
103  }
104  a->allocated_samples = nb_samples * !read_only;
105  a->nb_samples = nb_samples;
106  a->sample_fmt = sample_fmt;
107  a->channels = channels;
109  a->read_only = read_only;
110  a->allow_realloc = 0;
111  a->name = name ? name : "{no name}";
112 
114  a->samples_align = plane_size / a->stride;
115 
116  return 0;
117 }
118 
120  enum AVSampleFormat sample_fmt, const char *name)
121 {
122  AudioData *a;
123  int ret;
124 
126  return NULL;
127 
128  a = av_mallocz(sizeof(*a));
129  if (!a)
130  return NULL;
131 
132  a->sample_size = av_get_bytes_per_sample(sample_fmt);
133  if (!a->sample_size) {
134  av_free(a);
135  return NULL;
136  }
137  a->is_planar = ff_sample_fmt_is_planar(sample_fmt, channels);
138  a->planes = a->is_planar ? channels : 1;
139  a->stride = a->sample_size * (a->is_planar ? 1 : channels);
140 
141  a->class = &audio_data_class;
142  a->sample_fmt = sample_fmt;
143  a->channels = channels;
145  a->read_only = 0;
146  a->allow_realloc = 1;
147  a->name = name ? name : "{no name}";
148 
149  if (nb_samples > 0) {
150  ret = ff_audio_data_realloc(a, nb_samples);
151  if (ret < 0) {
152  av_free(a);
153  return NULL;
154  }
155  return a;
156  } else {
158  return a;
159  }
160 }
161 
162 int ff_audio_data_realloc(AudioData *a, int nb_samples)
163 {
164  int ret, new_buf_size, plane_size, p;
165 
166  /* check if buffer is already large enough */
167  if (a->allocated_samples >= nb_samples)
168  return 0;
169 
170  /* validate that the output is not read-only and realloc is allowed */
171  if (a->read_only || !a->allow_realloc)
172  return AVERROR(EINVAL);
173 
174  new_buf_size = av_samples_get_buffer_size(&plane_size,
175  a->allocated_channels, nb_samples,
176  a->sample_fmt, 0);
177  if (new_buf_size < 0)
178  return new_buf_size;
179 
180  /* if there is already data in the buffer and the sample format is planar,
181  allocate a new buffer and copy the data, otherwise just realloc the
182  internal buffer and set new data pointers */
183  if (a->nb_samples > 0 && a->is_planar) {
184  uint8_t *new_data[AVRESAMPLE_MAX_CHANNELS] = { NULL };
185 
186  ret = av_samples_alloc(new_data, &plane_size, a->allocated_channels,
187  nb_samples, a->sample_fmt, 0);
188  if (ret < 0)
189  return ret;
190 
191  for (p = 0; p < a->planes; p++)
192  memcpy(new_data[p], a->data[p], a->nb_samples * a->stride);
193 
194  av_freep(&a->buffer);
195  memcpy(a->data, new_data, sizeof(new_data));
196  a->buffer = a->data[0];
197  } else {
198  av_freep(&a->buffer);
199  a->buffer = av_malloc(new_buf_size);
200  if (!a->buffer)
201  return AVERROR(ENOMEM);
202  ret = av_samples_fill_arrays(a->data, &plane_size, a->buffer,
203  a->allocated_channels, nb_samples,
204  a->sample_fmt, 0);
205  if (ret < 0)
206  return ret;
207  }
208  a->buffer_size = new_buf_size;
209  a->allocated_samples = nb_samples;
210 
212  a->samples_align = plane_size / a->stride;
213 
214  return 0;
215 }
216 
218 {
219  if (!*a)
220  return;
221  av_free((*a)->buffer);
222  av_freep(a);
223 }
224 
226 {
227  int ret, p;
228 
229  /* validate input/output compatibility */
230  if (dst->sample_fmt != src->sample_fmt || dst->channels < src->channels)
231  return AVERROR(EINVAL);
232 
233  if (map && !src->is_planar) {
234  av_log(src, AV_LOG_ERROR, "cannot remap packed format during copy\n");
235  return AVERROR(EINVAL);
236  }
237 
238  /* if the input is empty, just empty the output */
239  if (!src->nb_samples) {
240  dst->nb_samples = 0;
241  return 0;
242  }
243 
244  /* reallocate output if necessary */
245  ret = ff_audio_data_realloc(dst, src->nb_samples);
246  if (ret < 0)
247  return ret;
248 
249  /* copy data */
250  if (map) {
251  if (map->do_remap) {
252  for (p = 0; p < src->planes; p++) {
253  if (map->channel_map[p] >= 0)
254  memcpy(dst->data[p], src->data[map->channel_map[p]],
255  src->nb_samples * src->stride);
256  }
257  }
258  if (map->do_copy || map->do_zero) {
259  for (p = 0; p < src->planes; p++) {
260  if (map->channel_copy[p])
261  memcpy(dst->data[p], dst->data[map->channel_copy[p]],
262  src->nb_samples * src->stride);
263  else if (map->channel_zero[p])
264  av_samples_set_silence(&dst->data[p], 0, src->nb_samples,
265  1, dst->sample_fmt);
266  }
267  }
268  } else {
269  for (p = 0; p < src->planes; p++)
270  memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
271  }
272 
273  dst->nb_samples = src->nb_samples;
274 
275  return 0;
276 }
277 
278 int ff_audio_data_combine(AudioData *dst, int dst_offset, AudioData *src,
279  int src_offset, int nb_samples)
280 {
281  int ret, p, dst_offset2, dst_move_size;
282 
283  /* validate input/output compatibility */
284  if (dst->sample_fmt != src->sample_fmt || dst->channels != src->channels) {
285  av_log(src, AV_LOG_ERROR, "sample format mismatch\n");
286  return AVERROR(EINVAL);
287  }
288 
289  /* validate offsets are within the buffer bounds */
290  if (dst_offset < 0 || dst_offset > dst->nb_samples ||
291  src_offset < 0 || src_offset > src->nb_samples) {
292  av_log(src, AV_LOG_ERROR, "offset out-of-bounds: src=%d dst=%d\n",
293  src_offset, dst_offset);
294  return AVERROR(EINVAL);
295  }
296 
297  /* check offsets and sizes to see if we can just do nothing and return */
298  if (nb_samples > src->nb_samples - src_offset)
299  nb_samples = src->nb_samples - src_offset;
300  if (nb_samples <= 0)
301  return 0;
302 
303  /* validate that the output is not read-only */
304  if (dst->read_only) {
305  av_log(dst, AV_LOG_ERROR, "dst is read-only\n");
306  return AVERROR(EINVAL);
307  }
308 
309  /* reallocate output if necessary */
310  ret = ff_audio_data_realloc(dst, dst->nb_samples + nb_samples);
311  if (ret < 0) {
312  av_log(dst, AV_LOG_ERROR, "error reallocating dst\n");
313  return ret;
314  }
315 
316  dst_offset2 = dst_offset + nb_samples;
317  dst_move_size = dst->nb_samples - dst_offset;
318 
319  for (p = 0; p < src->planes; p++) {
320  if (dst_move_size > 0) {
321  memmove(dst->data[p] + dst_offset2 * dst->stride,
322  dst->data[p] + dst_offset * dst->stride,
323  dst_move_size * dst->stride);
324  }
325  memcpy(dst->data[p] + dst_offset * dst->stride,
326  src->data[p] + src_offset * src->stride,
327  nb_samples * src->stride);
328  }
329  dst->nb_samples += nb_samples;
330 
331  return 0;
332 }
333 
334 void ff_audio_data_drain(AudioData *a, int nb_samples)
335 {
336  if (a->nb_samples <= nb_samples) {
337  /* drain the whole buffer */
338  a->nb_samples = 0;
339  } else {
340  int p;
341  int move_offset = a->stride * nb_samples;
342  int move_size = a->stride * (a->nb_samples - nb_samples);
343 
344  for (p = 0; p < a->planes; p++)
345  memmove(a->data[p], a->data[p] + move_offset, move_size);
346 
347  a->nb_samples -= nb_samples;
348  }
349 }
350 
352  int nb_samples)
353 {
354  uint8_t *offset_data[AVRESAMPLE_MAX_CHANNELS];
355  int offset_size, p;
356 
357  if (offset >= a->nb_samples)
358  return 0;
359  offset_size = offset * a->stride;
360  for (p = 0; p < a->planes; p++)
361  offset_data[p] = a->data[p] + offset_size;
362 
363  return av_audio_fifo_write(af, (void **)offset_data, nb_samples);
364 }
365 
367 {
368  int ret;
369 
370  if (a->read_only)
371  return AVERROR(EINVAL);
372 
373  ret = ff_audio_data_realloc(a, nb_samples);
374  if (ret < 0)
375  return ret;
376 
377  ret = av_audio_fifo_read(af, (void **)a->data, nb_samples);
378  if (ret >= 0)
379  a->nb_samples = ret;
380  return ret;
381 }
unsigned int buffer_size
allocated buffer size
Definition: audio_data.h:41
#define NULL
Definition: coverity.c:32
static void calc_ptr_alignment(AudioData *a)
Definition: audio_data.c:36
const char * name
name for debug logging
Definition: audio_data.h:55
int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
Read data from an AVAudioFifo.
Definition: audio_fifo.c:181
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:162
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Memory handling functions.
int ff_audio_data_add_to_fifo(AVAudioFifo *af, AudioData *a, int offset, int nb_samples)
Add samples in AudioData to an AVAudioFifo.
Definition: audio_data.c:351
int do_zero
zeroing needed
Definition: internal.h:49
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:119
channels
Definition: aptx.c:30
int allow_realloc
realloc is allowed
Definition: audio_data.h:52
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define src
Definition: vp8dsp.c:254
int channel_zero[AVRESAMPLE_MAX_CHANNELS]
dest index to zero
Definition: internal.h:48
int nb_samples
current number of samples
Definition: audio_data.h:43
static const AVClass audio_data_class
Definition: audio_data.c:27
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
int sample_size
bytes per sample
Definition: audio_data.h:49
int allocated_channels
allocated channel count
Definition: audio_data.h:46
uint8_t
#define av_malloc(s)
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
int read_only
data is read-only
Definition: audio_data.h:51
int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels)
Definition: audio_data.c:51
#define av_log(a,...)
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:59
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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
int stride
sample byte offset within a plane
Definition: audio_data.h:50
int channels
channel count
Definition: audio_data.h:45
int ff_audio_data_init(AudioData *a, uint8_t *const *src, int plane_size, int channels, int nb_samples, enum AVSampleFormat sample_fmt, int read_only, const char *name)
Initialize AudioData using a given source.
Definition: audio_data.c:73
int ff_audio_data_read_from_fifo(AVAudioFifo *af, AudioData *a, int nb_samples)
Read samples from an AVAudioFifo to AudioData.
Definition: audio_data.c:366
int is_planar
sample format is planar
Definition: audio_data.h:47
uint8_t * buffer
data buffer
Definition: audio_data.h:40
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
const AVClass * class
AVClass for logging.
Definition: audio_data.h:38
int channel_copy[AVRESAMPLE_MAX_CHANNELS]
dest index to copy from
Definition: internal.h:46
int do_remap
remap needed
Definition: internal.h:45
int ff_audio_data_combine(AudioData *dst, int dst_offset, AudioData *src, int src_offset, int nb_samples)
Append data from one AudioData to the end of another.
Definition: audio_data.c:278
void ff_audio_data_drain(AudioData *a, int nb_samples)
Drain samples from the start of the AudioData.
Definition: audio_data.c:334
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
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
Describe the class of an AVClass context structure.
Definition: log.h:67
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
const VDPAUPixFmtMap * map
int channel_map[AVRESAMPLE_MAX_CHANNELS]
source index of each output channel, -1 if not remapped
Definition: internal.h:44
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
int samples_align
allocated samples alignment
Definition: audio_data.h:54
int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
Copy data from one AudioData to another.
Definition: audio_data.c:225
int do_copy
copy needed
Definition: internal.h:47
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
#define av_free(p)
int allocated_samples
number of samples the buffer can hold
Definition: audio_data.h:42
enum AVSampleFormat sample_fmt
sample format
Definition: audio_data.h:44
#define av_freep(p)
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:217
int ptr_align
minimum data pointer alignment
Definition: audio_data.h:53
int planes
number of data planes
Definition: audio_data.h:48
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
const char * name
Definition: opengl_enc.c:102