00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030 #include "libavutil/intreadwrite.h"
00031 #include "avformat.h"
00032 #include "internal.h"
00033
00034 #define XA00_TAG MKTAG('X', 'A', 0, 0)
00035 #define XAI0_TAG MKTAG('X', 'A', 'I', 0)
00036 #define XAJ0_TAG MKTAG('X', 'A', 'J', 0)
00037
00038 typedef struct MaxisXADemuxContext {
00039 uint32_t out_size;
00040 uint32_t sent_bytes;
00041 } MaxisXADemuxContext;
00042
00043 static int xa_probe(AVProbeData *p)
00044 {
00045 int channels, srate, bits_per_sample;
00046 if (p->buf_size < 24)
00047 return 0;
00048 switch(AV_RL32(p->buf)) {
00049 case XA00_TAG:
00050 case XAI0_TAG:
00051 case XAJ0_TAG:
00052 break;
00053 default:
00054 return 0;
00055 }
00056 channels = AV_RL16(p->buf + 10);
00057 srate = AV_RL32(p->buf + 12);
00058 bits_per_sample = AV_RL16(p->buf + 22);
00059 if (!channels || channels > 8 || !srate || srate > 192000 ||
00060 bits_per_sample < 4 || bits_per_sample > 32)
00061 return 0;
00062 return AVPROBE_SCORE_MAX/2;
00063 }
00064
00065 static int xa_read_header(AVFormatContext *s)
00066 {
00067 MaxisXADemuxContext *xa = s->priv_data;
00068 AVIOContext *pb = s->pb;
00069 AVStream *st;
00070
00071
00072 st = avformat_new_stream(s, NULL);
00073 if (!st)
00074 return AVERROR(ENOMEM);
00075
00076 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00077 st->codec->codec_id = AV_CODEC_ID_ADPCM_EA_MAXIS_XA;
00078 avio_skip(pb, 4);
00079 xa->out_size = avio_rl32(pb);
00080 avio_skip(pb, 2);
00081 st->codec->channels = avio_rl16(pb);
00082 st->codec->sample_rate = avio_rl32(pb);
00083 avio_skip(pb, 4);
00084 avio_skip(pb, 2);
00085 avio_skip(pb, 2);
00086
00087 st->codec->bit_rate = av_clip(15LL * st->codec->channels * 8 *
00088 st->codec->sample_rate / 28, 0, INT_MAX);
00089
00090 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00091 st->start_time = 0;
00092
00093 return 0;
00094 }
00095
00096 static int xa_read_packet(AVFormatContext *s,
00097 AVPacket *pkt)
00098 {
00099 MaxisXADemuxContext *xa = s->priv_data;
00100 AVStream *st = s->streams[0];
00101 AVIOContext *pb = s->pb;
00102 unsigned int packet_size;
00103 int ret;
00104
00105 if (xa->sent_bytes >= xa->out_size)
00106 return AVERROR_EOF;
00107
00108 packet_size = 15*st->codec->channels;
00109
00110 ret = av_get_packet(pb, pkt, packet_size);
00111 if(ret < 0)
00112 return ret;
00113
00114 pkt->stream_index = st->index;
00115 xa->sent_bytes += packet_size;
00116 pkt->duration = 28;
00117
00118 return ret;
00119 }
00120
00121 AVInputFormat ff_xa_demuxer = {
00122 .name = "xa",
00123 .long_name = NULL_IF_CONFIG_SMALL("Maxis XA"),
00124 .priv_data_size = sizeof(MaxisXADemuxContext),
00125 .read_probe = xa_probe,
00126 .read_header = xa_read_header,
00127 .read_packet = xa_read_packet,
00128 };