FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
tta.c
Go to the documentation of this file.
1
/*
2
* TTA demuxer
3
* Copyright (c) 2006 Alex Beregszaszi
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg 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
* FFmpeg 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 FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
libavcodec/get_bits.h
"
23
#include "
apetag.h
"
24
#include "
avformat.h
"
25
#include "
avio_internal.h
"
26
#include "
internal.h
"
27
#include "
id3v1.h
"
28
#include "
libavutil/crc.h
"
29
#include "
libavutil/dict.h
"
30
31
typedef
struct
{
32
int
totalframes
, currentframe;
33
int
frame_size
;
34
int
last_frame_size
;
35
}
TTAContext
;
36
37
static
unsigned
long
tta_check_crc
(
unsigned
long
checksum,
const
uint8_t
*
buf
,
38
unsigned
int
len
)
39
{
40
return
av_crc
(
av_crc_get_table
(
AV_CRC_32_IEEE_LE
), checksum, buf, len);
41
}
42
43
static
int
tta_probe
(
AVProbeData
*p)
44
{
45
if
(
AV_RL32
(&p->
buf
[0]) ==
MKTAG
(
'T'
,
'T'
,
'A'
,
'1'
) &&
46
(
AV_RL16
(&p->
buf
[4]) == 1 ||
AV_RL16
(&p->
buf
[4]) == 2) &&
47
AV_RL16
(&p->
buf
[6]) > 0 &&
48
AV_RL16
(&p->
buf
[8]) > 0 &&
49
AV_RL32
(&p->
buf
[10]) > 0)
50
return
AVPROBE_SCORE_EXTENSION
+ 30;
51
return
0;
52
}
53
54
static
int
tta_read_header
(
AVFormatContext
*
s
)
55
{
56
TTAContext
*
c
= s->
priv_data
;
57
AVStream
*st;
58
int
i, channels,
bps
, samplerate;
59
uint64_t framepos, start_offset;
60
uint32_t nb_samples, crc;
61
62
ff_id3v1_read
(s);
63
64
start_offset =
avio_tell
(s->
pb
);
65
ffio_init_checksum
(s->
pb
,
tta_check_crc
, UINT32_MAX);
66
if
(
avio_rl32
(s->
pb
) !=
AV_RL32
(
"TTA1"
))
67
return
AVERROR_INVALIDDATA
;
68
69
avio_skip
(s->
pb
, 2);
// FIXME: flags
70
channels =
avio_rl16
(s->
pb
);
71
bps =
avio_rl16
(s->
pb
);
72
samplerate =
avio_rl32
(s->
pb
);
73
if
(samplerate <= 0 || samplerate > 1000000){
74
av_log
(s,
AV_LOG_ERROR
,
"nonsense samplerate\n"
);
75
return
AVERROR_INVALIDDATA
;
76
}
77
78
nb_samples =
avio_rl32
(s->
pb
);
79
if
(!nb_samples) {
80
av_log
(s,
AV_LOG_ERROR
,
"invalid number of samples\n"
);
81
return
AVERROR_INVALIDDATA
;
82
}
83
84
crc =
ffio_get_checksum
(s->
pb
) ^ UINT32_MAX;
85
if
(crc !=
avio_rl32
(s->
pb
)) {
86
av_log
(s,
AV_LOG_ERROR
,
"Header CRC error\n"
);
87
return
AVERROR_INVALIDDATA
;
88
}
89
90
c->
frame_size
= samplerate * 256 / 245;
91
c->
last_frame_size
= nb_samples % c->
frame_size
;
92
if
(!c->
last_frame_size
)
93
c->
last_frame_size
= c->
frame_size
;
94
c->
totalframes
= nb_samples / c->
frame_size
+ (c->
last_frame_size
< c->
frame_size
);
95
c->
currentframe
= 0;
96
97
if
(c->
totalframes
>= UINT_MAX/
sizeof
(uint32_t) || c->
totalframes
<= 0){
98
av_log
(s,
AV_LOG_ERROR
,
"totalframes %d invalid\n"
, c->
totalframes
);
99
return
AVERROR_INVALIDDATA
;
100
}
101
102
st =
avformat_new_stream
(s, NULL);
103
if
(!st)
104
return
AVERROR
(ENOMEM);
105
106
avpriv_set_pts_info
(st, 64, 1, samplerate);
107
st->
start_time
= 0;
108
st->
duration
= nb_samples;
109
110
framepos =
avio_tell
(s->
pb
) + 4*c->
totalframes
+ 4;
111
112
if
(
ff_alloc_extradata
(st->
codec
,
avio_tell
(s->
pb
) - start_offset))
113
return
AVERROR
(ENOMEM);
114
115
avio_seek
(s->
pb
, start_offset, SEEK_SET);
116
avio_read
(s->
pb
, st->
codec
->
extradata
, st->
codec
->
extradata_size
);
117
118
ffio_init_checksum
(s->
pb
,
tta_check_crc
, UINT32_MAX);
119
for
(i = 0; i < c->
totalframes
; i++) {
120
uint32_t
size
=
avio_rl32
(s->
pb
);
121
av_add_index_entry
(st, framepos, i * c->
frame_size
, size, 0,
122
AVINDEX_KEYFRAME
);
123
framepos +=
size
;
124
}
125
crc =
ffio_get_checksum
(s->
pb
) ^ UINT32_MAX;
126
if
(crc !=
avio_rl32
(s->
pb
)) {
127
av_log
(s,
AV_LOG_ERROR
,
"Seek table CRC error\n"
);
128
return
AVERROR_INVALIDDATA
;
129
}
130
131
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
132
st->
codec
->
codec_id
=
AV_CODEC_ID_TTA
;
133
st->
codec
->
channels
= channels;
134
st->
codec
->
sample_rate
= samplerate;
135
st->
codec
->
bits_per_coded_sample
=
bps
;
136
137
if
(s->
pb
->
seekable
) {
138
int64_t pos =
avio_tell
(s->
pb
);
139
ff_ape_parse_tag
(s);
140
avio_seek
(s->
pb
, pos, SEEK_SET);
141
}
142
143
return
0;
144
}
145
146
static
int
tta_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
147
{
148
TTAContext
*
c
= s->
priv_data
;
149
AVStream
*st = s->
streams
[0];
150
int
size
,
ret
;
151
152
// FIXME!
153
if
(c->
currentframe
>= c->
totalframes
)
154
return
AVERROR_EOF
;
155
156
size = st->
index_entries
[c->
currentframe
].
size
;
157
158
ret =
av_get_packet
(s->
pb
, pkt, size);
159
pkt->
dts
= st->
index_entries
[c->
currentframe
++].
timestamp
;
160
pkt->
duration
= c->
currentframe
== c->
totalframes
? c->
last_frame_size
:
161
c->
frame_size
;
162
return
ret
;
163
}
164
165
static
int
tta_read_seek
(
AVFormatContext
*
s
,
int
stream_index, int64_t timestamp,
int
flags
)
166
{
167
TTAContext
*
c
= s->
priv_data
;
168
AVStream
*st = s->
streams
[stream_index];
169
int
index
=
av_index_search_timestamp
(st, timestamp, flags);
170
if
(index < 0)
171
return
-1;
172
if
(
avio_seek
(s->
pb
, st->
index_entries
[index].
pos
, SEEK_SET) < 0)
173
return
-1;
174
175
c->
currentframe
=
index
;
176
177
return
0;
178
}
179
180
AVInputFormat
ff_tta_demuxer
= {
181
.
name
=
"tta"
,
182
.long_name =
NULL_IF_CONFIG_SMALL
(
"TTA (True Audio)"
),
183
.priv_data_size =
sizeof
(
TTAContext
),
184
.
read_probe
=
tta_probe
,
185
.
read_header
=
tta_read_header
,
186
.
read_packet
=
tta_read_packet
,
187
.
read_seek
=
tta_read_seek
,
188
.extensions =
"tta"
,
189
};
Generated on Sun Mar 23 2014 23:50:03 for FFmpeg by
1.8.2