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 "demux.h"
28 #include "internal.h"
29 #include "libavutil/avstring.h"
30 #include "libavutil/dict.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/tea.h"
34 #include "libavutil/opt.h"
35 
36 #define AA_MAGIC 1469084982 /* this identifies an audible .aa file */
37 #define MAX_TOC_ENTRIES 16
38 #define MAX_DICTIONARY_ENTRIES 128
39 #define TEA_BLOCK_SIZE 8
40 #define CHAPTER_HEADER_SIZE 8
41 #define TIMEPREC 1000
42 #define MP3_FRAME_SIZE 104
43 
44 typedef struct AADemuxContext {
45  AVClass *class;
46  uint8_t *aa_fixed_key;
51  struct AVTEA *tea_ctx;
52  uint8_t file_key[16];
58 
59 static int get_second_size(char *codec_name)
60 {
61  int result = -1;
62 
63  if (!strcmp(codec_name, "mp332")) {
64  result = 3982;
65  } else if (!strcmp(codec_name, "acelp16")) {
66  result = 2000;
67  } else if (!strcmp(codec_name, "acelp85")) {
68  result = 1045;
69  }
70 
71  return result;
72 }
73 
75 {
76  int largest_idx = -1;
77  uint32_t toc_size, npairs, header_seed = 0, start;
78  char codec_name[64] = {0};
79  uint8_t buf[24];
80  int64_t largest_size = -1, current_size = -1, chapter_pos;
81  struct toc_entry {
82  uint32_t offset;
83  uint32_t size;
84  } TOC[MAX_TOC_ENTRIES];
85  uint8_t header_key[16] = {0};
86  AADemuxContext *c = s->priv_data;
87  char file_key[2 * sizeof(c->file_key) + 1];
88  AVIOContext *pb = s->pb;
89  AVStream *st;
90  FFStream *sti;
91  int ret;
92 
93  /* parse .aa header */
94  avio_skip(pb, 4); // file size
95  avio_skip(pb, 4); // magic string
96  toc_size = avio_rb32(pb); // TOC size
97  avio_skip(pb, 4); // unidentified integer
98  if (toc_size > MAX_TOC_ENTRIES || toc_size < 2)
99  return AVERROR_INVALIDDATA;
100  for (uint32_t i = 0; i < toc_size; i++) { // read TOC
101  avio_skip(pb, 4); // TOC entry index
102  TOC[i].offset = avio_rb32(pb); // block offset
103  TOC[i].size = avio_rb32(pb); // block size
104  }
105  avio_skip(pb, 24); // header termination block (ignored)
106  npairs = avio_rb32(pb); // read dictionary entries
107  if (npairs > MAX_DICTIONARY_ENTRIES)
108  return AVERROR_INVALIDDATA;
109  for (uint32_t i = 0; i < npairs; i++) {
110  char key[128], val[128];
111  uint32_t nkey, nval;
112 
113  avio_skip(pb, 1); // unidentified integer
114  nkey = avio_rb32(pb); // key string length
115  nval = avio_rb32(pb); // value string length
116  avio_get_str(pb, nkey, key, sizeof(key));
117  avio_get_str(pb, nval, val, sizeof(val));
118  if (!strcmp(key, "codec")) {
119  av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val);
120  av_strlcpy(codec_name, val, sizeof(codec_name));
121  } else if (!strcmp(key, "HeaderSeed")) {
122  av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val);
123  header_seed = atoi(val);
124  } else if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890"
125  uint32_t header_key_part[4];
126  av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val);
127 
128  ret = sscanf(val, "%"SCNu32"%"SCNu32"%"SCNu32"%"SCNu32,
129  &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]);
130  if (ret != 4)
131  return AVERROR_INVALIDDATA;
132 
133  for (int idx = 0; idx < 4; idx++)
134  AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE!
135  ff_data_to_hex(key, header_key, sizeof(header_key), 1);
136  av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is %s\n", key);
137  } else {
138  av_dict_set(&s->metadata, key, val, 0);
139  }
140  }
141 
142  /* verify fixed key */
143  if (c->aa_fixed_key_len != 16) {
144  av_log(s, AV_LOG_ERROR, "aa_fixed_key value needs to be 16 bytes!\n");
145  return AVERROR(EINVAL);
146  }
147 
148  /* verify codec */
149  if ((c->codec_second_size = get_second_size(codec_name)) == -1) {
150  av_log(s, AV_LOG_ERROR, "unknown codec <%s>!\n", codec_name);
151  return AVERROR(EINVAL);
152  }
153 
154  /* decryption key derivation */
155  c->tea_ctx = av_tea_alloc();
156  if (!c->tea_ctx)
157  return AVERROR(ENOMEM);
158  av_tea_init(c->tea_ctx, c->aa_fixed_key, 16);
159  for (int i = 0; i < 6; i++)
160  AV_WB32(buf + 4 * i, header_seed + i);
161  av_tea_crypt(c->tea_ctx, buf, buf, 3, NULL, 0);
162  AV_WN64(c->file_key, AV_RN64(buf + 2) ^ AV_RN64(header_key));
163  AV_WN64(c->file_key + 8, AV_RN64(buf + 10) ^ AV_RN64(header_key + 8));
164  ff_data_to_hex(file_key, c->file_key, sizeof(c->file_key), 1);
165  av_log(s, AV_LOG_DEBUG, "File key is %s\n", file_key);
166  av_tea_init(c->tea_ctx, c->file_key, 16);
167 
168  /* decoder setup */
169  st = avformat_new_stream(s, NULL);
170  if (!st)
171  return AVERROR(ENOMEM);
172  sti = ffstream(st);
174  if (!strcmp(codec_name, "mp332")) {
176  st->codecpar->sample_rate = 22050;
178  avpriv_set_pts_info(st, 64, 8, 32000 * TIMEPREC);
179  // encoded audio frame is MP3_FRAME_SIZE bytes (+1 with padding, unlikely)
180  } else if (!strcmp(codec_name, "acelp85")) {
182  st->codecpar->block_align = 19;
183  st->codecpar->ch_layout.nb_channels = 1;
184  st->codecpar->sample_rate = 8500;
185  st->codecpar->bit_rate = 8500;
187  avpriv_set_pts_info(st, 64, 8, 8500 * TIMEPREC);
188  } else if (!strcmp(codec_name, "acelp16")) {
190  st->codecpar->block_align = 20;
191  st->codecpar->ch_layout.nb_channels = 1;
192  st->codecpar->sample_rate = 16000;
193  st->codecpar->bit_rate = 16000;
195  avpriv_set_pts_info(st, 64, 8, 16000 * TIMEPREC);
196  }
197 
198  /* determine, and jump to audio start offset */
199  for (uint32_t i = 1; i < toc_size; i++) { // skip the first entry!
200  current_size = TOC[i].size;
201  if (current_size > largest_size) {
202  largest_idx = i;
203  largest_size = current_size;
204  }
205  }
206  start = TOC[largest_idx].offset;
207  avio_seek(pb, start, SEEK_SET);
208 
209  // extract chapter positions. since all formats have constant bit rate, use it
210  // as time base in bytes/s, for easy stream position <-> timestamp conversion
211  st->start_time = 0;
212  c->content_start = start;
213  c->content_end = start + largest_size;
214 
215  while ((chapter_pos = avio_tell(pb)) >= 0 && chapter_pos < c->content_end) {
216  unsigned chapter_idx = s->nb_chapters;
217  uint32_t chapter_size = avio_rb32(pb);
218  if (chapter_size == 0 || avio_feof(pb))
219  break;
220  chapter_pos -= start + CHAPTER_HEADER_SIZE * chapter_idx;
221  avio_skip(pb, 4 + chapter_size);
222  if (!avpriv_new_chapter(s, chapter_idx, st->time_base,
223  chapter_pos * TIMEPREC,
224  (chapter_pos + chapter_size) * TIMEPREC, NULL))
225  return AVERROR(ENOMEM);
226  }
227 
228  st->duration = (largest_size - CHAPTER_HEADER_SIZE * s->nb_chapters) * TIMEPREC;
229 
230  avpriv_update_cur_dts(s, st, 0);
231  avio_seek(pb, start, SEEK_SET);
232  c->current_chapter_size = 0;
233  c->seek_offset = 0;
234 
235  return 0;
236 }
237 
239 {
240  int ret;
241  AADemuxContext *c = s->priv_data;
242  uint64_t pos = avio_tell(s->pb);
243 
244  // are we at the end of the audio content?
245  if (pos >= c->content_end) {
246  return AVERROR_EOF;
247  }
248 
249  // are we at the start of a chapter?
250  if (c->current_chapter_size == 0) {
251  c->current_chapter_size = avio_rb32(s->pb);
252  if (c->current_chapter_size == 0) {
253  return AVERROR_EOF;
254  }
255  av_log(s, AV_LOG_DEBUG, "Chapter %d (%" PRId64 " bytes)\n", c->chapter_idx, c->current_chapter_size);
256  c->chapter_idx = c->chapter_idx + 1;
257  avio_skip(s->pb, 4); // data start offset
258  c->current_codec_second_size = c->codec_second_size;
259  }
260 
261  // is this the last block in this chapter?
262  if (c->current_chapter_size / c->current_codec_second_size == 0) {
263  c->current_codec_second_size = c->current_chapter_size % c->current_codec_second_size;
264  }
265 
266  ret = av_get_packet(s->pb, pkt, c->current_codec_second_size);
267  if (ret != c->current_codec_second_size)
268  return AVERROR_EOF;
269 
270  // decrypt c->current_codec_second_size bytes in blocks of TEA_BLOCK_SIZE
271  // trailing bytes are left unencrypted!
272  av_tea_crypt(c->tea_ctx, pkt->data, pkt->data,
273  c->current_codec_second_size / TEA_BLOCK_SIZE, NULL, 1);
274 
275  // update state
276  c->current_chapter_size = c->current_chapter_size - c->current_codec_second_size;
277  if (c->current_chapter_size <= 0)
278  c->current_chapter_size = 0;
279 
280  if (c->seek_offset > c->current_codec_second_size)
281  c->seek_offset = 0; // ignore wrong estimate
282  pkt->data += c->seek_offset;
283  pkt->size -= c->seek_offset;
284  c->seek_offset = 0;
285 
286  return 0;
287 }
288 
290  int stream_index, int64_t timestamp, int flags)
291 {
292  AADemuxContext *c = s->priv_data;
293  AVChapter *ch;
294  int64_t chapter_pos, chapter_start, chapter_size;
295  int chapter_idx = 0;
296 
297  // find chapter containing seek timestamp
298  if (timestamp < 0)
299  timestamp = 0;
300 
301  while (chapter_idx < s->nb_chapters && timestamp >= s->chapters[chapter_idx]->end) {
302  ++chapter_idx;
303  }
304 
305  if (chapter_idx >= s->nb_chapters) {
306  chapter_idx = s->nb_chapters - 1;
307  if (chapter_idx < 0) return -1; // there is no chapter.
308  timestamp = s->chapters[chapter_idx]->end;
309  }
310 
311  ch = s->chapters[chapter_idx];
312 
313  // sync by clamping timestamp to nearest valid block position in its chapter
314  chapter_size = ch->end / TIMEPREC - ch->start / TIMEPREC;
315  chapter_pos = av_rescale_rnd((timestamp - ch->start) / TIMEPREC,
316  1, c->codec_second_size,
318  * c->codec_second_size;
319  if (chapter_pos >= chapter_size)
320  chapter_pos = chapter_size;
321  chapter_start = c->content_start + (ch->start / TIMEPREC) + CHAPTER_HEADER_SIZE * (1 + chapter_idx);
322 
323  // reinit read state
324  avio_seek(s->pb, chapter_start + chapter_pos, SEEK_SET);
325  c->current_codec_second_size = c->codec_second_size;
326  c->current_chapter_size = chapter_size - chapter_pos;
327  c->chapter_idx = 1 + chapter_idx;
328 
329  // for unaligned frames, estimate offset of first frame in block (assume no padding)
330  if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_MP3) {
331  c->seek_offset = (MP3_FRAME_SIZE - chapter_pos % MP3_FRAME_SIZE) % MP3_FRAME_SIZE;
332  }
333 
334  avpriv_update_cur_dts(s, s->streams[0], ch->start + (chapter_pos + c->seek_offset) * TIMEPREC);
335 
336  return 1;
337 }
338 
339 static int aa_probe(const AVProbeData *p)
340 {
341  uint8_t *buf = p->buf;
342 
343  // first 4 bytes are file size, next 4 bytes are the magic
344  if (AV_RB32(buf+4) != AA_MAGIC)
345  return 0;
346 
347  return AVPROBE_SCORE_MAX / 2;
348 }
349 
351 {
352  AADemuxContext *c = s->priv_data;
353 
354  av_freep(&c->tea_ctx);
355 
356  return 0;
357 }
358 
359 #define OFFSET(x) offsetof(AADemuxContext, x)
360 static const AVOption aa_options[] = {
361  { "aa_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
362  "Fixed key used for handling Audible AA files", OFFSET(aa_fixed_key),
363  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd2a51d673"},
364  .flags = AV_OPT_FLAG_DECODING_PARAM },
365  { NULL },
366 };
367 
368 static const AVClass aa_class = {
369  .class_name = "aa",
370  .item_name = av_default_item_name,
371  .option = aa_options,
372  .version = LIBAVUTIL_VERSION_INT,
373 };
374 
376  .p.name = "aa",
377  .p.long_name = NULL_IF_CONFIG_SMALL("Audible AA format files"),
378  .p.priv_class = &aa_class,
379  .p.extensions = "aa",
381  .priv_data_size = sizeof(AADemuxContext),
382  .read_probe = aa_probe,
387  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
388 };
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
AADemuxContext::content_end
int64_t content_end
Definition: aadec.c:55
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
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
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
aa_read_packet
static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: aadec.c:238
int64_t
long long int64_t
Definition: coverity.c:34
TIMEPREC
#define TIMEPREC
Definition: aadec.c:41
AV_RN64
#define AV_RN64(p)
Definition: intreadwrite.h:364
AVPacket::data
uint8_t * data
Definition: packet.h:539
AVOption
AVOption.
Definition: opt.h:429
AVChapter::start
int64_t start
Definition: avformat.h:1262
aa_read_seek
static int aa_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: aadec.c:289
av_tea_crypt
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
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:327
aa_read_close
static int aa_read_close(AVFormatContext *s)
Definition: aadec.c:350
avpriv_update_cur_dts
void avpriv_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: seek.c:37
aa_class
static const AVClass aa_class
Definition: aadec.c:368
AADemuxContext::tea_ctx
struct AVTEA * tea_ctx
Definition: aadec.c:51
AADemuxContext::aa_fixed_key
uint8_t * aa_fixed_key
Definition: aadec.c:46
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AADemuxContext::aa_fixed_key_len
int aa_fixed_key_len
Definition: aadec.c:47
AADemuxContext::codec_second_size
int codec_second_size
Definition: aadec.c:48
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:867
MAX_DICTIONARY_ENTRIES
#define MAX_DICTIONARY_ENTRIES
Definition: aadec.c:38
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
AVChapter
Definition: avformat.h:1259
val
static double val(void *priv, double ch)
Definition: aeval.c:77
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:447
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:807
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:448
AV_CODEC_ID_SIPR
@ AV_CODEC_ID_SIPR
Definition: codec_id.h:487
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
tea.h
Public header for libavutil TEA algorithm.
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AVChapter::end
int64_t end
chapter start/end time in time_base units
Definition: avformat.h:1262
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
AA_MAGIC
#define AA_MAGIC
Definition: aadec.c:36
key
const char * key
Definition: hwcontext_opencl.c:189
aa_options
static const AVOption aa_options[]
Definition: aadec.c:360
aa_probe
static int aa_probe(const AVProbeData *p)
Definition: aadec.c:339
FF_INFMT_FLAG_INIT_CLEANUP
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: demux.h:35
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:325
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2498
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:540
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:787
NULL
#define NULL
Definition: coverity.c:32
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
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
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:133
av_rescale_rnd
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
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AVPacket::size
int size
Definition: packet.h:540
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:94
get_second_size
static int get_second_size(char *codec_name)
Definition: aadec.c:59
FFStream
Definition: internal.h:132
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:866
size
int size
Definition: twinvq_data.h:10344
AV_RB32
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:96
MP3_FRAME_SIZE
#define MP3_FRAME_SIZE
Definition: aadec.c:42
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
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
AADemuxContext::current_chapter_size
int64_t current_chapter_size
Definition: aadec.c:53
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
TEA_BLOCK_SIZE
#define TEA_BLOCK_SIZE
Definition: aadec.c:39
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
aa_read_header
static int aa_read_header(AVFormatContext *s)
Definition: aadec.c:74
OFFSET
#define OFFSET(x)
Definition: aadec.c:359
MAX_TOC_ENTRIES
#define MAX_TOC_ENTRIES
Definition: aadec.c:37
demux.h
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:91
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
AVClass::class_name
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:80
av_tea_init
void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds)
Initialize an AVTEA context.
Definition: tea.c:42
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
dict.h
AADemuxContext::chapter_idx
int chapter_idx
Definition: aadec.c:50
av_tea_alloc
struct AVTEA * av_tea_alloc(void)
Allocate an AVTEA context To free the struct: av_free(ptr)
Definition: tea.c:35
AVFMT_NOGENSEARCH
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:486
ff_aa_demuxer
const FFInputFormat ff_aa_demuxer
Definition: aadec.c:375
AVSTREAM_PARSE_FULL_RAW
@ AVSTREAM_PARSE_FULL_RAW
full parsing and repack with timestamp and position generation by parser for raw this assumes that ea...
Definition: avformat.h:597
AADemuxContext::seek_offset
int seek_offset
Definition: aadec.c:56
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
AADemuxContext::file_key
uint8_t file_key[16]
Definition: aadec.c:52
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:516
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
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:88
FFInputFormat
Definition: demux.h:42
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_WN64
#define AV_WN64(p, v)
Definition: intreadwrite.h:376
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:797
avstring.h
AADemuxContext::content_start
int64_t content_start
Definition: aadec.c:54
CHAPTER_HEADER_SIZE
#define CHAPTER_HEADER_SIZE
Definition: aadec.c:40
AADemuxContext::current_codec_second_size
int current_codec_second_size
Definition: aadec.c:49
AADemuxContext
Definition: aadec.c:44
AVTEA
Definition: tea.c:30
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346