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