[FFmpeg-devel] [RFC] Monkey's Audio decoder
Michael Niedermayer
michaelni
Tue Sep 11 00:10:54 CEST 2007
Hi
On Mon, Sep 10, 2007 at 03:28:59PM +0300, Kostya wrote:
> Here's Monkey's Audio decoder made from libdemac by Benjamin Zores
> and made working by me.
>
> Please comment on decoder/demuxer structure
> (ape.c is demuxer, apedec.c is decoder).
just a incomplete review as the code is too messy for my taste and this
wasnt a real submission but just RFC ...
[...]
> typedef struct {
> int64_t pos;
> int nblocks;
> int size;
> int skip;
> int64_t pts;
> } APEFrame;
>
> typedef struct {
> /* Derived fields */
> uint32_t junklength;
> uint32_t firstframe;
> uint32_t totalsamples;
> int currentframe;
> APEFrame *frames;
>
> /* Info from Descriptor Block */
> char magic[4];
> int16_t fileversion;
> int16_t padding1;
> uint32_t descriptorlength;
> uint32_t headerlength;
> uint32_t seektablelength;
> uint32_t wavheaderlength;
> uint32_t audiodatalength;
> uint32_t audiodatalength_high;
> uint32_t wavtaillength;
> uint8_t md5[16];
>
> /* Info from Header Block */
> uint16_t compressiontype;
> uint16_t formatflags;
> uint32_t blocksperframe;
> uint32_t finalframeblocks;
> uint32_t totalframes;
> uint16_t bps;
> uint16_t channels;
> uint32_t samplerate;
>
> /* Seektable */
> uint32_t *seektable;
>
> int blocksout, blockssent;
> } APEContext;
>
> typedef struct {
> int16_t fileversion;
> uint16_t compression;
> uint16_t flags;
> } APECodecInfo;
why all the specific size fields, why not (unsigned) int?
[...]
> /* TODO: Skip any leading junk such as id3v2 tags */
> ape->junklength = 0;
unused
>
> tag = get_le32(pb);
> if (tag != MKTAG('M', 'A', 'C', ' '))
> return -1;
>
> ape->fileversion = get_le16(pb);
>
> if ((ape->fileversion < APE_MIN_VERSION) || (ape->fileversion > APE_MAX_VERSION)) {
superflous ()
> av_log(s, AV_LOG_ERROR, "Unsupported file version - %.2f\n", ape->fileversion / 1000.0);
you do not need floats here
[...]
> ape->padding1 = get_le16(pb);
> ape->descriptorlength = get_le32(pb);
> ape->headerlength = get_le32(pb);
> ape->seektablelength = get_le32(pb);
> ape->wavheaderlength = get_le32(pb);
> ape->audiodatalength = get_le32(pb);
> ape->audiodatalength_high = get_le32(pb);
> ape->wavtaillength = get_le32(pb);
these can be vertically aligned
> get_buffer(pb, ape->md5, 16);
>
> /* Skip any unknown bytes at the end of the descriptor.
> This is for future compatibility */
> if (ape->descriptorlength > 52)
> url_fseek(pb, ape->descriptorlength - 52, SEEK_CUR);
url_fskip()
[...]
> ape->totalframes = get_le32(pb);
> ape->finalframeblocks = get_le32(pb);
>
> if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) {
> url_fseek(pb, 4, SEEK_CUR); /* Skip the peak level */
> ape->headerlength += 4;
> }
>
> if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) {
> ape->seektablelength = get_le32(pb);
> ape->headerlength += 4;
> ape->seektablelength *= sizeof(int32_t);
> } else
> ape->seektablelength = ape->totalframes * sizeof(int32_t);
>
> if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT)
> ape->bps = 8;
> else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT)
> ape->bps = 24;
> else
> ape->bps = 16;
>
> if (ape->fileversion >= 3950)
> ape->blocksperframe = 73728 * 4;
> else if ((ape->fileversion >= 3900) ||
> (ape->fileversion >= 3800
> && ape->compressiontype >= 4000))
> ape->blocksperframe = 73728;
> else
> ape->blocksperframe = 9216;
>
> /* Skip any stored wav header */
> if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
> url_fseek(pb, ape->wavheaderlength, SEEK_CUR);
> }
>
> ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame));
exploitable interger overflow
[...]
> data = av_malloc(sizeof(APECodecInfo));
> data->fileversion = ape->fileversion;
> data->compression = ape->compressiontype;
> data->flags = ape->formatflags;
> st->codec->extradata = (void *) data;
> st->codec->extradata_size = sizeof(APECodecInfo);
no, rejected, you cannot put structs in extradata
>
> pts = 0;
> for(i = 0; i < ape->totalframes; i++){
> ape->frames[i].pts = pts;
> ape->frames[i].pts /= MAC_SUBFRAME_SIZE;
> av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME);
> pts += ape->blocksperframe;
pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
(if this doesnt work because its not a exact multiply then the timebase is
not set correctly)
also isnt the "av_index" enough? ape->frames looks somewhat redundant ...
[...]
> if(ape->blocksout--){
> av_new_packet(pkt, 4);
> AV_WL32(pkt->data, -1);
> pkt->pts = ape->frames[ape->currentframe - 1].pts + ape->blockssent;
> ape->blockssent++;
> return 0;
> }
what is that good for?
[...]
> static int ape_read_close(AVFormatContext * s)
> {
> return 0;
> }
unneeded
[...]
[...]
> #define inline
ehhh
[...]
> typedef enum {
> COMPRESSION_LEVEL_FAST = 1000,
> COMPRESSION_LEVEL_NORMAL = 2000,
> COMPRESSION_LEVEL_HIGH = 3000,
> COMPRESSION_LEVEL_EXTRA_HIGH = 4000,
> COMPRESSION_LEVEL_INSANE = 5000
> } compression_level_t;
vertical align please
>
> struct filter_t {
> int16_t *coeffs; /* ORDER entries */
>
> /* We store all the filter delays in a single buffer */
> int16_t *historybuffer; /* ORDER*2 + HISTORY_SIZE entries */
>
> int16_t *delay;
> int16_t *adaptcoeffs;
>
> int avg;
> };
not doxygen compatible comments
[...]
> #define FP_TO_INT(x,y) ((x + (1 << (y - 1))) >> y); /* round(x) */
this is useless just put the code where this is used, its just used once
>
> static inline void vector_add(int16_t * v1, int16_t * v2, int order)
> {
> int or = 1;
> if (order > 32)
> or = (order >> 5);
>
> while (or--) {
> int i;
>
> for (i = 0; i < 16; i++)
> *v1++ += *v2++;
>
> if (order > 16)
> for (i = 0; i < 16; i++)
> *v1++ += *v2++;
> }
> }
this can be simplified as was IIRC already mentioned some time ago
[...]
> Index: libavcodec/avcodec.h
> ===================================================================
> --- libavcodec/avcodec.h (revision 10469)
> +++ libavcodec/avcodec.h (working copy)
> @@ -259,6 +259,7 @@
> CODEC_ID_MLP,
> CODEC_ID_GSM_MS, /* as found in WAV */
> CODEC_ID_ATRAC3,
> + CODEC_ID_APE,
> CODEC_ID_VOXWARE,
breaks ABI
[...]
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070911/39d8e0c5/attachment.pgp>
More information about the ffmpeg-devel
mailing list