Revision 7458ccbb libavformat/avidec.c

View differences:

libavformat/avidec.c
18 18
 */
19 19
#include "avformat.h"
20 20
#include "avi.h"
21
#include "dv.h"
21 22

  
22 23
//#define DEBUG
23 24

  
24
static const struct AVI1Handler {
25
   enum CodecID vcid;
26
   enum CodecID acid;
27
   uint32_t tag;
28
} AVI1Handlers[] = {
29
  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'd') },
30
  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'h', 'd') },
31
  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'l') },
32
  /* This is supposed to be the last one */
33
  { CODEC_ID_NONE, CODEC_ID_NONE, 0 },
34
};
35

  
36 25
typedef struct AVIIndex {
37 26
    unsigned char tag[4];
38 27
    unsigned int flags, pos, len;
......
40 29
} AVIIndex;
41 30

  
42 31
typedef struct {
43
    int64_t riff_end;
44
    int64_t movi_end;
45
    int     type;
46
    uint8_t *buf;
47
    int      buf_size;
48
    int      stream_index;
32
    int64_t  riff_end;
33
    int64_t  movi_end;
49 34
    offset_t movi_list;
50 35
    AVIIndex *first, *last;
36
    void* dv_demux;
51 37
} AVIContext;
52 38

  
53 39
#ifdef DEBUG
......
97 83
    stream_index = -1;
98 84
    codec_type = -1;
99 85
    frame_period = 0;
100
    avi->type = 2;
101
    avi->buf = av_malloc(1);
102
    if (!avi->buf)
103
        return -1;
104
    avi->buf_size = 1;
105 86
    for(;;) {
106 87
        if (url_feof(pb))
107 88
            goto fail;
......
134 115
	    url_fskip(pb, 4 * 4);
135 116
            n = get_le32(pb);
136 117
            for(i=0;i<n;i++) {
137
                st = av_new_stream(s, 0);
118
                st = av_new_stream(s, i);
138 119
                if (!st)
139 120
                    goto fail;
140 121
	    }
......
144 125
            /* stream header */
145 126
            stream_index++;
146 127
            tag1 = get_le32(pb);
128
            handler = get_le32(pb); /* codec tag */
147 129
            switch(tag1) {
148 130
            case MKTAG('i', 'a', 'v', 's'):
149 131
	    case MKTAG('i', 'v', 'a', 's'):
132
                /* 
133
	         * After some consideration -- I don't think we 
134
	         * have to support anything but DV in a type1 AVIs.
135
	         */
150 136
	        if (s->nb_streams != 1)
151 137
		    goto fail;
152
		avi->type = 1;
153
		avi->stream_index = 0;
138
	        
139
		if (handler != MKTAG('d', 'v', 's', 'd') &&
140
	            handler != MKTAG('d', 'v', 'h', 'd') &&
141
		    handler != MKTAG('d', 'v', 's', 'l'))
142
	           goto fail;
143

  
144
	        avi->dv_demux = dv_init_demux(s, stream_index, stream_index + 1);
145
		if (!avi->dv_demux)
146
		    goto fail;
147
	        stream_index++;
154 148
	    case MKTAG('v', 'i', 'd', 's'):
155 149
                codec_type = CODEC_TYPE_VIDEO;
156 150

  
157 151
                if (stream_index >= s->nb_streams) {
158
                    url_fskip(pb, size - 4);
152
                    url_fskip(pb, size - 8);
159 153
                    break;
160 154
                } 
161 155

  
162 156
                st = s->streams[stream_index];
163 157

  
164
                handler = get_le32(pb); /* codec tag */
165 158
                get_le32(pb); /* flags */
166 159
                get_le16(pb); /* priority */
167 160
                get_le16(pb); /* language */
......
186 179
                    st->codec.frame_rate_base * AV_TIME_BASE / 
187 180
                    st->codec.frame_rate;
188 181
                
189
                if (avi->type == 1) {
190
                    AVStream *st;
191

  
192
                    st = av_new_stream(s, 0);
193
                    if (!st)
194
		        goto fail;
195
                    
196
		    stream_index++;
197
		    
198
		    for (i=0; AVI1Handlers[i].tag != 0; ++i)
199
		       if (AVI1Handlers[i].tag == handler)
200
		           break;
201

  
202
		    if (AVI1Handlers[i].tag != 0) {
203
		        s->streams[0]->codec.codec_type = CODEC_TYPE_VIDEO;
204
                        s->streams[0]->codec.codec_id   = AVI1Handlers[i].vcid;
205
		        s->streams[1]->codec.codec_type = CODEC_TYPE_AUDIO;
206
                        s->streams[1]->codec.codec_id   = AVI1Handlers[i].acid;
207
		    } else {
208
		        goto fail;
209
                    }
210
		}
211
		
212 182
		url_fskip(pb, size - 9 * 4);
213 183
                break;
214 184
            case MKTAG('a', 'u', 'd', 's'):
......
218 188
                    codec_type = CODEC_TYPE_AUDIO;
219 189

  
220 190
                    if (stream_index >= s->nb_streams) {
221
                        url_fskip(pb, size - 4);
191
                        url_fskip(pb, size - 8);
222 192
                        break;
223 193
                    } 
224 194
                    st = s->streams[stream_index];
225 195

  
226
                    get_le32(pb); /* tag */
227 196
                    get_le32(pb); /* flags */
228 197
                    get_le16(pb); /* priority */
229 198
                    get_le16(pb); /* language */
......
244 213
            break;
245 214
        case MKTAG('s', 't', 'r', 'f'):
246 215
            /* stream header */
247
            if (stream_index >= s->nb_streams || avi->type == 1) {
216
            if (stream_index >= s->nb_streams || avi->dv_demux) {
248 217
                url_fskip(pb, size);
249 218
            } else {
250 219
                st = s->streams[stream_index];
......
305 274
    /* check stream number */
306 275
    if (stream_index != s->nb_streams - 1) {
307 276
    fail:
308
        av_free(avi->buf);
309 277
        for(i=0;i<s->nb_streams;i++) {
310 278
            av_freep(&s->streams[i]->codec.extradata);
311 279
            av_freep(&s->streams[i]);
......
316 284
    return 0;
317 285
}
318 286

  
319
static void __destruct_pkt(struct AVPacket *pkt)
320
{
321
    pkt->data = NULL; pkt->size = 0;
322
    return;
323
}
324

  
325 287
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
326 288
{
327 289
    AVIContext *avi = s->priv_data;
328 290
    ByteIOContext *pb = &s->pb;
329 291
    int n, d[8], size, i;
292
    void* dstr;
330 293

  
331 294
    memset(d, -1, sizeof(int)*8);
332
    
333
    if (avi->type == 1 && avi->stream_index) {
334
        /* duplicate DV packet */
335
        av_init_packet(pkt);
336
        pkt->data = avi->buf;
337
        pkt->size = avi->buf_size;
338
        pkt->destruct = __destruct_pkt;
339
        pkt->stream_index = avi->stream_index;
340
        avi->stream_index = !avi->stream_index;
341
        return 0;
295
   
296
    if (avi->dv_demux) {
297
        size = dv_get_packet(avi->dv_demux, pkt);
298
	if (size >= 0)
299
	    return size;
342 300
    }
343

  
301
        
344 302
    for(i=url_ftell(pb); !url_feof(pb); i++) {
345 303
        int j;
346 304

  
......
387 345
            && n < s->nb_streams
388 346
            && i + size <= avi->movi_end) {
389 347
        
390
            if (avi->type == 1) {
391
                uint8_t *tbuf = av_realloc(avi->buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
392
                if (!tbuf)
393
                    return -1;
394
                avi->buf = tbuf;
395
                avi->buf_size = size;
396
                av_init_packet(pkt);
397
                pkt->data = avi->buf;
398
                pkt->size = avi->buf_size;
399
                pkt->destruct = __destruct_pkt;
400
                avi->stream_index = n;
401
            } else {
402
                av_new_packet(pkt, size);
403
            }
348
            av_new_packet(pkt, size);
404 349
            get_buffer(pb, pkt->data, size);
405
            if (size & 1)
350
            if (size & 1) {
406 351
                get_byte(pb);
407
            pkt->stream_index = n;
408
            pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read index for that
409
            return 0;
352
		size++;
353
	    }
354
	
355
	    if (avi->dv_demux) {
356
	        dstr = pkt->destruct;
357
	        size = dv_produce_packet(avi->dv_demux, pkt,
358
		                         pkt->data, pkt->size);
359
		pkt->destruct = dstr;
360
	    } else {
361
                pkt->stream_index = n;
362
                pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read 
363
		                            //        index for that
364
	    }
365
            return size;
410 366
        }
411 367
    }
412 368
    return -1;
......
416 372
{
417 373
    int i;
418 374
    AVIContext *avi = s->priv_data;
419
    av_free(avi->buf);
420 375

  
421 376
    for(i=0;i<s->nb_streams;i++) {
422 377
        AVStream *st = s->streams[i];
......
424 379
        av_free(st->codec.extradata);
425 380
    }
426 381

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

  
427 385
    return 0;
428 386
}
429 387

  

Also available in: Unified diff