Skip to content
Snippets Groups Projects
aea.c 3.08 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * MD STUDIO audio demuxer
     *
     * Copyright (c) 2009 Benjamin Larsson
     *
     * 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 libavformat/aea.c
     */
    
    #include "avformat.h"
    #include "raw.h"
    #include "libavutil/intreadwrite.h"
    
    #define AT1_SU_SIZE     212
    
    static int aea_read_probe(AVProbeData *p)
    {
        if (p->buf_size <= 2048+212)
            return 0;
    
        /* Magic is '00 08 00 00' in Little Endian*/
    
    Benjamin Larsson's avatar
    Benjamin Larsson committed
        if (AV_RL32(p->buf)==0x800) {
    
            int bsm_s, bsm_e, inb_s, inb_e, ch;
            ch    = p->buf[264];
    
            bsm_s = p->buf[2048];
            inb_s = p->buf[2048+1];
            inb_e = p->buf[2048+210];
            bsm_e = p->buf[2048+211];
    
    
            if (ch != 1 && ch != 2)
                return 0;
    
    
            /* Check so that the redundant bsm bytes and info bytes are valid
             * the block size mode bytes have to be the same
             * the info bytes have to be the same
             * the block size mode and info byte can't be the same
             */
            if (bsm_s == bsm_e && inb_s == inb_e && bsm_s != inb_s)
    
    Benjamin Larsson's avatar
    Benjamin Larsson committed
                return AVPROBE_SCORE_MAX / 2;
    
        }
        return 0;
    }
    
    static int aea_read_header(AVFormatContext *s,
                               AVFormatParameters *ap)
    {
        AVStream *st = av_new_stream(s, 0);
        if (!st)
            return AVERROR(ENOMEM);
    
        /* Parse the amount of channels and skip to pos 2048(0x800) */
        url_fskip(s->pb, 264);
        st->codec->channels = get_byte(s->pb);
        url_fskip(s->pb, 1783);
    
    
        st->codec->codec_type     = CODEC_TYPE_AUDIO;
        st->codec->codec_id       = CODEC_ID_ATRAC1;
        st->codec->sample_rate    = 44100;
        st->codec->bit_rate       = 292000;
    
        if (st->codec->channels != 1 && st->codec->channels != 2) {
            av_log(s,AV_LOG_ERROR,"Channels %d not supported!\n",st->codec->channels);
            return -1;
        }
    
    
    Benjamin Larsson's avatar
    Benjamin Larsson committed
        st->codec->channel_layout = (st->codec->channels == 1) ? CH_LAYOUT_MONO : CH_LAYOUT_STEREO;
    
    
        st->codec->block_align = AT1_SU_SIZE * st->codec->channels;
        return 0;
    }
    
    static int aea_read_packet(AVFormatContext *s, AVPacket *pkt)
    {
        int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);
    
        pkt->stream_index = 0;
        if (ret <= 0)
            return AVERROR(EIO);
    
        return ret;
    }
    
    AVInputFormat aea_demuxer = {
        "aea",
        NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
        0,
        aea_read_probe,
        aea_read_header,
        aea_read_packet,
        0,
        pcm_read_seek,
        .flags= AVFMT_GENERIC_INDEX,
        .extensions = "aea",
    };