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
takdec.c
Go to the documentation of this file.
1
/*
2
* Raw TAK demuxer
3
* Copyright (c) 2012 Paul B Mahol
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 "
libavutil/crc.h
"
23
#include "
libavcodec/tak.h
"
24
#include "
avformat.h
"
25
#include "
avio_internal.h
"
26
#include "
internal.h
"
27
#include "
rawdec.h
"
28
#include "
apetag.h
"
29
30
typedef
struct
TAKDemuxContext
{
31
int
mlast_frame
;
32
int64_t
data_end
;
33
}
TAKDemuxContext
;
34
35
static
int
tak_probe
(
AVProbeData
*p)
36
{
37
if
(!memcmp(p->
buf
,
"tBaK"
, 4))
38
return
AVPROBE_SCORE_EXTENSION
;
39
return
0;
40
}
41
42
static
unsigned
long
tak_check_crc
(
unsigned
long
checksum,
const
uint8_t
*
buf
,
43
unsigned
int
len
)
44
{
45
return
av_crc
(
av_crc_get_table
(
AV_CRC_24_IEEE
), checksum, buf, len);
46
}
47
48
static
int
tak_read_header
(
AVFormatContext
*
s
)
49
{
50
TAKDemuxContext
*
tc
= s->
priv_data
;
51
AVIOContext
*pb = s->
pb
;
52
GetBitContext
gb;
53
AVStream
*st;
54
uint8_t
*
buffer
= NULL;
55
int
ret
;
56
57
st =
avformat_new_stream
(s, 0);
58
if
(!st)
59
return
AVERROR
(ENOMEM);
60
61
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
62
st->
codec
->
codec_id
=
AV_CODEC_ID_TAK
;
63
st->
need_parsing
=
AVSTREAM_PARSE_FULL_RAW
;
64
65
tc->
mlast_frame
= 0;
66
if
(
avio_rl32
(pb) !=
MKTAG
(
't'
,
'B'
,
'a'
,
'K'
)) {
67
avio_seek
(pb, -4, SEEK_CUR);
68
return
0;
69
}
70
71
while
(!
url_feof
(pb)) {
72
enum
TAKMetaDataType
type
;
73
int
size
;
74
75
type =
avio_r8
(pb) & 0x7f;
76
size =
avio_rl24
(pb);
77
78
switch
(type) {
79
case
TAK_METADATA_STREAMINFO
:
80
case
TAK_METADATA_LAST_FRAME
:
81
case
TAK_METADATA_ENCODER
:
82
if
(size <= 3)
83
return
AVERROR_INVALIDDATA
;
84
85
buffer =
av_malloc
(size - 3 +
FF_INPUT_BUFFER_PADDING_SIZE
);
86
if
(!buffer)
87
return
AVERROR
(ENOMEM);
88
89
ffio_init_checksum
(pb,
tak_check_crc
, 0xCE04B7U);
90
if
(
avio_read
(pb, buffer, size - 3) != size - 3) {
91
av_freep
(&buffer);
92
return
AVERROR
(EIO);
93
}
94
if
(
ffio_get_checksum
(s->
pb
) !=
avio_rb24
(pb)) {
95
av_log
(s,
AV_LOG_ERROR
,
"%d metadata block CRC error.\n"
, type);
96
if
(s->
error_recognition
&
AV_EF_EXPLODE
) {
97
av_freep
(&buffer);
98
return
AVERROR_INVALIDDATA
;
99
}
100
}
101
102
init_get_bits8
(&gb, buffer, size - 3);
103
break
;
104
case
TAK_METADATA_MD5
: {
105
uint8_t
md5[16];
106
int
i;
107
108
if
(size != 19)
109
return
AVERROR_INVALIDDATA
;
110
ffio_init_checksum
(pb,
tak_check_crc
, 0xCE04B7U);
111
avio_read
(pb, md5, 16);
112
if
(
ffio_get_checksum
(s->
pb
) !=
avio_rb24
(pb)) {
113
av_log
(s,
AV_LOG_ERROR
,
"MD5 metadata block CRC error.\n"
);
114
if
(s->
error_recognition
&
AV_EF_EXPLODE
)
115
return
AVERROR_INVALIDDATA
;
116
}
117
118
av_log
(s,
AV_LOG_VERBOSE
,
"MD5="
);
119
for
(i = 0; i < 16; i++)
120
av_log
(s,
AV_LOG_VERBOSE
,
"%02x"
, md5[i]);
121
av_log
(s,
AV_LOG_VERBOSE
,
"\n"
);
122
break
;
123
}
124
case
TAK_METADATA_END
: {
125
int64_t curpos =
avio_tell
(pb);
126
127
if
(pb->
seekable
) {
128
ff_ape_parse_tag
(s);
129
avio_seek
(pb, curpos, SEEK_SET);
130
}
131
132
tc->
data_end
+= curpos;
133
return
0;
134
}
135
default
:
136
ret =
avio_skip
(pb, size);
137
if
(ret < 0)
138
return
ret
;
139
}
140
141
if
(type ==
TAK_METADATA_STREAMINFO
) {
142
TAKStreamInfo
ti;
143
144
avpriv_tak_parse_streaminfo
(&gb, &ti);
145
if
(ti.
samples
> 0)
146
st->
duration
= ti.
samples
;
147
st->
codec
->
bits_per_coded_sample
= ti.
bps
;
148
if
(ti.
ch_layout
)
149
st->
codec
->
channel_layout
= ti.
ch_layout
;
150
st->
codec
->
sample_rate
= ti.
sample_rate
;
151
st->
codec
->
channels
= ti.
channels
;
152
st->
start_time
= 0;
153
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
154
st->
codec
->
extradata
=
buffer
;
155
st->
codec
->
extradata_size
= size - 3;
156
buffer = NULL;
157
}
else
if
(type ==
TAK_METADATA_LAST_FRAME
) {
158
if
(size != 11)
159
return
AVERROR_INVALIDDATA
;
160
tc->
mlast_frame
= 1;
161
tc->
data_end
=
get_bits64
(&gb,
TAK_LAST_FRAME_POS_BITS
) +
162
get_bits
(&gb,
TAK_LAST_FRAME_SIZE_BITS
);
163
av_freep
(&buffer);
164
}
else
if
(type ==
TAK_METADATA_ENCODER
) {
165
av_log
(s,
AV_LOG_VERBOSE
,
"encoder version: %0X\n"
,
166
get_bits_long
(&gb,
TAK_ENCODER_VERSION_BITS
));
167
av_freep
(&buffer);
168
}
169
}
170
171
return
AVERROR_EOF
;
172
}
173
174
static
int
raw_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
175
{
176
TAKDemuxContext
*
tc
= s->
priv_data
;
177
int
ret
;
178
179
if
(tc->
mlast_frame
) {
180
AVIOContext
*pb = s->
pb
;
181
int64_t
size
, left;
182
183
left = tc->
data_end
-
avio_tell
(pb);
184
size =
FFMIN
(left, 1024);
185
if
(size <= 0)
186
return
AVERROR_EOF
;
187
188
ret =
av_get_packet
(pb, pkt, size);
189
if
(ret < 0)
190
return
ret
;
191
192
pkt->
stream_index
= 0;
193
}
else
{
194
ret =
ff_raw_read_partial_packet
(s, pkt);
195
}
196
197
return
ret
;
198
}
199
200
AVInputFormat
ff_tak_demuxer
= {
201
.
name
=
"tak"
,
202
.long_name =
NULL_IF_CONFIG_SMALL
(
"raw TAK"
),
203
.priv_data_size =
sizeof
(
TAKDemuxContext
),
204
.
read_probe
=
tak_probe
,
205
.
read_header
=
tak_read_header
,
206
.
read_packet
=
raw_read_packet
,
207
.
flags
=
AVFMT_GENERIC_INDEX
,
208
.extensions =
"tak"
,
209
.raw_codec_id =
AV_CODEC_ID_TAK
,
210
};
Generated on Sat Jan 25 2014 19:51:55 for FFmpeg by
1.8.2