Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
xa.c
Go to the documentation of this file.
1
/*
2
* Maxis XA (.xa) File Demuxer
3
* Copyright (c) 2008 Robert Marston
4
*
5
* This file is part of Libav.
6
*
7
* Libav is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* Libav is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
30
#include "
libavutil/intreadwrite.h
"
31
#include "
avformat.h
"
32
#include "
internal.h
"
33
34
#define XA00_TAG MKTAG('X', 'A', 0, 0)
35
#define XAI0_TAG MKTAG('X', 'A', 'I', 0)
36
#define XAJ0_TAG MKTAG('X', 'A', 'J', 0)
37
38
typedef
struct
MaxisXADemuxContext
{
39
uint32_t
out_size
;
40
uint32_t
sent_bytes
;
41
uint32_t
audio_frame_counter
;
42
}
MaxisXADemuxContext
;
43
44
static
int
xa_probe
(
AVProbeData
*p)
45
{
46
int
channels, srate, bits_per_sample;
47
if
(p->
buf_size
< 24)
48
return
0;
49
switch
(
AV_RL32
(p->
buf
)) {
50
case
XA00_TAG
:
51
case
XAI0_TAG
:
52
case
XAJ0_TAG
:
53
break
;
54
default
:
55
return
0;
56
}
57
channels =
AV_RL16
(p->
buf
+ 10);
58
srate =
AV_RL32
(p->
buf
+ 12);
59
bits_per_sample =
AV_RL16
(p->
buf
+ 22);
60
if
(!channels || channels > 8 || !srate || srate > 192000 ||
61
bits_per_sample < 4 || bits_per_sample > 32)
62
return
0;
63
return
AVPROBE_SCORE_MAX
/2;
64
}
65
66
static
int
xa_read_header
(
AVFormatContext
*s,
67
AVFormatParameters
*ap)
68
{
69
MaxisXADemuxContext
*xa = s->
priv_data
;
70
AVIOContext
*pb = s->
pb
;
71
AVStream
*st;
72
73
/*Set up the XA Audio Decoder*/
74
st =
avformat_new_stream
(s,
NULL
);
75
if
(!st)
76
return
AVERROR
(ENOMEM);
77
78
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
79
st->
codec
->
codec_id
=
CODEC_ID_ADPCM_EA_MAXIS_XA
;
80
avio_skip
(pb, 4);
/* Skip the XA ID */
81
xa->
out_size
=
avio_rl32
(pb);
82
avio_skip
(pb, 2);
/* Skip the tag */
83
st->
codec
->
channels
=
avio_rl16
(pb);
84
st->
codec
->
sample_rate
=
avio_rl32
(pb);
85
/* Value in file is average byte rate*/
86
st->
codec
->
bit_rate
=
avio_rl32
(pb) * 8;
87
st->
codec
->
block_align
=
avio_rl16
(pb);
88
st->
codec
->
bits_per_coded_sample
=
avio_rl16
(pb);
89
90
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
91
92
return
0;
93
}
94
95
static
int
xa_read_packet
(
AVFormatContext
*s,
96
AVPacket
*pkt)
97
{
98
MaxisXADemuxContext
*xa = s->
priv_data
;
99
AVStream
*st = s->
streams
[0];
100
AVIOContext
*pb = s->
pb
;
101
unsigned
int
packet_size;
102
int
ret;
103
104
if
(xa->
sent_bytes
> xa->
out_size
)
105
return
AVERROR
(EIO);
106
/* 1 byte header and 14 bytes worth of samples * number channels per block */
107
packet_size = 15*st->
codec
->
channels
;
108
109
ret =
av_get_packet
(pb, pkt, packet_size);
110
if
(ret < 0)
111
return
ret;
112
113
pkt->
stream_index
= st->
index
;
114
xa->
sent_bytes
+= packet_size;
115
pkt->
pts
= xa->
audio_frame_counter
;
116
/* 14 bytes Samples per channel with 2 samples per byte */
117
xa->
audio_frame_counter
+= 28 * st->
codec
->
channels
;
118
119
return
ret;
120
}
121
122
AVInputFormat
ff_xa_demuxer
= {
123
.
name
=
"xa"
,
124
.long_name =
NULL_IF_CONFIG_SMALL
(
"Maxis XA File Format"
),
125
.priv_data_size =
sizeof
(
MaxisXADemuxContext
),
126
.
read_probe
=
xa_probe
,
127
.
read_header
=
xa_read_header
,
128
.
read_packet
=
xa_read_packet
,
129
};