annotate ffmpeg/libavformat/xa.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * Maxis XA (.xa) File Demuxer
yading@11 3 * Copyright (c) 2008 Robert Marston
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 /**
yading@11 23 * @file
yading@11 24 * Maxis XA File Demuxer
yading@11 25 * by Robert Marston (rmarston@gmail.com)
yading@11 26 * for more information on the XA audio format see
yading@11 27 * http://wiki.multimedia.cx/index.php?title=Maxis_XA
yading@11 28 */
yading@11 29
yading@11 30 #include "libavutil/intreadwrite.h"
yading@11 31 #include "avformat.h"
yading@11 32 #include "internal.h"
yading@11 33
yading@11 34 #define XA00_TAG MKTAG('X', 'A', 0, 0)
yading@11 35 #define XAI0_TAG MKTAG('X', 'A', 'I', 0)
yading@11 36 #define XAJ0_TAG MKTAG('X', 'A', 'J', 0)
yading@11 37
yading@11 38 typedef struct MaxisXADemuxContext {
yading@11 39 uint32_t out_size;
yading@11 40 uint32_t sent_bytes;
yading@11 41 } MaxisXADemuxContext;
yading@11 42
yading@11 43 static int xa_probe(AVProbeData *p)
yading@11 44 {
yading@11 45 int channels, srate, bits_per_sample;
yading@11 46 if (p->buf_size < 24)
yading@11 47 return 0;
yading@11 48 switch(AV_RL32(p->buf)) {
yading@11 49 case XA00_TAG:
yading@11 50 case XAI0_TAG:
yading@11 51 case XAJ0_TAG:
yading@11 52 break;
yading@11 53 default:
yading@11 54 return 0;
yading@11 55 }
yading@11 56 channels = AV_RL16(p->buf + 10);
yading@11 57 srate = AV_RL32(p->buf + 12);
yading@11 58 bits_per_sample = AV_RL16(p->buf + 22);
yading@11 59 if (!channels || channels > 8 || !srate || srate > 192000 ||
yading@11 60 bits_per_sample < 4 || bits_per_sample > 32)
yading@11 61 return 0;
yading@11 62 return AVPROBE_SCORE_MAX/2;
yading@11 63 }
yading@11 64
yading@11 65 static int xa_read_header(AVFormatContext *s)
yading@11 66 {
yading@11 67 MaxisXADemuxContext *xa = s->priv_data;
yading@11 68 AVIOContext *pb = s->pb;
yading@11 69 AVStream *st;
yading@11 70
yading@11 71 /*Set up the XA Audio Decoder*/
yading@11 72 st = avformat_new_stream(s, NULL);
yading@11 73 if (!st)
yading@11 74 return AVERROR(ENOMEM);
yading@11 75
yading@11 76 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 77 st->codec->codec_id = AV_CODEC_ID_ADPCM_EA_MAXIS_XA;
yading@11 78 avio_skip(pb, 4); /* Skip the XA ID */
yading@11 79 xa->out_size = avio_rl32(pb);
yading@11 80 avio_skip(pb, 2); /* Skip the tag */
yading@11 81 st->codec->channels = avio_rl16(pb);
yading@11 82 st->codec->sample_rate = avio_rl32(pb);
yading@11 83 avio_skip(pb, 4); /* Skip average byte rate */
yading@11 84 avio_skip(pb, 2); /* Skip block align */
yading@11 85 avio_skip(pb, 2); /* Skip bits-per-sample */
yading@11 86
yading@11 87 st->codec->bit_rate = av_clip(15LL * st->codec->channels * 8 *
yading@11 88 st->codec->sample_rate / 28, 0, INT_MAX);
yading@11 89
yading@11 90 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
yading@11 91 st->start_time = 0;
yading@11 92
yading@11 93 return 0;
yading@11 94 }
yading@11 95
yading@11 96 static int xa_read_packet(AVFormatContext *s,
yading@11 97 AVPacket *pkt)
yading@11 98 {
yading@11 99 MaxisXADemuxContext *xa = s->priv_data;
yading@11 100 AVStream *st = s->streams[0];
yading@11 101 AVIOContext *pb = s->pb;
yading@11 102 unsigned int packet_size;
yading@11 103 int ret;
yading@11 104
yading@11 105 if (xa->sent_bytes >= xa->out_size)
yading@11 106 return AVERROR_EOF;
yading@11 107 /* 1 byte header and 14 bytes worth of samples * number channels per block */
yading@11 108 packet_size = 15*st->codec->channels;
yading@11 109
yading@11 110 ret = av_get_packet(pb, pkt, packet_size);
yading@11 111 if(ret < 0)
yading@11 112 return ret;
yading@11 113
yading@11 114 pkt->stream_index = st->index;
yading@11 115 xa->sent_bytes += packet_size;
yading@11 116 pkt->duration = 28;
yading@11 117
yading@11 118 return ret;
yading@11 119 }
yading@11 120
yading@11 121 AVInputFormat ff_xa_demuxer = {
yading@11 122 .name = "xa",
yading@11 123 .long_name = NULL_IF_CONFIG_SMALL("Maxis XA"),
yading@11 124 .priv_data_size = sizeof(MaxisXADemuxContext),
yading@11 125 .read_probe = xa_probe,
yading@11 126 .read_header = xa_read_header,
yading@11 127 .read_packet = xa_read_packet,
yading@11 128 };