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
29void 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
37static const GUID index_guid = {
38    0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
39};
40
41static 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) \
51if (!memcmp(g, &cmp, sizeof(GUID))) \
52    dprintf(NULL, "(GUID: %s) ", #cmp)
53
54static void print_guid(const GUID *g)
55{
56    int i;
57    PRINT_IF_GUID(g, ff_asf_header);
58    else PRINT_IF_GUID(g, ff_asf_file_header);
59    else PRINT_IF_GUID(g, ff_asf_stream_header);
60    else PRINT_IF_GUID(g, ff_asf_audio_stream);
61    else PRINT_IF_GUID(g, ff_asf_audio_conceal_none);
62    else PRINT_IF_GUID(g, ff_asf_video_stream);
63    else PRINT_IF_GUID(g, ff_asf_video_conceal_none);
64    else PRINT_IF_GUID(g, ff_asf_command_stream);
65    else PRINT_IF_GUID(g, ff_asf_comment_header);
66    else PRINT_IF_GUID(g, ff_asf_codec_comment_header);
67    else PRINT_IF_GUID(g, ff_asf_codec_comment1_header);
68    else PRINT_IF_GUID(g, ff_asf_data_header);
69    else PRINT_IF_GUID(g, index_guid);
70    else PRINT_IF_GUID(g, ff_asf_head1_guid);
71    else PRINT_IF_GUID(g, ff_asf_head2_guid);
72    else PRINT_IF_GUID(g, ff_asf_my_guid);
73    else PRINT_IF_GUID(g, ff_asf_ext_stream_header);
74    else PRINT_IF_GUID(g, ff_asf_extended_content_header);
75    else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header);
76    else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream);
77    else PRINT_IF_GUID(g, ff_asf_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
90static 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
97static 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
114static 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
125static int asf_probe(AVProbeData *pd)
126{
127    /* check file header */
128    if (!memcmp(pd->buf, &ff_asf_header, sizeof(GUID)))
129        return AVPROBE_SCORE_MAX;
130    else
131        return 0;
132}
133
134static 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
144static 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
161static 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, &ff_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, &ff_asf_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, &ff_asf_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            s->packet_size = asf->hdr.max_pktsize;
216        } else if (!memcmp(&g, &ff_asf_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, &ff_asf_audio_stream, sizeof(GUID))) {
244                type = CODEC_TYPE_AUDIO;
245            } else if (!memcmp(&g, &ff_asf_video_stream, sizeof(GUID))) {
246                type = CODEC_TYPE_VIDEO;
247            } else if (!memcmp(&g, &ff_asf_command_stream, sizeof(GUID))) {
248                type = CODEC_TYPE_DATA;
249            } else if (!memcmp(&g, &ff_asf_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, &ff_asf_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, &ff_asf_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, &ff_asf_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, &ff_asf_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, &ff_asf_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, &ff_asf_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, &ff_asf_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
551int 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= 32768;
559    if (s->packet_size > 0)
560        off= (url_ftell(pb) - s->data_offset) % s->packet_size + 3;
561
562    c=d=e=-1;
563    while(off-- > 0){
564        c=d; d=e;
565        e= get_byte(pb);
566        if(c == 0x82 && !d && !e)
567            break;
568    }
569
570    if (c != 0x82) {
571        if (!url_feof(pb))
572            av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, url_ftell(pb));
573    }
574    if ((c & 0x8f) == 0x82) {
575        if (d || e) {
576            if (!url_feof(pb))
577                av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
578            return -1;
579        }
580        c= get_byte(pb);
581        d= get_byte(pb);
582        rsize+=3;
583    }else{
584        url_fseek(pb, -1, SEEK_CUR); //FIXME
585    }
586
587    asf->packet_flags    = c;
588    asf->packet_property = d;
589
590    DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size);
591    DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored
592    DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
593
594    //the following checks prevent overflows and infinite loops
595    if(!packet_length || packet_length >= (1U<<29)){
596        av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb));
597        return -1;
598    }
599    if(padsize >= packet_length){
600        av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, url_ftell(pb));
601        return -1;
602    }
603
604    asf->packet_timestamp = get_le32(pb);
605    get_le16(pb); /* duration */
606    // rsize has at least 11 bytes which have to be present
607
608    if (asf->packet_flags & 0x01) {
609        asf->packet_segsizetype = get_byte(pb); rsize++;
610        asf->packet_segments = asf->packet_segsizetype & 0x3f;
611    } else {
612        asf->packet_segments = 1;
613        asf->packet_segsizetype = 0x80;
614    }
615    asf->packet_size_left = packet_length - padsize - rsize;
616    if (packet_length < asf->hdr.min_pktsize)
617        padsize += asf->hdr.min_pktsize - packet_length;
618    asf->packet_padsize = padsize;
619    dprintf(s, "packet: size=%d padsize=%d  left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left);
620    return 0;
621}
622
623/**
624 *
625 * @return <0 if error
626 */
627static int asf_read_frame_header(AVFormatContext *s, ByteIOContext *pb){
628    ASFContext *asf = s->priv_data;
629    int rsize = 1;
630    int num = get_byte(pb);
631    int64_t ts0, ts1;
632
633    asf->packet_segments--;
634    asf->packet_key_frame = num >> 7;
635    asf->stream_index = asf->asfid2avid[num & 0x7f];
636    // sequence should be ignored!
637    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
638    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
639    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
640//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);
641    if (asf->packet_replic_size >= 8) {
642        asf->packet_obj_size = get_le32(pb);
643        if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
644            av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
645            return -1;
646        }
647        asf->packet_frag_timestamp = get_le32(pb); // timestamp
648        if(asf->packet_replic_size >= 8+38+4){
649//            for(i=0; i<asf->packet_replic_size-8; i++)
650//                av_log(s, AV_LOG_DEBUG, "%02X ",get_byte(pb));
651//            av_log(s, AV_LOG_DEBUG, "\n");
652            url_fskip(pb, 10);
653            ts0= get_le64(pb);
654            ts1= get_le64(pb);
655            url_fskip(pb, 12);
656            get_le32(pb);
657            url_fskip(pb, asf->packet_replic_size - 8 - 38 - 4);
658            if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
659            else         asf->packet_frag_timestamp= AV_NOPTS_VALUE;
660        }else
661            url_fskip(pb, asf->packet_replic_size - 8);
662        rsize += asf->packet_replic_size; // FIXME - check validity
663    } else if (asf->packet_replic_size==1){
664        // multipacket - frag_offset is beginning timestamp
665        asf->packet_time_start = asf->packet_frag_offset;
666        asf->packet_frag_offset = 0;
667        asf->packet_frag_timestamp = asf->packet_timestamp;
668
669        asf->packet_time_delta = get_byte(pb);
670        rsize++;
671    }else if(asf->packet_replic_size!=0){
672        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
673        return -1;
674    }
675    if (asf->packet_flags & 0x01) {
676        DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
677        if(asf->packet_frag_size > asf->packet_size_left - rsize){
678            av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid\n");
679            return -1;
680        }
681        //printf("Fragsize %d\n", asf->packet_frag_size);
682    } else {
683        asf->packet_frag_size = asf->packet_size_left - rsize;
684        //printf("Using rest  %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);
685    }
686    if (asf->packet_replic_size == 1) {
687        asf->packet_multi_size = asf->packet_frag_size;
688        if (asf->packet_multi_size > asf->packet_size_left)
689            return -1;
690    }
691    asf->packet_size_left -= rsize;
692    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);
693
694    return 0;
695}
696
697int ff_asf_parse_packet(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt)
698{
699    ASFContext *asf = s->priv_data;
700    ASFStream *asf_st = 0;
701    for (;;) {
702        if(url_feof(pb))
703            return AVERROR(EIO);
704        if (asf->packet_size_left < FRAME_HEADER_SIZE
705            || asf->packet_segments < 1) {
706            //asf->packet_size_left <= asf->packet_padsize) {
707            int ret = asf->packet_size_left + asf->packet_padsize;
708            //printf("PacketLeftSize:%d  Pad:%d Pos:%"PRId64"\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb));
709            assert(ret>=0);
710            /* fail safe */
711            url_fskip(pb, ret);
712
713            asf->packet_pos= url_ftell(pb);
714            if (asf->data_object_size != (uint64_t)-1 &&
715                (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
716                return AVERROR(EIO); /* Do not exceed the size of the data object */
717            return 1;
718        }
719        if (asf->packet_time_start == 0) {
720            if(asf_read_frame_header(s, pb) < 0){
721                asf->packet_segments= 0;
722                continue;
723            }
724            if (asf->stream_index < 0
725                || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL
726                || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)
727                ) {
728                asf->packet_time_start = 0;
729                /* unhandled packet (should not happen) */
730                url_fskip(pb, asf->packet_frag_size);
731                asf->packet_size_left -= asf->packet_frag_size;
732                if(asf->stream_index < 0)
733                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
734                continue;
735            }
736            asf->asf_st = s->streams[asf->stream_index]->priv_data;
737        }
738        asf_st = asf->asf_st;
739
740        if (asf->packet_replic_size == 1) {
741            // frag_offset is here used as the beginning timestamp
742            asf->packet_frag_timestamp = asf->packet_time_start;
743            asf->packet_time_start += asf->packet_time_delta;
744            asf->packet_obj_size = asf->packet_frag_size = get_byte(pb);
745            asf->packet_size_left--;
746            asf->packet_multi_size--;
747            if (asf->packet_multi_size < asf->packet_obj_size)
748            {
749                asf->packet_time_start = 0;
750                url_fskip(pb, asf->packet_multi_size);
751                asf->packet_size_left -= asf->packet_multi_size;
752                continue;
753            }
754            asf->packet_multi_size -= asf->packet_obj_size;
755            //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);
756        }
757        if(   /*asf->packet_frag_size == asf->packet_obj_size*/
758              asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size
759           && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){
760            av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
761                asf_st->frag_offset, asf->packet_frag_size,
762                asf->packet_obj_size, asf_st->pkt.size);
763            asf->packet_obj_size= asf_st->pkt.size;
764        }
765
766        if (   asf_st->pkt.size != asf->packet_obj_size
767            || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { //FIXME is this condition sufficient?
768            if(asf_st->pkt.data){
769                av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size);
770                asf_st->frag_offset = 0;
771                av_free_packet(&asf_st->pkt);
772            }
773            /* new packet */
774            av_new_packet(&asf_st->pkt, asf->packet_obj_size);
775            asf_st->seq = asf->packet_seq;
776            asf_st->pkt.dts = asf->packet_frag_timestamp;
777            asf_st->pkt.stream_index = asf->stream_index;
778            asf_st->pkt.pos =
779            asf_st->packet_pos= asf->packet_pos;
780//printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n",
781//asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,
782//s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size);
783            if (s->streams[asf->stream_index]->codec->codec_type == CODEC_TYPE_AUDIO)
784                asf->packet_key_frame = 1;
785            if (asf->packet_key_frame)
786                asf_st->pkt.flags |= PKT_FLAG_KEY;
787        }
788
789        /* read data */
790        //printf("READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",
791        //       s->packet_size, asf_st->pkt.size, asf->packet_frag_offset,
792        //       asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);
793        asf->packet_size_left -= asf->packet_frag_size;
794        if (asf->packet_size_left < 0)
795            continue;
796
797        if(   asf->packet_frag_offset >= asf_st->pkt.size
798           || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){
799            av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
800                asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
801            continue;
802        }
803
804        get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,
805                   asf->packet_frag_size);
806        if (s->key && s->keylen == 20)
807            ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
808                            asf->packet_frag_size);
809        asf_st->frag_offset += asf->packet_frag_size;
810        /* test if whole packet is read */
811        if (asf_st->frag_offset == asf_st->pkt.size) {
812            //workaround for macroshit radio DVR-MS files
813            if(   s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO
814               && asf_st->pkt.size > 100){
815                int i;
816                for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
817                if(i == asf_st->pkt.size){
818                    av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
819                    asf_st->frag_offset = 0;
820                    av_free_packet(&asf_st->pkt);
821                    continue;
822                }
823            }
824
825            /* return packet */
826            if (asf_st->ds_span > 1) {
827              if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){
828                    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);
829              }else{
830                /* packet descrambling */
831                uint8_t *newdata = av_malloc(asf_st->pkt.size);
832                if (newdata) {
833                    int offset = 0;
834                    while (offset < asf_st->pkt.size) {
835                        int off = offset / asf_st->ds_chunk_size;
836                        int row = off / asf_st->ds_span;
837                        int col = off % asf_st->ds_span;
838                        int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
839                        //printf("off:%d  row:%d  col:%d  idx:%d\n", off, row, col, idx);
840
841                        assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
842                        assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
843                        memcpy(newdata + offset,
844                               asf_st->pkt.data + idx * asf_st->ds_chunk_size,
845                               asf_st->ds_chunk_size);
846                        offset += asf_st->ds_chunk_size;
847                    }
848                    av_free(asf_st->pkt.data);
849                    asf_st->pkt.data = newdata;
850                }
851              }
852            }
853            asf_st->frag_offset = 0;
854            *pkt= asf_st->pkt;
855            //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size);
856            asf_st->pkt.size = 0;
857            asf_st->pkt.data = 0;
858            break; // packet completed
859        }
860    }
861    return 0;
862}
863
864static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
865{
866    ASFContext *asf = s->priv_data;
867
868    for (;;) {
869        int ret;
870
871        /* parse cached packets, if any */
872        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
873            return ret;
874        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
875            assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
876        asf->packet_time_start = 0;
877    }
878
879    return 0;
880}
881
882// Added to support seeking after packets have been read
883// If information is not reset, read_packet fails due to
884// leftover information from previous reads
885static void asf_reset_header(AVFormatContext *s)
886{
887    ASFContext *asf = s->priv_data;
888    ASFStream *asf_st;
889    int i;
890
891    asf->packet_nb_frames = 0;
892    asf->packet_size_left = 0;
893    asf->packet_segments = 0;
894    asf->packet_flags = 0;
895    asf->packet_property = 0;
896    asf->packet_timestamp = 0;
897    asf->packet_segsizetype = 0;
898    asf->packet_segments = 0;
899    asf->packet_seq = 0;
900    asf->packet_replic_size = 0;
901    asf->packet_key_frame = 0;
902    asf->packet_padsize = 0;
903    asf->packet_frag_offset = 0;
904    asf->packet_frag_size = 0;
905    asf->packet_frag_timestamp = 0;
906    asf->packet_multi_size = 0;
907    asf->packet_obj_size = 0;
908    asf->packet_time_delta = 0;
909    asf->packet_time_start = 0;
910
911    for(i=0; i<s->nb_streams; i++){
912        asf_st= s->streams[i]->priv_data;
913        av_free_packet(&asf_st->pkt);
914        asf_st->frag_offset=0;
915        asf_st->seq=0;
916    }
917    asf->asf_st= NULL;
918}
919
920static int asf_read_close(AVFormatContext *s)
921{
922    int i;
923
924    asf_reset_header(s);
925    for(i=0;i<s->nb_streams;i++) {
926        AVStream *st = s->streams[i];
927        av_free(st->codec->palctrl);
928    }
929    return 0;
930}
931
932static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
933{
934    AVPacket pkt1, *pkt = &pkt1;
935    ASFStream *asf_st;
936    int64_t pts;
937    int64_t pos= *ppos;
938    int i;
939    int64_t start_pos[s->nb_streams];
940
941    for(i=0; i<s->nb_streams; i++){
942        start_pos[i]= pos;
943    }
944
945    if (s->packet_size > 0)
946        pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
947    *ppos= pos;
948    url_fseek(s->pb, pos, SEEK_SET);
949
950//printf("asf_read_pts\n");
951    asf_reset_header(s);
952    for(;;){
953        if (av_read_frame(s, pkt) < 0){
954            av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
955            return AV_NOPTS_VALUE;
956        }
957
958        pts= pkt->pts;
959
960        av_free_packet(pkt);
961        if(pkt->flags&PKT_FLAG_KEY){
962            i= pkt->stream_index;
963
964            asf_st= s->streams[i]->priv_data;
965
966//            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
967            pos= asf_st->packet_pos;
968
969            av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
970            start_pos[i]= asf_st->packet_pos + 1;
971
972            if(pkt->stream_index == stream_index)
973               break;
974        }
975    }
976
977    *ppos= pos;
978//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts);
979
980    return pts;
981}
982
983static void asf_build_simple_index(AVFormatContext *s, int stream_index)
984{
985    GUID g;
986    ASFContext *asf = s->priv_data;
987    int64_t gsize, itime;
988    int64_t pos, current_pos, index_pts;
989    int i;
990    int pct,ict;
991
992    current_pos = url_ftell(s->pb);
993
994    url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
995    get_guid(s->pb, &g);
996    if (!memcmp(&g, &index_guid, sizeof(GUID))) {
997        gsize = get_le64(s->pb);
998        get_guid(s->pb, &g);
999        itime=get_le64(s->pb);
1000        pct=get_le32(s->pb);
1001        ict=get_le32(s->pb);
1002        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
1003
1004        for (i=0;i<ict;i++){
1005            int pktnum=get_le32(s->pb);
1006            int pktct =get_le16(s->pb);
1007            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
1008
1009            pos=s->data_offset + s->packet_size*(int64_t)pktnum;
1010            index_pts=av_rescale(itime, i, 10000);
1011
1012            av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
1013        }
1014        asf->index_read= 1;
1015    }
1016    url_fseek(s->pb, current_pos, SEEK_SET);
1017}
1018
1019static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
1020{
1021    ASFContext *asf = s->priv_data;
1022    AVStream *st = s->streams[stream_index];
1023    int64_t pos;
1024    int index;
1025
1026    if (s->packet_size <= 0)
1027        return -1;
1028
1029    /* Try using the protocol's read_seek if available */
1030    if(s->pb) {
1031        int ret = av_url_read_fseek(s->pb, stream_index, pts, flags);
1032        if(ret >= 0)
1033            asf_reset_header(s);
1034        if (ret != AVERROR(ENOSYS))
1035            return ret;
1036    }
1037
1038    if (!asf->index_read)
1039        asf_build_simple_index(s, stream_index);
1040
1041    if(!(asf->index_read && st->index_entries)){
1042        if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
1043            return -1;
1044    }else{
1045        index= av_index_search_timestamp(st, pts, flags);
1046        if(index<0)
1047            return -1;
1048
1049        /* find the position */
1050        pos = st->index_entries[index].pos;
1051        pts = st->index_entries[index].timestamp;
1052
1053    // various attempts to find key frame have failed so far
1054    //    asf_reset_header(s);
1055    //    url_fseek(s->pb, pos, SEEK_SET);
1056    //    key_pos = pos;
1057    //     for(i=0;i<16;i++){
1058    //         pos = url_ftell(s->pb);
1059    //         if (av_read_frame(s, &pkt) < 0){
1060    //             av_log(s, AV_LOG_INFO, "seek failed\n");
1061    //             return -1;
1062    //         }
1063    //         asf_st = s->streams[stream_index]->priv_data;
1064    //         pos += st->parser->frame_offset;
1065    //
1066    //         if (pkt.size > b) {
1067    //             b = pkt.size;
1068    //             key_pos = pos;
1069    //         }
1070    //
1071    //         av_free_packet(&pkt);
1072    //     }
1073
1074        /* do the seek */
1075        av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
1076        url_fseek(s->pb, pos, SEEK_SET);
1077    }
1078    asf_reset_header(s);
1079    return 0;
1080}
1081
1082AVInputFormat asf_demuxer = {
1083    "asf",
1084    NULL_IF_CONFIG_SMALL("ASF format"),
1085    sizeof(ASFContext),
1086    asf_probe,
1087    asf_read_header,
1088    asf_read_packet,
1089    asf_read_close,
1090    asf_read_seek,
1091    asf_read_pts,
1092    .metadata_conv = ff_asf_metadata_conv,
1093};
1094