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
(!
avio_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 Fri Dec 5 2014 04:42:02 for FFmpeg by
1.8.2