[FFmpeg-devel] [PATCH] Add support for playing Audible AAXC (.aaxc) files
From 1a6adbf86fd02775bea467a54c81cc23cc2f6049 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 1 Jan 2000 09:00:00 + Subject: [PATCH] Add support for playing Audible AAXC (.aaxc) files Note: audible_key and audible_iv values are variable (per file) and are externally fed. It is possible to extend https://github.com/mkb79/Audible to derive the audible_key and audible_key values. Relevant code: def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher): buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii") digest = hashlib.sha256(buf).digest() key = digest[0:16] iv = digest[16:] # decrypt "voucher" using AES in CBC mode with no padding cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(voucher).rstrip(b"\x00") return json.loads(plaintext) The decrypted "voucher" has the required audible_key and audible_iv values. Signed-off-by: Vesselin Bontchev --- libavformat/isom.h | 4 libavformat/mov.c | 43 +++ 2 files changed, 47 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 4943b80ccf..6f7de09155 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -285,6 +285,10 @@ typedef struct MOVContext { int activation_bytes_size; void *audible_fixed_key; int audible_fixed_key_size; +void *audible_key; +int audible_key_size; +void *audible_iv; +int audible_iv_size; struct AVAES *aes_decrypt; uint8_t *decryption_key; int decryption_key_len; diff --git a/libavformat/mov.c b/libavformat/mov.c index f280f360b6..32cb4428a9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1084,6 +1084,40 @@ fail: return ret; } +static int mov_aaxc_crypto(MOVContext *c) +{ +int ret = 0; + +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +ret = AVERROR(ENOMEM); +goto fail; +} + +/* verify audible_key */ +if (c->audible_key_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* verify audible_iv */ +if (c->audible_iv_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +memcpy(c->file_key, c->audible_key, 16); +memcpy(c->file_iv, c->audible_iv, 16); + +c->aax_mode = 1; + +fail: + +return ret; +} + // Audible AAX (and AAX+) bytestream decryption static int aax_filter(uint8_t *input, int size, MOVContext *c) { @@ -1132,6 +1166,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, AV_DICT_DONT_STRDUP_VAL); +// Logic for handling Audible's .aaxc files +if (!strcmp(type, "aaxc")) { +mov_aaxc_crypto(c); +} + return 0; } @@ -8068,6 +8107,10 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key), AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"}, -- 2.26.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2] Add support for playing Audible AAXC (.aaxc) files
From 854a6197ecae1ddf226876952d0e7935830db2cf Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 1 Jan 2000 09:00:00 + Subject: [PATCH v2] Add support for playing Audible AAXC (.aaxc) files The AAXC container format is the same as the (already supported) Audible AAX format but it uses a different encryption scheme. Note: audible_key and audible_iv values are variable (per file) and are externally fed. It is possible to extend https://github.com/mkb79/Audible to derive the audible_key and audible_key values. Relevant code: def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher): buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii") digest = hashlib.sha256(buf).digest() key = digest[0:16] iv = digest[16:] # decrypt "voucher" using AES in CBC mode with no padding cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(voucher).rstrip(b"\x00") return json.loads(plaintext) The decrypted "voucher" has the required audible_key and audible_iv values. Signed-off-by: Vesselin Bontchev --- libavformat/isom.h | 4 libavformat/mov.c | 43 +++ 2 files changed, 47 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 4943b80ccf..6f7de09155 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -285,6 +285,10 @@ typedef struct MOVContext { int activation_bytes_size; void *audible_fixed_key; int audible_fixed_key_size; +void *audible_key; +int audible_key_size; +void *audible_iv; +int audible_iv_size; struct AVAES *aes_decrypt; uint8_t *decryption_key; int decryption_key_len; diff --git a/libavformat/mov.c b/libavformat/mov.c index f01502a5f8..075afe589d 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1085,6 +1085,40 @@ fail: return ret; } +static int mov_aaxc_crypto(MOVContext *c) +{ +int ret = 0; + +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +ret = AVERROR(ENOMEM); +goto fail; +} + +/* verify audible_key */ +if (c->audible_key_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* verify audible_iv */ +if (c->audible_iv_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +memcpy(c->file_key, c->audible_key, 16); +memcpy(c->file_iv, c->audible_iv, 16); + +c->aax_mode = 1; + +fail: + +return ret; +} + // Audible AAX (and AAX+) bytestream decryption static int aax_filter(uint8_t *input, int size, MOVContext *c) { @@ -1133,6 +1167,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, AV_DICT_DONT_STRDUP_VAL); +// Logic for handling Audible's .aaxc files +if (!strcmp(type, "aaxc")) { +mov_aaxc_crypto(c); +} + return 0; } @@ -8069,6 +8108,10 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key), AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"}, -- 2.26.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3] Add support for playing Audible AAXC (.aaxc) files
From cb25a130797370e2801cecc34740764c6d2d264b Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 1 Jan 2000 09:00:00 + Subject: [PATCH v3] Add support for playing Audible AAXC (.aaxc) files The AAXC container format is the same as the (already supported) Audible AAX format but it uses a different encryption scheme. Note: audible_key and audible_iv values are variable (per file) and are externally fed. It is possible to extend https://github.com/mkb79/Audible to derive the audible_key and audible_key values. Relevant code: def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher): buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii") digest = hashlib.sha256(buf).digest() key = digest[0:16] iv = digest[16:] # decrypt "voucher" using AES in CBC mode with no padding cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(voucher).rstrip(b"\x00") return json.loads(plaintext) The decrypted "voucher" has the required audible_key and audible_iv values. Signed-off-by: Vesselin Bontchev --- libavformat/isom.h | 4 libavformat/mov.c | 42 ++ 2 files changed, 46 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 4943b80ccf..6f7de09155 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -285,6 +285,10 @@ typedef struct MOVContext { int activation_bytes_size; void *audible_fixed_key; int audible_fixed_key_size; +void *audible_key; +int audible_key_size; +void *audible_iv; +int audible_iv_size; struct AVAES *aes_decrypt; uint8_t *decryption_key; int decryption_key_len; diff --git a/libavformat/mov.c b/libavformat/mov.c index 0c4e468dd4..d31653eb6e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1085,6 +1085,39 @@ fail: return ret; } +static int mov_aaxc_crypto(MOVContext *c) +{ +int ret = 0; + +/* verify audible_key */ +if (c->audible_key_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* verify audible_iv */ +if (c->audible_iv_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +ret = AVERROR(ENOMEM); +goto fail; +} + +memcpy(c->file_key, c->audible_key, 16); +memcpy(c->file_iv, c->audible_iv, 16); +c->aax_mode = 1; + +fail: + +return ret; +} + // Audible AAX (and AAX+) bytestream decryption static int aax_filter(uint8_t *input, int size, MOVContext *c) { @@ -1133,6 +1166,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, AV_DICT_DONT_STRDUP_VAL); +// Logic for handling Audible's .aaxc files +if (!strcmp(type, "aaxc")) { +mov_aaxc_crypto(c); +} + return 0; } @@ -8073,6 +8111,10 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key), AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"}, -- 2.26.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3] Add support for playing Audible AAXC (.aaxc) files
08.04.2020, 06:54, "Vesselin Bontchev" : > The AAXC container format is the same as the (already supported) Audible > AAX format but it uses a different encryption scheme. > > Note: audible_key and audible_iv values are variable (per file) and are > externally fed. Can we please merge this patch? Thanks, Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] [v4] Add support for playing Audible AAXC (.aaxc) files
The AAXC container format is the same as the (already supported) Audible AAX format but it uses a different encryption scheme. Note: audible_key and audible_iv values are variable (per file) and are externally fed. It is possible to extend https://github.com/mkb79/Audible to derive the audible_key and audible_key values. Relevant code: def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher): buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii") digest = hashlib.sha256(buf).digest() key = digest[0:16] iv = digest[16:] # decrypt "voucher" using AES in CBC mode with no padding cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(voucher).rstrip(b"\x00") # improve this! return json.loads(plaintext) The decrypted "voucher" has the required audible_key and audible_iv values. Update (Nov-2020): This patch has now been tested by multiple folks - details at the following URL: https://github.com/mkb79/Audible/issues/3 Signed-off-by: Vesselin Bontchev ... Thanks Carl for all the reviews. Hopefully we can merge this patch soon :) Vesselin From c0b9c0d246cbce8ab7b86d6bbc7beb72ea24f729 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 1 Jan 2000 09:00:00 + Subject: [PATCH] [v4] Add support for playing Audible AAXC (.aaxc) files The AAXC container format is the same as the (already supported) Audible AAX format but it uses a different encryption scheme. Note: audible_key and audible_iv values are variable (per file) and are externally fed. It is possible to extend https://github.com/mkb79/Audible to derive the audible_key and audible_key values. Relevant code: def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher): buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii") digest = hashlib.sha256(buf).digest() key = digest[0:16] iv = digest[16:] # decrypt "voucher" using AES in CBC mode with no padding cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(voucher).rstrip(b"\x00") # improve this! return json.loads(plaintext) The decrypted "voucher" has the required audible_key and audible_iv values. Update (Nov-2020): This patch has now been tested by multiple folks - details at the following URL: https://github.com/mkb79/Audible/issues/3 Signed-off-by: Vesselin Bontchev --- libavformat/isom.h | 4 libavformat/mov.c | 33 + 2 files changed, 37 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 78495fd336..5a6d504090 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -286,6 +286,10 @@ typedef struct MOVContext { int activation_bytes_size; void *audible_fixed_key; int audible_fixed_key_size; +void *audible_key; +int audible_key_size; +void *audible_iv; +int audible_iv_size; struct AVAES *aes_decrypt; uint8_t *decryption_key; int decryption_key_len; diff --git a/libavformat/mov.c b/libavformat/mov.c index dd0db6bca7..2b90e31170 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1075,6 +1075,30 @@ fail: return ret; } +static int mov_aaxc_crypto(MOVContext *c) +{ +if (c->audible_key_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n"); +return AVERROR(EINVAL); +} + +if (c->audible_iv_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n"); +return AVERROR(EINVAL); +} + +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +return AVERROR(ENOMEM); +} + +memcpy(c->file_key, c->audible_key, 16); +memcpy(c->file_iv, c->audible_iv, 16); +c->aax_mode = 1; + +return 0; +} + // Audible AAX (and AAX+) bytestream decryption static int aax_filter(uint8_t *input, int size, MOVContext *c) { @@ -1123,6 +1147,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, AV_DICT_DONT_STRDUP_VAL); +// Logic for handling Audible's .aaxc files +if (!strcmp(type, "aaxc")) { +mov_aaxc_crypto(c); +} + return 0; } @@ -8170,6 +8199,10 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key), +AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, +{ "audible_iv", "AES-128 IV for
[FFmpeg-devel] [PATCH] Add support for Audible AAX (and AAX+) files
From 52e1d041fa9181a3610734b99444899df2b49e49 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- libavformat/mov.c | 158 + 1 file changed, 158 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 6d59863..3055de9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libavutil/attributes.h" #include "libavutil/channel_layout.h" @@ -37,6 +38,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/hash.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +810,128 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } +static unsigned int aax_mode = 0; +static unsigned char file_key[20]; +static unsigned char file_iv[20]; +static struct AVAES *aes_decrypt; + +static int hexchar2int(char c) { +if (c >= '0' && c <= '9') return c - '0'; +if (c >= 'a' && c <= 'f') return c - 'a' + 10; +if (c >= 'A' && c <= 'F') return c - 'A' + 10; +return -1; +} + +static void hex_encode(unsigned char *s, int len, unsigned char *o) +{ +char itoa16_private[16] = "0123456789abcdef"; +int i; +for (i = 0; i < len; ++i) { +o[0] = itoa16_private[s[i] >> 4]; +o[1] = itoa16_private[s[i] & 15]; +o += 2; +} +} + +#define DRM_BLOB_SIZE 56 + +// AAX (and AAX+) support is licensed under GPLv3 +static int aax_parser(MOVContext *c, AVIOContext *pb) +{ +unsigned char activation_bytes[4]; + +// extracted from libAAX_SDK.so and AAXSDKWin.dll files! +unsigned char fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; +unsigned char intermediate_key[20] = {0}; +unsigned char intermediate_iv[20] = {0}; +unsigned char input[4096] = {0}; +unsigned char output[4096] = {0}; +unsigned char file_checksum[20] = {0}; +unsigned char file_checksum_encoded[41] = {0}; +unsigned char file_key_encoded[41] = {0}; +unsigned char file_iv_encoded[41] = {0}; +unsigned char calculated_checksum[20]; +struct AVHashContext *ctx; +int a, b, i; +const char *magic = "drm"; +char *s; + +av_hash_alloc(&ctx, "SHA160"); + +aes_decrypt = av_aes_alloc(); +if (!aes_decrypt) { +return AVERROR(ENOMEM); +} + +/* extract activation data */ +s = getenv("activation_bytes"); +if (!s || strlen(s) < 8) { +av_log(c->fc, AV_LOG_ERROR, "[aax] export activation_bytes= is missing!\n"); +exit(-1); +} +av_log(c->fc, AV_LOG_DEBUG, "[aax] activation_bytes == %s!\n", s); +for (i = 0; i < 4 && isxdigit(*s); i++) { +a = hexchar2int(*s++); +b = hexchar2int(*s++); +activation_bytes[i] = (a << 4) | b; +} + +/* drm blob processing */ +avio_seek(pb, 0x246, 0); +avio_read(pb, input, 3); +if (strncmp(input, magic, 3)) { +av_log(c->fc, AV_LOG_ERROR, "[aax] drm blob is missing from this file!\n"); +exit(-1); +} +avio_seek(pb, 0x251, 0); +avio_read(pb, input, DRM_BLOB_SIZE); +avio_seek(pb, 0x28d, 0); +avio_read(pb, file_checksum, 20); +hex_encode(file_checksum, 20, file_checksum_encoded); +av_log(c->fc, AV_LOG_DEBUG, "[aax] file checksum == %s\n", file_checksum_encoded); + +/* AAX (and AAX+) key derivation */ +av_hash_init(ctx); +av_hash_update(ctx, fixed_key, 16); +av_hash_update(ctx, activation_bytes, 4); +av_hash_final(ctx, intermediate_key); +av_hash_init(ctx); +av_hash_update(ctx, fixed_key, 16); +av_hash_update(ctx, intermediate_key, 20); +av_hash_update(ctx, activation_bytes, 4); +av_hash_final(ctx, intermediate_iv); +av_hash_init(ctx); +av_hash_update(ctx, intermediate_key, 16); +av_hash_update(ctx, intermediate_iv, 16); +av_hash_final(ctx, calculated_checksum); +if (memcmp(calculated_checksum, file_checksum, 20)) { +av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums, terminating!\n"); +exit(-1); +} +av_aes_init(aes_decrypt, intermediate_key, 128, 1); +av_aes_crypt(aes_decrypt, output, input, DRM_BLOB_SIZE, intermediate_iv, 1); +for (i = 0; i < 4; i++) { +if (activation_bytes[i] != output[3 - i]) { +av_log(c->f
[FFmpeg-devel] [PATCH v2] Add support for Audible AAX (and AAX+) files
Hi, alglib1.cpp is a plugin for RainbowCrack 1.6.1 (http://project-rainbowcrack.com/), and it enables offline attacks against Audible AAX files. VesselinFrom 95a40310e0eecadc5b2c653609163ec8d2682d94 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- libavformat/isom.h |3 + libavformat/mov.c | 163 2 files changed, 166 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 5d48989..6a054e8 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -198,6 +198,9 @@ typedef struct MOVContext { MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; int atom_depth; +unsigned int aax_mode; ///< 'aax' file has been detected +unsigned char file_key[20]; +unsigned char file_iv[20]; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index 6d59863..62495a8 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libavutil/attributes.h" #include "libavutil/channel_layout.h" @@ -37,6 +38,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/hash.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +810,126 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } + +static int hexchar2int(char c) { +if (c >= '0' && c <= '9') return c - '0'; +if (c >= 'a' && c <= 'f') return c - 'a' + 10; +if (c >= 'A' && c <= 'F') return c - 'A' + 10; +return -1; +} + +static void hex_encode(unsigned char *s, int len, unsigned char *o) +{ +char itoa16_private[16] = "0123456789abcdef"; +int i; +for (i = 0; i < len; ++i) { +o[0] = itoa16_private[s[i] >> 4]; +o[1] = itoa16_private[s[i] & 15]; +o += 2; +} +} + +#define DRM_BLOB_SIZE 56 + +static int aax_parser(MOVContext *c, AVIOContext *pb) +{ +unsigned char activation_bytes[4]; + +// extracted from libAAX_SDK.so and AAXSDKWin.dll files! +unsigned char fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; +unsigned char intermediate_key[20] = {0}; +unsigned char intermediate_iv[20] = {0}; +unsigned char input[64] = {0}; +unsigned char output[64] = {0}; +unsigned char file_checksum[20] = {0}; +unsigned char file_checksum_encoded[41] = {0}; +unsigned char file_key_encoded[41] = {0}; +unsigned char file_iv_encoded[41] = {0}; +unsigned char calculated_checksum[20]; +struct AVHashContext *ctx; +struct AVAES *aes_decrypt; +int a, b, i; +const char *magic = "drm"; +char *s; + +av_hash_alloc(&ctx, "SHA160"); +aes_decrypt = av_aes_alloc(); +if (!aes_decrypt) { +return AVERROR(ENOMEM); +} + +/* drm blob processing */ +avio_seek(pb, 0x246, 0); +avio_read(pb, input, 3); +if (strncmp(input, magic, 3)) { +av_log(c->fc, AV_LOG_FATAL, "[aax] drm blob is missing from this file!\n"); +exit(-1); +} +avio_seek(pb, 0x251, 0); +avio_read(pb, input, DRM_BLOB_SIZE); +avio_seek(pb, 0x28d, 0); +avio_read(pb, file_checksum, 20); +hex_encode(file_checksum, 20, file_checksum_encoded); +av_log(c->fc, AV_LOG_DEBUG, "[aax] file checksum == %s\n", file_checksum_encoded); + +/* extract activation data */ +s = getenv("activation_bytes"); +if (!s || strlen(s) < 8) { +av_log(c->fc, AV_LOG_FATAL, "[aax] export activation_bytes= is missing!\n"); +exit(-1); // XXX exit more gracefully +} +av_log(c->fc, AV_LOG_DEBUG, "[aax] activation_bytes == %s!\n", s); +for (i = 0; i < 4 && isxdigit(*s); i++) { +a = hexchar2int(*s++); +b = hexchar2int(*s++); +activation_bytes[i] = (a << 4) | b; +} + +/* AAX (and AAX+) key derivation */ +av_hash_init(ctx); +av_hash_update(ctx, fixed_key, 16); +av_hash_update(ctx, activation_bytes, 4); +av_hash_final(ctx, intermediate_key); +av_hash_init(ctx); +av_hash_update(ctx, fixed_key, 16); +av_hash_update(ctx, intermediate_key, 20); +av_hash_update(ctx, activation_bytes, 4); +av_hash_final(ctx, intermediate_iv); +av_hash_init(ctx); +av_hash_update(ctx, intermediate_
[FFmpeg-devel] [PATCH v3] Add support for Audible AAX (and AAX+) files
Hi, I have uploaded some Audible samples to the https://gitlab.com/vesselin.bontchev/audible-samples/ page. Currently only .aax files are supported, see https://en.wikipedia.org/wiki/Audible.com#Quality page for more information. $ export activation_bytes=62689101 # ffmpeg -i Audible_AAX_sample_62689101.aax -vn -c:a copy -v debug output.mp4 VesselinFrom affa4a9315209976ff15e6ccf79bcf3b76088c6f Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- libavformat/isom.h | 3 + libavformat/mov.c | 163 + 2 files changed, 166 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 5d48989..6a054e8 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -198,6 +198,9 @@ typedef struct MOVContext { MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; int atom_depth; +unsigned int aax_mode; ///< 'aax' file has been detected +unsigned char file_key[20]; +unsigned char file_iv[20]; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index 6d59863..2d4f3e6 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libavutil/attributes.h" #include "libavutil/channel_layout.h" @@ -37,6 +38,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/sha.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +810,126 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } + +static int hexchar2int(char c) { +if (c >= '0' && c <= '9') return c - '0'; +if (c >= 'a' && c <= 'f') return c - 'a' + 10; +if (c >= 'A' && c <= 'F') return c - 'A' + 10; +return -1; +} + +static void hex_encode(unsigned char *s, int len, unsigned char *o) +{ +char itoa16_private[16] = "0123456789abcdef"; +int i; +for (i = 0; i < len; ++i) { +o[0] = itoa16_private[s[i] >> 4]; +o[1] = itoa16_private[s[i] & 15]; +o += 2; +} +} + +#define DRM_BLOB_SIZE 56 + +static int aax_parser(MOVContext *c, AVIOContext *pb) +{ +unsigned char activation_bytes[4]; + +// extracted from libAAX_SDK.so and AAXSDKWin.dll files! +unsigned char fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; +unsigned char intermediate_key[20] = {0}; +unsigned char intermediate_iv[20] = {0}; +unsigned char input[64] = {0}; +unsigned char output[64] = {0}; +unsigned char file_checksum[20] = {0}; +unsigned char file_checksum_encoded[41] = {0}; +unsigned char file_key_encoded[41] = {0}; +unsigned char file_iv_encoded[41] = {0}; +unsigned char calculated_checksum[20]; +struct AVSHA *ctx; +struct AVAES *aes_decrypt; +int a, b, i; +const char *magic = "drm"; +char *s; + +ctx = av_sha_alloc(); +aes_decrypt = av_aes_alloc(); +if (!aes_decrypt) { +return AVERROR(ENOMEM); +} + +/* drm blob processing */ +avio_seek(pb, 0x246, 0); +avio_read(pb, input, 3); +if (strncmp(input, magic, 3)) { +av_log(c->fc, AV_LOG_FATAL, "[aax] drm blob is missing from this file!\n"); +exit(-1); +} +avio_seek(pb, 0x251, 0); +avio_read(pb, input, DRM_BLOB_SIZE); +avio_seek(pb, 0x28d, 0); +avio_read(pb, file_checksum, 20); +hex_encode(file_checksum, 20, file_checksum_encoded); +av_log(c->fc, AV_LOG_DEBUG, "[aax] file checksum == %s\n", file_checksum_encoded); + +/* extract activation data */ +s = getenv("activation_bytes"); +if (!s || strlen(s) < 8) { +av_log(c->fc, AV_LOG_FATAL, "[aax] export activation_bytes= is missing!\n"); +exit(-1); // XXX exit more gracefully +} +av_log(c->fc, AV_LOG_DEBUG, "[aax] activation_bytes == %s!\n", s); +for (i = 0; i < 4 && isxdigit(*s); i++) { +a = hexchar2int(*s++); +b = hexchar2int(*s++); +activation_bytes[i] = (a << 4) | b; +} + +/* AAX (and AAX+) key derivation */ +av_sha_init(ctx, 160); +av_sha_update(ctx, fixed_key, 16); +av_sha_update(ctx, activation_bytes, 4); +av_sha_final(ctx, intermediate_key); +av_sha_init(ctx, 160); +av_sha_update(ctx, fixed_key, 16); +av_sha_update(ctx, intermedia
[FFmpeg-devel] [PATCH v4] Add support for Audible AAX (and AAX+) files
Thanks for all the feedback, and help. VesselinFrom 1ed235454a61fe1f8d993d09d3d6398e7609c624 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- libavformat/isom.h |5 ++ libavformat/mov.c | 138 2 files changed, 143 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 5d48989..9fa02e7 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -198,6 +198,11 @@ typedef struct MOVContext { MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; int atom_depth; +unsigned int aax_mode; ///< 'aax' file has been detected +unsigned char file_key[20]; +unsigned char file_iv[20]; +void *activation_bytes; +int activation_bytes_size; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index d1b29a2..6f9bf50 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libavutil/attributes.h" #include "libavutil/channel_layout.h" @@ -37,6 +38,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/sha.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +810,109 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } +static void hex_encode(unsigned char *s, int len, unsigned char *o) +{ +char itoa16_private[16] = "0123456789abcdef"; +int i; +for (i = 0; i < len; ++i) { +o[0] = itoa16_private[s[i] >> 4]; +o[1] = itoa16_private[s[i] & 15]; +o += 2; +} +} + +#define DRM_BLOB_SIZE 56 + +static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +// extracted from libAAX_SDK.so and AAXSDKWin.dll files! +unsigned char fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; +unsigned char intermediate_key[20] = {0}; +unsigned char intermediate_iv[20] = {0}; +unsigned char input[64] = {0}; +unsigned char output[64] = {0}; +unsigned char file_checksum[20] = {0}; +unsigned char file_checksum_encoded[41] = {0}; +unsigned char file_key_encoded[41] = {0}; +unsigned char file_iv_encoded[41] = {0}; +unsigned char calculated_checksum[20]; +struct AVSHA *ctx; +struct AVAES *aes_decrypt; +int i; +unsigned char *activation_bytes = (unsigned char*) c->activation_bytes; + +av_log(c->fc, AV_LOG_DEBUG, "[aax] aax file detected!\n"); +c->aax_mode = 1; + +ctx = av_sha_alloc(); +aes_decrypt = av_aes_alloc(); +if (!aes_decrypt) { +return AVERROR(ENOMEM); +} + +/* drm blob processing */ +ffio_read_size(pb, output, 8); // go to offset 8, absolute postion 0x251 +ffio_read_size(pb, input, DRM_BLOB_SIZE); +ffio_read_size(pb, output, 4); // go to offset 4, absolute postion 0x28d +ffio_read_size(pb, file_checksum, 20); +hex_encode(file_checksum, 20, file_checksum_encoded); +av_log(c->fc, AV_LOG_DEBUG, "[aax] file checksum == %s\n", file_checksum_encoded); + +/* verify activation data */ +if (!activation_bytes || c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is missing!\n"); +return AVERROR_INVALIDDATA; +} +if (c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n"); +return AVERROR_INVALIDDATA; +} + +/* AAX (and AAX+) key derivation */ +av_sha_init(ctx, 160); +av_sha_update(ctx, fixed_key, 16); +av_sha_update(ctx, activation_bytes, 4); +av_sha_final(ctx, intermediate_key); +av_sha_init(ctx, 160); +av_sha_update(ctx, fixed_key, 16); +av_sha_update(ctx, intermediate_key, 20); +av_sha_update(ctx, activation_bytes, 4); +av_sha_final(ctx, intermediate_iv); +av_sha_init(ctx, 160); +av_sha_update(ctx, intermediate_key, 16); +av_sha_update(ctx, intermediate_iv, 16); +av_sha_final(ctx, calculated_checksum); +if (memcmp(calculated_checksum, file_checksum, 20)) { +av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n"); +return AVERROR_INVALIDDATA; +} +av_aes_init(aes_decrypt, intermediate_key, 128, 1); +av_aes_crypt(aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1); +for (i = 0; i < 4; i++) { +if (activation_bytes[i] != output[3 - i]
Re: [FFmpeg-devel] [PATCH v4] Add support for Audible AAX (and AAX+) files
Hi Carl, Hendrik, I would like to get this patch merged in FFmpeg. Is there something I can do to make this happen? Thanks again, Vesselin 14.07.2015, 01:17, "Vesselin Bontchev" : > Thanks for all the feedback, and help. > > Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v5] Add support for Audible AAX (and AAX+) files
Hi, A sample Audible .aax file can be downloaded from the following link, https://gitlab.com/vesselin.bontchev/audible-samples/tree/master Usage, ffmpeg -activation_bytes 62689101 -i Audible_AAX_sample_62689101.aax -vn -c:a copy -v debug output.mp4 Thanks, VesselinFrom 933c6d8fd44ff4683e16fbed9d5ca01253fc9f94 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- doc/general.texi | 2 + doc/muxers.texi| 7 +++ libavformat/isom.h | 6 +++ libavformat/mov.c | 122 + 4 files changed, 137 insertions(+) diff --git a/doc/general.texi b/doc/general.texi index dc22d90..617be66 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -226,6 +226,8 @@ library: @item 4xm @tab @tab X @tab 4X Technologies format, used in some games. @item 8088flex TMV @tab @tab X +@item AAX @tab @tab X +@tab Audible Enhanced Audio format, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/doc/muxers.texi b/doc/muxers.texi index d75d7de..b5fc598 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -667,6 +667,13 @@ point on IIS with this muxer. Example: ffmpeg -re @var{} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1) @end example +@subsection Audible AAX + +Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret. +@example +ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4 +@end example + @section mp3 The MP3 muxer writes a raw MP3 stream with the following optional features: diff --git a/libavformat/isom.h b/libavformat/isom.h index 5d48989..6ea1da1 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -198,6 +198,12 @@ typedef struct MOVContext { MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; int atom_depth; +unsigned int aax_mode; ///< 'aax' file has been detected +uint8_t file_key[20]; +uint8_t file_iv[20]; +void *activation_bytes; +int activation_bytes_size; +struct AVAES *aes_decrypt; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index 9d6b2e4..b248eb7 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -37,6 +37,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/sha.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +809,116 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } +#define DRM_BLOB_SIZE 56 + +static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +// extracted from libAAX_SDK.so and AAXSDKWin.dll files! +uint8_t fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; +uint8_t intermediate_key[20]; +uint8_t intermediate_iv[20]; +uint8_t input[64]; +uint8_t output[64]; +uint8_t file_checksum[20]; +uint8_t calculated_checksum[20]; +struct AVSHA *sha; +int i; +int ret = 0; +uint8_t *activation_bytes = c->activation_bytes; + +av_log(c->fc, AV_LOG_DEBUG, "[aax] aax file detected!\n"); +c->aax_mode = 1; + +sha = av_sha_alloc(); +if (!sha) +return AVERROR(ENOMEM); +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +ret = AVERROR(ENOMEM); +goto fail; +} + +/* drm blob processing */ +avio_read(pb, output, 8); // go to offset 8, absolute postion 0x251 +avio_read(pb, input, DRM_BLOB_SIZE); +avio_read(pb, output, 4); // go to offset 4, absolute postion 0x28d +avio_read(pb, file_checksum, 20); + +av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools +for (i = 0; i < 20; i++) +av_log(sha, AV_LOG_INFO, "%02x", file_checksum[i]); +av_log(c->fc, AV_LOG_INFO, "\n"); + +/* verify activation data */ +if (!activation_bytes || c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is missing!\n"); +ret = AVERROR(EINVAL); +goto fail; +} +if (c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* AAX (and AAX+) key derivation */ +av_sha_i
Re: [FFmpeg-devel] [PATCH v5] Add support for Audible AAX (and AAX+) files
16.07.2015, 03:58, "Vesselin Bontchev" : > Hi, > > A sample Audible .aax file can be downloaded from the following link, > > https://gitlab.com/vesselin.bontchev/audible-samples/tree/master > > Usage, > > ffmpeg -activation_bytes 62689101 -i Audible_AAX_sample_62689101.aax -vn -c:a > copy -v debug output.mp4 Hi, I am attaching a Python script to fetch the "activation bytes" from Audible servers (as an alternative to doing offline attacks on the AAX files). Vesselin #!/usr/bin/env python import traceback try: import requests except ImportError: print("Please install the missing python-requests package.") import hashlib import binascii import sys import base64 import time def password_encoder(password): shift = 8 output = "8" # rot(8) for c in password: t = ord(c) - shift output = output + "{:02x}".format(t) return output payload = {'action': 'register', 'user_alias': '', 'epassword': '', 'domain': 'www.audible.com', 'player_type': 'software', 'license_type': 'individual', 'license_name': '', 'player_slots': 8, 'player_manuf': 'Audible', 'client_code': 'generic', 'player_model': 'Desktop', 'time_unused': int(time.time()), 'player_id': ''} if __name__ == "__main__": if len(sys.argv) < 3: sys.stderr.write("Usage: %s \n" % sys.argv[0]) sys.exit(-1) payload["user_alias"] = sys.argv[1] payload["epassword"] = password_encoder(sys.argv[2]) # generate base64 digest of a random 20 byte string ;) fake_hash = hashlib.sha1(b"").digest() payload["player_id"] = base64.encodestring(fake_hash).rstrip() # sys.stderr.write("[+] Player ID is %s\n\n" % (payload["player_id"])) url = "http://www.audible.com/cgi-bin/licensemgr.cgi"; headers = { 'User-Agent': "AudibleActivation", 'Host': 'www.audible.com', 'Cache-Control': 'no-cache', 'Cookie': 'AM=5.5.0.5; ADM=6.6.0.15; download_audio=' } # print(headers, payload) try: response = requests.get(url, headers=headers, params=payload) data = response.content if b"BAD_LOGIN" in data or b"Whoops" in data: print(data) print("\nActivation failed! ;(") sys.exit(-1) k = data.rfind(b"group_id") l = data[k:].find(b")") keys = data[k + l + 1 + 1:] output_keys = [] # each key is of 70 bytes for i in range(0, 8): key = keys[i * 70 + i:(i + 1) * 70 + i] h = binascii.hexlify(bytes(key)) h = [h[i:i+2] for i in range(0, len(h), 2)] h = b",".join(h) output_keys.append(h) except SystemExit as e: sys.exit(e) except: traceback.print_exc() # only 4 bytes of output_keys[0] are necessary for decryption! ;) print(output_keys[0].replace(b",", b"")[0:8]) # de-register! payload["action"] = "de-register" response = requests.get(url, headers=headers, params=payload) # print(response.text) # print(password_decoder(payload["epassword"])) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v5] Add support for Audible AAX (and AAX+) files
18.07.2015, 01:45, "Michael Niedermayer" : > On Thu, Jul 16, 2015 at 03:57:26AM +0300, Vesselin Bontchev wrote: >> + // extracted from libAAX_SDK.so and AAXSDKWin.dll files! > >> + uint8_t fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, 0xcd, >> + 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 }; > > I think this should not be hardcoded but provided by the user via > an AVOption. I fear that doing this will impact the usability negatively. Are there strong reasons for suggesting this change? How about documenting the fixed key (and then going the AVOption way), sounds fair? Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v6] Add support for Audible AAX (and AAX+) files
Thanks for all the feedback. VesselinFrom 99d97f2d1f0a62fb75ba9af4c20edaa59f02bb51 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sat, 11 Jul 2015 18:02:47 + Subject: [PATCH] Add support for Audible AAX (and AAX+) files --- doc/general.texi | 2 + doc/muxers.texi| 7 +++ libavformat/isom.h | 8 libavformat/mov.c | 128 + 4 files changed, 145 insertions(+) diff --git a/doc/general.texi b/doc/general.texi index dc22d90..617be66 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -226,6 +226,8 @@ library: @item 4xm @tab @tab X @tab 4X Technologies format, used in some games. @item 8088flex TMV @tab @tab X +@item AAX @tab @tab X +@tab Audible Enhanced Audio format, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/doc/muxers.texi b/doc/muxers.texi index d75d7de..b5fc598 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -667,6 +667,13 @@ point on IIS with this muxer. Example: ffmpeg -re @var{} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1) @end example +@subsection Audible AAX + +Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret. +@example +ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4 +@end example + @section mp3 The MP3 muxer writes a raw MP3 stream with the following optional features: diff --git a/libavformat/isom.h b/libavformat/isom.h index 5d48989..aee9d6e 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -198,6 +198,14 @@ typedef struct MOVContext { MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; int atom_depth; +unsigned int aax_mode; ///< 'aax' file has been detected +uint8_t file_key[20]; +uint8_t file_iv[20]; +void *activation_bytes; +int activation_bytes_size; +void *audible_fixed_key; +int audible_fixed_key_size; +struct AVAES *aes_decrypt; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index 9d6b2e4..92bf2f8 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -37,6 +37,8 @@ #include "libavutil/dict.h" #include "libavutil/display.h" #include "libavutil/opt.h" +#include "libavutil/aes.h" +#include "libavutil/sha.h" #include "libavutil/timecode.h" #include "libavcodec/ac3tab.h" #include "avformat.h" @@ -807,6 +809,120 @@ static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; /* now go for moov */ } +#define DRM_BLOB_SIZE 56 + +static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +uint8_t intermediate_key[20]; +uint8_t intermediate_iv[20]; +uint8_t input[64]; +uint8_t output[64]; +uint8_t file_checksum[20]; +uint8_t calculated_checksum[20]; +struct AVSHA *sha; +int i; +int ret = 0; +uint8_t *activation_bytes = c->activation_bytes; +uint8_t *fixed_key = c->audible_fixed_key; + +c->aax_mode = 1; + +sha = av_sha_alloc(); +if (!sha) +return AVERROR(ENOMEM); +c->aes_decrypt = av_aes_alloc(); +if (!c->aes_decrypt) { +ret = AVERROR(ENOMEM); +goto fail; +} + +/* drm blob processing */ +avio_read(pb, output, 8); // go to offset 8, absolute postion 0x251 +avio_read(pb, input, DRM_BLOB_SIZE); +avio_read(pb, output, 4); // go to offset 4, absolute postion 0x28d +avio_read(pb, file_checksum, 20); + +av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools +for (i = 0; i < 20; i++) +av_log(sha, AV_LOG_INFO, "%02x", file_checksum[i]); +av_log(c->fc, AV_LOG_INFO, "\n"); + +/* verify activation data */ +if (!activation_bytes || c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is missing!\n"); +ret = AVERROR(EINVAL); +goto fail; +} +if (c->activation_bytes_size != 4) { +av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* verify fixed key */ +if (c->audible_fixed_key_size != 16) { +av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n"); +ret = AVERROR(EINVAL); +goto fail; +} + +/* AAX (and AAX+) key derivation */ +av_sha_init(sha, 160); +av_sha_update(sha, fixed_key, 16); +av_sha_update(sha, activation_bytes, 4); +av_sha_final(sha, intermediate_key); +av_sha_init(sha, 160); +
Re: [FFmpeg-devel] [PATCH v5] Add support for Audible AAX (and AAX+) files
18.07.2015, 13:03, "Paul B Mahol" : > Dana 18. 7. 2015. 11:46 osoba "Vesselin Bontchev" < > vesselin.bontc...@yandex.com> napisala je: >> 18.07.2015, 01:45, "Michael Niedermayer" : >> > On Thu, Jul 16, 2015 at 03:57:26AM +0300, Vesselin Bontchev wrote: >> >> + // extracted from libAAX_SDK.so and AAXSDKWin.dll files! >> > >> >> + uint8_t fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87, >> > >> > I think this should not be hardcoded but provided by the user via >> > an AVOption. >> >> I fear that doing this will impact the usability negatively. Are there >> strong reasons for suggesting this change? > Using AVOption will set default key to what is already now hardcoded. Thanks for explaining this! I have now uploaded a new revision (v6) of the patch, which uses an AVOption. Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v1] Add support for TEA (Tiny Encryption Algorithm)
Hi, I need support for TEA (Tiny Encryption Algorithm) in FFmpeg for my upcoming patch (which makes Audible AA files playable). Thanks, VesselinFrom 491afe746e3a1f723798224ee56fd57a028ed4da Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 22:25:53 +0200 Subject: [PATCH] Add support for TEA (Tiny Encryption Algorithm) --- libavutil/Makefile |3 + libavutil/tea.c| 203 libavutil/tea.h| 66 + 3 files changed, 272 insertions(+) create mode 100644 libavutil/tea.c create mode 100644 libavutil/tea.h diff --git a/libavutil/Makefile b/libavutil/Makefile index 6fa810e..70f8bae 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -63,6 +63,7 @@ HEADERS = adler32.h \ twofish.h \ version.h \ xtea.h\ + tea.h \ HEADERS-$(CONFIG_LZO) += lzo.h @@ -135,6 +136,7 @@ OBJS = adler32.o\ utils.o \ xga_font_data.o \ xtea.o \ + tea.o\ OBJS-$(!HAVE_ATOMICS_NATIVE)+= atomic.o \ @@ -192,6 +194,7 @@ TESTPROGS = adler32 \ twofish \ utf8\ xtea\ +tea \ TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo diff --git a/libavutil/tea.c b/libavutil/tea.c new file mode 100644 index 000..5d3954a --- /dev/null +++ b/libavutil/tea.c @@ -0,0 +1,203 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief TEA 32-bit implementation + * @author Vesselin Bontchev + * @ingroup lavu_tea + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "tea.h" + +void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) +{ +int i; + +for (i = 0; i < 4; i++) +ctx->key[i] = AV_RB32(key + (i << 2)); + +ctx->rounds = rounds; +} + +static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ +uint32_t v0, v1; +int rounds = ctx->rounds; +uint32_t k0, k1, k2, k3; +k0 = ctx->key[0]; +k1 = ctx->key[1]; +k2 = ctx->key[2]; +k3 = ctx->key[3]; + +v0 = AV_RB32(src); +v1 = AV_RB32(src + 4); + +if (decrypt) { +int i; +uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); + +for (i = 0; i < rounds / 2; i++) { +v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +sum -= delta; +} +if (iv) { +v0 ^= AV_RB32(iv); +v1 ^= AV_RB32(iv + 4); +memcpy(iv, src, 8); +} +} else { +int i; +uint32_t sum = 0, delta = 0x9E3779B9U; + +for (i = 0; i < 32; i++) { +sum += delta; +v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +} +} + +AV_WB32(dst, v0); +AV_WB32(dst + 4, v1); +} + +void av_tea_crypt(AVT
[FFmpeg-devel] [PATCH v2] Add support for TEA (Tiny Encryption Algorithm)
Thanks for all the feedback. VesselinFrom 6e427af7f9450856c5d96734647e760d1d0f7ce2 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 22:25:53 +0200 Subject: [PATCH] Add support for TEA (Tiny Encryption Algorithm) --- libavutil/Makefile |3 + libavutil/tea.c | 213 ++ libavutil/tea.h | 71 tests/fate/libavutil.mak |4 + 4 files changed, 291 insertions(+) create mode 100644 libavutil/tea.c create mode 100644 libavutil/tea.h diff --git a/libavutil/Makefile b/libavutil/Makefile index 6fa810e..70f8bae 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -63,6 +63,7 @@ HEADERS = adler32.h \ twofish.h \ version.h \ xtea.h\ + tea.h \ HEADERS-$(CONFIG_LZO) += lzo.h @@ -135,6 +136,7 @@ OBJS = adler32.o\ utils.o \ xga_font_data.o \ xtea.o \ + tea.o\ OBJS-$(!HAVE_ATOMICS_NATIVE)+= atomic.o \ @@ -192,6 +194,7 @@ TESTPROGS = adler32 \ twofish \ utf8\ xtea\ +tea \ TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo diff --git a/libavutil/tea.c b/libavutil/tea.c new file mode 100644 index 000..bf76718 --- /dev/null +++ b/libavutil/tea.c @@ -0,0 +1,213 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "tea.h" + +typedef struct AVTEA { +uint32_t key[16]; +int rounds; +} AVTEA; + +struct AVTEA *av_tea_alloc(void) +{ +return av_mallocz(sizeof(struct AVTEA)); +} + +const int av_tea_size = sizeof(AVTEA); + +void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) +{ +int i; + +for (i = 0; i < 4; i++) +ctx->key[i] = AV_RB32(key + (i << 2)); + +ctx->rounds = rounds; +} + +static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ +uint32_t v0, v1; +int rounds = ctx->rounds; +uint32_t k0, k1, k2, k3; +k0 = ctx->key[0]; +k1 = ctx->key[1]; +k2 = ctx->key[2]; +k3 = ctx->key[3]; + +v0 = AV_RB32(src); +v1 = AV_RB32(src + 4); + +if (decrypt) { +int i; +uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); + +for (i = 0; i < rounds / 2; i++) { +v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +sum -= delta; +} +if (iv) { +v0 ^= AV_RB32(iv); +v1 ^= AV_RB32(iv + 4); +memcpy(iv, src, 8); +} +} else { +int i; +uint32_t sum = 0, delta = 0x9E3779B9U; + +for (i = 0; i < rounds / 2; i++) { +sum += delta; +v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +} +} + +AV_WB32(dst, v0); +AV_WB32(d
[FFmpeg-devel] [PATCH v3] Add support for TEA (Tiny Encryption Algorithm)
From 492262598aa5d029b6bd9c8da4ccdfad4403bc83 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 22:25:53 +0200 Subject: [PATCH] Add support for TEA (Tiny Encryption Algorithm) --- libavutil/Makefile |3 + libavutil/tea.c | 213 ++ libavutil/tea.h | 71 tests/fate/libavutil.mak |4 + tests/ref/fate/tea |1 + 5 files changed, 292 insertions(+) create mode 100644 libavutil/tea.c create mode 100644 libavutil/tea.h create mode 100644 tests/ref/fate/tea diff --git a/libavutil/Makefile b/libavutil/Makefile index 6fa810e..70f8bae 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -63,6 +63,7 @@ HEADERS = adler32.h \ twofish.h \ version.h \ xtea.h\ + tea.h \ HEADERS-$(CONFIG_LZO) += lzo.h @@ -135,6 +136,7 @@ OBJS = adler32.o\ utils.o \ xga_font_data.o \ xtea.o \ + tea.o\ OBJS-$(!HAVE_ATOMICS_NATIVE)+= atomic.o \ @@ -192,6 +194,7 @@ TESTPROGS = adler32 \ twofish \ utf8\ xtea\ +tea \ TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo diff --git a/libavutil/tea.c b/libavutil/tea.c new file mode 100644 index 000..bf76718 --- /dev/null +++ b/libavutil/tea.c @@ -0,0 +1,213 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "tea.h" + +typedef struct AVTEA { +uint32_t key[16]; +int rounds; +} AVTEA; + +struct AVTEA *av_tea_alloc(void) +{ +return av_mallocz(sizeof(struct AVTEA)); +} + +const int av_tea_size = sizeof(AVTEA); + +void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) +{ +int i; + +for (i = 0; i < 4; i++) +ctx->key[i] = AV_RB32(key + (i << 2)); + +ctx->rounds = rounds; +} + +static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ +uint32_t v0, v1; +int rounds = ctx->rounds; +uint32_t k0, k1, k2, k3; +k0 = ctx->key[0]; +k1 = ctx->key[1]; +k2 = ctx->key[2]; +k3 = ctx->key[3]; + +v0 = AV_RB32(src); +v1 = AV_RB32(src + 4); + +if (decrypt) { +int i; +uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); + +for (i = 0; i < rounds / 2; i++) { +v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +sum -= delta; +} +if (iv) { +v0 ^= AV_RB32(iv); +v1 ^= AV_RB32(iv + 4); +memcpy(iv, src, 8); +} +} else { +int i; +uint32_t sum = 0, delta = 0x9E3779B9U; + +for (i = 0; i < rounds / 2; i++) { +sum += delta; +v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); +v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); +} +} +
Re: [FFmpeg-devel] [PATCH v2] Add support for TEA (Tiny Encryption Algorithm)
20.07.2015, 04:15, "Michael Niedermayer" : > On Mon, Jul 20, 2015 at 02:16:28AM +0300, Vesselin Bontchev wrote: >> >> Date: Sun, 19 Jul 2015 22:25:53 +0200 >> Subject: [PATCH] Add support for TEA (Tiny Encryption Algorithm) > > fails fate test > reference file './tests/ref/fate/tea' not found Oops, the new patch revision (v3) should fix this problem. Thanks, Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Uploading Audible AAX samples
Hi, I need help in uploading some Audible AAX samples to our FTP server (upload.ffmpeg.org). I can't use the FTP protocol at the moment, due to some ISP problems. The samples are available at the following URL, https://gitlab.com/vesselin.bontchev/audible-samples/tree/master Finally, it would be awesome if the samples are visible at, http://samples.ffmpeg.org/audible/ Thanks, Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Add support for Audible AA files
Hi! This patch adds support for Audible AA files. Audible samples can be obtained from, https://gitlab.com/vesselin.bontchev/audible-samples/tree/master https://samples.ffmpeg.org/audible/ Currently, this code generates corrupt audio output (in some places, and deterministically). By posting this patch, I am hoping to get some early feedback, and help in making this work. Thanks, VesselinFrom ba73543efc3fdc4b5c61e9cb56f998d748716e00 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 10 ++ doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 381 +++ libavformat/allformats.c | 1 + 5 files changed, 395 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..df95233 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,16 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + +@example +ffmpeg -v debug -i input.aa -c:a copy output.wav +@end example + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..8405f8d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -395,6 +395,7 @@ OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o \ OBJS-$(CONFIG_RTSP_MUXER)+= rtsp.o rtspenc.o httpauth.o \ urldecode.o OBJS-$(CONFIG_SAMI_DEMUXER) += samidec.o subtitles.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o OBJS-$(CONFIG_SAP_MUXER) += sapenc.o OBJS-$(CONFIG_SBG_DEMUXER) += sbgdec.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..bd994e8 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,381 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Inspired by https://github.com/jteeuwen/audible, and + * https://code.google.com/p/pyaudibletags/source projects. + * + * See https://en.wikipedia.org/wiki/Audible.com#Quality for + * format details. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/fifo.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 64 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +int64_t data_end; +uint32_t HeaderSeed; +uint32_t Filesize; +uint32_t Magic; +uint32_t tocSize; +uint32_t npairs; +union { +unsigned char key[16]; +uint32_t part[4]; +} HeaderKey; +uint32_t TOC[MAX_TOC_ENTRIES][2]; + +void *aa_fixed_key; +int aa_fixed_key_size; +uint32_t start; +uint32_t end; +int32_t codec_second_size; +char codec_name[64]; +struct AVTEA *tea_ctx; +uint8_t final_key[16]; +int64_t current_chapter_size; +int64_t current_codec_second_size; +uint32_t trailing_bytes; +int64_t total_parsed; +struct AVFifoBuffer *cbuf; +int chapter_idx; +} AADemuxContext; + +static int32_t GetSecondSizeByCodecID(char
Re: [FFmpeg-devel] [PATCH] Add support for Audible AA files
27.07.2015, 16:16, "Nicolas George" : > Le nonidi 9 thermidor, an CCXXIII, Vesselin Bontchev a écrit : >> This patch adds support for Audible AA files. >> >> Audible samples can be obtained from, >> >> https://gitlab.com/vesselin.bontchev/audible-samples/tree/master >> https://samples.ffmpeg.org/audible/ > >> Currently, this code generates corrupt audio output (in some places, and >> deterministically). > > Does this happen with the Go and Python implementations too? There are no existing Go, or Python implementations actually. >> From ba73543efc3fdc4b5c61e9cb56f998d748716e00 Mon Sep 17 00:00:00 2001 >> Subject: [PATCH] Add support for Audible AA files >> + avio_read(s->pb, src, trailing_bytes); >> + memcpy(buf + written, dst, trailing_bytes); > > Looks strange: you read to src but copy dst. May this be the cause of the > glitches? Good catch! This fixed the glitches entirely. ... I am attaching a new revision (v2) of the patch. I still need to take care of memory leaks, and also harden input processing. This said, the code should already be looking much better (thanks for all the help!). VesselinFrom e907a1c79b10f15a23caf62c85fffd9dcd2d4ec3 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 10 ++ doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 337 +++ libavformat/allformats.c | 1 + 5 files changed, 351 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..df95233 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,16 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + +@example +ffmpeg -v debug -i input.aa -c:a copy output.wav +@end example + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..5d71c74 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,337 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + *
[FFmpeg-devel] [PATCH v3] Add support for Audible AA files
Hi, I am attaching a new revision (v3) of the "Audible AA" patch. VesselinFrom 30757211a81f5b0c852e1f4e620c03b9ae08f99e Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 10 ++ doc/general.texi |2 + libavformat/Makefile |1 + libavformat/aadec.c | 340 ++ libavformat/allformats.c |1 + 5 files changed, 354 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..df95233 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,16 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + +@example +ffmpeg -v debug -i input.aa -c:a copy output.wav +@end example + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..a4c7f11 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,340 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +void *aa_fixed_key; +int aa_fixed_key_size; +int32_t codec_second_size; +struct AVTEA *tea_ctx; +
[FFmpeg-devel] [PATCH v4] Add support for Audible AA files
Thanks for all the feedback. VesselinFrom d035dc7dd0c95079ca9f94c7acb7aab0d48f16cb Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 321 +++ libavformat/allformats.c | 1 + 5 files changed, 331 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..c86e8a4 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..958c845 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,321 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of FFmpeg. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +void *aa_fixed_key; +int aa_fixed_key_size; +int32_t codec_second_size; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +int64_t current_codec_second_size; +int chapter_idx; +} AADemuxContext; + +static int32_t get_second_size(char *codec_name) +{ +int32_t result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(codec_name, "acelp16")) { +result = 2000; +} else if (!strcmp(codec_name, "acelp85")) { +result = 1045; +} + +return result; +} + +static int aa_read_header(AVFormatContext *s) +{ +int i, j, idx; +uint32_t nkey; +uint32_t nval; +char key[128]; +char val[128]; +uint8_t output[24]; +uint8_t dst[8]; +uint8_t src[8]; +int largest_idx = -1; +int64_t largest_size = -1; +int64_t current_size = -1; +uint32_t start; +char codec_name[64] = {0}; +int ret
Re: [FFmpeg-devel] [PATCH v3] Add support for Audible AA files
28.07.2015, 19:23, "Carl Eugen Hoyos" : > Vesselin Bontchev yandex.com> writes: > >> +@example >> +ffmpeg -v debug -i input.aa -c:a copy output.wav > > I don't think this is a very useful example, instead > please document the option that the demuxer has in > short words (you don't have to document the default > value imo). I have removed the example in revision v4. >> + * Redistribution and use in source and binary forms, >> with or without modification, >> + * are permitted provided that the following conditions are met: > >> + * FFmpeg is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU Lesser General Public > > Please choose one license for the new file you are > adding (and keep the copyright notices). I am not very good at this stuff. Hopefully, things are acceptable in revision v4. > And if you disagree with one of my comments, please > say so ;-) Heh, thanks! :) Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v5] Add support for Audible AA files
I sneaked in some more fixes in this revision :) VesselinFrom 5db4be22af277030cdbe234843e7aae55bf667e1 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 326 +++ libavformat/allformats.c | 1 + 5 files changed, 336 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..c86e8a4 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..7f320e5 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,326 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of FFmpeg. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define MAX_DICTIONARY_ENTRIES 128 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +void *aa_fixed_key; +int aa_fixed_key_size; +int32_t codec_second_size; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +int64_t current_codec_second_size; +int chapter_idx; +} AADemuxContext; + +static int32_t get_second_size(char *codec_name) +{ +int32_t result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(codec_name, "acelp16")) { +result = 2000; +} else if (!strcmp(codec_name, "acelp85")) { +result = 1045; +} + +return result; +} + +static int aa_read_header(AVFormatContext *s) +{ +int i, j, idx; +uint32_t nkey; +uint32_t nval; +char key[128]; +char val[128]; +uint8_t output[24]; +uint8_t dst[8]; +uint8_t src[8]; +int largest_idx = -1; +int64_t largest_size = -1; +int64_t current_size = -1; +
Re: [FFmpeg-devel] [PATCH v5] Add support for Audible AA files
28.07.2015, 20:09, "Vesselin Bontchev" : > I sneaked in some more fixes in this revision :) Hi Carl, Is the licensing blurb okay now? All, Hopefully, the code is now good enough to be merged. All feedback is welcome! Thanks, Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v6] Add support for Audible AA files
Please review. Thanks, VesselinFrom 06b0c0013404a67c72ea14a3c90730c0c4bd5b9a Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 325 +++ libavformat/allformats.c | 1 + 5 files changed, 335 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..c86e8a4 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..771bcfd --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,325 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define MAX_DICTIONARY_ENTRIES 128 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +void *aa_fixed_key; +int aa_fixed_key_size; +int32_t codec_second_size; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +int64_t current_codec_second_size; +int chapter_idx; +} AADemuxContext; + +static int32_t get_second_size(char *codec_name) +{ +int32_t result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(codec_name, "acelp16")) { +result = 2000; +} else if (!strcmp(codec_name, "acelp85")) { +result = 1045; +} + +return result; +} + +static int aa_read_header(AVFormatContext *s) +{ +int i, j, idx; +uint32_t nkey; +uint32_t nval; +char key[128]; +char val[128]; +uint8_t output[24]; +uint8_t dst[8]; +uint8_t src[8]; +int largest_idx = -1; +int64_t largest_size = -1; +int64_t current_size = -1; +uint32_t start; +char codec_name[64] = {0}; +int ret
Re: [FFmpeg-devel] [PATCH v5] Add support for Audible AA files
30.07.2015, 11:35, "Carl Eugen Hoyos" : > Vesselin Bontchev yandex.com> writes: >> + if (c->aa_fixed_key_size != 16) { >> // AVOption with a default value > > Again: Where is this variable set? > You don't have to add a comment, just > tell me, I don't see it. +#define OFFSET(x) offsetof(AADemuxContext, x) +#define FLAGS AV_OPT_FLAG_DECODING_PARAM +static const AVOption aa_options[] = { +{ "aa_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! +"Fixed key used for handling Audible AA files", OFFSET(aa_fixed_key), +AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd2a51d673"}, +.flags = AV_OPT_FLAG_DECODING_PARAM }, +{ NULL }, +}; Is this what you are asking for? I am pretty new to FFmpeg source code. Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/mov: fix regression in processing .aax files
From 418d573659dd011de503e45622307974cf437df5 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Fri, 31 Jul 2015 12:16:08 +0200 Subject: [PATCH] avformat/mov: fix regression in processing .aax files Commit 0a551cbe introduced "activation_bytes" option, and not specifying this option (while calling ffmpeg / ffprobe) causes the program to quit early. Before this commit, ffprobe was capable of processing metadata in .aax files. --- libavformat/mov.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index fdba34c..6a81848 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -849,13 +849,13 @@ static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom) /* verify activation data */ if (!activation_bytes || c->activation_bytes_size != 4) { -av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is missing!\n"); -ret = AVERROR(EINVAL); +av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n"); +ret = 0; /* allow ffprobe to continue working on .aax files */ goto fail; } if (c->activation_bytes_size != 4) { -av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n"); -ret = AVERROR(EINVAL); +av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes value needs to be 4 bytes!\n"); +ret = 0; /* allow ffprobe to continue working on .aax files */ goto fail; } -- 2.1.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/mov: fix regression in processing .aax files
01.08.2015, 03:43, "Michael Niedermayer" : > On Fri, Jul 31, 2015 at 01:36:58PM +0300, Vesselin Bontchev wrote: >> mov.c | 8 >> >> From 418d573659dd011de503e45622307974cf437df5 Mon Sep 17 00:00:00 2001 >> From: Vesselin Bontchev >> >> /* verify activation data */ >> if (!activation_bytes || c->activation_bytes_size != 4) { > > not part of this patch but > both check for c->activation_bytes_size != 4 > is this intended? isn't the 2nd unreachable that way? Good catch, this is not intended at all! >> - av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is >> missing!\n"); >> - ret = AVERROR(EINVAL); >> + av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is >> missing!\n"); >> + ret = 0; /* allow ffprobe to continue working on .aax files */ >> goto fail; >> } > >> if (c->activation_bytes_size != 4) { >> - av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 >> bytes!\n"); >> - ret = AVERROR(EINVAL); >> + av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes value needs to be 4 >> bytes!\n"); >> + ret = 0; /* allow ffprobe to continue working on .aax files */ >> goto fail; >> } > > are both needed for ffprobe ? > wouldn't ffprobe simply have it not set and take the first if() always You are absolutely right. I am attaching a new fixed revision of the patch. VesselinFrom 3710003b6f44dda82fce2eb2c166214f6842c677 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Fri, 31 Jul 2015 12:16:08 +0200 Subject: [PATCH] avformat/mov: fix regression in processing .aax files Commit 0a551cbe introduced "activation_bytes" option, and not specifying this option (while calling ffmpeg / ffprobe) causes the program to quit early. Before this commit, ffprobe was capable of processing metadata in .aax files. --- libavformat/mov.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index fdba34c..154d2f8 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -848,9 +848,9 @@ static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_INFO, "\n"); /* verify activation data */ -if (!activation_bytes || c->activation_bytes_size != 4) { -av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes option is missing!\n"); -ret = AVERROR(EINVAL); +if (!activation_bytes) { +av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n"); +ret = 0; /* allow ffprobe to continue working on .aax files */ goto fail; } if (c->activation_bytes_size != 4) { -- 2.4.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v6] Add support for Audible AA files
30.07.2015, 13:48, "Vesselin Bontchev" : > Please review. > > Thanks, > Vesselin Hi! Is this patch in good enough shape to be merged? Or is there something more I can do to get this patch merged upstream? Thanks, Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v6] Add support for Audible AA files
02.08.2015, 07:44, "James Almer" : > On 30/07/15 7:46 AM, Vesselin Bontchev wrote: >> From 06b0c0013404a67c72ea14a3c90730c0c4bd5b9a Mon Sep 17 00:00:00 2001 >> From: Vesselin Bontchev >> Date: Sun, 19 Jul 2015 23:16:36 +0200 >> Subject: [PATCH] Add support for Audible AA files >> >> + AVIOContext *pb = s->pb; >> + AVStream *st = avformat_new_stream(s, NULL); >> + if (!st) >> + return AVERROR(ENOMEM); >> + c->tea_ctx = av_tea_alloc(); > > You could move this below right before tea_init and replace all of the gotos > below > with simple returns. Thanks, this really makes the code look better! :) >> + /* verify fixed key */ >> + if (c->aa_fixed_key_size != 16) { > > This is zeroed during init but apparently never touched after that. > You should probably check the length of the AVOption aa_fixed_key instead. http://ffmpeg.org/doxygen/trunk/group__avoptions.html seems to say that this field is automatically updated (and in practice it does get updated according to what you pass in). >> +static const AVOption aa_options[] = { >> + { "aa_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files! >> + "Fixed key used for handling Audible AA files", OFFSET(aa_fixed_key), >> + AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd2a51d673"}, > > This should probably be AV_OPT_TYPE_STRING. We want to hex decode the value of "aa_fixed_key". So, AV_OPT_TYPE_BINARY seems to be appropriate. I have incorporated rest of your feedback into a new revision of the patch, thanks! Vesselin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v7] Add support for Audible AA files
From 0568a9385aa024ff015adab1c8f085de73edc644 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 305 +++ libavformat/allformats.c | 1 + 5 files changed, 315 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e45e1af..c86e8a4 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..e336283 --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,305 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define MAX_DICTIONARY_ENTRIES 128 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +uint8_t *aa_fixed_key; +int aa_fixed_key_len; +int32_t codec_second_size; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +int64_t current_codec_second_size; +int chapter_idx; +} AADemuxContext; + +static int32_t get_second_size(char *codec_name) +{ +int32_t result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(codec_name, "acelp16")) { +result = 2000; +} else if (!strcmp(codec_name, "acelp85")) { +result = 1045; +} + +return result; +} + +static int aa_read_header(AVFormatContext *s) +{ +int i, j, idx, largest_idx = -1; +uint32_t nkey, nval, toc_size, npairs, header_seed, start; +char key[128], val[128], codec_name[64] = {0}; +uint8_t output[24], dst[8], src[8]; +int64_t largest_size = -1, current_size = -1; +struct toc_entry { +uint32_t offset; +uint32_t size; +} TOC[MAX_TOC_ENTRIES]; +union { +
[FFmpeg-devel] [PATCH v8] Add support for Audible AA files
Hi! It would be awesome to have this patch merged in FFmpeg. VesselinFrom d8a6d0d7052ebdb7caa8dd9a7d571a68339d7acc Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 303 +++ libavformat/allformats.c | 1 + 5 files changed, 313 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/doc/demuxers.texi b/doc/demuxers.texi index eb7cd4b..34bfc9b 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..8e6140e --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,303 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define MAX_DICTIONARY_ENTRIES 128 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +uint8_t *aa_fixed_key; +int aa_fixed_key_len; +int codec_second_size; +int current_codec_second_size; +int chapter_idx; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +} AADemuxContext; + +static int get_second_size(char *codec_name) +{ +int result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(codec_name, "acelp16")) { +result = 2000; +} else if (!strcmp(codec_name, "acelp85")) { +result = 1045; +} + +return result; +} + +static int aa_read_header(AVFormatContext *s) +{ +int i, j, idx, largest_idx = -1; +uint32_t nkey, nval, toc_size, npairs, header_seed, start; +char key[128], val[128], codec_name[64] = {0}; +uint8_t output[24], dst[8], src[8]; +int64_t largest_size = -1, current_size = -1; +struct toc_entry { +uint32_t offset; +
[FFmpeg-devel] [PATCH v9] Add support for Audible AA files
This patch revision (v9) adds me to the MAINTAINERS file. VesselinFrom a9457dead0dac503c9aeca8d49bc89d5c9b607d9 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Sun, 19 Jul 2015 23:16:36 +0200 Subject: [PATCH] Add support for Audible AA files https://en.wikipedia.org/wiki/Audible.com#Quality --- MAINTAINERS | 1 + doc/demuxers.texi| 6 + doc/general.texi | 2 + libavformat/Makefile | 1 + libavformat/aadec.c | 303 +++ libavformat/allformats.c | 1 + 6 files changed, 314 insertions(+) create mode 100644 libavformat/aadec.c diff --git a/MAINTAINERS b/MAINTAINERS index b2aaf3c..94405e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -399,6 +399,7 @@ Generic parts: Muxers/Demuxers: 4xm.c Mike Melanson + aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com) adtsenc.c Robert Swain afc.c Paul B Mahol aiffdec.c Baptiste Coudurier, Matthieu Bouron diff --git a/doc/demuxers.texi b/doc/demuxers.texi index eb7cd4b..34bfc9b 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -18,6 +18,12 @@ enabled demuxers. The description of some of the currently available demuxers follows. +@section aa + +Audible Format 2, 3, and 4 demuxer. + +This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files. + @section applehttp Apple HTTP Live Streaming demuxer. diff --git a/doc/general.texi b/doc/general.texi index a260e79..2b782e0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -228,6 +228,8 @@ library: @item 8088flex TMV @tab @tab X @item AAX @tab @tab X @tab Audible Enhanced Audio format, used in audiobooks. +@item AA@tab @tab X +@tab Audible Format 2, 3, and 4, used in audiobooks. @item ACT Voice @tab @tab X @tab contains G.729 audio @item Adobe Filmstrip @tab X @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index cc73fd8..466da51 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -59,6 +59,7 @@ OBJS-$(CONFIG_SHARED)+= log2_tab.o golomb_tab.o # muxers/demuxers OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o +OBJS-$(CONFIG_AA_DEMUXER)+= aadec.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o apetag.o img2.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o diff --git a/libavformat/aadec.c b/libavformat/aadec.c new file mode 100644 index 000..8e6140e --- /dev/null +++ b/libavformat/aadec.c @@ -0,0 +1,303 @@ +/* + * Audible AA demuxer + * Copyright (c) 2015 Vesselin Bontchev + * + * Header parsing is borrowed from https://github.com/jteeuwen/audible project. + * Copyright (c) 2001-2014, Jim Teeuwen + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + *list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/tea.h" +#include "libavutil/opt.h" + +#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */ +#define MAX_CODEC_SECOND_SIZE 3982 +#define MAX_TOC_ENTRIES 16 +#define MAX_DICTIONARY_ENTRIES 128 +#define TEA_BLOCK_SIZE 8 + +typedef struct AADemuxContext { +AVClass *class; +uint8_t *aa_fixed_key; +int aa_fixed_key_len; +int codec_second_size; +int current_codec_second_size; +int chapter_idx; +struct AVTEA *tea_ctx; +uint8_t file_key[16]; +int64_t current_chapter_size; +} AADemuxContext; + +static int get_second_size(char *codec_name) +{ +int result = -1; + +if (!strcmp(codec_name, "mp332")) { +result = 3982; +} else if (!strcmp(cod
[FFmpeg-devel] [PATCH] avformat/aa: initialize "header_seed" and "header_key"
From 8e28e0721c61cface6496fe4657ff5d3c3d2e6b8 Mon Sep 17 00:00:00 2001 From: Vesselin Bontchev Date: Thu, 10 Sep 2015 08:59:56 +0200 Subject: [PATCH] avformat/aa: initialize "header_seed" and "header_key" Fixes CID 1322364, CID 1322363 Signed-off-by: Vesselin Bontchev --- libavformat/aadec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/aadec.c b/libavformat/aadec.c index ba700d5..266a8e8 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -65,7 +65,7 @@ static int get_second_size(char *codec_name) static int aa_read_header(AVFormatContext *s) { int i, j, idx, largest_idx = -1; -uint32_t nkey, nval, toc_size, npairs, header_seed, start; +uint32_t nkey, nval, toc_size, npairs, header_seed = 0, start; char key[128], val[128], codec_name[64] = {0}; uint8_t output[24], dst[8], src[8]; int64_t largest_size = -1, current_size = -1; @@ -74,7 +74,7 @@ static int aa_read_header(AVFormatContext *s) uint32_t size; } TOC[MAX_TOC_ENTRIES]; uint32_t header_key_part[4]; -uint8_t header_key[16]; +uint8_t header_key[16] = {0}; AADemuxContext *c = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; -- 2.5.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel