FFmpeg
aadec.c
Go to the documentation of this file.
1 /*
2  * Audible AA demuxer
3  * Copyright (c) 2015 Vesselin Bontchev
4  *
5  * Header parsing is borrowed from https://github.com/jteeuwen/audible project.
6  * Copyright (c) 2001-2014, Jim Teeuwen
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "avformat.h"
27 #include "internal.h"
28 #include "libavutil/dict.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/tea.h"
31 #include "libavutil/opt.h"
32 
33 #define AA_MAGIC 1469084982 /* this identifies an audible .aa file */
34 #define MAX_CODEC_SECOND_SIZE 3982
35 #define MAX_TOC_ENTRIES 16
36 #define MAX_DICTIONARY_ENTRIES 128
37 #define TEA_BLOCK_SIZE 8
38 #define CHAPTER_HEADER_SIZE 8
39 #define TIMEPREC 1000
40 #define MP3_FRAME_SIZE 104
41 
42 typedef struct AADemuxContext {
43  AVClass *class;
49  struct AVTEA *tea_ctx;
52  int64_t content_start;
53  int64_t content_end;
56 
57 static int get_second_size(char *codec_name)
58 {
59  int result = -1;
60 
61  if (!strcmp(codec_name, "mp332")) {
62  result = 3982;
63  } else if (!strcmp(codec_name, "acelp16")) {
64  result = 2000;
65  } else if (!strcmp(codec_name, "acelp85")) {
66  result = 1045;
67  }
68 
69  return result;
70 }
71 
73 {
74  int i, j, idx, largest_idx = -1;
75  uint32_t nkey, nval, toc_size, npairs, header_seed = 0, start;
76  char key[128], val[128], codec_name[64] = {0};
77  uint8_t output[24], dst[8], src[8];
78  int64_t largest_size = -1, current_size = -1, chapter_pos;
79  struct toc_entry {
80  uint32_t offset;
81  uint32_t size;
82  } TOC[MAX_TOC_ENTRIES];
83  uint32_t header_key_part[4];
84  uint8_t header_key[16] = {0};
86  AVIOContext *pb = s->pb;
87  AVStream *st;
88  int ret;
89 
90  /* parse .aa header */
91  avio_skip(pb, 4); // file size
92  avio_skip(pb, 4); // magic string
93  toc_size = avio_rb32(pb); // TOC size
94  avio_skip(pb, 4); // unidentified integer
95  if (toc_size > MAX_TOC_ENTRIES)
96  return AVERROR_INVALIDDATA;
97  for (i = 0; i < toc_size; i++) { // read TOC
98  avio_skip(pb, 4); // TOC entry index
99  TOC[i].offset = avio_rb32(pb); // block offset
100  TOC[i].size = avio_rb32(pb); // block size
101  }
102  avio_skip(pb, 24); // header termination block (ignored)
103  npairs = avio_rb32(pb); // read dictionary entries
104  if (npairs > MAX_DICTIONARY_ENTRIES)
105  return AVERROR_INVALIDDATA;
106  for (i = 0; i < npairs; i++) {
107  memset(val, 0, sizeof(val));
108  memset(key, 0, sizeof(key));
109  avio_skip(pb, 1); // unidentified integer
110  nkey = avio_rb32(pb); // key string length
111  nval = avio_rb32(pb); // value string length
112  avio_get_str(pb, nkey, key, sizeof(key));
113  avio_get_str(pb, nval, val, sizeof(val));
114  if (!strcmp(key, "codec")) {
115  av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val);
116  strncpy(codec_name, val, sizeof(codec_name) - 1);
117  } else if (!strcmp(key, "HeaderSeed")) {
118  av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val);
119  header_seed = atoi(val);
120  } else if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890"
121  av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val);
122 
123  ret = sscanf(val, "%"SCNu32"%"SCNu32"%"SCNu32"%"SCNu32,
124  &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]);
125  if (ret != 4)
126  return AVERROR_INVALIDDATA;
127 
128  for (idx = 0; idx < 4; idx++) {
129  AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE!
130  }
131  av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is ");
132  for (i = 0; i < 16; i++)
133  av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]);
134  av_log(s, AV_LOG_DEBUG, "\n");
135  } else {
136  av_dict_set(&s->metadata, key, val, 0);
137  }
138  }
139 
140  /* verify fixed key */
141  if (c->aa_fixed_key_len != 16) {
142  av_log(s, AV_LOG_ERROR, "aa_fixed_key value needs to be 16 bytes!\n");
143  return AVERROR(EINVAL);
144  }
145 
146  /* verify codec */
147  if ((c->codec_second_size = get_second_size(codec_name)) == -1) {
148  av_log(s, AV_LOG_ERROR, "unknown codec <%s>!\n", codec_name);
149  return AVERROR(EINVAL);
150  }
151 
152  /* decryption key derivation */
153  c->tea_ctx = av_tea_alloc();
154  if (!c->tea_ctx)
155  return AVERROR(ENOMEM);
156  av_tea_init(c->tea_ctx, c->aa_fixed_key, 16);
157  output[0] = output[1] = 0; // purely for padding purposes
158  memcpy(output + 2, header_key, 16);
159  idx = 0;
160  for (i = 0; i < 3; i++) { // TEA CBC with weird mixed endianness
161  AV_WB32(src, header_seed);
162  AV_WB32(src + 4, header_seed + 1);
163  header_seed += 2;
164  av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 0); // TEA ECB encrypt
165  for (j = 0; j < TEA_BLOCK_SIZE && idx < 18; j+=1, idx+=1) {
166  output[idx] = output[idx] ^ dst[j];
167  }
168  }
169  memcpy(c->file_key, output + 2, 16); // skip first 2 bytes of output
170  av_log(s, AV_LOG_DEBUG, "File key is ");
171  for (i = 0; i < 16; i++)
172  av_log(s, AV_LOG_DEBUG, "%02x", c->file_key[i]);
173  av_log(s, AV_LOG_DEBUG, "\n");
174 
175  /* decoder setup */
176  st = avformat_new_stream(s, NULL);
177  if (!st) {
178  av_freep(&c->tea_ctx);
179  return AVERROR(ENOMEM);
180  }
182  if (!strcmp(codec_name, "mp332")) {
184  st->codecpar->sample_rate = 22050;
186  avpriv_set_pts_info(st, 64, 8, 32000 * TIMEPREC);
187  // encoded audio frame is MP3_FRAME_SIZE bytes (+1 with padding, unlikely)
188  } else if (!strcmp(codec_name, "acelp85")) {
190  st->codecpar->block_align = 19;
191  st->codecpar->channels = 1;
192  st->codecpar->sample_rate = 8500;
193  st->codecpar->bit_rate = 8500;
195  avpriv_set_pts_info(st, 64, 8, 8500 * TIMEPREC);
196  } else if (!strcmp(codec_name, "acelp16")) {
198  st->codecpar->block_align = 20;
199  st->codecpar->channels = 1;
200  st->codecpar->sample_rate = 16000;
201  st->codecpar->bit_rate = 16000;
203  avpriv_set_pts_info(st, 64, 8, 16000 * TIMEPREC);
204  }
205 
206  /* determine, and jump to audio start offset */
207  for (i = 1; i < toc_size; i++) { // skip the first entry!
208  current_size = TOC[i].size;
209  if (current_size > largest_size) {
210  largest_idx = i;
211  largest_size = current_size;
212  }
213  }
214  start = TOC[largest_idx].offset;
215  avio_seek(pb, start, SEEK_SET);
216 
217  // extract chapter positions. since all formats have constant bit rate, use it
218  // as time base in bytes/s, for easy stream position <-> timestamp conversion
219  st->start_time = 0;
220  c->content_start = start;
221  c->content_end = start + largest_size;
222 
223  while ((chapter_pos = avio_tell(pb)) >= 0 && chapter_pos < c->content_end) {
224  int chapter_idx = s->nb_chapters;
225  uint32_t chapter_size = avio_rb32(pb);
226  if (chapter_size == 0) break;
227  chapter_pos -= start + CHAPTER_HEADER_SIZE * chapter_idx;
228  avio_skip(pb, 4 + chapter_size);
229  if (!avpriv_new_chapter(s, chapter_idx, st->time_base,
230  chapter_pos * TIMEPREC, (chapter_pos + chapter_size) * TIMEPREC, NULL))
231  return AVERROR(ENOMEM);
232  }
233 
234  st->duration = (largest_size - CHAPTER_HEADER_SIZE * s->nb_chapters) * TIMEPREC;
235 
236  ff_update_cur_dts(s, st, 0);
237  avio_seek(pb, start, SEEK_SET);
238  c->current_chapter_size = 0;
239  c->seek_offset = 0;
240 
241  return 0;
242 }
243 
245 {
246  uint8_t dst[TEA_BLOCK_SIZE];
248  int i;
249  int trailing_bytes;
250  int blocks;
252  int written = 0;
253  int ret;
254  AADemuxContext *c = s->priv_data;
255  uint64_t pos = avio_tell(s->pb);
256 
257  // are we at the end of the audio content?
258  if (pos >= c->content_end) {
259  return AVERROR_EOF;
260  }
261 
262  // are we at the start of a chapter?
263  if (c->current_chapter_size == 0) {
265  if (c->current_chapter_size == 0) {
266  return AVERROR_EOF;
267  }
268  av_log(s, AV_LOG_DEBUG, "Chapter %d (%" PRId64 " bytes)\n", c->chapter_idx, c->current_chapter_size);
269  c->chapter_idx = c->chapter_idx + 1;
270  avio_skip(s->pb, 4); // data start offset
271  pos += 8;
273  }
274 
275  // is this the last block in this chapter?
278  }
279 
280  // decrypt c->current_codec_second_size bytes
282  for (i = 0; i < blocks; i++) {
283  ret = avio_read(s->pb, src, TEA_BLOCK_SIZE);
284  if (ret != TEA_BLOCK_SIZE)
285  return (ret < 0) ? ret : AVERROR_EOF;
286  av_tea_init(c->tea_ctx, c->file_key, 16);
287  av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
288  memcpy(buf + written, dst, TEA_BLOCK_SIZE);
289  written = written + TEA_BLOCK_SIZE;
290  }
291  trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
292  if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
293  ret = avio_read(s->pb, src, trailing_bytes);
294  if (ret != trailing_bytes)
295  return (ret < 0) ? ret : AVERROR_EOF;
296  memcpy(buf + written, src, trailing_bytes);
297  written = written + trailing_bytes;
298  }
299 
300  // update state
302  if (c->current_chapter_size <= 0)
303  c->current_chapter_size = 0;
304 
305  if (c->seek_offset > written)
306  c->seek_offset = 0; // ignore wrong estimate
307 
308  ret = av_new_packet(pkt, written - c->seek_offset);
309  if (ret < 0)
310  return ret;
311  memcpy(pkt->data, buf + c->seek_offset, written - c->seek_offset);
312  pkt->pos = pos;
313 
314  c->seek_offset = 0;
315  return 0;
316 }
317 
319  int stream_index, int64_t timestamp, int flags)
320 {
321  AADemuxContext *c = s->priv_data;
322  AVChapter *ch;
323  int64_t chapter_pos, chapter_start, chapter_size;
324  int chapter_idx = 0;
325 
326  // find chapter containing seek timestamp
327  if (timestamp < 0)
328  timestamp = 0;
329 
330  while (chapter_idx < s->nb_chapters && timestamp >= s->chapters[chapter_idx]->end) {
331  ++chapter_idx;
332  }
333 
334  if (chapter_idx >= s->nb_chapters) {
335  chapter_idx = s->nb_chapters - 1;
336  if (chapter_idx < 0) return -1; // there is no chapter.
337  timestamp = s->chapters[chapter_idx]->end;
338  }
339 
340  ch = s->chapters[chapter_idx];
341 
342  // sync by clamping timestamp to nearest valid block position in its chapter
343  chapter_size = ch->end / TIMEPREC - ch->start / TIMEPREC;
344  chapter_pos = av_rescale_rnd((timestamp - ch->start) / TIMEPREC,
345  1, c->codec_second_size,
347  * c->codec_second_size;
348  if (chapter_pos >= chapter_size)
349  chapter_pos = chapter_size;
350  chapter_start = c->content_start + (ch->start / TIMEPREC) + CHAPTER_HEADER_SIZE * (1 + chapter_idx);
351 
352  // reinit read state
353  avio_seek(s->pb, chapter_start + chapter_pos, SEEK_SET);
355  c->current_chapter_size = chapter_size - chapter_pos;
356  c->chapter_idx = 1 + chapter_idx;
357 
358  // for unaligned frames, estimate offset of first frame in block (assume no padding)
359  if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_MP3) {
360  c->seek_offset = (MP3_FRAME_SIZE - chapter_pos % MP3_FRAME_SIZE) % MP3_FRAME_SIZE;
361  }
362 
363  ff_update_cur_dts(s, s->streams[0], ch->start + (chapter_pos + c->seek_offset) * TIMEPREC);
364 
365  return 1;
366 }
367 
368 static int aa_probe(const AVProbeData *p)
369 {
370  uint8_t *buf = p->buf;
371 
372  // first 4 bytes are file size, next 4 bytes are the magic
373  if (AV_RB32(buf+4) != AA_MAGIC)
374  return 0;
375 
376  return AVPROBE_SCORE_MAX / 2;
377 }
378 
380 {
381  AADemuxContext *c = s->priv_data;
382 
383  av_freep(&c->tea_ctx);
384 
385  return 0;
386 }
387 
388 #define OFFSET(x) offsetof(AADemuxContext, x)
389 static const AVOption aa_options[] = {
390  { "aa_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
391  "Fixed key used for handling Audible AA files", OFFSET(aa_fixed_key),
392  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd2a51d673"},
393  .flags = AV_OPT_FLAG_DECODING_PARAM },
394  { NULL },
395 };
396 
397 static const AVClass aa_class = {
398  .class_name = "aa",
399  .item_name = av_default_item_name,
400  .option = aa_options,
401  .version = LIBAVUTIL_VERSION_INT,
402 };
403 
405  .name = "aa",
406  .long_name = NULL_IF_CONFIG_SMALL("Audible AA format files"),
407  .priv_class = &aa_class,
408  .priv_data_size = sizeof(AADemuxContext),
409  .extensions = "aa",
410  .read_probe = aa_probe,
416 };
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition: avformat.h:1587
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2511
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:863
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVOption.
Definition: opt.h:246
int seek_offset
Definition: aadec.c:54
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int64_t pos
byte position in stream, -1 if unknown
Definition: avcodec.h:1497
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4892
uint8_t file_key[16]
Definition: aadec.c:50
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
#define AA_MAGIC
Definition: aadec.c:33
static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: aadec.c:244
int64_t content_start
Definition: aadec.c:52
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
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/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(INT64_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 *(INT64_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 *(INT64_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
Definition: audioconvert.c:56
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int current_codec_second_size
Definition: aadec.c:47
static int aa_probe(const AVProbeData *p)
Definition: aadec.c:368
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:334
const char * key
static AVPacket pkt
#define src
Definition: vp8dsp.c:254
struct AVTEA * av_tea_alloc(void)
Allocate an AVTEA context To free the struct: av_free(ptr)
Definition: tea.c:35
AVChapter * avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: utils.c:4593
#define MP3_FRAME_SIZE
Definition: aadec.c:40
Format I/O context.
Definition: avformat.h:1358
void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
Update cur_dts of all streams based on the given timestamp and AVStream.
Definition: utils.c:1953
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
Public dictionary API.
uint8_t
Round toward +infinity.
Definition: mathematics.h:83
AVOptions.
#define MAX_CODEC_SECOND_SIZE
Definition: aadec.c:34
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:803
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
static const AVOption aa_options[]
Definition: aadec.c:389
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
enum AVStreamParseType need_parsing
Definition: avformat.h:1099
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 output
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4465
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
Definition: tea.c:30
uint8_t * data
Definition: avcodec.h:1477
#define AVERROR_EOF
End of file.
Definition: error.h:55
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
ptrdiff_t size
Definition: opengl_enc.c:100
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
AVInputFormat ff_aa_demuxer
Definition: aadec.c:404
full parsing and repack with timestamp and position generation by parser for raw this assumes that ea...
Definition: avformat.h:804
#define av_log(a,...)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:650
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1598
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
int64_t content_end
Definition: aadec.c:53
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: avcodec.h:565
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
static int aa_read_header(AVFormatContext *s)
Definition: aadec.c:72
uint8_t * aa_fixed_key
Definition: aadec.c:44
AVChapter ** chapters
Definition: avformat.h:1588
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:448
int64_t current_chapter_size
Definition: aadec.c:51
int block_align
Audio only.
Definition: avcodec.h:4074
Public header for libavutil TEA algorithm.
void av_tea_crypt(AVTEA *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: tea.c:95
struct AVTEA * tea_ctx
Definition: aadec.c:49
#define MAX_DICTIONARY_ENTRIES
Definition: aadec.c:36
#define s(width, name)
Definition: cbs_vp9.c:257
#define OFFSET(x)
Definition: aadec.c:388
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:58
offset must point to a pointer immediately followed by an int for the length
Definition: opt.h:229
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
static int aa_read_close(AVFormatContext *s)
Definition: aadec.c:379
Stream structure.
Definition: avformat.h:881
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
int64_t end
chapter start/end time in time_base units
Definition: avformat.h:1318
#define TIMEPREC
Definition: aadec.c:39
AVIOContext * pb
I/O context.
Definition: avformat.h:1400
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:474
#define MAX_TOC_ENTRIES
Definition: aadec.c:35
void * buf
Definition: avisynth_c.h:766
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
Describe the class of an AVClass context structure.
Definition: log.h:67
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:277
static int get_second_size(char *codec_name)
Definition: aadec.c:57
static const AVClass aa_class
Definition: aadec.c:397
This structure contains the data a format has to probe a file.
Definition: avformat.h:446
Round toward -infinity.
Definition: mathematics.h:82
#define flags(name, subs,...)
Definition: cbs_av1.c:561
int chapter_idx
Definition: aadec.c:48
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
int64_t start
Definition: avformat.h:1318
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:930
int sample_rate
Audio only.
Definition: avcodec.h:4067
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:458
Main libavformat public API header.
void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds)
Initialize an AVTEA context.
Definition: tea.c:42
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
Definition: avformat.h:920
#define TEA_BLOCK_SIZE
Definition: aadec.c:37
int codec_second_size
Definition: aadec.c:46
#define CHAPTER_HEADER_SIZE
Definition: aadec.c:38
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:475
int aa_fixed_key_len
Definition: aadec.c:45
void * priv_data
Format private data.
Definition: avformat.h:1386
static int aa_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: aadec.c:318
int channels
Audio only.
Definition: avcodec.h:4063
and forward the result(frame or status change) to the corresponding input.If nothing is possible
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:766
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:654
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:882
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:910
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
This structure stores compressed data.
Definition: avcodec.h:1454