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 AUDIO_SAMPLING_RATE 44100
36
37
typedef
struct
MTVDemuxContext
{
38
39
unsigned
int
file_size
;
///< filesize, not always right
40
unsigned
int
segments
;
///< number of 512 byte segments
41
unsigned
int
audio_identifier
;
///< 'MP3' on all files I have seen
42
unsigned
int
audio_br
;
///< bitrate of audio channel (mp3)
43
unsigned
int
img_colorfmt
;
///< frame colorfmt rgb 565/555
44
unsigned
int
img_bpp
;
///< frame bits per pixel
45
unsigned
int
img_width
;
46
unsigned
int
img_height
;
47
unsigned
int
img_segment_size
;
///< size of image segment
48
unsigned
int
video_fps
;
49
unsigned
int
full_segment_size
;
50
51
}
MTVDemuxContext
;
52
53
static
int
mtv_probe
(
AVProbeData
*p)
54
{
55
/* Magic is 'AMV' */
56
if
(*p->
buf
!=
'A'
|| *(p->
buf
+ 1) !=
'M'
|| *(p->
buf
+ 2) !=
'V'
)
57
return
0;
58
59
/* Check for nonzero in bpp and (width|height) header fields */
60
if
(p->
buf_size
< 57 || !(p->
buf
[51] &&
AV_RL16
(&p->
buf
[52]) |
AV_RL16
(&p->
buf
[54])))
61
return
0;
62
63
/* If width or height are 0 then imagesize header field should not */
64
if
(!
AV_RL16
(&p->
buf
[52]) || !
AV_RL16
(&p->
buf
[54]))
65
{
66
if
(!!
AV_RL16
(&p->
buf
[56]))
67
return
AVPROBE_SCORE_EXTENSION
;
68
else
69
return
0;
70
}
71
72
if
(p->
buf
[51] != 16)
73
return
AVPROBE_SCORE_EXTENSION
/ 2;
// But we are going to assume 16bpp anyway ..
74
75
return
AVPROBE_SCORE_MAX
;
76
}
77
78
static
int
mtv_read_header
(
AVFormatContext
*
s
)
79
{
80
MTVDemuxContext
*mtv = s->
priv_data
;
81
AVIOContext
*pb = s->
pb
;
82
AVStream
*st;
83
unsigned
int
audio_subsegments;
84
85
avio_skip
(pb, 3);
86
mtv->
file_size
=
avio_rl32
(pb);
87
mtv->
segments
=
avio_rl32
(pb);
88
avio_skip
(pb, 32);
89
mtv->
audio_identifier
=
avio_rl24
(pb);
90
mtv->
audio_br
=
avio_rl16
(pb);
91
mtv->
img_colorfmt
=
avio_rl24
(pb);
92
mtv->
img_bpp
=
avio_r8
(pb);
93
mtv->
img_width
=
avio_rl16
(pb);
94
mtv->
img_height
=
avio_rl16
(pb);
95
mtv->
img_segment_size
=
avio_rl16
(pb);
96
97
/* Calculate width and height if missing from header */
98
99
if
(mtv->
img_bpp
>>3){
100
if
(!mtv->
img_width
&& mtv->
img_height
)
101
mtv->
img_width
=mtv->
img_segment_size
/ (mtv->
img_bpp
>>3)
102
/ mtv->
img_height
;
103
104
if
(!mtv->
img_height
&& mtv->
img_width
)
105
mtv->
img_height
=mtv->
img_segment_size
/ (mtv->
img_bpp
>>3)
106
/ mtv->
img_width
;
107
}
108
if
(!mtv->
img_height
|| !mtv->
img_width
|| !mtv->
img_segment_size
){
109
av_log
(s,
AV_LOG_ERROR
,
"width or height or segment_size is invalid and I cannot calculate them from other information\n"
);
110
return
AVERROR
(EINVAL);
111
}
112
113
avio_skip
(pb, 4);
114
audio_subsegments =
avio_rl16
(pb);
115
116
if
(audio_subsegments == 0) {
117
avpriv_request_sample
(s,
"MTV files without audio"
);
118
return
AVERROR_PATCHWELCOME
;
119
}
120
121
mtv->
full_segment_size
=
122
audio_subsegments * (
MTV_AUDIO_PADDING_SIZE
+
MTV_ASUBCHUNK_DATA_SIZE
) +
123
mtv->
img_segment_size
;
124
mtv->
video_fps
= (mtv->
audio_br
/ 4) / audio_subsegments;
125
126
// FIXME Add sanity check here
127
128
// all systems go! init decoders
129
130
// video - raw rgb565
131
132
st =
avformat_new_stream
(s, NULL);
133
if
(!st)
134
return
AVERROR
(ENOMEM);
135
136
avpriv_set_pts_info
(st, 64, 1, mtv->
video_fps
);
137
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
138
st->
codec
->
codec_id
=
AV_CODEC_ID_RAWVIDEO
;
139
st->
codec
->
pix_fmt
=
AV_PIX_FMT_RGB565BE
;
140
st->
codec
->
width
= mtv->
img_width
;
141
st->
codec
->
height
= mtv->
img_height
;
142
st->
codec
->
sample_rate
= mtv->
video_fps
;
143
st->
codec
->
extradata
=
av_strdup
(
"BottomUp"
);
144
st->
codec
->
extradata_size
= 9;
145
146
// audio - mp3
147
148
st =
avformat_new_stream
(s, NULL);
149
if
(!st)
150
return
AVERROR
(ENOMEM);
151
152
avpriv_set_pts_info
(st, 64, 1,
AUDIO_SAMPLING_RATE
);
153
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
154
st->
codec
->
codec_id
=
AV_CODEC_ID_MP3
;
155
st->
codec
->
bit_rate
= mtv->
audio_br
;
156
st->
need_parsing
=
AVSTREAM_PARSE_FULL
;
157
158
// Jump over header
159
160
if
(
avio_seek
(pb,
MTV_HEADER_SIZE
, SEEK_SET) !=
MTV_HEADER_SIZE
)
161
return
AVERROR
(EIO);
162
163
return
0;
164
165
}
166
167
static
int
mtv_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
168
{
169
MTVDemuxContext
*mtv = s->
priv_data
;
170
AVIOContext
*pb = s->
pb
;
171
int
ret
;
172
173
if
((
avio_tell
(pb) - s->
data_offset
+ mtv->
img_segment_size
) % mtv->
full_segment_size
)
174
{
175
avio_skip
(pb,
MTV_AUDIO_PADDING_SIZE
);
176
177
ret =
av_get_packet
(pb, pkt,
MTV_ASUBCHUNK_DATA_SIZE
);
178
if
(ret < 0)
179
return
ret
;
180
181
pkt->
pos
-=
MTV_AUDIO_PADDING_SIZE
;
182
pkt->
stream_index
= 1;
183
184
}
else
185
{
186
ret =
av_get_packet
(pb, pkt, mtv->
img_segment_size
);
187
if
(ret < 0)
188
return
ret
;
189
190
pkt->
stream_index
= 0;
191
}
192
193
return
ret
;
194
}
195
196
AVInputFormat
ff_mtv_demuxer
= {
197
.
name
=
"mtv"
,
198
.long_name =
NULL_IF_CONFIG_SMALL
(
"MTV"
),
199
.priv_data_size =
sizeof
(
MTVDemuxContext
),
200
.
read_probe
=
mtv_probe
,
201
.
read_header
=
mtv_read_header
,
202
.
read_packet
=
mtv_read_packet
,
203
};
Generated on Sat Jan 25 2014 19:52:03 for FFmpeg by
1.8.2