[FFmpeg-devel] [PATCH v3] Add support for Audible AA files
Michael Niedermayer
michael at niedermayer.cc
Tue Jul 28 17:21:19 CEST 2015
On Tue, Jul 28, 2015 at 05:25:21PM +0300, Vesselin Bontchev wrote:
> Hi,
>
> I am attaching a new revision (v3) of the "Audible AA" patch.
>
> Vesselin
[...]
> + avio_skip(pb, 24); // header termination block (ignored)
> + npairs = avio_rb32(pb); // read dictionary entries
> + for (i = 0; i < npairs; i++) {
> + memset(val, 0, sizeof(val));
> + memset(key, 0, sizeof(key));
> + avio_skip(pb, 1); // unidentified integer
> + nkey = avio_rb32(pb); // key string length
> + nval = avio_rb32(pb); // value string length
> + if (nkey > sizeof(key)) {
> + avio_skip(pb, nkey);
> + } else {
> + avio_read(pb, key, nkey); // key string
> + }
> + if (nval > sizeof(val)) {
> + avio_skip(pb, nval);
> + } else {
> + avio_read(pb, val, nval); // value string
> + }
> + if (!strcmp(key, "codec")) {
> + strncpy(codec_name, val, sizeof(codec_name) - 1);
> + }
> + if (!strcmp(key, "HeaderSeed")) {
> + header_seed = atoi(val);
> + }
> + if (!strcmp(key, "HeaderKey")) {
> + sscanf(val, "%d%d%d%d", &header_key.part[0], &header_key.part[1], &header_key.part[2], &header_key.part[3]);
> + for (idx = 0; idx < 4; idx++) {
> + header_key.part[idx] = AV_RB32(&header_key.part[idx]); // convert to BE!
> + }
> + }
> + }
there should be some check to break out of the array when the end
is reached or some error
otherwise this could take a long time with craftet data
[...]
> +static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> + uint8_t dst[TEA_BLOCK_SIZE];
> + uint8_t src[TEA_BLOCK_SIZE];
> + int i;
> + int trailing_bytes;
> + int blocks;
> + uint8_t buf[MAX_CODEC_SECOND_SIZE * 2];
> + int written = 0;
> + int ret = 0;
> + AADemuxContext *c = s->priv_data;
> +
> + // are we at the start of a chapter?
> + if (c->current_chapter_size == 0) {
> + c->current_chapter_size = avio_rb32(s->pb);
> + if (c->current_chapter_size == 0) {
> + ret = AVERROR_EOF;
> + goto end;
> + }
> + av_log(s, AV_LOG_DEBUG, "[aa] chapter %d (%ld bytes)\n", c->chapter_idx, c->current_chapter_size);
> + c->chapter_idx = c->chapter_idx + 1;
> + avio_skip(s->pb, 4); // data start offset
> + c->current_codec_second_size = c->codec_second_size;
> + }
> +
> + // is this the last block in this chapter?
> + if (c->current_chapter_size / c->current_codec_second_size == 0) {
> + c->current_codec_second_size = c->current_chapter_size % c->current_codec_second_size;
> + }
> +
> + // decrypt c->current_codec_second_size bytes
> + blocks = c->current_codec_second_size / TEA_BLOCK_SIZE;
> + for (i = 0; i < blocks; i++) {
> + avio_read(s->pb, src, TEA_BLOCK_SIZE);
> + av_tea_init(c->tea_ctx, c->file_key, 16);
> + av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
> + memcpy(buf + written, dst, TEA_BLOCK_SIZE);
> + written = written + TEA_BLOCK_SIZE;
> + }
> + trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
> + if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
> + avio_read(s->pb, src, trailing_bytes);
> + memcpy(buf + written, src, trailing_bytes);
> + written = written + trailing_bytes;
> + }
> +
> + // update state
> + c->current_chapter_size = c->current_chapter_size - c->current_codec_second_size;
> + if (c->current_chapter_size <= 0)
> + c->current_chapter_size = 0;
> +
> + av_new_packet(pkt, written);
missing failure check
> + memcpy(pkt->data, buf, written);
> +
> +end:
> + return ret;
if you dont plan to add additional stuff here then goto end could be
replaced by direct returns
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
When you are offended at any man's fault, turn to yourself and study your
own failings. Then you will forget your anger. -- Epictetus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150728/3da75d59/attachment.sig>
More information about the ffmpeg-devel
mailing list