Mercurial > libavformat.hg
annotate sierravmd.c @ 584:4e3bab6555ae libavformat
When playing
ftp://ftp.mplayerhq.hu/MPlayer/samples/V-codecs/QPEG/VWbig6.avi with my
decoder (should appear soon) it hadn't changed palette even there are
palette change chunks in that AVI.
Here is small patch to make it work (zero number of colors to change in
that chunk actually means to change ALL colors).
patch by (Kostya <cannonball>at<bw-team>dot<com>)
author | michael |
---|---|
date | Fri, 12 Nov 2004 01:32:35 +0000 |
parents | 0fdc96c2f2fe |
children | 57e9d1bdcb09 |
rev | line source |
---|---|
338 | 1 /* |
2 * Sierra VMD Format Demuxer | |
3 * Copyright (c) 2004 The ffmpeg Project | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 | |
20 /** | |
21 * @file sierravmd.c | |
22 * Sierra VMD file demuxer | |
23 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
24 * for more information on the Sierra VMD file format, visit: |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
25 * http://www.pcisys.net/~melanson/codecs/ |
338 | 26 */ |
27 | |
28 #include "avformat.h" | |
29 | |
30 #define VMD_HEADER_SIZE 0x0330 | |
31 #define BYTES_PER_FRAME_RECORD 16 | |
32 | |
33 typedef struct { | |
34 int stream_index; | |
35 offset_t frame_offset; | |
36 unsigned int frame_size; | |
37 int64_t pts; | |
38 int keyframe; | |
39 unsigned char frame_record[BYTES_PER_FRAME_RECORD]; | |
40 } vmd_frame_t; | |
41 | |
42 typedef struct VmdDemuxContext { | |
43 int video_stream_index; | |
44 int audio_stream_index; | |
45 | |
46 unsigned int audio_type; | |
47 unsigned int audio_samplerate; | |
48 unsigned int audio_bits; | |
49 unsigned int audio_channels; | |
50 | |
51 unsigned int frame_count; | |
52 vmd_frame_t *frame_table; | |
53 unsigned int current_frame; | |
54 | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
55 int sample_rate; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
56 int64_t audio_sample_counter; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
57 int audio_frame_divisor; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
58 int audio_block_align; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
59 |
338 | 60 unsigned char vmd_header[VMD_HEADER_SIZE]; |
61 } VmdDemuxContext; | |
62 | |
63 static int vmd_probe(AVProbeData *p) | |
64 { | |
65 if (p->buf_size < 2) | |
66 return 0; | |
67 | |
68 /* check if the first 2 bytes of the file contain the appropriate size | |
69 * of a VMD header chunk */ | |
70 if (LE_16(&p->buf[0]) != VMD_HEADER_SIZE - 2) | |
71 return 0; | |
72 | |
73 /* only return half certainty since this check is a bit sketchy */ | |
74 return AVPROBE_SCORE_MAX / 2; | |
75 } | |
76 | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
77 /* This is a support function to determine the duration, in sample |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
78 * frames, of a particular audio chunk, taking into account silent |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
79 * encodings. */ |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
80 static int vmd_calculate_audio_duration(unsigned char *audio_chunk, |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
81 int audio_chunk_size, int block_align) |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
82 { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
83 unsigned char *p = audio_chunk + 16; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
84 unsigned char *p_end = audio_chunk + audio_chunk_size; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
85 int total_samples = 0; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
86 unsigned int sound_flags; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
87 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
88 if (audio_chunk_size < 16) |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
89 return 0; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
90 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
91 sound_flags = LE_32(p); |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
92 p += 4; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
93 while (p < p_end) { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
94 total_samples += block_align; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
95 if ((sound_flags & 0x01) == 0) |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
96 p += block_align; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
97 sound_flags >>= 1; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
98 } |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
99 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
100 return total_samples; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
101 } |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
102 |
338 | 103 static int vmd_read_header(AVFormatContext *s, |
104 AVFormatParameters *ap) | |
105 { | |
106 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data; | |
107 ByteIOContext *pb = &s->pb; | |
108 AVStream *st; | |
109 unsigned int toc_offset; | |
110 unsigned char *raw_frame_table; | |
111 int raw_frame_table_size; | |
112 unsigned char *current_frame_record; | |
113 offset_t current_offset; | |
114 int i; | |
115 unsigned int total_frames; | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
116 int64_t video_pts_inc; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
117 int64_t current_video_pts = 0; |
338 | 118 |
119 /* fetch the main header, including the 2 header length bytes */ | |
120 url_fseek(pb, 0, SEEK_SET); | |
121 if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE) | |
482 | 122 return AVERROR_IO; |
338 | 123 |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
124 vmd->audio_sample_counter = 0; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
125 vmd->audio_frame_divisor = 1; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
126 vmd->audio_block_align = 1; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
127 |
338 | 128 /* start up the decoders */ |
129 st = av_new_stream(s, 0); | |
130 if (!st) | |
131 return AVERROR_NOMEM; | |
462
b69898ffc92a
move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents:
387
diff
changeset
|
132 av_set_pts_info(st, 33, 1, 90000); |
338 | 133 vmd->video_stream_index = st->index; |
134 st->codec.codec_type = CODEC_TYPE_VIDEO; | |
135 st->codec.codec_id = CODEC_ID_VMDVIDEO; | |
136 st->codec.codec_tag = 0; /* no fourcc */ | |
137 st->codec.width = LE_16(&vmd->vmd_header[12]); | |
138 st->codec.height = LE_16(&vmd->vmd_header[14]); | |
139 st->codec.extradata_size = VMD_HEADER_SIZE; | |
140 st->codec.extradata = av_malloc(VMD_HEADER_SIZE); | |
141 memcpy(st->codec.extradata, vmd->vmd_header, VMD_HEADER_SIZE); | |
142 | |
143 /* if sample rate is 0, assume no audio */ | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
144 vmd->sample_rate = LE_16(&vmd->vmd_header[804]); |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
145 if (vmd->sample_rate) { |
338 | 146 st = av_new_stream(s, 0); |
147 if (!st) | |
148 return AVERROR_NOMEM; | |
462
b69898ffc92a
move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents:
387
diff
changeset
|
149 av_set_pts_info(st, 33, 1, 90000); |
338 | 150 vmd->audio_stream_index = st->index; |
151 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
152 st->codec.codec_id = CODEC_ID_VMDAUDIO; | |
153 st->codec.codec_tag = 0; /* no codec tag */ | |
154 st->codec.channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1; | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
155 st->codec.sample_rate = vmd->sample_rate; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
156 st->codec.block_align = vmd->audio_block_align = |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
157 LE_16(&vmd->vmd_header[806]); |
338 | 158 if (st->codec.block_align & 0x8000) { |
159 st->codec.bits_per_sample = 16; | |
160 st->codec.block_align = -(st->codec.block_align - 0x10000); | |
161 } else | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
162 st->codec.bits_per_sample = 16; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
163 // st->codec.bits_per_sample = 8; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
164 st->codec.bit_rate = st->codec.sample_rate * |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
165 st->codec.bits_per_sample * st->codec.channels; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
166 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
167 /* for calculating pts */ |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
168 vmd->audio_frame_divisor = st->codec.bits_per_sample / 8 / |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
169 st->codec.channels; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
170 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
171 video_pts_inc = 90000; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
172 video_pts_inc *= st->codec.block_align; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
173 video_pts_inc /= st->codec.sample_rate; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
174 } else { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
175 /* if no audio, assume 10 frames/second */ |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
176 video_pts_inc = 90000 / 10; |
338 | 177 } |
178 | |
179 /* skip over the offset table and load the table of contents; don't | |
180 * care about the offset table since demuxer will calculate those | |
181 * independently */ | |
182 toc_offset = LE_32(&vmd->vmd_header[812]); | |
183 vmd->frame_count = LE_16(&vmd->vmd_header[6]); | |
184 url_fseek(pb, toc_offset + vmd->frame_count * 6, SEEK_SET); | |
185 | |
186 /* each on-disk VMD frame has an audio part and a video part; demuxer | |
187 * accounts them separately */ | |
188 vmd->frame_count *= 2; | |
189 raw_frame_table = NULL; | |
190 vmd->frame_table = NULL; | |
191 raw_frame_table_size = vmd->frame_count * BYTES_PER_FRAME_RECORD; | |
192 raw_frame_table = av_malloc(raw_frame_table_size); | |
193 vmd->frame_table = av_malloc(vmd->frame_count * sizeof(vmd_frame_t)); | |
194 if (!raw_frame_table || !vmd->frame_table) { | |
195 av_free(raw_frame_table); | |
196 av_free(vmd->frame_table); | |
197 return AVERROR_NOMEM; | |
198 } | |
199 if (get_buffer(pb, raw_frame_table, raw_frame_table_size) != | |
200 raw_frame_table_size) { | |
201 av_free(raw_frame_table); | |
202 av_free(vmd->frame_table); | |
482 | 203 return AVERROR_IO; |
338 | 204 } |
205 | |
206 current_offset = LE_32(&vmd->vmd_header[20]); | |
207 current_frame_record = raw_frame_table; | |
208 total_frames = vmd->frame_count; | |
209 i = 0; | |
210 while (total_frames--) { | |
211 | |
212 /* if the frame size is 0, do not count the frame and bring the | |
213 * total frame count down */ | |
214 vmd->frame_table[i].frame_size = LE_32(¤t_frame_record[2]); | |
215 | |
216 /* this logic is present so that 0-length audio chunks are not | |
217 * accounted */ | |
218 if (!vmd->frame_table[i].frame_size) { | |
219 vmd->frame_count--; /* one less frame to count */ | |
220 current_frame_record += BYTES_PER_FRAME_RECORD; | |
221 continue; | |
222 } | |
223 | |
224 if (current_frame_record[0] == 0x02) | |
225 vmd->frame_table[i].stream_index = vmd->video_stream_index; | |
226 else | |
227 vmd->frame_table[i].stream_index = vmd->audio_stream_index; | |
228 vmd->frame_table[i].frame_offset = current_offset; | |
229 current_offset += vmd->frame_table[i].frame_size; | |
230 memcpy(vmd->frame_table[i].frame_record, current_frame_record, | |
231 BYTES_PER_FRAME_RECORD); | |
232 | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
233 /* figure out the pts for this frame */ |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
234 if (current_frame_record[0] == 0x02) { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
235 vmd->frame_table[i].pts = current_video_pts; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
236 current_video_pts += video_pts_inc; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
237 } else if (current_frame_record[0] == 0x01) { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
238 /* figure out the pts during the dispatch phase */ |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
239 vmd->frame_table[i].pts = 0; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
240 } |
338 | 241 |
242 current_frame_record += BYTES_PER_FRAME_RECORD; | |
243 i++; | |
244 } | |
245 | |
246 av_free(raw_frame_table); | |
247 | |
248 vmd->current_frame = 0; | |
249 | |
250 return 0; | |
251 } | |
252 | |
253 static int vmd_read_packet(AVFormatContext *s, | |
254 AVPacket *pkt) | |
255 { | |
256 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data; | |
257 ByteIOContext *pb = &s->pb; | |
258 int ret = 0; | |
259 vmd_frame_t *frame; | |
260 | |
261 if (vmd->current_frame >= vmd->frame_count) | |
482 | 262 return AVERROR_IO; |
338 | 263 |
264 frame = &vmd->frame_table[vmd->current_frame]; | |
265 /* position the stream (will probably be there already) */ | |
266 url_fseek(pb, frame->frame_offset, SEEK_SET); | |
267 | |
268 if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD)) | |
269 return AVERROR_NOMEM; | |
270 memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD); | |
271 ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD, | |
272 frame->frame_size); | |
273 | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
274 if (ret != frame->frame_size) { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
275 av_free_packet(pkt); |
482 | 276 ret = AVERROR_IO; |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
277 } |
338 | 278 pkt->stream_index = frame->stream_index; |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
279 if (frame->frame_record[0] == 0x02) |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
280 pkt->pts = frame->pts; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
281 else { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
282 pkt->pts = vmd->audio_sample_counter; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
283 pkt->pts *= 90000; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
284 pkt->pts /= vmd->sample_rate; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
285 // pkt->pts /= vmd->audio_frame_divisor; |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
286 vmd->audio_sample_counter += vmd_calculate_audio_duration( |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
287 pkt->data, pkt->size, vmd->audio_block_align); |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
288 |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
289 } |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
290 printf (" dispatching %s frame with %d bytes and pts %lld (%0.1f sec)\n", |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
291 (frame->frame_record[0] == 0x02) ? "video" : "audio", |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
292 frame->frame_size + BYTES_PER_FRAME_RECORD, |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
293 pkt->pts, (float)(pkt->pts / 90000.0)); |
338 | 294 |
295 vmd->current_frame++; | |
296 | |
297 return ret; | |
298 } | |
299 | |
300 static int vmd_read_close(AVFormatContext *s) | |
301 { | |
302 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data; | |
303 | |
304 av_free(vmd->frame_table); | |
305 | |
306 return 0; | |
307 } | |
308 | |
309 static AVInputFormat vmd_iformat = { | |
310 "vmd", | |
311 "Sierra VMD format", | |
312 sizeof(VmdDemuxContext), | |
313 vmd_probe, | |
314 vmd_read_header, | |
315 vmd_read_packet, | |
316 vmd_read_close, | |
317 }; | |
318 | |
319 int vmd_init(void) | |
320 { | |
321 av_register_input_format(&vmd_iformat); | |
322 return 0; | |
323 } |