Statistics
| Branch: | Revision:

ffmpeg / libavformat / asfdec.c @ 5e293c42

History | View | Annotate | Download (39 KB)

1
/*
2
 * ASF compatible demuxer
3
 * Copyright (c) 2000, 2001 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
#include "libavutil/common.h"
23
#include "libavcodec/mpegaudio.h"
24
#include "avformat.h"
25
#include "riff.h"
26
#include "asf.h"
27
#include "asfcrypt.h"
28

    
29
void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format);
30

    
31
#undef NDEBUG
32
#include <assert.h>
33

    
34
#define FRAME_HEADER_SIZE 17
35
// Fix Me! FRAME_HEADER_SIZE may be different.
36

    
37
static const GUID index_guid = {
38
    0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
39
};
40

    
41
static const GUID stream_bitrate_guid = { /* (http://get.to/sdp) */
42
    0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
43
};
44
/**********************************/
45
/* decoding */
46

    
47
//#define DEBUG
48

    
49
#ifdef DEBUG
50
#define PRINT_IF_GUID(g,cmp) \
51
if (!memcmp(g, &cmp, sizeof(GUID))) \
52
    dprintf(NULL, "(GUID: %s) ", #cmp)
53

    
54
static void print_guid(const GUID *g)
55
{
56
    int i;
57
    PRINT_IF_GUID(g, asf_header);
58
    else PRINT_IF_GUID(g, file_header);
59
    else PRINT_IF_GUID(g, stream_header);
60
    else PRINT_IF_GUID(g, audio_stream);
61
    else PRINT_IF_GUID(g, audio_conceal_none);
62
    else PRINT_IF_GUID(g, video_stream);
63
    else PRINT_IF_GUID(g, video_conceal_none);
64
    else PRINT_IF_GUID(g, command_stream);
65
    else PRINT_IF_GUID(g, comment_header);
66
    else PRINT_IF_GUID(g, codec_comment_header);
67
    else PRINT_IF_GUID(g, codec_comment1_header);
68
    else PRINT_IF_GUID(g, data_header);
69
    else PRINT_IF_GUID(g, index_guid);
70
    else PRINT_IF_GUID(g, head1_guid);
71
    else PRINT_IF_GUID(g, head2_guid);
72
    else PRINT_IF_GUID(g, my_guid);
73
    else PRINT_IF_GUID(g, ext_stream_header);
74
    else PRINT_IF_GUID(g, extended_content_header);
75
    else PRINT_IF_GUID(g, ext_stream_embed_stream_header);
76
    else PRINT_IF_GUID(g, ext_stream_audio_stream);
77
    else PRINT_IF_GUID(g, metadata_header);
78
    else PRINT_IF_GUID(g, stream_bitrate_guid);
79
    else
80
        dprintf(NULL, "(GUID: unknown) ");
81
    for(i=0;i<16;i++)
82
        dprintf(NULL, " 0x%02x,", (*g)[i]);
83
    dprintf(NULL, "}\n");
84
}
85
#undef PRINT_IF_GUID
86
#else
87
#define print_guid(g)
88
#endif
89

    
90
static void get_guid(ByteIOContext *s, GUID *g)
91
{
92
    assert(sizeof(*g) == 16);
93
    get_buffer(s, *g, sizeof(*g));
94
}
95

    
96
#if 0
97
static void get_str16(ByteIOContext *pb, char *buf, int buf_size)
98
{
99
    int len, c;
100
    char *q;
101

102
    len = get_le16(pb);
103
    q = buf;
104
    while (len > 0) {
105
        c = get_le16(pb);
106
        if ((q - buf) < buf_size - 1)
107
            *q++ = c;
108
        len--;
109
    }
110
    *q = '\0';
111
}
112
#endif
113

    
114
static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size)
115
{
116
    char* q = buf;
117
    len /= 2;
118
    while (len--) {
119
        uint8_t tmp;
120
        PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;)
121
    }
122
    *q = '\0';
123
}
124

    
125
static int asf_probe(AVProbeData *pd)
126
{
127
    /* check file header */
128
    if (!memcmp(pd->buf, &asf_header, sizeof(GUID)))
129
        return AVPROBE_SCORE_MAX;
130
    else
131
        return 0;
132
}
133

    
134
static int get_value(ByteIOContext *pb, int type){
135
    switch(type){
136
        case 2: return get_le32(pb);
137
        case 3: return get_le32(pb);
138
        case 4: return get_le64(pb);
139
        case 5: return get_le16(pb);
140
        default:return INT_MIN;
141
    }
142
}
143

    
144
static void get_tag(AVFormatContext *s, const char *key, int type, int len)
145
{
146
    char value[1024];
147
    if (type <= 1) {         // unicode or byte
148
        get_str16_nolen(s->pb, len, value, sizeof(value));
149
    } else if (type <= 5) {  // boolean or DWORD or QWORD or WORD
150
        uint64_t num = get_value(s->pb, type);
151
        snprintf(value, sizeof(value), "%"PRIu64, num);
152
    } else {
153
        url_fskip(s->pb, len);
154
        return;
155
    }
156
    if (strncmp(key, "WM/", 3))
157
        key += 3;
158
    av_metadata_set(&s->metadata, key, value);
159
}
160

    
161
static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
162
{
163
    ASFContext *asf = s->priv_data;
164
    GUID g;
165
    ByteIOContext *pb = s->pb;
166
    AVStream *st;
167
    ASFStream *asf_st;
168
    int size, i;
169
    int64_t gsize;
170
    AVRational dar[128];
171
    uint32_t bitrate[128];
172

    
173
    memset(dar, 0, sizeof(dar));
174
    memset(bitrate, 0, sizeof(bitrate));
175

    
176
    get_guid(pb, &g);
177
    if (memcmp(&g, &asf_header, sizeof(GUID)))
178
        return -1;
179
    get_le64(pb);
180
    get_le32(pb);
181
    get_byte(pb);
182
    get_byte(pb);
183
    memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
184
    for(;;) {
185
        get_guid(pb, &g);
186
        gsize = get_le64(pb);
187
        dprintf(s, "%08"PRIx64": ", url_ftell(pb) - 24);
188
        print_guid(&g);
189
        dprintf(s, "  size=0x%"PRIx64"\n", gsize);
190
        if (!memcmp(&g, &data_header, sizeof(GUID))) {
191
            asf->data_object_offset = url_ftell(pb);
192
            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
193
            if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
194
                asf->data_object_size = gsize - 24;
195
            } else {
196
                asf->data_object_size = (uint64_t)-1;
197
            }
198
            break;
199
        }
200
        if (gsize < 24)
201
            return -1;
202
        if (!memcmp(&g, &file_header, sizeof(GUID))) {
203
            get_guid(pb, &asf->hdr.guid);
204
            asf->hdr.file_size          = get_le64(pb);
205
            asf->hdr.create_time        = get_le64(pb);
206
            asf->nb_packets             = get_le64(pb);
207
            asf->hdr.play_time          = get_le64(pb);
208
            asf->hdr.send_time          = get_le64(pb);
209
            asf->hdr.preroll            = get_le32(pb);
210
            asf->hdr.ignore             = get_le32(pb);
211
            asf->hdr.flags              = get_le32(pb);
212
            asf->hdr.min_pktsize        = get_le32(pb);
213
            asf->hdr.max_pktsize        = get_le32(pb);
214
            asf->hdr.max_bitrate        = get_le32(pb);
215
            asf->packet_size = asf->hdr.max_pktsize;
216
        } else if (!memcmp(&g, &stream_header, sizeof(GUID))) {
217
            enum CodecType type;
218
            int type_specific_size, sizeX;
219
            uint64_t total_size;
220
            unsigned int tag1;
221
            int64_t pos1, pos2, start_time;
222
            int test_for_ext_stream_audio, is_dvr_ms_audio=0;
223

    
224
            pos1 = url_ftell(pb);
225

    
226
            st = av_new_stream(s, 0);
227
            if (!st)
228
                return AVERROR(ENOMEM);
229
            av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
230
            asf_st = av_mallocz(sizeof(ASFStream));
231
            if (!asf_st)
232
                return AVERROR(ENOMEM);
233
            st->priv_data = asf_st;
234
            start_time = asf->hdr.preroll;
235

    
236
            if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
237
                st->duration = asf->hdr.send_time /
238
                    (10000000 / 1000) - start_time;
239
            }
240
            get_guid(pb, &g);
241

    
242
            test_for_ext_stream_audio = 0;
243
            if (!memcmp(&g, &audio_stream, sizeof(GUID))) {
244
                type = CODEC_TYPE_AUDIO;
245
            } else if (!memcmp(&g, &video_stream, sizeof(GUID))) {
246
                type = CODEC_TYPE_VIDEO;
247
            } else if (!memcmp(&g, &command_stream, sizeof(GUID))) {
248
                type = CODEC_TYPE_DATA;
249
            } else if (!memcmp(&g, &ext_stream_embed_stream_header, sizeof(GUID))) {
250
                test_for_ext_stream_audio = 1;
251
                type = CODEC_TYPE_UNKNOWN;
252
            } else {
253
                return -1;
254
            }
255
            get_guid(pb, &g);
256
            total_size = get_le64(pb);
257
            type_specific_size = get_le32(pb);
258
            get_le32(pb);
259
            st->id = get_le16(pb) & 0x7f; /* stream id */
260
            // mapping of asf ID to AV stream ID;
261
            asf->asfid2avid[st->id] = s->nb_streams - 1;
262

    
263
            get_le32(pb);
264

    
265
            if (test_for_ext_stream_audio) {
266
                get_guid(pb, &g);
267
                if (!memcmp(&g, &ext_stream_audio_stream, sizeof(GUID))) {
268
                    type = CODEC_TYPE_AUDIO;
269
                    is_dvr_ms_audio=1;
270
                    get_guid(pb, &g);
271
                    get_le32(pb);
272
                    get_le32(pb);
273
                    get_le32(pb);
274
                    get_guid(pb, &g);
275
                    get_le32(pb);
276
                }
277
            }
278

    
279
            st->codec->codec_type = type;
280
            if (type == CODEC_TYPE_AUDIO) {
281
                get_wav_header(pb, st->codec, type_specific_size);
282
                if (is_dvr_ms_audio) {
283
                    // codec_id and codec_tag are unreliable in dvr_ms
284
                    // files. Set them later by probing stream.
285
                    st->codec->codec_id = CODEC_ID_PROBE;
286
                    st->codec->codec_tag = 0;
287
                }
288
                if (st->codec->codec_id == CODEC_ID_AAC) {
289
                    st->need_parsing = AVSTREAM_PARSE_NONE;
290
                } else {
291
                    st->need_parsing = AVSTREAM_PARSE_FULL;
292
                }
293
                /* We have to init the frame size at some point .... */
294
                pos2 = url_ftell(pb);
295
                if (gsize >= (pos2 + 8 - pos1 + 24)) {
296
                    asf_st->ds_span = get_byte(pb);
297
                    asf_st->ds_packet_size = get_le16(pb);
298
                    asf_st->ds_chunk_size = get_le16(pb);
299
                    get_le16(pb); //ds_data_size
300
                    get_byte(pb); //ds_silence_data
301
                }
302
                //printf("Descrambling: ps:%d cs:%d ds:%d s:%d  sd:%d\n",
303
                //       asf_st->ds_packet_size, asf_st->ds_chunk_size,
304
                //       asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data);
305
                if (asf_st->ds_span > 1) {
306
                    if (!asf_st->ds_chunk_size
307
                        || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
308
                        || asf_st->ds_packet_size % asf_st->ds_chunk_size)
309
                        asf_st->ds_span = 0; // disable descrambling
310
                }
311
                switch (st->codec->codec_id) {
312
                case CODEC_ID_MP3:
313
                    st->codec->frame_size = MPA_FRAME_SIZE;
314
                    break;
315
                case CODEC_ID_PCM_S16LE:
316
                case CODEC_ID_PCM_S16BE:
317
                case CODEC_ID_PCM_U16LE:
318
                case CODEC_ID_PCM_U16BE:
319
                case CODEC_ID_PCM_S8:
320
                case CODEC_ID_PCM_U8:
321
                case CODEC_ID_PCM_ALAW:
322
                case CODEC_ID_PCM_MULAW:
323
                    st->codec->frame_size = 1;
324
                    break;
325
                default:
326
                    /* This is probably wrong, but it prevents a crash later */
327
                    st->codec->frame_size = 1;
328
                    break;
329
                }
330
            } else if (type == CODEC_TYPE_VIDEO) {
331
                get_le32(pb);
332
                get_le32(pb);
333
                get_byte(pb);
334
                size = get_le16(pb); /* size */
335
                sizeX= get_le32(pb); /* size */
336
                st->codec->width = get_le32(pb);
337
                st->codec->height = get_le32(pb);
338
                /* not available for asf */
339
                get_le16(pb); /* panes */
340
                st->codec->bits_per_coded_sample = get_le16(pb); /* depth */
341
                tag1 = get_le32(pb);
342
                url_fskip(pb, 20);
343
//                av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);
344
                size= sizeX;
345
                if (size > 40) {
346
                    st->codec->extradata_size = size - 40;
347
                    st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
348
                    get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
349
                }
350

    
351
        /* Extract palette from extradata if bpp <= 8 */
352
        /* This code assumes that extradata contains only palette */
353
        /* This is true for all paletted codecs implemented in ffmpeg */
354
        if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
355
            st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
356
#ifdef WORDS_BIGENDIAN
357
            for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
358
                st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]);
359
#else
360
            memcpy(st->codec->palctrl->palette, st->codec->extradata,
361
                   FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
362
#endif
363
            st->codec->palctrl->palette_changed = 1;
364
        }
365

    
366
                st->codec->codec_tag = tag1;
367
                st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1);
368
                if(tag1 == MKTAG('D', 'V', 'R', ' '))
369
                    st->need_parsing = AVSTREAM_PARSE_FULL;
370
            }
371
            pos2 = url_ftell(pb);
372
            url_fskip(pb, gsize - (pos2 - pos1 + 24));
373
        } else if (!memcmp(&g, &comment_header, sizeof(GUID))) {
374
            int len1, len2, len3, len4, len5;
375

    
376
            len1 = get_le16(pb);
377
            len2 = get_le16(pb);
378
            len3 = get_le16(pb);
379
            len4 = get_le16(pb);
380
            len5 = get_le16(pb);
381
            get_tag(s, "title"    , 0, len1);
382
            get_tag(s, "author"   , 0, len2);
383
            get_tag(s, "copyright", 0, len3);
384
            get_tag(s, "comment"  , 0, len4);
385
            url_fskip(pb, len5);
386
        } else if (!memcmp(&g, &stream_bitrate_guid, sizeof(GUID))) {
387
            int stream_count = get_le16(pb);
388
            int j;
389

    
390
//            av_log(s, AV_LOG_ERROR, "stream bitrate properties\n");
391
//            av_log(s, AV_LOG_ERROR, "streams %d\n", streams);
392
            for(j = 0; j < stream_count; j++) {
393
                int flags, bitrate, stream_id;
394

    
395
                flags= get_le16(pb);
396
                bitrate= get_le32(pb);
397
                stream_id= (flags & 0x7f);
398
//                av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate);
399
                asf->stream_bitrates[stream_id]= bitrate;
400
            }
401
       } else if (!memcmp(&g, &extended_content_header, sizeof(GUID))) {
402
                int desc_count, i;
403

    
404
                desc_count = get_le16(pb);
405
                for(i=0;i<desc_count;i++)
406
                {
407
                        int name_len,value_type,value_len;
408
                        char name[1024];
409

    
410
                        name_len = get_le16(pb);
411
                        get_str16_nolen(pb, name_len, name, sizeof(name));
412
                        value_type = get_le16(pb);
413
                        value_len = get_le16(pb);
414
                        get_tag(s, name, value_type, value_len);
415
                }
416
        } else if (!memcmp(&g, &metadata_header, sizeof(GUID))) {
417
            int n, stream_num, name_len, value_len, value_type, value_num;
418
            n = get_le16(pb);
419

    
420
            for(i=0;i<n;i++) {
421
                char name[1024];
422

    
423
                get_le16(pb); //lang_list_index
424
                stream_num= get_le16(pb);
425
                name_len=   get_le16(pb);
426
                value_type= get_le16(pb);
427
                value_len=  get_le32(pb);
428

    
429
                get_str16_nolen(pb, name_len, name, sizeof(name));
430
//av_log(s, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name);
431
                value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere
432
                url_fskip(pb, value_len - 2);
433

    
434
                if(stream_num<128){
435
                    if     (!strcmp(name, "AspectRatioX")) dar[stream_num].num= value_num;
436
                    else if(!strcmp(name, "AspectRatioY")) dar[stream_num].den= value_num;
437
                }
438
            }
439
        } else if (!memcmp(&g, &ext_stream_header, sizeof(GUID))) {
440
            int ext_len, payload_ext_ct, stream_ct;
441
            uint32_t ext_d, leak_rate, stream_num;
442
            int64_t pos_ex_st;
443
            pos_ex_st = url_ftell(pb);
444

    
445
            get_le64(pb); // starttime
446
            get_le64(pb); // endtime
447
            leak_rate = get_le32(pb); // leak-datarate
448
            get_le32(pb); // bucket-datasize
449
            get_le32(pb); // init-bucket-fullness
450
            get_le32(pb); // alt-leak-datarate
451
            get_le32(pb); // alt-bucket-datasize
452
            get_le32(pb); // alt-init-bucket-fullness
453
            get_le32(pb); // max-object-size
454
            get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)
455
            stream_num = get_le16(pb); // stream-num
456
            get_le16(pb); // stream-language-id-index
457
            get_le64(pb); // avg frametime in 100ns units
458
            stream_ct = get_le16(pb); //stream-name-count
459
            payload_ext_ct = get_le16(pb); //payload-extension-system-count
460

    
461
            if (stream_num < 128)
462
                bitrate[stream_num] = leak_rate;
463

    
464
            for (i=0; i<stream_ct; i++){
465
                get_le16(pb);
466
                ext_len = get_le16(pb);
467
                url_fseek(pb, ext_len, SEEK_CUR);
468
            }
469

    
470
            for (i=0; i<payload_ext_ct; i++){
471
                get_guid(pb, &g);
472
                ext_d=get_le16(pb);
473
                ext_len=get_le32(pb);
474
                url_fseek(pb, ext_len, SEEK_CUR);
475
            }
476

    
477
            // there could be a optional stream properties object to follow
478
            // if so the next iteration will pick it up
479
        } else if (!memcmp(&g, &head1_guid, sizeof(GUID))) {
480
            int v1, v2;
481
            get_guid(pb, &g);
482
            v1 = get_le32(pb);
483
            v2 = get_le16(pb);
484
#if 0
485
        } else if (!memcmp(&g, &codec_comment_header, sizeof(GUID))) {
486
            int len, v1, n, num;
487
            char str[256], *q;
488
            char tag[16];
489

490
            get_guid(pb, &g);
491
            print_guid(&g);
492

493
            n = get_le32(pb);
494
            for(i=0;i<n;i++) {
495
                num = get_le16(pb); /* stream number */
496
                get_str16(pb, str, sizeof(str));
497
                get_str16(pb, str, sizeof(str));
498
                len = get_le16(pb);
499
                q = tag;
500
                while (len > 0) {
501
                    v1 = get_byte(pb);
502
                    if ((q - tag) < sizeof(tag) - 1)
503
                        *q++ = v1;
504
                    len--;
505
                }
506
                *q = '\0';
507
            }
508
#endif
509
        } else if (url_feof(pb)) {
510
            return -1;
511
        } else {
512
            url_fseek(pb, gsize - 24, SEEK_CUR);
513
        }
514
    }
515
    get_guid(pb, &g);
516
    get_le64(pb);
517
    get_byte(pb);
518
    get_byte(pb);
519
    if (url_feof(pb))
520
        return -1;
521
    asf->data_offset = url_ftell(pb);
522
    asf->packet_size_left = 0;
523

    
524

    
525
    for(i=0; i<128; i++){
526
        int stream_num= asf->asfid2avid[i];
527
        if(stream_num>=0){
528
            AVStream *st = s->streams[stream_num];
529
            if (!st->codec->bit_rate)
530
                st->codec->bit_rate = bitrate[i];
531
            if (dar[i].num > 0 && dar[i].den > 0)
532
                av_reduce(&st->sample_aspect_ratio.num,
533
                          &st->sample_aspect_ratio.den,
534
                          dar[i].num, dar[i].den, INT_MAX);
535
//av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
536
        }
537
    }
538

    
539
    return 0;
540
}
541

    
542
#define DO_2BITS(bits, var, defval) \
543
    switch (bits & 3) \
544
    { \
545
    case 3: var = get_le32(pb); rsize += 4; break; \
546
    case 2: var = get_le16(pb); rsize += 2; break; \
547
    case 1: var = get_byte(pb); rsize++; break; \
548
    default: var = defval; break; \
549
    }
550

    
551
int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb)
552
{
553
    ASFContext *asf = s->priv_data;
554
    uint32_t packet_length, padsize;
555
    int rsize = 8;
556
    int c, d, e, off;
557

    
558
    off= (url_ftell(pb) - s->data_offset) % asf->packet_size + 3;
559

    
560
    c=d=e=-1;
561
    while(off-- > 0){
562
        c=d; d=e;
563
        e= get_byte(pb);
564
        if(c == 0x82 && !d && !e)
565
            break;
566
    }
567

    
568
    if (c != 0x82) {
569
        if (!url_feof(pb))
570
            av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, url_ftell(pb));
571
    }
572
    if ((c & 0x8f) == 0x82) {
573
        if (d || e) {
574
            if (!url_feof(pb))
575
                av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
576
            return -1;
577
        }
578
        c= get_byte(pb);
579
        d= get_byte(pb);
580
        rsize+=3;
581
    }else{
582
        url_fseek(pb, -1, SEEK_CUR); //FIXME
583
    }
584

    
585
    asf->packet_flags    = c;
586
    asf->packet_property = d;
587

    
588
    DO_2BITS(asf->packet_flags >> 5, packet_length, asf->packet_size);
589
    DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored
590
    DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
591

    
592
    //the following checks prevent overflows and infinite loops
593
    if(packet_length >= (1U<<29)){
594
        av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb));
595
        return -1;
596
    }
597
    if(padsize >= packet_length){
598
        av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, url_ftell(pb));
599
        return -1;
600
    }
601

    
602
    asf->packet_timestamp = get_le32(pb);
603
    get_le16(pb); /* duration */
604
    // rsize has at least 11 bytes which have to be present
605

    
606
    if (asf->packet_flags & 0x01) {
607
        asf->packet_segsizetype = get_byte(pb); rsize++;
608
        asf->packet_segments = asf->packet_segsizetype & 0x3f;
609
    } else {
610
        asf->packet_segments = 1;
611
        asf->packet_segsizetype = 0x80;
612
    }
613
    asf->packet_size_left = packet_length - padsize - rsize;
614
    if (packet_length < asf->hdr.min_pktsize)
615
        padsize += asf->hdr.min_pktsize - packet_length;
616
    asf->packet_padsize = padsize;
617
    dprintf(s, "packet: size=%d padsize=%d  left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left);
618
    return 0;
619
}
620

    
621
/**
622
 *
623
 * @return <0 if error
624
 */
625
static int asf_read_frame_header(AVFormatContext *s, ByteIOContext *pb){
626
    ASFContext *asf = s->priv_data;
627
    int rsize = 1;
628
    int num = get_byte(pb);
629
    int64_t ts0, ts1;
630

    
631
    asf->packet_segments--;
632
    asf->packet_key_frame = num >> 7;
633
    asf->stream_index = asf->asfid2avid[num & 0x7f];
634
    // sequence should be ignored!
635
    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
636
    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
637
    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
638
//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size);
639
    if (asf->packet_replic_size >= 8) {
640
        asf->packet_obj_size = get_le32(pb);
641
        if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
642
            av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
643
            return -1;
644
        }
645
        asf->packet_frag_timestamp = get_le32(pb); // timestamp
646
        if(asf->packet_replic_size >= 8+38+4){
647
//            for(i=0; i<asf->packet_replic_size-8; i++)
648
//                av_log(s, AV_LOG_DEBUG, "%02X ",get_byte(pb));
649
//            av_log(s, AV_LOG_DEBUG, "\n");
650
            url_fskip(pb, 10);
651
            ts0= get_le64(pb);
652
            ts1= get_le64(pb);
653
            url_fskip(pb, 12);
654
            get_le32(pb);
655
            url_fskip(pb, asf->packet_replic_size - 8 - 38 - 4);
656
            if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
657
            else         asf->packet_frag_timestamp= AV_NOPTS_VALUE;
658
        }else
659
            url_fskip(pb, asf->packet_replic_size - 8);
660
        rsize += asf->packet_replic_size; // FIXME - check validity
661
    } else if (asf->packet_replic_size==1){
662
        // multipacket - frag_offset is beginning timestamp
663
        asf->packet_time_start = asf->packet_frag_offset;
664
        asf->packet_frag_offset = 0;
665
        asf->packet_frag_timestamp = asf->packet_timestamp;
666

    
667
        asf->packet_time_delta = get_byte(pb);
668
        rsize++;
669
    }else if(asf->packet_replic_size!=0){
670
        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
671
        return -1;
672
    }
673
    if (asf->packet_flags & 0x01) {
674
        DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
675
        if(asf->packet_frag_size > asf->packet_size_left - rsize){
676
            av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid\n");
677
            return -1;
678
        }
679
        //printf("Fragsize %d\n", asf->packet_frag_size);
680
    } else {
681
        asf->packet_frag_size = asf->packet_size_left - rsize;
682
        //printf("Using rest  %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);
683
    }
684
    if (asf->packet_replic_size == 1) {
685
        asf->packet_multi_size = asf->packet_frag_size;
686
        if (asf->packet_multi_size > asf->packet_size_left)
687
            return -1;
688
    }
689
    asf->packet_size_left -= rsize;
690
    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);
691

    
692
    return 0;
693
}
694

    
695
int ff_asf_parse_packet(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt)
696
{
697
    ASFContext *asf = s->priv_data;
698
    ASFStream *asf_st = 0;
699
    for (;;) {
700
        if(url_feof(pb))
701
            return AVERROR(EIO);
702
        if (asf->packet_size_left < FRAME_HEADER_SIZE
703
            || asf->packet_segments < 1) {
704
            //asf->packet_size_left <= asf->packet_padsize) {
705
            int ret = asf->packet_size_left + asf->packet_padsize;
706
            //printf("PacketLeftSize:%d  Pad:%d Pos:%"PRId64"\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb));
707
            assert(ret>=0);
708
            /* fail safe */
709
            url_fskip(pb, ret);
710

    
711
            asf->packet_pos= url_ftell(pb);
712
            if (asf->data_object_size != (uint64_t)-1 &&
713
                (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
714
                return AVERROR(EIO); /* Do not exceed the size of the data object */
715
            return 1;
716
        }
717
        if (asf->packet_time_start == 0) {
718
            if(asf_read_frame_header(s, pb) < 0){
719
                asf->packet_segments= 0;
720
                continue;
721
            }
722
            if (asf->stream_index < 0
723
                || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL
724
                || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)
725
                ) {
726
                asf->packet_time_start = 0;
727
                /* unhandled packet (should not happen) */
728
                url_fskip(pb, asf->packet_frag_size);
729
                asf->packet_size_left -= asf->packet_frag_size;
730
                if(asf->stream_index < 0)
731
                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
732
                continue;
733
            }
734
            asf->asf_st = s->streams[asf->stream_index]->priv_data;
735
        }
736
        asf_st = asf->asf_st;
737

    
738
        if (asf->packet_replic_size == 1) {
739
            // frag_offset is here used as the beginning timestamp
740
            asf->packet_frag_timestamp = asf->packet_time_start;
741
            asf->packet_time_start += asf->packet_time_delta;
742
            asf->packet_obj_size = asf->packet_frag_size = get_byte(pb);
743
            asf->packet_size_left--;
744
            asf->packet_multi_size--;
745
            if (asf->packet_multi_size < asf->packet_obj_size)
746
            {
747
                asf->packet_time_start = 0;
748
                url_fskip(pb, asf->packet_multi_size);
749
                asf->packet_size_left -= asf->packet_multi_size;
750
                continue;
751
            }
752
            asf->packet_multi_size -= asf->packet_obj_size;
753
            //printf("COMPRESS size  %d  %d  %d   ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size);
754
        }
755
        if(   /*asf->packet_frag_size == asf->packet_obj_size*/
756
              asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size
757
           && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){
758
            av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
759
                asf_st->frag_offset, asf->packet_frag_size,
760
                asf->packet_obj_size, asf_st->pkt.size);
761
            asf->packet_obj_size= asf_st->pkt.size;
762
        }
763

    
764
        if (   asf_st->pkt.size != asf->packet_obj_size
765
            || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { //FIXME is this condition sufficient?
766
            if(asf_st->pkt.data){
767
                av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size);
768
                asf_st->frag_offset = 0;
769
                av_free_packet(&asf_st->pkt);
770
            }
771
            /* new packet */
772
            av_new_packet(&asf_st->pkt, asf->packet_obj_size);
773
            asf_st->seq = asf->packet_seq;
774
            asf_st->pkt.dts = asf->packet_frag_timestamp;
775
            asf_st->pkt.stream_index = asf->stream_index;
776
            asf_st->pkt.pos =
777
            asf_st->packet_pos= asf->packet_pos;
778
//printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n",
779
//asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,
780
//s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size);
781
            if (s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO)
782
                asf->packet_key_frame = 1;
783
            if (asf->packet_key_frame)
784
                asf_st->pkt.flags |= PKT_FLAG_KEY;
785
        }
786

    
787
        /* read data */
788
        //printf("READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",
789
        //       asf->packet_size, asf_st->pkt.size, asf->packet_frag_offset,
790
        //       asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);
791
        asf->packet_size_left -= asf->packet_frag_size;
792
        if (asf->packet_size_left < 0)
793
            continue;
794

    
795
        if(   asf->packet_frag_offset >= asf_st->pkt.size
796
           || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){
797
            av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
798
                asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
799
            continue;
800
        }
801

    
802
        get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,
803
                   asf->packet_frag_size);
804
        if (s->key && s->keylen == 20)
805
            ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
806
                            asf->packet_frag_size);
807
        asf_st->frag_offset += asf->packet_frag_size;
808
        /* test if whole packet is read */
809
        if (asf_st->frag_offset == asf_st->pkt.size) {
810
            //workaround for macroshit radio DVR-MS files
811
            if(   s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO
812
               && asf_st->pkt.size > 100){
813
                int i;
814
                for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
815
                if(i == asf_st->pkt.size){
816
                    av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
817
                    asf_st->frag_offset = 0;
818
                    av_free_packet(&asf_st->pkt);
819
                    continue;
820
                }
821
            }
822

    
823
            /* return packet */
824
            if (asf_st->ds_span > 1) {
825
              if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){
826
                    av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * ds_span (%d %d %d)\n", asf_st->pkt.size, asf_st->ds_packet_size, asf_st->ds_span);
827
              }else{
828
                /* packet descrambling */
829
                uint8_t *newdata = av_malloc(asf_st->pkt.size);
830
                if (newdata) {
831
                    int offset = 0;
832
                    while (offset < asf_st->pkt.size) {
833
                        int off = offset / asf_st->ds_chunk_size;
834
                        int row = off / asf_st->ds_span;
835
                        int col = off % asf_st->ds_span;
836
                        int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
837
                        //printf("off:%d  row:%d  col:%d  idx:%d\n", off, row, col, idx);
838

    
839
                        assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
840
                        assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
841
                        memcpy(newdata + offset,
842
                               asf_st->pkt.data + idx * asf_st->ds_chunk_size,
843
                               asf_st->ds_chunk_size);
844
                        offset += asf_st->ds_chunk_size;
845
                    }
846
                    av_free(asf_st->pkt.data);
847
                    asf_st->pkt.data = newdata;
848
                }
849
              }
850
            }
851
            asf_st->frag_offset = 0;
852
            *pkt= asf_st->pkt;
853
            //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size);
854
            asf_st->pkt.size = 0;
855
            asf_st->pkt.data = 0;
856
            break; // packet completed
857
        }
858
    }
859
    return 0;
860
}
861

    
862
static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
863
{
864
    ASFContext *asf = s->priv_data;
865

    
866
    for (;;) {
867
        int ret;
868

    
869
        /* parse cached packets, if any */
870
        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
871
            return ret;
872
        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
873
            assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
874
        asf->packet_time_start = 0;
875
    }
876

    
877
    return 0;
878
}
879

    
880
// Added to support seeking after packets have been read
881
// If information is not reset, read_packet fails due to
882
// leftover information from previous reads
883
static void asf_reset_header(AVFormatContext *s)
884
{
885
    ASFContext *asf = s->priv_data;
886
    ASFStream *asf_st;
887
    int i;
888

    
889
    asf->packet_nb_frames = 0;
890
    asf->packet_size_left = 0;
891
    asf->packet_segments = 0;
892
    asf->packet_flags = 0;
893
    asf->packet_property = 0;
894
    asf->packet_timestamp = 0;
895
    asf->packet_segsizetype = 0;
896
    asf->packet_segments = 0;
897
    asf->packet_seq = 0;
898
    asf->packet_replic_size = 0;
899
    asf->packet_key_frame = 0;
900
    asf->packet_padsize = 0;
901
    asf->packet_frag_offset = 0;
902
    asf->packet_frag_size = 0;
903
    asf->packet_frag_timestamp = 0;
904
    asf->packet_multi_size = 0;
905
    asf->packet_obj_size = 0;
906
    asf->packet_time_delta = 0;
907
    asf->packet_time_start = 0;
908

    
909
    for(i=0; i<s->nb_streams; i++){
910
        asf_st= s->streams[i]->priv_data;
911
        av_free_packet(&asf_st->pkt);
912
        asf_st->frag_offset=0;
913
        asf_st->seq=0;
914
    }
915
    asf->asf_st= NULL;
916
}
917

    
918
static int asf_read_close(AVFormatContext *s)
919
{
920
    int i;
921

    
922
    asf_reset_header(s);
923
    for(i=0;i<s->nb_streams;i++) {
924
        AVStream *st = s->streams[i];
925
        av_free(st->codec->palctrl);
926
    }
927
    return 0;
928
}
929

    
930
static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
931
{
932
    ASFContext *asf = s->priv_data;
933
    AVPacket pkt1, *pkt = &pkt1;
934
    ASFStream *asf_st;
935
    int64_t pts;
936
    int64_t pos= *ppos;
937
    int i;
938
    int64_t start_pos[s->nb_streams];
939

    
940
    for(i=0; i<s->nb_streams; i++){
941
        start_pos[i]= pos;
942
    }
943

    
944
    pos= (pos+asf->packet_size-1-s->data_offset)/asf->packet_size*asf->packet_size+ s->data_offset;
945
    *ppos= pos;
946
    url_fseek(s->pb, pos, SEEK_SET);
947

    
948
//printf("asf_read_pts\n");
949
    asf_reset_header(s);
950
    for(;;){
951
        if (av_read_frame(s, pkt) < 0){
952
            av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
953
            return AV_NOPTS_VALUE;
954
        }
955

    
956
        pts= pkt->pts;
957

    
958
        av_free_packet(pkt);
959
        if(pkt->flags&PKT_FLAG_KEY){
960
            i= pkt->stream_index;
961

    
962
            asf_st= s->streams[i]->priv_data;
963

    
964
//            assert((asf_st->packet_pos - s->data_offset) % asf->packet_size == 0);
965
            pos= asf_st->packet_pos;
966

    
967
            av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
968
            start_pos[i]= asf_st->packet_pos + 1;
969

    
970
            if(pkt->stream_index == stream_index)
971
               break;
972
        }
973
    }
974

    
975
    *ppos= pos;
976
//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts);
977

    
978
    return pts;
979
}
980

    
981
static void asf_build_simple_index(AVFormatContext *s, int stream_index)
982
{
983
    GUID g;
984
    ASFContext *asf = s->priv_data;
985
    int64_t gsize, itime;
986
    int64_t pos, current_pos, index_pts;
987
    int i;
988
    int pct,ict;
989

    
990
    current_pos = url_ftell(s->pb);
991

    
992
    url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
993
    get_guid(s->pb, &g);
994
    if (!memcmp(&g, &index_guid, sizeof(GUID))) {
995
        gsize = get_le64(s->pb);
996
        get_guid(s->pb, &g);
997
        itime=get_le64(s->pb);
998
        pct=get_le32(s->pb);
999
        ict=get_le32(s->pb);
1000
        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
1001

    
1002
        for (i=0;i<ict;i++){
1003
            int pktnum=get_le32(s->pb);
1004
            int pktct =get_le16(s->pb);
1005
            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
1006

    
1007
            pos=s->data_offset + asf->packet_size*(int64_t)pktnum;
1008
            index_pts=av_rescale(itime, i, 10000);
1009

    
1010
            av_add_index_entry(s->streams[stream_index], pos, index_pts, asf->packet_size, 0, AVINDEX_KEYFRAME);
1011
        }
1012
        asf->index_read= 1;
1013
    }
1014
    url_fseek(s->pb, current_pos, SEEK_SET);
1015
}
1016

    
1017
static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
1018
{
1019
    ASFContext *asf = s->priv_data;
1020
    AVStream *st = s->streams[stream_index];
1021
    int64_t pos;
1022
    int index;
1023

    
1024
    if (asf->packet_size <= 0)
1025
        return -1;
1026

    
1027
    /* Try using the protocol's read_seek if available */
1028
    if(s->pb) {
1029
        int ret = av_url_read_fseek(s->pb, stream_index, pts, flags);
1030
        if(ret >= 0)
1031
            asf_reset_header(s);
1032
        if (ret != AVERROR(ENOSYS))
1033
            return ret;
1034
    }
1035

    
1036
    if (!asf->index_read)
1037
        asf_build_simple_index(s, stream_index);
1038

    
1039
    if(!(asf->index_read && st->index_entries)){
1040
        if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
1041
            return -1;
1042
    }else{
1043
        index= av_index_search_timestamp(st, pts, flags);
1044
        if(index<0)
1045
            return -1;
1046

    
1047
        /* find the position */
1048
        pos = st->index_entries[index].pos;
1049
        pts = st->index_entries[index].timestamp;
1050

    
1051
    // various attempts to find key frame have failed so far
1052
    //    asf_reset_header(s);
1053
    //    url_fseek(s->pb, pos, SEEK_SET);
1054
    //    key_pos = pos;
1055
    //     for(i=0;i<16;i++){
1056
    //         pos = url_ftell(s->pb);
1057
    //         if (av_read_frame(s, &pkt) < 0){
1058
    //             av_log(s, AV_LOG_INFO, "seek failed\n");
1059
    //             return -1;
1060
    //         }
1061
    //         asf_st = s->streams[stream_index]->priv_data;
1062
    //         pos += st->parser->frame_offset;
1063
    //
1064
    //         if (pkt.size > b) {
1065
    //             b = pkt.size;
1066
    //             key_pos = pos;
1067
    //         }
1068
    //
1069
    //         av_free_packet(&pkt);
1070
    //     }
1071

    
1072
        /* do the seek */
1073
        av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
1074
        url_fseek(s->pb, pos, SEEK_SET);
1075
    }
1076
    asf_reset_header(s);
1077
    return 0;
1078
}
1079

    
1080
AVInputFormat asf_demuxer = {
1081
    "asf",
1082
    NULL_IF_CONFIG_SMALL("ASF format"),
1083
    sizeof(ASFContext),
1084
    asf_probe,
1085
    asf_read_header,
1086
    asf_read_packet,
1087
    asf_read_close,
1088
    asf_read_seek,
1089
    asf_read_pts,
1090
};