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
00033 #define XA00_TAG MKTAG('X', 'A', 0, 0)
00034 #define XAI0_TAG MKTAG('X', 'A', 'I', 0)
00035 #define XAJ0_TAG MKTAG('X', 'A', 'J', 0)
00036
00037 typedef struct MaxisXADemuxContext {
00038 uint32_t out_size;
00039 uint32_t sent_bytes;
00040 uint32_t audio_frame_counter;
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 AVFormatParameters *ap)
00067 {
00068 MaxisXADemuxContext *xa = s->priv_data;
00069 ByteIOContext *pb = s->pb;
00070 AVStream *st;
00071
00072
00073 st = av_new_stream(s, 0);
00074 if (!st)
00075 return AVERROR(ENOMEM);
00076
00077 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00078 st->codec->codec_id = CODEC_ID_ADPCM_EA_MAXIS_XA;
00079 url_fskip(pb, 4);
00080 xa->out_size = get_le32(pb);
00081 url_fskip(pb, 2);
00082 st->codec->channels = get_le16(pb);
00083 st->codec->sample_rate = get_le32(pb);
00084
00085 st->codec->bit_rate = get_le32(pb) * 8;
00086 st->codec->block_align = get_le16(pb);
00087 st->codec->bits_per_coded_sample = get_le16(pb);
00088
00089 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
00090
00091 return 0;
00092 }
00093
00094 static int xa_read_packet(AVFormatContext *s,
00095 AVPacket *pkt)
00096 {
00097 MaxisXADemuxContext *xa = s->priv_data;
00098 AVStream *st = s->streams[0];
00099 ByteIOContext *pb = s->pb;
00100 unsigned int packet_size;
00101 int ret;
00102
00103 if(xa->sent_bytes > xa->out_size)
00104 return AVERROR(EIO);
00105
00106 packet_size = 15*st->codec->channels;
00107
00108 ret = av_get_packet(pb, pkt, packet_size);
00109 if(ret < 0)
00110 return ret;
00111
00112 pkt->stream_index = st->index;
00113 xa->sent_bytes += packet_size;
00114 pkt->pts = xa->audio_frame_counter;
00115
00116 xa->audio_frame_counter += 28 * st->codec->channels;
00117
00118 return ret;
00119 }
00120
00121 AVInputFormat xa_demuxer = {
00122 "xa",
00123 NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
00124 sizeof(MaxisXADemuxContext),
00125 xa_probe,
00126 xa_read_header,
00127 xa_read_packet,
00128 };