3 * Copyright (c) 2001 Fabrice Bellard.
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.
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.
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
25 typedef struct AVIIndex
{
27 unsigned int flags
, pos
, len
;
28 struct AVIIndex
*next
;
35 AVIIndex
*first
, *last
;
36 DVDemuxContext
* dv_demux
;
40 static void print_tag(const char *str
, unsigned int tag
, int size
)
42 printf("%s: tag=%c%c%c%c size=0x%x\n",
51 static int get_riff(AVIContext
*avi
, ByteIOContext
*pb
)
54 /* check RIFF header */
57 if (tag
!= MKTAG('R', 'I', 'F', 'F'))
59 avi
->riff_end
= get_le32(pb
); /* RIFF chunk size */
60 avi
->riff_end
+= url_ftell(pb
); /* RIFF chunk end */
62 if (tag
!= MKTAG('A', 'V', 'I', ' ') && tag
!= MKTAG('A', 'V', 'I', 'X'))
68 static int avi_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
70 AVIContext
*avi
= s
->priv_data
;
71 ByteIOContext
*pb
= &s
->pb
;
72 uint32_t tag
, tag1
, handler
;
73 int codec_type
, stream_index
, frame_period
, bit_rate
, scale
, rate
;
74 unsigned int size
, nb_frames
;
77 int xan_video
= 0; /* hack to support Xan A/V */
79 if (get_riff(avi
, pb
) < 0)
92 print_tag("tag", tag
, size
);
96 case MKTAG('L', 'I', 'S', 'T'):
97 /* ignored, except when start of video packets */
100 print_tag("list", tag1
, 0);
102 if (tag1
== MKTAG('m', 'o', 'v', 'i')) {
103 avi
->movi_end
= url_ftell(pb
) + size
- 4;
105 printf("movi end=%Lx\n", avi
->movi_end
);
110 case MKTAG('a', 'v', 'i', 'h'):
112 /* using frame_period is bad idea */
113 frame_period
= get_le32(pb
);
114 bit_rate
= get_le32(pb
) * 8;
115 url_fskip(pb
, 4 * 4);
118 st
= av_new_stream(s
, i
);
122 url_fskip(pb
, size
- 7 * 4);
124 case MKTAG('s', 't', 'r', 'h'):
128 handler
= get_le32(pb
); /* codec tag */
130 case MKTAG('i', 'a', 'v', 's'):
131 case MKTAG('i', 'v', 'a', 's'):
133 * After some consideration -- I don't think we
134 * have to support anything but DV in a type1 AVIs.
136 if (s
->nb_streams
!= 1)
139 if (handler
!= MKTAG('d', 'v', 's', 'd') &&
140 handler
!= MKTAG('d', 'v', 'h', 'd') &&
141 handler
!= MKTAG('d', 'v', 's', 'l'))
144 av_freep(&s
->streams
[0]->codec
.extradata
);
145 av_freep(&s
->streams
[0]);
147 avi
->dv_demux
= dv_init_demux(s
);
150 stream_index
= s
->nb_streams
- 1;
151 url_fskip(pb
, size
- 8);
153 case MKTAG('v', 'i', 'd', 's'):
154 codec_type
= CODEC_TYPE_VIDEO
;
156 if (stream_index
>= s
->nb_streams
) {
157 url_fskip(pb
, size
- 8);
161 st
= s
->streams
[stream_index
];
163 get_le32(pb
); /* flags */
164 get_le16(pb
); /* priority */
165 get_le16(pb
); /* language */
166 get_le32(pb
); /* XXX: initial frame ? */
167 scale
= get_le32(pb
); /* scale */
168 rate
= get_le32(pb
); /* rate */
171 st
->codec
.frame_rate
= rate
;
172 st
->codec
.frame_rate_base
= scale
;
173 }else if(frame_period
){
174 st
->codec
.frame_rate
= 1000000;
175 st
->codec
.frame_rate_base
= frame_period
;
177 st
->codec
.frame_rate
= 25;
178 st
->codec
.frame_rate_base
= 1;
180 get_le32(pb
); /* start */
181 nb_frames
= get_le32(pb
);
183 st
->duration
= (double)nb_frames
*
184 st
->codec
.frame_rate_base
* AV_TIME_BASE
/
185 st
->codec
.frame_rate
;
187 url_fskip(pb
, size
- 9 * 4);
189 case MKTAG('a', 'u', 'd', 's'):
191 unsigned int length
, rate
;
193 codec_type
= CODEC_TYPE_AUDIO
;
195 if (stream_index
>= s
->nb_streams
) {
196 url_fskip(pb
, size
- 8);
199 st
= s
->streams
[stream_index
];
201 get_le32(pb
); /* flags */
202 get_le16(pb
); /* priority */
203 get_le16(pb
); /* language */
204 get_le32(pb
); /* initial frame */
205 get_le32(pb
); /* scale */
207 get_le32(pb
); /* start */
208 length
= get_le32(pb
); /* length, in samples or bytes */
211 st
->duration
= (int64_t)length
* AV_TIME_BASE
/ rate
;
212 url_fskip(pb
, size
- 9 * 4);
219 case MKTAG('s', 't', 'r', 'f'):
221 if (stream_index
>= s
->nb_streams
|| avi
->dv_demux
) {
224 st
= s
->streams
[stream_index
];
226 case CODEC_TYPE_VIDEO
:
227 get_le32(pb
); /* size */
228 st
->codec
.width
= get_le32(pb
);
229 st
->codec
.height
= get_le32(pb
);
230 get_le16(pb
); /* panes */
231 st
->codec
.bits_per_sample
= get_le16(pb
); /* depth */
233 get_le32(pb
); /* ImageSize */
234 get_le32(pb
); /* XPelsPerMeter */
235 get_le32(pb
); /* YPelsPerMeter */
236 get_le32(pb
); /* ClrUsed */
237 get_le32(pb
); /* ClrImportant */
239 st
->codec
.extradata_size
= size
- 10*4;
240 st
->codec
.extradata
= av_malloc(st
->codec
.extradata_size
);
241 get_buffer(pb
, st
->codec
.extradata
, st
->codec
.extradata_size
);
243 if(st
->codec
.extradata_size
& 1) //FIXME check if the encoder really did this correctly
246 /* Extract palette from extradata if bpp <= 8 */
247 /* This code assumes that extradata contains only palette */
248 /* This is true for all paletted codecs implemented in ffmpeg */
249 if (st
->codec
.extradata_size
&& (st
->codec
.bits_per_sample
<= 8)) {
250 st
->codec
.palctrl
= av_mallocz(sizeof(AVPaletteControl
));
251 #ifdef WORDS_BIGENDIAN
252 for (i
= 0; i
< FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
)/4; i
++)
253 st
->codec
.palctrl
->palette
[i
] = bswap_32(((uint32_t*)st
->codec
.extradata
)[i
]);
255 memcpy(st
->codec
.palctrl
->palette
, st
->codec
.extradata
,
256 FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
));
258 st
->codec
.palctrl
->palette_changed
= 1;
262 print_tag("video", tag1
, 0);
264 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
265 st
->codec
.codec_tag
= tag1
;
266 st
->codec
.codec_id
= codec_get_id(codec_bmp_tags
, tag1
);
267 if (st
->codec
.codec_id
== CODEC_ID_XAN_WC4
)
269 // url_fskip(pb, size - 5 * 4);
271 case CODEC_TYPE_AUDIO
:
272 get_wav_header(pb
, &st
->codec
, size
);
273 if (size
%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
275 /* special case time: To support Xan DPCM, hardcode
276 * the format if Xxan is the video codec */
278 st
->codec
.codec_id
= CODEC_ID_XAN_DPCM
;
294 /* check stream number */
295 if (stream_index
!= s
->nb_streams
- 1) {
297 for(i
=0;i
<s
->nb_streams
;i
++) {
298 av_freep(&s
->streams
[i
]->codec
.extradata
);
299 av_freep(&s
->streams
[i
]);
307 static int avi_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
309 AVIContext
*avi
= s
->priv_data
;
310 ByteIOContext
*pb
= &s
->pb
;
311 int n
, d
[8], size
, i
;
314 memset(d
, -1, sizeof(int)*8);
317 size
= dv_get_packet(avi
->dv_demux
, pkt
);
322 for(i
=url_ftell(pb
); !url_feof(pb
); i
++) {
325 if (i
>= avi
->movi_end
) { /* Let's see if it's an OpenDML AVI */
326 uint32_t tag
, size
, tag2
;
327 url_fskip(pb
, avi
->riff_end
- url_ftell(pb
));
328 if (get_riff(avi
, pb
) < 0)
334 if (tag
== MKTAG('L','I','S','T') && tag2
== MKTAG('m','o','v','i'))
335 avi
->movi_end
= url_ftell(pb
) + size
- 4;
344 size
= d
[4] + (d
[5]<<8) + (d
[6]<<16) + (d
[7]<<24);
347 n
= (d
[2] - '0') * 10 + (d
[3] - '0');
348 if( d
[2] >= '0' && d
[2] <= '9'
349 && d
[3] >= '0' && d
[3] <= '9'
350 && d
[0] == 'i' && d
[1] == 'x'
352 && i
+ size
<= avi
->movi_end
){
358 n
= (d
[0] - '0') * 10 + (d
[1] - '0');
359 if( d
[0] >= '0' && d
[0] <= '9'
360 && d
[1] >= '0' && d
[1] <= '9'
361 && ((d
[2] == 'd' && d
[3] == 'c') ||
362 (d
[2] == 'w' && d
[3] == 'b') ||
363 (d
[2] == 'd' && d
[3] == 'b') ||
364 (d
[2] == '_' && d
[3] == '_'))
366 && i
+ size
<= avi
->movi_end
) {
368 av_new_packet(pkt
, size
);
369 get_buffer(pb
, pkt
->data
, size
);
376 dstr
= pkt
->destruct
;
377 size
= dv_produce_packet(avi
->dv_demux
, pkt
,
378 pkt
->data
, pkt
->size
);
379 pkt
->destruct
= dstr
;
381 pkt
->stream_index
= n
;
382 pkt
->flags
|= PKT_FLAG_KEY
; // FIXME: We really should read
391 static int avi_read_close(AVFormatContext
*s
)
394 AVIContext
*avi
= s
->priv_data
;
396 for(i
=0;i
<s
->nb_streams
;i
++) {
397 AVStream
*st
= s
->streams
[i
];
398 // av_free(st->priv_data);
399 av_free(st
->codec
.extradata
);
400 av_free(st
->codec
.palctrl
);
404 av_free(avi
->dv_demux
);
409 static int avi_probe(AVProbeData
*p
)
411 /* check file header */
412 if (p
->buf_size
<= 32)
414 if (p
->buf
[0] == 'R' && p
->buf
[1] == 'I' &&
415 p
->buf
[2] == 'F' && p
->buf
[3] == 'F' &&
416 p
->buf
[8] == 'A' && p
->buf
[9] == 'V' &&
417 p
->buf
[10] == 'I' && p
->buf
[11] == ' ')
418 return AVPROBE_SCORE_MAX
;
423 static AVInputFormat avi_iformat
= {
433 int avidec_init(void)
435 av_register_input_format(&avi_iformat
);