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 uint32_t audio_frame_counter;
00042 } MaxisXADemuxContext;
00043
00044 static int xa_probe(AVProbeData *p)
00045 {
00046 int channels, srate, bits_per_sample;
00047 if (p->buf_size < 24)
00048 return 0;
00049 switch(AV_RL32(p->buf)) {
00050 case XA00_TAG:
00051 case XAI0_TAG:
00052 case XAJ0_TAG:
00053 break;
00054 default:
00055 return 0;
00056 }
00057 channels = AV_RL16(p->buf + 10);
00058 srate = AV_RL32(p->buf + 12);
00059 bits_per_sample = AV_RL16(p->buf + 22);
00060 if (!channels || channels > 8 || !srate || srate > 192000 ||
00061 bits_per_sample < 4 || bits_per_sample > 32)
00062 return 0;
00063 return AVPROBE_SCORE_MAX/2;
00064 }
00065
00066 static int xa_read_header(AVFormatContext *s,
00067 AVFormatParameters *ap)
00068 {
00069 MaxisXADemuxContext *xa = s->priv_data;
00070 AVIOContext *pb = s->pb;
00071 AVStream *st;
00072
00073
00074 st = avformat_new_stream(s, NULL);
00075 if (!st)
00076 return AVERROR(ENOMEM);
00077
00078 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00079 st->codec->codec_id = CODEC_ID_ADPCM_EA_MAXIS_XA;
00080 avio_skip(pb, 4);
00081 xa->out_size = avio_rl32(pb);
00082 avio_skip(pb, 2);
00083 st->codec->channels = avio_rl16(pb);
00084 st->codec->sample_rate = avio_rl32(pb);
00085
00086 st->codec->bit_rate = avio_rl32(pb) * 8;
00087 st->codec->block_align = avio_rl16(pb);
00088 st->codec->bits_per_coded_sample = avio_rl16(pb);
00089
00090 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00091
00092 return 0;
00093 }
00094
00095 static int xa_read_packet(AVFormatContext *s,
00096 AVPacket *pkt)
00097 {
00098 MaxisXADemuxContext *xa = s->priv_data;
00099 AVStream *st = s->streams[0];
00100 AVIOContext *pb = s->pb;
00101 unsigned int packet_size;
00102 int ret;
00103
00104 if(xa->sent_bytes > xa->out_size)
00105 return AVERROR(EIO);
00106
00107 packet_size = 15*st->codec->channels;
00108
00109 ret = av_get_packet(pb, pkt, packet_size);
00110 if(ret < 0)
00111 return ret;
00112
00113 pkt->stream_index = st->index;
00114 xa->sent_bytes += packet_size;
00115 pkt->pts = xa->audio_frame_counter;
00116
00117 xa->audio_frame_counter += 28 * st->codec->channels;
00118
00119 return ret;
00120 }
00121
00122 AVInputFormat ff_xa_demuxer = {
00123 .name = "xa",
00124 .long_name = NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
00125 .priv_data_size = sizeof(MaxisXADemuxContext),
00126 .read_probe = xa_probe,
00127 .read_header = xa_read_header,
00128 .read_packet = xa_read_packet,
00129 };