#include "apetag.h"
/* The earliest and latest file formats supported by this library */
-#define APE_MIN_VERSION 3950
+#define APE_MIN_VERSION 3800
#define APE_MAX_VERSION 3990
#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE]
/* Seektable */
uint32_t *seektable;
+ uint8_t *bittable;
} APEContext;
static int ape_probe(AVProbeData * p)
} else {
for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) {
if (i < ape_ctx->totalframes - 1) {
- av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)\n",
+ av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)",
i, ape_ctx->seektable[i],
ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
+ if (ape_ctx->bittable)
+ av_log(s, AV_LOG_DEBUG, " + %2d bits\n",
+ ape_ctx->bittable[i]);
+ av_log(s, AV_LOG_DEBUG, "\n");
} else {
av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32"\n", i, ape_ctx->seektable[i]);
}
if(!ape->frames)
return AVERROR(ENOMEM);
ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength;
+ if (ape->fileversion < 3810)
+ ape->firstframe += ape->totalframes;
ape->currentframe = 0;
return AVERROR(ENOMEM);
for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++)
ape->seektable[i] = avio_rl32(pb);
+ if (ape->fileversion < 3810) {
+ ape->bittable = av_malloc(ape->totalframes);
+ if (!ape->bittable)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < ape->totalframes; i++)
+ ape->bittable[i] = avio_r8(pb);
+ }
}
ape->frames[0].pos = ape->firstframe;
}
ape->frames[i].size = (ape->frames[i].size + 3) & ~3;
}
-
+ if (ape->fileversion < 3810) {
+ for (i = 0; i < ape->totalframes; i++) {
+ if (i < ape->totalframes - 1 && ape->bittable[i + 1])
+ ape->frames[i].size += 4;
+ ape->frames[i].skip <<= 3;
+ ape->frames[i].skip += ape->bittable[i];
+ }
+ }
ape_dumpinfo(s, ape);
- /* try to read APE tags */
- if (pb->seekable) {
- ff_ape_parse_tag(s);
- avio_seek(pb, 0, SEEK_SET);
- }
-
av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n",
ape->fileversion / 1000, (ape->fileversion % 1000) / 10,
ape->compressiontype);
total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = CODEC_ID_APE;
+ st->codec->codec_id = AV_CODEC_ID_APE;
st->codec->codec_tag = MKTAG('A', 'P', 'E', ' ');
st->codec->channels = ape->channels;
st->codec->sample_rate = ape->samplerate;
pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
}
+ /* try to read APE tags */
+ if (pb->seekable) {
+ ff_ape_parse_tag(s);
+ avio_seek(pb, 0, SEEK_SET);
+ }
+
return 0;
}
av_freep(&ape->frames);
av_freep(&ape->seektable);
+ av_freep(&ape->bittable);
return 0;
}