33 #define AA_MAGIC 1469084982
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
40 #define MP3_FRAME_SIZE 104
61 if (!strcmp(codec_name,
"mp332")) {
63 }
else if (!strcmp(codec_name,
"acelp16")) {
65 }
else if (!strcmp(codec_name,
"acelp85")) {
74 int i, j, idx, largest_idx = -1;
75 uint32_t toc_size, npairs, header_seed = 0, start;
76 char codec_name[64] = {0};
78 int64_t largest_size = -1, current_size = -1, chapter_pos;
83 uint32_t header_key_part[4];
97 for (
i = 0;
i < toc_size;
i++) {
106 for (
i = 0;
i < npairs;
i++) {
115 if (!strcmp(
key,
"codec")) {
118 }
else if (!strcmp(
key,
"HeaderSeed")) {
120 header_seed = atoi(
val);
121 }
else if (!strcmp(
key,
"HeaderKey")) {
124 ret = sscanf(
val,
"%"SCNu32
"%"SCNu32
"%"SCNu32
"%"SCNu32,
125 &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]);
129 for (idx = 0; idx < 4; idx++) {
130 AV_WB32(&header_key[idx * 4], header_key_part[idx]);
133 for (
i = 0;
i < 16;
i++)
142 if (
c->aa_fixed_key_len != 16) {
158 output[0] = output[1] = 0;
159 memcpy(output + 2, header_key, 16);
161 for (
i = 0;
i < 3;
i++) {
167 output[idx] = output[idx] ^ dst[j];
170 memcpy(
c->file_key, output + 2, 16);
172 for (
i = 0;
i < 16;
i++)
183 if (!strcmp(codec_name,
"mp332")) {
189 }
else if (!strcmp(codec_name,
"acelp85")) {
197 }
else if (!strcmp(codec_name,
"acelp16")) {
208 for (
i = 1;
i < toc_size;
i++) {
209 current_size = TOC[
i].size;
210 if (current_size > largest_size) {
212 largest_size = current_size;
215 start = TOC[largest_idx].offset;
221 c->content_start = start;
222 c->content_end = start + largest_size;
224 while ((chapter_pos =
avio_tell(pb)) >= 0 && chapter_pos < c->content_end) {
225 unsigned chapter_idx =
s->nb_chapters;
243 c->current_chapter_size = 0;
263 if (
pos >=
c->content_end) {
268 if (
c->current_chapter_size == 0) {
270 if (
c->current_chapter_size == 0) {
273 av_log(
s,
AV_LOG_DEBUG,
"Chapter %d (%" PRId64
" bytes)\n",
c->chapter_idx,
c->current_chapter_size);
274 c->chapter_idx =
c->chapter_idx + 1;
277 c->current_codec_second_size =
c->codec_second_size;
281 if (
c->current_chapter_size /
c->current_codec_second_size == 0) {
282 c->current_codec_second_size =
c->current_chapter_size %
c->current_codec_second_size;
287 for (
i = 0;
i < blocks;
i++) {
297 if (trailing_bytes != 0) {
299 if (ret != trailing_bytes)
301 memcpy(buf + written,
src, trailing_bytes);
302 written = written + trailing_bytes;
306 c->current_chapter_size =
c->current_chapter_size -
c->current_codec_second_size;
307 if (
c->current_chapter_size <= 0)
308 c->current_chapter_size = 0;
310 if (
c->seek_offset > written)
316 memcpy(
pkt->
data, buf +
c->seek_offset, written -
c->seek_offset);
324 int stream_index, int64_t timestamp,
int flags)
328 int64_t chapter_pos, chapter_start, chapter_size;
335 while (chapter_idx < s->nb_chapters && timestamp >=
s->chapters[chapter_idx]->end) {
339 if (chapter_idx >=
s->nb_chapters) {
340 chapter_idx =
s->nb_chapters - 1;
341 if (chapter_idx < 0)
return -1;
342 timestamp =
s->chapters[chapter_idx]->end;
345 ch =
s->chapters[chapter_idx];
350 1,
c->codec_second_size,
352 *
c->codec_second_size;
353 if (chapter_pos >= chapter_size)
354 chapter_pos = chapter_size;
358 avio_seek(
s->pb, chapter_start + chapter_pos, SEEK_SET);
359 c->current_codec_second_size =
c->codec_second_size;
360 c->current_chapter_size = chapter_size - chapter_pos;
361 c->chapter_idx = 1 + chapter_idx;
393 #define OFFSET(x) offsetof(AADemuxContext, x)
396 "Fixed key used for handling Audible AA files",
OFFSET(aa_fixed_key),
static int aa_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
static int aa_read_header(AVFormatContext *s)
static int aa_probe(const AVProbeData *p)
#define CHAPTER_HEADER_SIZE
AVInputFormat ff_aa_demuxer
static int get_second_size(char *codec_name)
#define MAX_DICTIONARY_ENTRIES
static const AVClass aa_class
static const AVOption aa_options[]
#define MAX_CODEC_SECOND_SIZE
static int aa_read_close(AVFormatContext *s)
static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
static double val(void *priv, double ch)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
unsigned int avio_rb32(AVIOContext *s)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define flags(name, subs,...)
static int read_header(FFV1Context *f)
@ AV_OPT_TYPE_BINARY
offset must point to a pointer immediately followed by an int for the length
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AVERROR_EOF
End of file.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
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.
@ AV_ROUND_DOWN
Round toward -infinity.
@ AV_ROUND_UP
Round toward +infinity.
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.
void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds)
Initialize an AVTEA context.
struct AVTEA * av_tea_alloc(void)
Allocate an AVTEA context To free the struct: av_free(ptr)
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.
#define LIBAVUTIL_VERSION_INT
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static av_cold int read_close(AVFormatContext *ctx)
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
int64_t current_chapter_size
int current_codec_second_size
int64_t end
chapter start/end time in time_base units
Describe the class of an AVClass context structure.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
enum AVMediaType codec_type
General type of the encoded data.
int block_align
Audio only.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
Audio only.
This structure stores compressed data.
int64_t pos
byte position in stream, -1 if unknown
This structure contains the data a format has to probe a file.
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int64_t duration
Decoding: duration of the stream, in stream time base.
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
enum AVStreamParseType need_parsing
Public header for libavutil TEA algorithm.
static const uint8_t offset[127][2]