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
mm.c
Go to the documentation of this file.
1
/*
2
* American Laser Games MM Format Demuxer
3
* Copyright (c) 2006 Peter Ross
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
* American Laser Games MM Format Demuxer
25
* by Peter Ross (pross@xvid.org)
26
*
27
* The MM format was used by IBM-PC ports of ALG's "arcade shooter" games,
28
* including Mad Dog McCree and Crime Patrol.
29
*
30
* Technical details here:
31
* http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM
32
*/
33
34
#include "
libavutil/channel_layout.h
"
35
#include "
libavutil/intreadwrite.h
"
36
#include "
avformat.h
"
37
#include "
internal.h
"
38
39
#define MM_PREAMBLE_SIZE 6
40
41
#define MM_TYPE_HEADER 0x0
42
#define MM_TYPE_INTER 0x5
43
#define MM_TYPE_INTRA 0x8
44
#define MM_TYPE_INTRA_HH 0xc
45
#define MM_TYPE_INTER_HH 0xd
46
#define MM_TYPE_INTRA_HHV 0xe
47
#define MM_TYPE_INTER_HHV 0xf
48
#define MM_TYPE_AUDIO 0x15
49
#define MM_TYPE_PALETTE 0x31
50
51
#define MM_HEADER_LEN_V 0x16
/* video only */
52
#define MM_HEADER_LEN_AV 0x18
/* video + audio */
53
54
#define MM_PALETTE_COUNT 128
55
#define MM_PALETTE_SIZE (MM_PALETTE_COUNT*3)
56
57
typedef
struct
{
58
unsigned
int
audio_pts,
video_pts
;
59
}
MmDemuxContext
;
60
61
static
int
probe
(
AVProbeData
*p)
62
{
63
int
len
, type, fps, w, h;
64
if
(p->
buf_size
<
MM_HEADER_LEN_AV
+
MM_PREAMBLE_SIZE
)
65
return
0;
66
/* the first chunk is always the header */
67
if
(
AV_RL16
(&p->
buf
[0]) !=
MM_TYPE_HEADER
)
68
return
0;
69
len =
AV_RL32
(&p->
buf
[2]);
70
if
(len !=
MM_HEADER_LEN_V
&& len !=
MM_HEADER_LEN_AV
)
71
return
0;
72
fps =
AV_RL16
(&p->
buf
[8]);
73
w =
AV_RL16
(&p->
buf
[12]);
74
h =
AV_RL16
(&p->
buf
[14]);
75
if
(!fps || fps > 60 || !w || w > 2048 || !h || h > 2048)
76
return
0;
77
type =
AV_RL16
(&p->
buf
[len]);
78
if
(!type || type > 0x31)
79
return
0;
80
81
/* only return half certainty since this check is a bit sketchy */
82
return
AVPROBE_SCORE_MAX
/ 2;
83
}
84
85
static
int
read_header
(
AVFormatContext
*s)
86
{
87
MmDemuxContext
*mm = s->
priv_data
;
88
AVIOContext
*pb = s->
pb
;
89
AVStream
*st;
90
91
unsigned
int
type, length;
92
unsigned
int
frame_rate,
width
,
height
;
93
94
type =
avio_rl16
(pb);
95
length =
avio_rl32
(pb);
96
97
if
(type !=
MM_TYPE_HEADER
)
98
return
AVERROR_INVALIDDATA
;
99
100
/* read header */
101
avio_rl16
(pb);
/* total number of chunks */
102
frame_rate =
avio_rl16
(pb);
103
avio_rl16
(pb);
/* ibm-pc video bios mode */
104
width =
avio_rl16
(pb);
105
height =
avio_rl16
(pb);
106
avio_skip
(pb, length - 10);
/* unknown data */
107
108
/* video stream */
109
st =
avformat_new_stream
(s,
NULL
);
110
if
(!st)
111
return
AVERROR
(ENOMEM);
112
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
113
st->
codec
->
codec_id
=
AV_CODEC_ID_MMVIDEO
;
114
st->
codec
->
codec_tag
= 0;
/* no fourcc */
115
st->
codec
->
width
=
width
;
116
st->
codec
->
height
=
height
;
117
avpriv_set_pts_info
(st, 64, 1, frame_rate);
118
119
/* audio stream */
120
if
(length ==
MM_HEADER_LEN_AV
) {
121
st =
avformat_new_stream
(s,
NULL
);
122
if
(!st)
123
return
AVERROR
(ENOMEM);
124
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
125
st->
codec
->
codec_tag
= 0;
/* no fourcc */
126
st->
codec
->
codec_id
=
AV_CODEC_ID_PCM_U8
;
127
st->
codec
->
channels
= 1;
128
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
129
st->
codec
->
sample_rate
= 8000;
130
avpriv_set_pts_info
(st, 64, 1, 8000);
/* 8000 hz */
131
}
132
133
mm->
audio_pts
= 0;
134
mm->
video_pts
= 0;
135
return
0;
136
}
137
138
static
int
read_packet
(
AVFormatContext
*s,
139
AVPacket
*
pkt
)
140
{
141
MmDemuxContext
*mm = s->
priv_data
;
142
AVIOContext
*pb = s->
pb
;
143
unsigned
char
preamble[
MM_PREAMBLE_SIZE
];
144
unsigned
int
type, length;
145
146
while
(1) {
147
148
if
(
avio_read
(pb, preamble,
MM_PREAMBLE_SIZE
) !=
MM_PREAMBLE_SIZE
) {
149
return
AVERROR
(EIO);
150
}
151
152
type =
AV_RL16
(&preamble[0]);
153
length =
AV_RL16
(&preamble[2]);
154
155
switch
(type) {
156
case
MM_TYPE_PALETTE
:
157
case
MM_TYPE_INTER
:
158
case
MM_TYPE_INTRA
:
159
case
MM_TYPE_INTRA_HH
:
160
case
MM_TYPE_INTER_HH
:
161
case
MM_TYPE_INTRA_HHV
:
162
case
MM_TYPE_INTER_HHV
:
163
/* output preamble + data */
164
if
(
av_new_packet
(pkt, length +
MM_PREAMBLE_SIZE
))
165
return
AVERROR
(ENOMEM);
166
memcpy(pkt->
data
, preamble,
MM_PREAMBLE_SIZE
);
167
if
(
avio_read
(pb, pkt->
data
+
MM_PREAMBLE_SIZE
, length) != length)
168
return
AVERROR
(EIO);
169
pkt->
size
= length +
MM_PREAMBLE_SIZE
;
170
pkt->
stream_index
= 0;
171
pkt->
pts
= mm->
video_pts
;
172
if
(type!=
MM_TYPE_PALETTE
)
173
mm->
video_pts
++;
174
return
0;
175
176
case
MM_TYPE_AUDIO
:
177
if
(
av_get_packet
(s->
pb
, pkt, length)<0)
178
return
AVERROR
(ENOMEM);
179
pkt->
stream_index
= 1;
180
pkt->
pts
= mm->
audio_pts
++;
181
return
0;
182
183
default
:
184
av_log
(s,
AV_LOG_INFO
,
"unknown chunk type 0x%x\n"
, type);
185
avio_skip
(pb, length);
186
}
187
}
188
}
189
190
AVInputFormat
ff_mm_demuxer
= {
191
.
name
=
"mm"
,
192
.long_name =
NULL_IF_CONFIG_SMALL
(
"American Laser Games MM"
),
193
.priv_data_size =
sizeof
(
MmDemuxContext
),
194
.
read_probe
=
probe
,
195
.
read_header
=
read_header
,
196
.
read_packet
=
read_packet
,
197
};
Generated on Sat May 25 2013 03:58:47 for FFmpeg by
1.8.2