Originally committed as revision 4999 to svn://svn.ffmpeg.org/ffmpeg/trunk
Mike Melanson authored on 2006/02/12 15:49:40... | ... |
@@ -698,6 +698,8 @@ library: |
698 | 698 |
@item Nullsoft Video (NSV) format @tab @tab X |
699 | 699 |
@item ADTS AAC audio @tab X @tab X |
700 | 700 |
@item Creative VOC @tab X @tab X @tab Created for the Sound Blaster Pro. |
701 |
+@item American Laser Games MM @tab @tab X |
|
702 |
+@tab Multimedia format used in games like Mad Dog McCree |
|
701 | 703 |
@end multitable |
702 | 704 |
|
703 | 705 |
@code{X} means that encoding (resp. decoding) is supported. |
... | ... |
@@ -788,6 +790,7 @@ following image formats are supported: |
788 | 788 |
@item Autodesk Animator Studio Codec @tab @tab X @tab fourcc: AASC |
789 | 789 |
@item Fraps FPS1 @tab @tab X @tab |
790 | 790 |
@item CamStudio @tab @tab X @tab fourcc: CSCD |
791 |
+@item American Laser Games Video @tab @tab X @tab Used in games like Mad Dog McCree |
|
791 | 792 |
@end multitable |
792 | 793 |
|
793 | 794 |
@code{X} means that encoding (resp. decoding) is supported. |
... | ... |
@@ -539,6 +539,10 @@ void avcodec_register_all(void) |
539 | 539 |
register_avcodec(&bmp_decoder); |
540 | 540 |
#endif |
541 | 541 |
|
542 |
+#if CONFIG_MMVIDEO_DECODER |
|
543 |
+ register_avcodec(&mmvideo_decoder); |
|
544 |
+#endif //CONFIG_MMVIDEO_DECODER |
|
545 |
+ |
|
542 | 546 |
/* pcm codecs */ |
543 | 547 |
#if defined (CONFIG_ENCODERS) && defined (CONFIG_DECODERS) |
544 | 548 |
#define PCM_CODEC(id, name) \ |
... | ... |
@@ -115,6 +115,7 @@ enum CodecID { |
115 | 115 |
CODEC_ID_TRUEMOTION2, |
116 | 116 |
CODEC_ID_BMP, |
117 | 117 |
CODEC_ID_CSCD, |
118 |
+ CODEC_ID_MMVIDEO, |
|
118 | 119 |
|
119 | 120 |
/* various pcm "codecs" */ |
120 | 121 |
CODEC_ID_PCM_S16LE= 0x10000, |
... | ... |
@@ -2226,6 +2227,7 @@ extern AVCodec fraps_decoder; |
2226 | 2226 |
extern AVCodec libgsm_encoder; |
2227 | 2227 |
extern AVCodec libgsm_decoder; |
2228 | 2228 |
extern AVCodec bmp_decoder; |
2229 |
+extern AVCodec mmvideo_decoder; |
|
2229 | 2230 |
|
2230 | 2231 |
/* pcm codecs */ |
2231 | 2232 |
#define PCM_CODEC(id, name) \ |
2232 | 2233 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,204 @@ |
0 |
+/* |
|
1 |
+ * American Laser Games MM Video Decoder |
|
2 |
+ * Copyright (c) 2006 Peter Ross |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License as published by the Free Software Foundation; either |
|
7 |
+ * version 2 of the License, or (at your option) any later version. |
|
8 |
+ * |
|
9 |
+ * This library is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 |
+ * Lesser General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU Lesser General Public |
|
15 |
+ * License along with this library; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+/** |
|
20 |
+ * @file mm.c |
|
21 |
+ * American Laser Games MM Video Decoder |
|
22 |
+ * by Peter Ross (suxen_drol at hotmail dot com) |
|
23 |
+ * |
|
24 |
+ * The MM format was used by IBM-PC ports of ALG's "arcade shooter" games, |
|
25 |
+ * including Mad Dog McCree and Crime Patrol. |
|
26 |
+ * |
|
27 |
+ * Technical details here: |
|
28 |
+ * http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+#include "avcodec.h" |
|
32 |
+ |
|
33 |
+#define MM_PREAMBLE_SIZE 6 |
|
34 |
+ |
|
35 |
+#define MM_TYPE_INTER 0x5 |
|
36 |
+#define MM_TYPE_INTRA 0x8 |
|
37 |
+#define MM_TYPE_INTRA_HH 0xc |
|
38 |
+#define MM_TYPE_INTER_HH 0xd |
|
39 |
+#define MM_TYPE_INTRA_HHV 0xe |
|
40 |
+#define MM_TYPE_INTER_HHV 0xf |
|
41 |
+ |
|
42 |
+typedef struct MmContext { |
|
43 |
+ AVCodecContext *avctx; |
|
44 |
+ AVFrame frame; |
|
45 |
+} MmContext; |
|
46 |
+ |
|
47 |
+static int mm_decode_init(AVCodecContext *avctx) |
|
48 |
+{ |
|
49 |
+ MmContext *s = avctx->priv_data; |
|
50 |
+ |
|
51 |
+ s->avctx = avctx; |
|
52 |
+ |
|
53 |
+ if (s->avctx->palctrl == NULL) { |
|
54 |
+ av_log(avctx, AV_LOG_ERROR, "mmvideo: palette expected.\n"); |
|
55 |
+ return -1; |
|
56 |
+ } |
|
57 |
+ |
|
58 |
+ avctx->pix_fmt = PIX_FMT_PAL8; |
|
59 |
+ avctx->has_b_frames = 0; |
|
60 |
+ |
|
61 |
+ if (avcodec_check_dimensions(avctx, avctx->width, avctx->height)) |
|
62 |
+ return -1; |
|
63 |
+ |
|
64 |
+ s->frame.reference = 1; |
|
65 |
+ if (avctx->get_buffer(avctx, &s->frame)) { |
|
66 |
+ av_log(s->avctx, AV_LOG_ERROR, "mmvideo: get_buffer() failed\n"); |
|
67 |
+ return -1; |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ return 0; |
|
71 |
+} |
|
72 |
+ |
|
73 |
+static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) |
|
74 |
+{ |
|
75 |
+ int i, x, y; |
|
76 |
+ i=0; x=0; y=0; |
|
77 |
+ |
|
78 |
+ while(i<buf_size) { |
|
79 |
+ int run_length, color; |
|
80 |
+ |
|
81 |
+ if (buf[i] & 0x80) { |
|
82 |
+ run_length = 1; |
|
83 |
+ color = buf[i]; |
|
84 |
+ i++; |
|
85 |
+ }else{ |
|
86 |
+ run_length = (buf[i] & 0x7f) + 2; |
|
87 |
+ color = buf[i+1]; |
|
88 |
+ i+=2; |
|
89 |
+ } |
|
90 |
+ |
|
91 |
+ if (half_horiz) |
|
92 |
+ run_length *=2; |
|
93 |
+ |
|
94 |
+ if (color) { |
|
95 |
+ memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length); |
|
96 |
+ if (half_vert) |
|
97 |
+ memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); |
|
98 |
+ } |
|
99 |
+ x+= run_length; |
|
100 |
+ |
|
101 |
+ if (x >= s->avctx->width) { |
|
102 |
+ x=0; |
|
103 |
+ y += half_vert ? 2 : 1; |
|
104 |
+ } |
|
105 |
+ } |
|
106 |
+} |
|
107 |
+ |
|
108 |
+static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) |
|
109 |
+{ |
|
110 |
+ const int data_ptr = 2 + LE_16(&buf[0]); |
|
111 |
+ int d, r, y; |
|
112 |
+ d = data_ptr; r = 2; y = 0; |
|
113 |
+ |
|
114 |
+ while(r < data_ptr) { |
|
115 |
+ int i, j; |
|
116 |
+ int length = buf[r] & 0x7f; |
|
117 |
+ int x = buf[r+1] + ((buf[r] & 0x80) << 1); |
|
118 |
+ r += 2; |
|
119 |
+ |
|
120 |
+ if (length==0) { |
|
121 |
+ y += x; |
|
122 |
+ continue; |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ for(i=0; i<length; i++) { |
|
126 |
+ for(j=0; j<8; j++) { |
|
127 |
+ int replace = (buf[r+i] >> (7-j)) & 1; |
|
128 |
+ if (replace) { |
|
129 |
+ int color = buf[d]; |
|
130 |
+ s->frame.data[0][y*s->frame.linesize[0] + x] = color; |
|
131 |
+ if (half_horiz) |
|
132 |
+ s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; |
|
133 |
+ if (half_vert) { |
|
134 |
+ s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color; |
|
135 |
+ if (half_horiz) |
|
136 |
+ s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; |
|
137 |
+ } |
|
138 |
+ d++; |
|
139 |
+ } |
|
140 |
+ x += half_horiz ? 2 : 1; |
|
141 |
+ } |
|
142 |
+ } |
|
143 |
+ |
|
144 |
+ r += length; |
|
145 |
+ y += half_vert ? 2 : 1; |
|
146 |
+ } |
|
147 |
+} |
|
148 |
+ |
|
149 |
+static int mm_decode_frame(AVCodecContext *avctx, |
|
150 |
+ void *data, int *data_size, |
|
151 |
+ uint8_t *buf, int buf_size) |
|
152 |
+{ |
|
153 |
+ MmContext *s = avctx->priv_data; |
|
154 |
+ AVPaletteControl *palette_control = avctx->palctrl; |
|
155 |
+ int type; |
|
156 |
+ |
|
157 |
+ if (palette_control->palette_changed) { |
|
158 |
+ memcpy(s->frame.data[1], palette_control->palette, AVPALETTE_SIZE); |
|
159 |
+ palette_control->palette_changed = 0; |
|
160 |
+ } |
|
161 |
+ |
|
162 |
+ type = LE_16(&buf[0]); |
|
163 |
+ buf += MM_PREAMBLE_SIZE; |
|
164 |
+ buf_size -= MM_PREAMBLE_SIZE; |
|
165 |
+ |
|
166 |
+ switch(type) { |
|
167 |
+ case MM_TYPE_INTRA : mm_decode_intra(s, 0, 0, buf, buf_size); break; |
|
168 |
+ case MM_TYPE_INTRA_HH : mm_decode_intra(s, 1, 0, buf, buf_size); break; |
|
169 |
+ case MM_TYPE_INTRA_HHV : mm_decode_intra(s, 1, 1, buf, buf_size); break; |
|
170 |
+ case MM_TYPE_INTER : mm_decode_inter(s, 0, 0, buf, buf_size); break; |
|
171 |
+ case MM_TYPE_INTER_HH : mm_decode_inter(s, 1, 0, buf, buf_size); break; |
|
172 |
+ case MM_TYPE_INTER_HHV : mm_decode_inter(s, 1, 1, buf, buf_size); break; |
|
173 |
+ default : |
|
174 |
+ return -1; |
|
175 |
+ } |
|
176 |
+ |
|
177 |
+ *data_size = sizeof(AVFrame); |
|
178 |
+ *(AVFrame*)data = s->frame; |
|
179 |
+ |
|
180 |
+ return buf_size; |
|
181 |
+} |
|
182 |
+ |
|
183 |
+static int mm_decode_end(AVCodecContext *avctx) |
|
184 |
+{ |
|
185 |
+ MmContext *s = avctx->priv_data; |
|
186 |
+ |
|
187 |
+ if(s->frame.data[0]) |
|
188 |
+ avctx->release_buffer(avctx, &s->frame); |
|
189 |
+ |
|
190 |
+ return 0; |
|
191 |
+} |
|
192 |
+ |
|
193 |
+AVCodec mmvideo_decoder = { |
|
194 |
+ "mmvideo", |
|
195 |
+ CODEC_TYPE_VIDEO, |
|
196 |
+ CODEC_ID_MMVIDEO, |
|
197 |
+ sizeof(MmContext), |
|
198 |
+ mm_decode_init, |
|
199 |
+ NULL, |
|
200 |
+ mm_decode_end, |
|
201 |
+ mm_decode_frame, |
|
202 |
+ CODEC_CAP_DR1, |
|
203 |
+}; |
... | ... |
@@ -23,7 +23,7 @@ OBJS+=mpeg.o mpegts.o mpegtsenc.o ffm.o crc.o img.o img2.o raw.o rm.o \ |
23 | 23 |
nut.o wc3movie.o mp3.o westwood.o segafilm.o idcin.o flic.o \ |
24 | 24 |
sierravmd.o matroska.o sol.o electronicarts.o nsvdec.o asf.o \ |
25 | 25 |
ogg2.o oggparsevorbis.o oggparsetheora.o oggparseflac.o daud.o aiff.o \ |
26 |
- voc.o tta.o |
|
26 |
+ voc.o tta.o mm.o |
|
27 | 27 |
|
28 | 28 |
# muxers |
29 | 29 |
ifeq ($(CONFIG_MUXERS),yes) |
567 | 570 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,216 @@ |
0 |
+/* |
|
1 |
+ * American Laser Games MM Format Demuxer |
|
2 |
+ * Copyright (c) 2006 Peter Ross |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License as published by the Free Software Foundation; either |
|
7 |
+ * version 2 of the License, or (at your option) any later version. |
|
8 |
+ * |
|
9 |
+ * This library is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 |
+ * Lesser General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU Lesser General Public |
|
15 |
+ * License along with this library; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+/** |
|
20 |
+ * @file mm.c |
|
21 |
+ * American Laser Games MM Format Demuxer |
|
22 |
+ * by Peter Ross (suxen_drol at hotmail dot com) |
|
23 |
+ * |
|
24 |
+ * The MM format was used by IBM-PC ports of ALG's "arcade shooter" games, |
|
25 |
+ * including Mad Dog McCree and Crime Patrol. |
|
26 |
+ * |
|
27 |
+ * Technical details here: |
|
28 |
+ * http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+#include "avformat.h" |
|
32 |
+ |
|
33 |
+#define MM_PREAMBLE_SIZE 6 |
|
34 |
+ |
|
35 |
+#define MM_TYPE_HEADER 0x0 |
|
36 |
+#define MM_TYPE_INTER 0x5 |
|
37 |
+#define MM_TYPE_INTRA 0x8 |
|
38 |
+#define MM_TYPE_INTRA_HH 0xc |
|
39 |
+#define MM_TYPE_INTER_HH 0xd |
|
40 |
+#define MM_TYPE_INTRA_HHV 0xe |
|
41 |
+#define MM_TYPE_INTER_HHV 0xf |
|
42 |
+#define MM_TYPE_AUDIO 0x15 |
|
43 |
+#define MM_TYPE_PALETTE 0x31 |
|
44 |
+ |
|
45 |
+#define MM_HEADER_LEN_V 0x16 /* video only */ |
|
46 |
+#define MM_HEADER_LEN_AV 0x18 /* video + audio */ |
|
47 |
+ |
|
48 |
+#define MM_PALETTE_COUNT 128 |
|
49 |
+#define MM_PALETTE_SIZE (MM_PALETTE_COUNT*3) |
|
50 |
+ |
|
51 |
+typedef struct { |
|
52 |
+ AVPaletteControl palette_control; |
|
53 |
+ unsigned int audio_pts, video_pts; |
|
54 |
+} MmDemuxContext; |
|
55 |
+ |
|
56 |
+static int mm_probe(AVProbeData *p) |
|
57 |
+{ |
|
58 |
+ /* the first chunk is always the header */ |
|
59 |
+ if (p->buf_size < MM_PREAMBLE_SIZE) |
|
60 |
+ return 0; |
|
61 |
+ if (LE_16(&p->buf[0]) != MM_TYPE_HEADER) |
|
62 |
+ return 0; |
|
63 |
+ if (LE_32(&p->buf[2]) != MM_HEADER_LEN_V && LE_32(&p->buf[2]) != MM_HEADER_LEN_AV) |
|
64 |
+ return 0; |
|
65 |
+ |
|
66 |
+ /* only return half certainty since this check is a bit sketchy */ |
|
67 |
+ return AVPROBE_SCORE_MAX / 2; |
|
68 |
+} |
|
69 |
+ |
|
70 |
+static int mm_read_header(AVFormatContext *s, |
|
71 |
+ AVFormatParameters *ap) |
|
72 |
+{ |
|
73 |
+ MmDemuxContext *mm = (MmDemuxContext *)s->priv_data; |
|
74 |
+ ByteIOContext *pb = &s->pb; |
|
75 |
+ AVStream *st; |
|
76 |
+ |
|
77 |
+ unsigned int type, length; |
|
78 |
+ unsigned int frame_rate, width, height; |
|
79 |
+ |
|
80 |
+ type = get_le16(pb); |
|
81 |
+ length = get_le32(pb); |
|
82 |
+ |
|
83 |
+ if (type != MM_TYPE_HEADER) |
|
84 |
+ return AVERROR_INVALIDDATA; |
|
85 |
+ |
|
86 |
+ /* read header */ |
|
87 |
+ get_le16(pb); /* total number of chunks */ |
|
88 |
+ frame_rate = get_le16(pb); |
|
89 |
+ get_le16(pb); /* ibm-pc video bios mode */ |
|
90 |
+ width = get_le16(pb); |
|
91 |
+ height = get_le16(pb); |
|
92 |
+ url_fseek(pb, length - 10, SEEK_CUR); /* unknown data */ |
|
93 |
+ |
|
94 |
+ /* video stream */ |
|
95 |
+ st = av_new_stream(s, 0); |
|
96 |
+ if (!st) |
|
97 |
+ return AVERROR_NOMEM; |
|
98 |
+ st->codec->codec_type = CODEC_TYPE_VIDEO; |
|
99 |
+ st->codec->codec_id = CODEC_ID_MMVIDEO; |
|
100 |
+ st->codec->codec_tag = 0; /* no fourcc */ |
|
101 |
+ st->codec->width = width; |
|
102 |
+ st->codec->height = height; |
|
103 |
+ st->codec->palctrl = &mm->palette_control; |
|
104 |
+ av_set_pts_info(st, 64, 1, frame_rate); |
|
105 |
+ |
|
106 |
+ /* audio stream */ |
|
107 |
+ if (length == MM_HEADER_LEN_AV) { |
|
108 |
+ st = av_new_stream(s, 0); |
|
109 |
+ if (!st) |
|
110 |
+ return AVERROR_NOMEM; |
|
111 |
+ st->codec->codec_type = CODEC_TYPE_AUDIO; |
|
112 |
+ st->codec->codec_tag = 0; /* no fourcc */ |
|
113 |
+ st->codec->codec_id = CODEC_ID_PCM_U8; |
|
114 |
+ st->codec->channels = 1; |
|
115 |
+ st->codec->sample_rate = 8000; |
|
116 |
+ av_set_pts_info(st, 64, 1, 8000); /* 8000 hz */ |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ mm->palette_control.palette_changed = 0; |
|
120 |
+ mm->audio_pts = 0; |
|
121 |
+ mm->video_pts = 0; |
|
122 |
+ return 0; |
|
123 |
+} |
|
124 |
+ |
|
125 |
+static int mm_read_packet(AVFormatContext *s, |
|
126 |
+ AVPacket *pkt) |
|
127 |
+{ |
|
128 |
+ MmDemuxContext *mm = (MmDemuxContext *)s->priv_data; |
|
129 |
+ ByteIOContext *pb = &s->pb; |
|
130 |
+ unsigned char preamble[MM_PREAMBLE_SIZE]; |
|
131 |
+ unsigned char pal[MM_PALETTE_SIZE]; |
|
132 |
+ unsigned int type, length; |
|
133 |
+ int i; |
|
134 |
+ |
|
135 |
+ while(1) { |
|
136 |
+ |
|
137 |
+ if (get_buffer(pb, preamble, MM_PREAMBLE_SIZE) != MM_PREAMBLE_SIZE) { |
|
138 |
+ return AVERROR_IO; |
|
139 |
+ } |
|
140 |
+ |
|
141 |
+ type = LE_16(&preamble[0]); |
|
142 |
+ length = LE_16(&preamble[2]); |
|
143 |
+ |
|
144 |
+ switch(type) { |
|
145 |
+ case MM_TYPE_PALETTE : |
|
146 |
+ url_fseek(pb, 4, SEEK_CUR); /* unknown data */ |
|
147 |
+ if (get_buffer(pb, pal, MM_PALETTE_SIZE) != MM_PALETTE_SIZE) |
|
148 |
+ return AVERROR_IO; |
|
149 |
+ url_fseek(pb, length - (4 + MM_PALETTE_SIZE), SEEK_CUR); |
|
150 |
+ |
|
151 |
+ for (i=0; i<MM_PALETTE_COUNT; i++) { |
|
152 |
+ int r = pal[i*3 + 0]; |
|
153 |
+ int g = pal[i*3 + 1]; |
|
154 |
+ int b = pal[i*3 + 2]; |
|
155 |
+ mm->palette_control.palette[i] = (r << 16) | (g << 8) | (b); |
|
156 |
+ /* repeat palette, where each components is multiplied by four */ |
|
157 |
+ mm->palette_control.palette[i+128] = (r << 18) | (g << 10) | (b<<2); |
|
158 |
+ } |
|
159 |
+ mm->palette_control.palette_changed = 1; |
|
160 |
+ break; |
|
161 |
+ |
|
162 |
+ case MM_TYPE_INTER : |
|
163 |
+ case MM_TYPE_INTRA : |
|
164 |
+ case MM_TYPE_INTRA_HH : |
|
165 |
+ case MM_TYPE_INTER_HH : |
|
166 |
+ case MM_TYPE_INTRA_HHV : |
|
167 |
+ case MM_TYPE_INTER_HHV : |
|
168 |
+ /* output preamble + data */ |
|
169 |
+ if (av_new_packet(pkt, length + MM_PREAMBLE_SIZE)) |
|
170 |
+ return AVERROR_NOMEM; |
|
171 |
+ memcpy(pkt->data, preamble, MM_PREAMBLE_SIZE); |
|
172 |
+ if (get_buffer(pb, pkt->data + MM_PREAMBLE_SIZE, length) != length) |
|
173 |
+ return AVERROR_IO; |
|
174 |
+ pkt->size = length + MM_PREAMBLE_SIZE; |
|
175 |
+ pkt->stream_index = 0; |
|
176 |
+ pkt->pts = mm->video_pts++; |
|
177 |
+ return 0; |
|
178 |
+ |
|
179 |
+ case MM_TYPE_AUDIO : |
|
180 |
+ if (av_get_packet(&s->pb, pkt, length)<0) |
|
181 |
+ return AVERROR_NOMEM; |
|
182 |
+ pkt->size = length; |
|
183 |
+ pkt->stream_index = 1; |
|
184 |
+ pkt->pts = mm->audio_pts++; |
|
185 |
+ return 0; |
|
186 |
+ |
|
187 |
+ default : |
|
188 |
+ av_log(NULL, AV_LOG_INFO, "mm: unknown chunk type 0x%x\n", type); |
|
189 |
+ url_fseek(pb, length, SEEK_CUR); |
|
190 |
+ } |
|
191 |
+ } |
|
192 |
+ |
|
193 |
+ return 0; |
|
194 |
+} |
|
195 |
+ |
|
196 |
+static int mm_read_close(AVFormatContext *s) |
|
197 |
+{ |
|
198 |
+ return 0; |
|
199 |
+} |
|
200 |
+ |
|
201 |
+static AVInputFormat mm_iformat = { |
|
202 |
+ "mm", |
|
203 |
+ "American Laser Games MM format", |
|
204 |
+ sizeof(MmDemuxContext), |
|
205 |
+ mm_probe, |
|
206 |
+ mm_read_header, |
|
207 |
+ mm_read_packet, |
|
208 |
+ mm_read_close, |
|
209 |
+}; |
|
210 |
+ |
|
211 |
+int mm_init(void) |
|
212 |
+{ |
|
213 |
+ av_register_input_format(&mm_iformat); |
|
214 |
+ return 0; |
|
215 |
+} |