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
mtv.c
Go to the documentation of this file.
1
/*
2
* mtv demuxer
3
* Copyright (c) 2006 Reynaldo H. Verdejo Pinochet
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
/**
23
* @file
24
* MTV demuxer.
25
*/
26
27
#include "
libavutil/bswap.h
"
28
#include "
libavutil/intreadwrite.h
"
29
#include "
avformat.h
"
30
#include "
internal.h
"
31
32
#define MTV_ASUBCHUNK_DATA_SIZE 500
33
#define MTV_HEADER_SIZE 512
34
#define MTV_AUDIO_PADDING_SIZE 12
35
#define MTV_IMAGE_DEFAULT_BPP 16
36
#define MTV_AUDIO_SAMPLING_RATE 44100
37
38
typedef
struct
MTVDemuxContext
{
39
40
unsigned
int
file_size
;
///< filesize, not always right
41
unsigned
int
segments
;
///< number of 512 byte segments
42
unsigned
int
audio_identifier
;
///< 'MP3' on all files I have seen
43
unsigned
int
audio_br
;
///< bitrate of audio channel (mp3)
44
unsigned
int
img_colorfmt
;
///< frame colorfmt rgb 565/555
45
unsigned
int
img_bpp
;
///< frame bits per pixel
46
unsigned
int
img_width
;
47
unsigned
int
img_height
;
48
unsigned
int
img_segment_size
;
///< size of image segment
49
unsigned
int
video_fps
;
50
unsigned
int
full_segment_size
;
51
52
}
MTVDemuxContext
;
53
54
static
int
mtv_probe
(
AVProbeData
*p)
55
{
56
/* we need at least 57 bytes from the header
57
* to try parsing all required fields
58
*/
59
if
(p->
buf_size
< 57)
60
return
0;
61
62
/* Magic is 'AMV' */
63
if
(*p->
buf
!=
'A'
|| *(p->
buf
+ 1) !=
'M'
|| *(p->
buf
+ 2) !=
'V'
)
64
return
0;
65
66
/* Audio magic is always MP3 */
67
if
(p->
buf
[43] !=
'M'
|| p->
buf
[44] !=
'P'
|| p->
buf
[45] !=
'3'
)
68
return
0;
69
70
/* Check for nonzero in bpp and (width|height) header fields */
71
if
(!(p->
buf
[51] &&
AV_RL16
(&p->
buf
[52]) |
AV_RL16
(&p->
buf
[54])))
72
return
0;
73
74
/* If width or height are 0 then imagesize header field should not */
75
if
(!
AV_RL16
(&p->
buf
[52]) || !
AV_RL16
(&p->
buf
[54]))
76
{
77
if
(!!
AV_RL16
(&p->
buf
[56]))
78
return
AVPROBE_SCORE_EXTENSION
;
79
else
80
return
0;
81
}
82
83
/* Image bpp is not an absolutely required
84
* field as we latter claim it should be 16
85
* no matter what. All samples in the wild
86
* are RGB565/555.
87
*/
88
if
(p->
buf
[51] !=
MTV_IMAGE_DEFAULT_BPP
)
89
return
AVPROBE_SCORE_EXTENSION
/ 2;
90
91
/* We had enough data to parse header values
92
* but we expect to be able to get 512 bytes
93
* of header to be sure.
94
*/
95
if
(p->
buf_size
<
MTV_HEADER_SIZE
)
96
return
AVPROBE_SCORE_EXTENSION
;
97
98
return
AVPROBE_SCORE_MAX
;
99
}
100
101
static
int
mtv_read_header
(
AVFormatContext
*
s
)
102
{
103
MTVDemuxContext
*mtv = s->
priv_data
;
104
AVIOContext
*pb = s->
pb
;
105
AVStream
*st;
106
unsigned
int
audio_subsegments;
107
108
avio_skip
(pb, 3);
109
mtv->
file_size
=
avio_rl32
(pb);
110
mtv->
segments
=
avio_rl32
(pb);
111
avio_skip
(pb, 32);
112
mtv->
audio_identifier
=
avio_rl24
(pb);
113
mtv->
audio_br
=
avio_rl16
(pb);
114
mtv->
img_colorfmt
=
avio_rl24
(pb);
115
mtv->
img_bpp
=
avio_r8
(pb)>>3;
116
mtv->
img_width
=
avio_rl16
(pb);
117
mtv->
img_height
=
avio_rl16
(pb);
118
mtv->
img_segment_size
=
avio_rl16
(pb);
119
120
/* Assume 16bpp even if claimed otherwise.
121
* We know its going to be RGBG565/555 anyway
122
*/
123
if
(mtv->
img_bpp
!=
MTV_IMAGE_DEFAULT_BPP
) {
124
av_log
(s,
AV_LOG_WARNING
,
"Header claims %dbpp (!= 16). Ignoring\n"
,
125
mtv->
img_bpp
);
126
mtv->
img_bpp
=
MTV_IMAGE_DEFAULT_BPP
;
127
}
128
129
/* Calculate width and height if missing from header */
130
131
if
(!mtv->
img_width
&& mtv->
img_height
)
132
mtv->
img_width
=mtv->
img_segment_size
/ (mtv->
img_bpp
)
133
/ mtv->
img_height
;
134
135
if
(!mtv->
img_height
&& mtv->
img_width
)
136
mtv->
img_height
=mtv->
img_segment_size
/ (mtv->
img_bpp
)
137
/ mtv->
img_width
;
138
139
if
(!mtv->
img_height
|| !mtv->
img_width
|| !mtv->
img_segment_size
){
140
av_log
(s,
AV_LOG_ERROR
,
"width or height or segment_size is invalid and I cannot calculate them from other information\n"
);
141
return
AVERROR
(EINVAL);
142
}
143
144
avio_skip
(pb, 4);
145
audio_subsegments =
avio_rl16
(pb);
146
147
if
(audio_subsegments == 0) {
148
avpriv_request_sample
(s,
"MTV files without audio"
);
149
return
AVERROR_PATCHWELCOME
;
150
}
151
152
mtv->
full_segment_size
=
153
audio_subsegments * (
MTV_AUDIO_PADDING_SIZE
+
MTV_ASUBCHUNK_DATA_SIZE
) +
154
mtv->
img_segment_size
;
155
mtv->
video_fps
= (mtv->
audio_br
/ 4) / audio_subsegments;
156
157
// FIXME Add sanity check here
158
159
// all systems go! init decoders
160
161
// video - raw rgb565
162
163
st =
avformat_new_stream
(s, NULL);
164
if
(!st)
165
return
AVERROR
(ENOMEM);
166
167
avpriv_set_pts_info
(st, 64, 1, mtv->
video_fps
);
168
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
169
st->
codec
->
codec_id
=
AV_CODEC_ID_RAWVIDEO
;
170
st->
codec
->
pix_fmt
=
AV_PIX_FMT_RGB565BE
;
171
st->
codec
->
width
= mtv->
img_width
;
172
st->
codec
->
height
= mtv->
img_height
;
173
st->
codec
->
extradata
=
av_strdup
(
"BottomUp"
);
174
st->
codec
->
extradata_size
= 9;
175
176
// audio - mp3
177
178
st =
avformat_new_stream
(s, NULL);
179
if
(!st)
180
return
AVERROR
(ENOMEM);
181
182
avpriv_set_pts_info
(st, 64, 1,
MTV_AUDIO_SAMPLING_RATE
);
183
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
184
st->
codec
->
codec_id
=
AV_CODEC_ID_MP3
;
185
st->
codec
->
bit_rate
= mtv->
audio_br
;
186
st->
need_parsing
=
AVSTREAM_PARSE_FULL
;
187
188
// Jump over header
189
190
if
(
avio_seek
(pb,
MTV_HEADER_SIZE
, SEEK_SET) !=
MTV_HEADER_SIZE
)
191
return
AVERROR
(EIO);
192
193
return
0;
194
195
}
196
197
static
int
mtv_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
198
{
199
MTVDemuxContext
*mtv = s->
priv_data
;
200
AVIOContext
*pb = s->
pb
;
201
int
ret
;
202
203
if
((
avio_tell
(pb) - s->
data_offset
+ mtv->
img_segment_size
) % mtv->
full_segment_size
)
204
{
205
avio_skip
(pb,
MTV_AUDIO_PADDING_SIZE
);
206
207
ret =
av_get_packet
(pb, pkt,
MTV_ASUBCHUNK_DATA_SIZE
);
208
if
(ret < 0)
209
return
ret
;
210
211
pkt->
pos
-=
MTV_AUDIO_PADDING_SIZE
;
212
pkt->
stream_index
= 1;
213
214
}
else
215
{
216
ret =
av_get_packet
(pb, pkt, mtv->
img_segment_size
);
217
if
(ret < 0)
218
return
ret
;
219
220
pkt->
stream_index
= 0;
221
}
222
223
return
ret
;
224
}
225
226
AVInputFormat
ff_mtv_demuxer
= {
227
.
name
=
"mtv"
,
228
.long_name =
NULL_IF_CONFIG_SMALL
(
"MTV"
),
229
.priv_data_size =
sizeof
(
MTVDemuxContext
),
230
.
read_probe
=
mtv_probe
,
231
.
read_header
=
mtv_read_header
,
232
.
read_packet
=
mtv_read_packet
,
233
};
Generated on Sun Jul 20 2014 23:06:04 for FFmpeg by
1.8.2