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
memset(buffer + size - 3, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
89
90
ffio_init_checksum
(pb,
tak_check_crc
, 0xCE04B7U);
91
if
(
avio_read
(pb, buffer, size - 3) != size - 3) {
92
av_freep
(&buffer);
93
return
AVERROR
(EIO);
94
}
95
if
(
ffio_get_checksum
(s->
pb
) !=
avio_rb24
(pb)) {
96
av_log
(s,
AV_LOG_ERROR
,
"%d metadata block CRC error.\n"
, type);
97
if
(s->
error_recognition
&
AV_EF_EXPLODE
) {
98
av_freep
(&buffer);
99
return
AVERROR_INVALIDDATA
;
100
}
101
}
102
103
init_get_bits8
(&gb, buffer, size - 3);
104
break
;
105
case
TAK_METADATA_MD5
: {
106
uint8_t
md5[16];
107
int
i;
108
109
if
(size != 19)
110
return
AVERROR_INVALIDDATA
;
111
ffio_init_checksum
(pb,
tak_check_crc
, 0xCE04B7U);
112
avio_read
(pb, md5, 16);
113
if
(
ffio_get_checksum
(s->
pb
) !=
avio_rb24
(pb)) {
114
av_log
(s,
AV_LOG_ERROR
,
"MD5 metadata block CRC error.\n"
);
115
if
(s->
error_recognition
&
AV_EF_EXPLODE
)
116
return
AVERROR_INVALIDDATA
;
117
}
118
119
av_log
(s,
AV_LOG_VERBOSE
,
"MD5="
);
120
for
(i = 0; i < 16; i++)
121
av_log
(s,
AV_LOG_VERBOSE
,
"%02x"
, md5[i]);
122
av_log
(s,
AV_LOG_VERBOSE
,
"\n"
);
123
break
;
124
}
125
case
TAK_METADATA_END
: {
126
int64_t curpos =
avio_tell
(pb);
127
128
if
(pb->
seekable
) {
129
ff_ape_parse_tag
(s);
130
avio_seek
(pb, curpos, SEEK_SET);
131
}
132
133
tc->
data_end
+= curpos;
134
return
0;
135
}
136
default
:
137
ret =
avio_skip
(pb, size);
138
if
(ret < 0)
139
return
ret
;
140
}
141
142
if
(type ==
TAK_METADATA_STREAMINFO
) {
143
TAKStreamInfo
ti;
144
145
avpriv_tak_parse_streaminfo
(&gb, &ti);
146
if
(ti.
samples
> 0)
147
st->
duration
= ti.
samples
;
148
st->
codec
->
bits_per_coded_sample
= ti.
bps
;
149
if
(ti.
ch_layout
)
150
st->
codec
->
channel_layout
= ti.
ch_layout
;
151
st->
codec
->
sample_rate
= ti.
sample_rate
;
152
st->
codec
->
channels
= ti.
channels
;
153
st->
start_time
= 0;
154
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
155
st->
codec
->
extradata
=
buffer
;
156
st->
codec
->
extradata_size
= size - 3;
157
buffer = NULL;
158
}
else
if
(type ==
TAK_METADATA_LAST_FRAME
) {
159
if
(size != 11)
160
return
AVERROR_INVALIDDATA
;
161
tc->
mlast_frame
= 1;
162
tc->
data_end
=
get_bits64
(&gb,
TAK_LAST_FRAME_POS_BITS
) +
163
get_bits
(&gb,
TAK_LAST_FRAME_SIZE_BITS
);
164
av_freep
(&buffer);
165
}
else
if
(type ==
TAK_METADATA_ENCODER
) {
166
av_log
(s,
AV_LOG_VERBOSE
,
"encoder version: %0X\n"
,
167
get_bits_long
(&gb,
TAK_ENCODER_VERSION_BITS
));
168
av_freep
(&buffer);
169
}
170
}
171
172
return
AVERROR_EOF
;
173
}
174
175
static
int
raw_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
176
{
177
TAKDemuxContext
*
tc
= s->
priv_data
;
178
int
ret
;
179
180
if
(tc->
mlast_frame
) {
181
AVIOContext
*pb = s->
pb
;
182
int64_t
size
, left;
183
184
left = tc->
data_end
-
avio_tell
(pb);
185
size =
FFMIN
(left, 1024);
186
if
(size <= 0)
187
return
AVERROR_EOF
;
188
189
ret =
av_get_packet
(pb, pkt, size);
190
if
(ret < 0)
191
return
ret
;
192
193
pkt->
stream_index
= 0;
194
}
else
{
195
ret =
ff_raw_read_partial_packet
(s, pkt);
196
}
197
198
return
ret
;
199
}
200
201
AVInputFormat
ff_tak_demuxer
= {
202
.
name
=
"tak"
,
203
.long_name =
NULL_IF_CONFIG_SMALL
(
"raw TAK"
),
204
.priv_data_size =
sizeof
(
TAKDemuxContext
),
205
.
read_probe
=
tak_probe
,
206
.
read_header
=
tak_read_header
,
207
.
read_packet
=
raw_read_packet
,
208
.
flags
=
AVFMT_GENERIC_INDEX
,
209
.extensions =
"tak"
,
210
.raw_codec_id =
AV_CODEC_ID_TAK
,
211
};
Generated on Sun Mar 23 2014 23:50:03 for FFmpeg by
1.8.2