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