avidec.c 12.5 KB
Newer Older
F
Fabrice Bellard 已提交
1 2
/*
 * AVI decoder.
F
Fabrice Bellard 已提交
3
 * Copyright (c) 2001 Fabrice Bellard.
F
Fabrice Bellard 已提交
4
 *
F
Fabrice Bellard 已提交
5 6 7 8
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
F
Fabrice Bellard 已提交
9
 *
F
Fabrice Bellard 已提交
10
 * This library is distributed in the hope that it will be useful,
F
Fabrice Bellard 已提交
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
F
Fabrice Bellard 已提交
12 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
F
Fabrice Bellard 已提交
14
 *
F
Fabrice Bellard 已提交
15 16 17
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
F
Fabrice Bellard 已提交
18 19 20
 */
#include "avformat.h"
#include "avi.h"
21
#include "dv.h"
F
Fabrice Bellard 已提交
22 23 24 25 26 27 28 29 30 31

//#define DEBUG

typedef struct AVIIndex {
    unsigned char tag[4];
    unsigned int flags, pos, len;
    struct AVIIndex *next;
} AVIIndex;

typedef struct {
32 33
    int64_t  riff_end;
    int64_t  movi_end;
F
Fabrice Bellard 已提交
34 35
    offset_t movi_list;
    AVIIndex *first, *last;
36
    void* dv_demux;
F
Fabrice Bellard 已提交
37 38 39
} AVIContext;

#ifdef DEBUG
Z
Zdenek Kabelac 已提交
40
static void print_tag(const char *str, unsigned int tag, int size)
F
Fabrice Bellard 已提交
41 42 43 44 45 46 47 48 49 50
{
    printf("%s: tag=%c%c%c%c size=0x%x\n",
           str, tag & 0xff,
           (tag >> 8) & 0xff,
           (tag >> 16) & 0xff,
           (tag >> 24) & 0xff,
           size);
}
#endif

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
static int get_riff(AVIContext *avi, ByteIOContext *pb)
{
    uint32_t tag; 
    /* check RIFF header */
    tag = get_le32(pb);

    if (tag != MKTAG('R', 'I', 'F', 'F'))
        return -1;
    avi->riff_end = get_le32(pb);   /* RIFF chunk size */
    avi->riff_end += url_ftell(pb); /* RIFF chunk end */
    tag = get_le32(pb);
    if (tag != MKTAG('A', 'V', 'I', ' ') && tag != MKTAG('A', 'V', 'I', 'X'))
        return -1;
    
    return 0;
}

Z
Zdenek Kabelac 已提交
68
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
F
Fabrice Bellard 已提交
69
{
F
Fabrice Bellard 已提交
70
    AVIContext *avi = s->priv_data;
F
Fabrice Bellard 已提交
71
    ByteIOContext *pb = &s->pb;
72
    uint32_t tag, tag1, handler;
73
    int codec_type, stream_index, frame_period, bit_rate, scale, rate;
74 75
    unsigned int size, nb_frames;
    int i, n;
F
Fabrice Bellard 已提交
76
    AVStream *st;
M
Mike Melanson 已提交
77
    int xan_video = 0;  /* hack to support Xan A/V */
F
Fabrice Bellard 已提交
78

79
    if (get_riff(avi, pb) < 0)
F
Fabrice Bellard 已提交
80
        return -1;
Z
Zdenek Kabelac 已提交
81

F
Fabrice Bellard 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    /* first list tag */
    stream_index = -1;
    codec_type = -1;
    frame_period = 0;
    for(;;) {
        if (url_feof(pb))
            goto fail;
        tag = get_le32(pb);
        size = get_le32(pb);
#ifdef DEBUG
        print_tag("tag", tag, size);
#endif

        switch(tag) {
        case MKTAG('L', 'I', 'S', 'T'):
            /* ignored, except when start of video packets */
            tag1 = get_le32(pb);
#ifdef DEBUG
            print_tag("list", tag1, 0);
#endif
            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
                avi->movi_end = url_ftell(pb) + size - 4;
#ifdef DEBUG
                printf("movi end=%Lx\n", avi->movi_end);
#endif
                goto end_of_header;
            }
            break;
        case MKTAG('a', 'v', 'i', 'h'):
Z
Zdenek Kabelac 已提交
111 112
	    /* avi header */
            /* using frame_period is bad idea */
F
Fabrice Bellard 已提交
113 114
            frame_period = get_le32(pb);
            bit_rate = get_le32(pb) * 8;
Z
Zdenek Kabelac 已提交
115
	    url_fskip(pb, 4 * 4);
116 117
            n = get_le32(pb);
            for(i=0;i<n;i++) {
118
                st = av_new_stream(s, i);
F
Fabrice Bellard 已提交
119 120
                if (!st)
                    goto fail;
Z
Zdenek Kabelac 已提交
121
	    }
F
Fabrice Bellard 已提交
122 123 124 125 126 127
            url_fskip(pb, size - 7 * 4);
            break;
        case MKTAG('s', 't', 'r', 'h'):
            /* stream header */
            stream_index++;
            tag1 = get_le32(pb);
128
            handler = get_le32(pb); /* codec tag */
F
Fabrice Bellard 已提交
129
            switch(tag1) {
130 131
            case MKTAG('i', 'a', 'v', 's'):
	    case MKTAG('i', 'v', 'a', 's'):
132 133 134 135
                /* 
	         * After some consideration -- I don't think we 
	         * have to support anything but DV in a type1 AVIs.
	         */
136 137
	        if (s->nb_streams != 1)
		    goto fail;
138 139 140 141 142 143 144 145 146 147
	        
		if (handler != MKTAG('d', 'v', 's', 'd') &&
	            handler != MKTAG('d', 'v', 'h', 'd') &&
		    handler != MKTAG('d', 'v', 's', 'l'))
	           goto fail;

	        avi->dv_demux = dv_init_demux(s, stream_index, stream_index + 1);
		if (!avi->dv_demux)
		    goto fail;
	        stream_index++;
148
	    case MKTAG('v', 'i', 'd', 's'):
F
Fabrice Bellard 已提交
149
                codec_type = CODEC_TYPE_VIDEO;
150 151

                if (stream_index >= s->nb_streams) {
152
                    url_fskip(pb, size - 8);
153 154 155 156 157
                    break;
                } 

                st = s->streams[stream_index];

F
Fabrice Bellard 已提交
158 159 160 161
                get_le32(pb); /* flags */
                get_le16(pb); /* priority */
                get_le16(pb); /* language */
                get_le32(pb); /* XXX: initial frame ? */
162 163
                scale = get_le32(pb); /* scale */
                rate = get_le32(pb); /* rate */
164

165 166
                if(scale && rate){
                    st->codec.frame_rate = rate;
167
                    st->codec.frame_rate_base = scale;
168 169
                }else if(frame_period){
                    st->codec.frame_rate = 1000000;
170
                    st->codec.frame_rate_base = frame_period;
171 172 173 174
                }else{
                    st->codec.frame_rate = 25;
                    st->codec.frame_rate_base = 1;
                }
175 176 177 178 179 180
                get_le32(pb); /* start */
                nb_frames = get_le32(pb);
                st->start_time = 0;
                st->duration = (double)nb_frames * 
                    st->codec.frame_rate_base * AV_TIME_BASE / 
                    st->codec.frame_rate;
181
                
182
		url_fskip(pb, size - 9 * 4);
F
Fabrice Bellard 已提交
183 184
                break;
            case MKTAG('a', 'u', 'd', 's'):
185 186 187 188 189 190
                {
                    unsigned int length, rate;

                    codec_type = CODEC_TYPE_AUDIO;

                    if (stream_index >= s->nb_streams) {
191
                        url_fskip(pb, size - 8);
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
                        break;
                    } 
                    st = s->streams[stream_index];

                    get_le32(pb); /* flags */
                    get_le16(pb); /* priority */
                    get_le16(pb); /* language */
                    get_le32(pb); /* initial frame */
                    get_le32(pb); /* scale */
                    rate = get_le32(pb);
                    get_le32(pb); /* start */
                    length = get_le32(pb); /* length, in samples or bytes */
                    st->start_time = 0;
                    if (rate != 0)
                        st->duration = (int64_t)length * AV_TIME_BASE / rate;
                    url_fskip(pb, size - 9 * 4);
                }
209 210 211
                break;
            default:
                goto fail;
F
Fabrice Bellard 已提交
212 213 214 215
            }
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
216
            if (stream_index >= s->nb_streams || avi->dv_demux) {
F
Fabrice Bellard 已提交
217 218 219 220 221 222 223 224 225
                url_fskip(pb, size);
            } else {
                st = s->streams[stream_index];
                switch(codec_type) {
                case CODEC_TYPE_VIDEO:
                    get_le32(pb); /* size */
                    st->codec.width = get_le32(pb);
                    st->codec.height = get_le32(pb);
                    get_le16(pb); /* panes */
226
                    st->codec.bits_per_sample= get_le16(pb); /* depth */
F
Fabrice Bellard 已提交
227
                    tag1 = get_le32(pb);
228 229 230 231 232 233 234
                    get_le32(pb); /* ImageSize */
                    get_le32(pb); /* XPelsPerMeter */
                    get_le32(pb); /* YPelsPerMeter */
                    get_le32(pb); /* ClrUsed */
                    get_le32(pb); /* ClrImportant */

                    st->codec.extradata_size= size - 10*4;
M
Michael Niedermayer 已提交
235
                    st->codec.extradata= av_malloc(st->codec.extradata_size);
236
                    get_buffer(pb, st->codec.extradata, st->codec.extradata_size);
M
Michael Niedermayer 已提交
237 238 239
                    
                    if(st->codec.extradata_size & 1) //FIXME check if the encoder really did this correctly
                        get_byte(pb);
240

F
Fabrice Bellard 已提交
241 242 243 244 245 246
#ifdef DEBUG
                    print_tag("video", tag1, 0);
#endif
                    st->codec.codec_type = CODEC_TYPE_VIDEO;
                    st->codec.codec_tag = tag1;
                    st->codec.codec_id = codec_get_id(codec_bmp_tags, tag1);
M
Mike Melanson 已提交
247 248
                    if (st->codec.codec_id == CODEC_ID_XAN_WC4)
                        xan_video = 1;
249
//                    url_fskip(pb, size - 5 * 4);
F
Fabrice Bellard 已提交
250
                    break;
251
                case CODEC_TYPE_AUDIO:
252
                    get_wav_header(pb, &st->codec, size);
253 254
                    if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
                        url_fskip(pb, 1);
M
Mike Melanson 已提交
255 256 257 258
                    /* special case time: To support Xan DPCM, hardcode
                     * the format if Xxan is the video codec */
                    if (xan_video)
                        st->codec.codec_id = CODEC_ID_XAN_DPCM;
F
Fabrice Bellard 已提交
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
                    break;
                default:
                    url_fskip(pb, size);
                    break;
                }
            }
            break;
        default:
            /* skip tag */
            size += (size & 1);
            url_fskip(pb, size);
            break;
        }
    }
 end_of_header:
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
    fail:
        for(i=0;i<s->nb_streams;i++) {
M
Michael Niedermayer 已提交
278
            av_freep(&s->streams[i]->codec.extradata);
M
10l  
Michael Niedermayer 已提交
279
            av_freep(&s->streams[i]);
F
Fabrice Bellard 已提交
280 281 282
        }
        return -1;
    }
Z
Zdenek Kabelac 已提交
283

F
Fabrice Bellard 已提交
284 285 286
    return 0;
}

Z
Zdenek Kabelac 已提交
287
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
F
Fabrice Bellard 已提交
288 289 290
{
    AVIContext *avi = s->priv_data;
    ByteIOContext *pb = &s->pb;
291
    int n, d[8], size, i;
292
    void* dstr;
293

294
    memset(d, -1, sizeof(int)*8);
295 296 297 298 299
   
    if (avi->dv_demux) {
        size = dv_get_packet(avi->dv_demux, pkt);
	if (size >= 0)
	    return size;
300
    }
301
        
302
    for(i=url_ftell(pb); !url_feof(pb); i++) {
303
        int j;
Z
Zdenek Kabelac 已提交
304

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	if (i >= avi->movi_end) { /* Let's see if it's an OpenDML AVI */
	    uint32_t tag, size, tag2;
	    url_fskip(pb, avi->riff_end - url_ftell(pb));
	    if (get_riff(avi, pb) < 0)
	        return -1;
	    
	    tag = get_le32(pb);
	    size = get_le32(pb);
	    tag2 = get_le32(pb);
	    if (tag == MKTAG('L','I','S','T') && tag2 == MKTAG('m','o','v','i'))
	        avi->movi_end = url_ftell(pb) + size - 4; 
	    else
	        return -1;
	}

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
        for(j=0; j<7; j++)
            d[j]= d[j+1];
        d[7]= get_byte(pb);
        
        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
        
        //parse ix##
        n= (d[2] - '0') * 10 + (d[3] - '0');
        if(    d[2] >= '0' && d[2] <= '9'
            && d[3] >= '0' && d[3] <= '9'
            && d[0] == 'i' && d[1] == 'x'
            && n < s->nb_streams
            && i + size <= avi->movi_end){
            
            url_fskip(pb, size);
        }
        
        //parse ##dc/##wb
        n= (d[0] - '0') * 10 + (d[1] - '0');
        if(    d[0] >= '0' && d[0] <= '9'
            && d[1] >= '0' && d[1] <= '9'
341 342 343 344
            && ((d[2] == 'd' && d[3] == 'c') || 
	        (d[2] == 'w' && d[3] == 'b') || 
		(d[2] == 'd' && d[3] == 'b') ||
		(d[2] == '_' && d[3] == '_'))
345
            && n < s->nb_streams
346
            && i + size <= avi->movi_end) {
347
        
348
            av_new_packet(pkt, size);
349
            get_buffer(pb, pkt->data, size);
350
            if (size & 1) {
351
                get_byte(pb);
352 353 354 355 356 357 358 359 360 361 362 363 364 365
		size++;
	    }
	
	    if (avi->dv_demux) {
	        dstr = pkt->destruct;
	        size = dv_produce_packet(avi->dv_demux, pkt,
		                         pkt->data, pkt->size);
		pkt->destruct = dstr;
	    } else {
                pkt->stream_index = n;
                pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read 
		                            //        index for that
	    }
            return size;
366 367 368
        }
    }
    return -1;
F
Fabrice Bellard 已提交
369 370
}

Z
Zdenek Kabelac 已提交
371
static int avi_read_close(AVFormatContext *s)
F
Fabrice Bellard 已提交
372
{
M
Michael Niedermayer 已提交
373 374 375 376 377 378 379 380 381
    int i;
    AVIContext *avi = s->priv_data;

    for(i=0;i<s->nb_streams;i++) {
        AVStream *st = s->streams[i];
//        av_free(st->priv_data);
        av_free(st->codec.extradata);
    }

382 383 384
    if (avi->dv_demux)
        av_free(avi->dv_demux);

F
Fabrice Bellard 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
    return 0;
}

static int avi_probe(AVProbeData *p)
{
    /* check file header */
    if (p->buf_size <= 32)
        return 0;
    if (p->buf[0] == 'R' && p->buf[1] == 'I' &&
        p->buf[2] == 'F' && p->buf[3] == 'F' &&
        p->buf[8] == 'A' && p->buf[9] == 'V' &&
        p->buf[10] == 'I' && p->buf[11] == ' ')
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

static AVInputFormat avi_iformat = {
    "avi",
    "avi format",
    sizeof(AVIContext),
    avi_probe,
    avi_read_header,
    avi_read_packet,
    avi_read_close,
};

int avidec_init(void)
{
    av_register_input_format(&avi_iformat);
F
Fabrice Bellard 已提交
415 416
    return 0;
}