FFmpeg  4.3
dstdec.c
Go to the documentation of this file.
1 /*
2  * Direct Stream Transfer (DST) decoder
3  * Copyright (c) 2014 Peter Ross <pross@xvid.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Direct Stream Transfer (DST) decoder
25  * ISO/IEC 14496-3 Part 3 Subpart 10: Technical description of lossless coding of oversampled audio
26  */
27 
28 #include "libavutil/avassert.h"
29 #include "libavutil/intreadwrite.h"
30 #include "internal.h"
31 #include "get_bits.h"
32 #include "avcodec.h"
33 #include "golomb.h"
34 #include "mathops.h"
35 #include "dsd.h"
36 
37 #define DST_MAX_CHANNELS 6
38 #define DST_MAX_ELEMENTS (2 * DST_MAX_CHANNELS)
39 
40 #define DSD_FS44(sample_rate) (sample_rate * 8LL / 44100)
41 
42 #define DST_SAMPLES_PER_FRAME(sample_rate) (588 * DSD_FS44(sample_rate))
43 
44 static const int8_t fsets_code_pred_coeff[3][3] = {
45  { -8 },
46  { -16, 8 },
47  { -9, -5, 6 },
48 };
49 
50 static const int8_t probs_code_pred_coeff[3][3] = {
51  { -8 },
52  { -16, 8 },
53  { -24, 24, -8 },
54 };
55 
56 typedef struct ArithCoder {
57  unsigned int a;
58  unsigned int c;
59  int overread;
60 } ArithCoder;
61 
62 typedef struct Table {
63  unsigned int elements;
64  unsigned int length[DST_MAX_ELEMENTS];
66 } Table;
67 
68 typedef struct DSTContext {
69  AVClass *class;
70 
75  DECLARE_ALIGNED(16, int16_t, filter)[DST_MAX_ELEMENTS][16][256];
77 } DSTContext;
78 
80 {
81  DSTContext *s = avctx->priv_data;
82  int i;
83 
84  if (avctx->channels > DST_MAX_CHANNELS) {
85  avpriv_request_sample(avctx, "Channel count %d", avctx->channels);
86  return AVERROR_PATCHWELCOME;
87  }
88 
89  if (DST_SAMPLES_PER_FRAME(avctx->sample_rate) & 7) {
90  return AVERROR_PATCHWELCOME;
91  }
92 
94 
95  for (i = 0; i < avctx->channels; i++)
96  memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf));
97 
99 
100  return 0;
101 }
102 
103 static int read_map(GetBitContext *gb, Table *t, unsigned int map[DST_MAX_CHANNELS], int channels)
104 {
105  int ch;
106  t->elements = 1;
107  map[0] = 0;
108  if (!get_bits1(gb)) {
109  for (ch = 1; ch < channels; ch++) {
110  int bits = av_log2(t->elements) + 1;
111  map[ch] = get_bits(gb, bits);
112  if (map[ch] == t->elements) {
113  t->elements++;
114  if (t->elements >= DST_MAX_ELEMENTS)
115  return AVERROR_INVALIDDATA;
116  } else if (map[ch] > t->elements) {
117  return AVERROR_INVALIDDATA;
118  }
119  }
120  } else {
121  memset(map, 0, sizeof(*map) * DST_MAX_CHANNELS);
122  }
123  return 0;
124 }
125 
126 static av_always_inline int get_sr_golomb_dst(GetBitContext *gb, unsigned int k)
127 {
128  int v = get_ur_golomb_jpegls(gb, k, get_bits_left(gb), 0);
129  if (v && get_bits1(gb))
130  v = -v;
131  return v;
132 }
133 
134 static void read_uncoded_coeff(GetBitContext *gb, int *dst, unsigned int elements,
135  int coeff_bits, int is_signed, int offset)
136 {
137  int i;
138 
139  for (i = 0; i < elements; i++) {
140  dst[i] = (is_signed ? get_sbits(gb, coeff_bits) : get_bits(gb, coeff_bits)) + offset;
141  }
142 }
143 
144 static int read_table(GetBitContext *gb, Table *t, const int8_t code_pred_coeff[3][3],
145  int length_bits, int coeff_bits, int is_signed, int offset)
146 {
147  unsigned int i, j, k;
148  for (i = 0; i < t->elements; i++) {
149  t->length[i] = get_bits(gb, length_bits) + 1;
150  if (!get_bits1(gb)) {
151  read_uncoded_coeff(gb, t->coeff[i], t->length[i], coeff_bits, is_signed, offset);
152  } else {
153  int method = get_bits(gb, 2), lsb_size;
154  if (method == 3)
155  return AVERROR_INVALIDDATA;
156 
157  read_uncoded_coeff(gb, t->coeff[i], method + 1, coeff_bits, is_signed, offset);
158 
159  lsb_size = get_bits(gb, 3);
160  for (j = method + 1; j < t->length[i]; j++) {
161  int c, x = 0;
162  for (k = 0; k < method + 1; k++)
163  x += code_pred_coeff[method][k] * (unsigned)t->coeff[i][j - k - 1];
164  c = get_sr_golomb_dst(gb, lsb_size);
165  if (x >= 0)
166  c -= (x + 4) / 8;
167  else
168  c += (-x + 3) / 8;
169  if (!is_signed) {
170  if (c < offset || c >= offset + (1<<coeff_bits))
171  return AVERROR_INVALIDDATA;
172  }
173  t->coeff[i][j] = c;
174  }
175  }
176  }
177  return 0;
178 }
179 
180 static void ac_init(ArithCoder *ac, GetBitContext *gb)
181 {
182  ac->a = 4095;
183  ac->c = get_bits(gb, 12);
184  ac->overread = 0;
185 }
186 
187 static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, int *e)
188 {
189  unsigned int k = (ac->a >> 8) | ((ac->a >> 7) & 1);
190  unsigned int q = k * p;
191  unsigned int a_q = ac->a - q;
192 
193  *e = ac->c < a_q;
194  if (*e) {
195  ac->a = a_q;
196  } else {
197  ac->a = q;
198  ac->c -= a_q;
199  }
200 
201  if (ac->a < 2048) {
202  int n = 11 - av_log2(ac->a);
203  ac->a <<= n;
204  if (get_bits_left(gb) < n)
205  ac->overread ++;
206  ac->c = (ac->c << n) | get_bits(gb, n);
207  }
208 }
209 
211 {
212  return (ff_reverse[c & 127] >> 1) + 1;
213 }
214 
215 static void build_filter(int16_t table[DST_MAX_ELEMENTS][16][256], const Table *fsets)
216 {
217  int i, j, k, l;
218 
219  for (i = 0; i < fsets->elements; i++) {
220  int length = fsets->length[i];
221 
222  for (j = 0; j < 16; j++) {
223  int total = av_clip(length - j * 8, 0, 8);
224 
225  for (k = 0; k < 256; k++) {
226  int v = 0;
227 
228  for (l = 0; l < total; l++)
229  v += (((k >> l) & 1) * 2 - 1) * fsets->coeff[i][j * 8 + l];
230  table[i][j][k] = v;
231  }
232  }
233  }
234 }
235 
236 static int decode_frame(AVCodecContext *avctx, void *data,
237  int *got_frame_ptr, AVPacket *avpkt)
238 {
239  unsigned samples_per_frame = DST_SAMPLES_PER_FRAME(avctx->sample_rate);
240  unsigned map_ch_to_felem[DST_MAX_CHANNELS];
241  unsigned map_ch_to_pelem[DST_MAX_CHANNELS];
242  unsigned i, ch, same_map, dst_x_bit;
243  unsigned half_prob[DST_MAX_CHANNELS];
244  const int channels = avctx->channels;
245  DSTContext *s = avctx->priv_data;
246  GetBitContext *gb = &s->gb;
247  ArithCoder *ac = &s->ac;
248  AVFrame *frame = data;
249  uint8_t *dsd;
250  float *pcm;
251  int ret;
252 
253  if (avpkt->size <= 1)
254  return AVERROR_INVALIDDATA;
255 
256  frame->nb_samples = samples_per_frame / 8;
257  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
258  return ret;
259  dsd = frame->data[0];
260  pcm = (float *)frame->data[0];
261 
262  if ((ret = init_get_bits8(gb, avpkt->data, avpkt->size)) < 0)
263  return ret;
264 
265  if (!get_bits1(gb)) {
266  skip_bits1(gb);
267  if (get_bits(gb, 6))
268  return AVERROR_INVALIDDATA;
269  memcpy(frame->data[0], avpkt->data + 1, FFMIN(avpkt->size - 1, frame->nb_samples * channels));
270  goto dsd;
271  }
272 
273  /* Segmentation (10.4, 10.5, 10.6) */
274 
275  if (!get_bits1(gb)) {
276  avpriv_request_sample(avctx, "Not Same Segmentation");
277  return AVERROR_PATCHWELCOME;
278  }
279 
280  if (!get_bits1(gb)) {
281  avpriv_request_sample(avctx, "Not Same Segmentation For All Channels");
282  return AVERROR_PATCHWELCOME;
283  }
284 
285  if (!get_bits1(gb)) {
286  avpriv_request_sample(avctx, "Not End Of Channel Segmentation");
287  return AVERROR_PATCHWELCOME;
288  }
289 
290  /* Mapping (10.7, 10.8, 10.9) */
291 
292  same_map = get_bits1(gb);
293 
294  if ((ret = read_map(gb, &s->fsets, map_ch_to_felem, channels)) < 0)
295  return ret;
296 
297  if (same_map) {
298  s->probs.elements = s->fsets.elements;
299  memcpy(map_ch_to_pelem, map_ch_to_felem, sizeof(map_ch_to_felem));
300  } else {
301  avpriv_request_sample(avctx, "Not Same Mapping");
302  if ((ret = read_map(gb, &s->probs, map_ch_to_pelem, channels)) < 0)
303  return ret;
304  }
305 
306  /* Half Probability (10.10) */
307 
308  for (ch = 0; ch < channels; ch++)
309  half_prob[ch] = get_bits1(gb);
310 
311  /* Filter Coef Sets (10.12) */
312 
313  ret = read_table(gb, &s->fsets, fsets_code_pred_coeff, 7, 9, 1, 0);
314  if (ret < 0)
315  return ret;
316 
317  /* Probability Tables (10.13) */
318 
319  ret = read_table(gb, &s->probs, probs_code_pred_coeff, 6, 7, 0, 1);
320  if (ret < 0)
321  return ret;
322 
323  /* Arithmetic Coded Data (10.11) */
324 
325  if (get_bits1(gb))
326  return AVERROR_INVALIDDATA;
327  ac_init(ac, gb);
328 
329  build_filter(s->filter, &s->fsets);
330 
331  memset(s->status, 0xAA, sizeof(s->status));
332  memset(dsd, 0, frame->nb_samples * 4 * channels);
333 
334  ac_get(ac, gb, prob_dst_x_bit(s->fsets.coeff[0][0]), &dst_x_bit);
335 
336  for (i = 0; i < samples_per_frame; i++) {
337  for (ch = 0; ch < channels; ch++) {
338  const unsigned felem = map_ch_to_felem[ch];
339  int16_t (*filter)[256] = s->filter[felem];
340  uint8_t *status = s->status[ch];
341  int prob, residual, v;
342 
343 #define F(x) filter[(x)][status[(x)]]
344  const int16_t predict = F( 0) + F( 1) + F( 2) + F( 3) +
345  F( 4) + F( 5) + F( 6) + F( 7) +
346  F( 8) + F( 9) + F(10) + F(11) +
347  F(12) + F(13) + F(14) + F(15);
348 #undef F
349 
350  if (!half_prob[ch] || i >= s->fsets.length[felem]) {
351  unsigned pelem = map_ch_to_pelem[ch];
352  unsigned index = FFABS(predict) >> 3;
353  prob = s->probs.coeff[pelem][FFMIN(index, s->probs.length[pelem] - 1)];
354  } else {
355  prob = 128;
356  }
357 
358  if (ac->overread > 16)
359  return AVERROR_INVALIDDATA;
360 
361  ac_get(ac, gb, prob, &residual);
362  v = ((predict >> 15) ^ residual) & 1;
363  dsd[((i >> 3) * channels + ch) << 2] |= v << (7 - (i & 0x7 ));
364 
365  AV_WL64A(status + 8, (AV_RL64A(status + 8) << 1) | ((AV_RL64A(status) >> 63) & 1));
366  AV_WL64A(status, (AV_RL64A(status) << 1) | v);
367  }
368  }
369 
370 dsd:
371  for (i = 0; i < channels; i++) {
372  ff_dsd2pcm_translate(&s->dsdctx[i], frame->nb_samples, 0,
373  frame->data[0] + i * 4,
374  channels * 4, pcm + i, channels);
375  }
376 
377  *got_frame_ptr = 1;
378 
379  return avpkt->size;
380 }
381 
383  .name = "dst",
384  .long_name = NULL_IF_CONFIG_SMALL("DST (Digital Stream Transfer)"),
385  .type = AVMEDIA_TYPE_AUDIO,
386  .id = AV_CODEC_ID_DST,
387  .priv_data_size = sizeof(DSTContext),
388  .init = decode_init,
389  .decode = decode_frame,
390  .capabilities = AV_CODEC_CAP_DR1,
391  .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
393 };
AVCodec
AVCodec.
Definition: codec.h:190
ac_get
static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, int *e)
Definition: dstdec.c:187
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
DSTContext::status
uint8_t status[DST_MAX_CHANNELS][16]
Definition: dstdec.c:74
DSTContext::ac
ArithCoder ac
Definition: dstdec.c:72
elements
static const ElemCat * elements[ELEMENT_COUNT]
Definition: signature.h:566
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1186
DSTContext::fsets
Table fsets
Definition: dstdec.c:73
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:716
decode_frame
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: dstdec.c:236
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
ff_reverse
const uint8_t ff_reverse[256]
Definition: reverse.c:23
table
static const uint16_t table[]
Definition: prosumer.c:206
data
const char data[16]
Definition: mxf.c:91
read_table
static int read_table(GetBitContext *gb, Table *t, const int8_t code_pred_coeff[3][3], int length_bits, int coeff_bits, int is_signed, int offset)
Definition: dstdec.c:144
F
#define F(x)
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
dsd.h
golomb.h
exp golomb vlc stuff
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
ac_init
static void ac_init(ArithCoder *ac, GetBitContext *gb)
Definition: dstdec.c:180
GetBitContext
Definition: get_bits.h:61
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
read_map
static int read_map(GetBitContext *gb, Table *t, unsigned int map[DST_MAX_CHANNELS], int channels)
Definition: dstdec.c:103
avassert.h
get_ur_golomb_jpegls
static int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len)
read unsigned golomb rice code (jpegls).
Definition: golomb.h:428
av_cold
#define av_cold
Definition: attributes.h:90
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: dstdec.c:79
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
bits
uint8_t bits
Definition: vp3data.h:202
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
channels
channels
Definition: aptx.h:33
get_bits.h
ArithCoder
Definition: dstdec.c:56
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
if
if(ret)
Definition: filter_design.txt:179
ch
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_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 &&HAVE_MMX) 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
Definition: audioconvert.c:56
AV_WL64A
#define AV_WL64A(p, v)
Definition: intreadwrite.h:557
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
AV_CODEC_ID_DST
@ AV_CODEC_ID_DST
Definition: codec_id.h:492
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
DSTContext::gb
GetBitContext gb
Definition: dstdec.c:71
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
mathops.h
DSTContext::filter
int16_t filter[DST_MAX_ELEMENTS][16][256]
Definition: dstdec.c:75
fsets_code_pred_coeff
static const int8_t fsets_code_pred_coeff[3][3]
Definition: dstdec.c:44
index
int index
Definition: gxfenc.c:89
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ff_dst_decoder
AVCodec ff_dst_decoder
Definition: dstdec.c:382
ff_init_dsd_data
av_cold void ff_init_dsd_data(void)
Definition: dsd.c:46
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1854
ArithCoder::c
unsigned int c
Definition: dstdec.c:58
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
AVPacket::size
int size
Definition: packet.h:356
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:186
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1194
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
probs_code_pred_coeff
static const int8_t probs_code_pred_coeff[3][3]
Definition: dstdec.c:50
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
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
skip_bits1
static void skip_bits1(GetBitContext *s)
Definition: get_bits.h:538
DSTContext::dsdctx
DSDContext dsdctx[DST_MAX_CHANNELS]
Definition: dstdec.c:76
av_log2
#define av_log2
Definition: intmath.h:83
AVCodecContext::channels
int channels
number of audio channels
Definition: avcodec.h:1187
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:112
prob_dst_x_bit
static uint8_t prob_dst_x_bit(int c)
Definition: dstdec.c:210
DSTContext::probs
Table probs
Definition: dstdec.c:73
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
get_sr_golomb_dst
static av_always_inline int get_sr_golomb_dst(GetBitContext *gb, unsigned int k)
Definition: dstdec.c:126
predict
static av_always_inline void predict(PredictorState *ps, float *coef, int output_enable)
Definition: aacdec.c:174
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
av_always_inline
#define av_always_inline
Definition: attributes.h:49
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
DSDContext
Per-channel buffer.
Definition: dsd.h:42
read_uncoded_coeff
static void read_uncoded_coeff(GetBitContext *gb, int *dst, unsigned int elements, int coeff_bits, int is_signed, int offset)
Definition: dstdec.c:134
DST_MAX_CHANNELS
#define DST_MAX_CHANNELS
Definition: dstdec.c:37
avcodec.h
DSTContext
Definition: dstdec.c:68
ff_dsd2pcm_translate
void ff_dsd2pcm_translate(DSDContext *s, size_t samples, int lsbf, const uint8_t *src, ptrdiff_t src_stride, float *dst, ptrdiff_t dst_stride)
Definition: dsd.c:55
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:373
build_filter
static void build_filter(int16_t table[DST_MAX_ELEMENTS][16][256], const Table *fsets)
Definition: dstdec.c:215
Table::length
unsigned int length[DST_MAX_ELEMENTS]
Definition: dstdec.c:64
AVCodecContext
main external API structure.
Definition: avcodec.h:526
AV_RL64A
#define AV_RL64A(p)
Definition: intreadwrite.h:554
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:39
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:85
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
ArithCoder::overread
int overread
Definition: dstdec.c:59
ArithCoder::a
unsigned int a
Definition: dstdec.c:57
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
Table::coeff
int coeff[DST_MAX_ELEMENTS][128]
Definition: dstdec.c:65
Table
Definition: dstdec.c:62
DST_MAX_ELEMENTS
#define DST_MAX_ELEMENTS
Definition: dstdec.c:38
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
DST_SAMPLES_PER_FRAME
#define DST_SAMPLES_PER_FRAME(sample_rate)
Definition: dstdec.c:42
Table::elements
unsigned int elements
Definition: dstdec.c:63