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);
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
> 0 && mtv->
img_bpp
>= 8)
132
mtv->
img_width
=mtv->
img_segment_size
/ (mtv->
img_bpp
>>3)
133
/ mtv->
img_height
;
134
135
if
(!mtv->
img_height
&& mtv->
img_width
> 0 && mtv->
img_bpp
>= 8)
136
mtv->
img_height
=mtv->
img_segment_size
/ (mtv->
img_bpp
>>3)
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_INVALIDDATA
;
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->
internal
->
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 Mar 8 2015 02:35:11 for FFmpeg by
1.8.2