1 /*
2  * Microsoft Advanced Streaming Format demuxer
3  * Copyright (c) 2014 Alexandra Hájková
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/attributes.h"
23 #include "libavutil/common.h"
24 #include "libavutil/dict.h"
25 #include "libavutil/internal.h"
26 #include "libavutil/mathematics.h"
27 #include "libavutil/time_internal.h"
28 
29 #include "avformat.h"
30 #include "avlanguage.h"
31 #include "demux.h"
32 #include "internal.h"
33 #include "riff.h"
34 #include "asf.h"
35 #include "asfcrypt.h"
36 
37 #define ASF_BOOL                              0x2
38 #define ASF_WORD                              0x5
39 #define ASF_GUID                              0x6
40 #define ASF_DWORD                             0x3
41 #define ASF_QWORD                             0x4
42 #define ASF_UNICODE                           0x0
43 #define ASF_FLAG_BROADCAST                    0x1
44 #define ASF_BYTE_ARRAY                        0x1
45 #define ASF_TYPE_AUDIO                        0x2
46 #define ASF_TYPE_VIDEO                        0x1
47 #define ASF_STREAM_NUM                        0x7F
48 #define ASF_MAX_STREAMS                       128
49 #define BMP_HEADER_SIZE                       40
50 #define ASF_NUM_OF_PAYLOADS                   0x3F
51 #define ASF_ERROR_CORRECTION_LENGTH_TYPE      0x60
52 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
53 
54 typedef struct GUIDParseTable {
55     const char *name;
56     ff_asf_guid guid;
57     int (*read_object)(AVFormatContext *, const struct GUIDParseTable *);
58     int is_subobject;
59 } GUIDParseTable;
60 
61 typedef struct ASFPacket {
62     AVPacket *avpkt;
63     int64_t dts;
64     uint32_t frame_num; // ASF payloads with the same number are parts of the same frame
65     int flags;
66     int data_size;
67     int duration;
68     int size_left;
69     uint8_t stream_index;
70 } ASFPacket;
71 
72 typedef struct ASFStream {
73     uint8_t stream_index; // from packet header
74     int index;  // stream index in AVFormatContext, set in asf_read_stream_properties
75     int type;
76     int indexed; // added index entries from the Simple Index Object or not
77     int8_t span;   // for deinterleaving
78     uint16_t virtual_pkt_len;
79     uint16_t virtual_chunk_len;
80     int16_t lang_idx;
81     ASFPacket pkt;
82 } ASFStream;
83 
84 typedef struct ASFStreamData{
85     char langs[32];
86     AVDictionary *asf_met; // for storing per-stream metadata
87     AVRational aspect_ratio;
88 } ASFStreamData;
89 
90 typedef struct ASFContext {
91     int data_reached;
92     int is_simple_index; // is simple index present or not 1/0
93     int is_header;
94 
95     uint64_t preroll;
96     uint64_t nb_packets; // ASF packets
97     uint32_t packet_size;
98     int64_t send_time;
99     int duration;
100 
101     uint32_t b_flags;    // flags with broadcast flag
102     uint32_t prop_flags; // file properties object flags
103 
104     uint64_t data_size; // data object size
105     uint64_t unknown_size; // size of the unknown object
106 
107     int64_t offset; // offset of the current object
108 
109     int64_t data_offset;
110     int64_t first_packet_offset; // packet offset
111     int64_t unknown_offset;   // for top level header objects or subobjects without specified behavior
112     int in_asf_read_unknown;
113 
114     // ASF file must not contain more than 128 streams according to the specification
115     ASFStream *asf_st[ASF_MAX_STREAMS];
116     ASFStreamData asf_sd[ASF_MAX_STREAMS];
117     int nb_streams;
118 
119     int stream_index; // from packet header, for the subpayload case
120 
121     // packet parameters
122     uint64_t sub_header_offset; // offset of subpayload header
123     int64_t sub_dts;
124     uint8_t dts_delta; // for subpayloads
125     uint32_t packet_size_internal; // packet size stored inside ASFPacket, can be 0
126     int64_t packet_offset; // offset of the current packet inside Data Object
127     uint32_t pad_len; // padding after payload
128     uint32_t rep_data_len;
129 
130     // packet state
131     uint64_t sub_left;  // subpayloads left or not
132     unsigned int nb_sub; // number of subpayloads read so far from the current ASF packet
133     uint16_t mult_sub_len; // total length of subpayloads array inside multiple payload
134     uint64_t nb_mult_left; // multiple payloads left
135     int return_subpayload;
136     enum {
137         PARSE_PACKET_HEADER,
138         READ_SINGLE,
139         READ_MULTI,
140         READ_MULTI_SUB
141     } state;
142 } ASFContext;
143 
144 static int detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t size);
145 static const GUIDParseTable *find_guid(ff_asf_guid guid);
146 
asf_probe(const AVProbeData *pd)147 static int asf_probe(const AVProbeData *pd)
148 {
149     /* check file header */
150     if (!ff_guidcmp(pd->buf, &ff_asf_header))
151         return AVPROBE_SCORE_MAX/2;
152     else
153         return 0;
154 }
155 
swap_guid(ff_asf_guid guid)156 static void swap_guid(ff_asf_guid guid)
157 {
158     FFSWAP(unsigned char, guid[0], guid[3]);
159     FFSWAP(unsigned char, guid[1], guid[2]);
160     FFSWAP(unsigned char, guid[4], guid[5]);
161     FFSWAP(unsigned char, guid[6], guid[7]);
162 }
163 
align_position(AVIOContext *pb, int64_t offset, uint64_t size)164 static void align_position(AVIOContext *pb,  int64_t offset, uint64_t size)
165 {
166     if (size < INT64_MAX - offset && avio_tell(pb) != offset + size)
167         avio_seek(pb, offset + size, SEEK_SET);
168 }
169 
asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g)170 static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g)
171 {
172     ASFContext *asf = s->priv_data;
173     AVIOContext *pb = s->pb;
174     uint64_t size   = avio_rl64(pb);
175     int ret;
176 
177     if (size > INT64_MAX || asf->in_asf_read_unknown > 5)
178         return AVERROR_INVALIDDATA;
179 
180     if (asf->is_header)
181         asf->unknown_size = size;
182     asf->is_header = 0;
183     if (!g->is_subobject) {
184         if (!(ret = strcmp(g->name, "Header Extension")))
185             avio_skip(pb, 22); // skip reserved fields and Data Size
186         asf->in_asf_read_unknown ++;
187         ret = detect_unknown_subobject(s, asf->unknown_offset,
188                                             asf->unknown_size);
189         asf->in_asf_read_unknown --;
190         if (ret < 0)
191             return ret;
192     } else {
193         if (size < 24) {
194             av_log(s, AV_LOG_ERROR, "Too small size %"PRIu64" (< 24).\n", size);
195             return AVERROR_INVALIDDATA;
196         }
197         avio_skip(pb, size - 24);
198     }
199 
200     return 0;
201 }
202 
get_asf_string(AVIOContext *pb, int maxlen, char *buf, int buflen)203 static int get_asf_string(AVIOContext *pb, int maxlen, char *buf, int buflen)
204 {
205     char *q = buf;
206     int ret = 0;
207     if (buflen <= 0)
208         return AVERROR(EINVAL);
209     while (ret + 1 < maxlen) {
210         uint8_t tmp;
211         uint32_t ch;
212         GET_UTF16(ch, (ret += 2) <= maxlen ? avio_rl16(pb) : 0, break;);
213         PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)
214     }
215     *q = 0;
216 
217     return ret;
218 }
219 
asf_read_marker(AVFormatContext *s, const GUIDParseTable *g)220 static int asf_read_marker(AVFormatContext *s, const GUIDParseTable *g)
221 {
222     ASFContext *asf = s->priv_data;
223     AVIOContext *pb = s->pb;
224     uint64_t size   = avio_rl64(pb);
225     int i, nb_markers, ret;
226     size_t len;
227     char name[1024];
228 
229     avio_skip(pb, 8);
230     avio_skip(pb, 8); // skip reserved GUID
231     nb_markers = avio_rl32(pb);
232     avio_skip(pb, 2); // skip reserved field
233     len = avio_rl16(pb);
234     for (i = 0; i < len; i++)
235         avio_skip(pb, 1);
236 
237     for (i = 0; i < nb_markers; i++) {
238         int64_t pts;
239 
240         avio_skip(pb, 8);
241         pts = avio_rl64(pb);
242         pts -= asf->preroll * 10000;
243         avio_skip(pb, 2); // entry length
244         avio_skip(pb, 4); // send time
245         avio_skip(pb, 4); // flags
246         len = avio_rl32(pb);
247 
248         if (avio_feof(pb))
249             return AVERROR_INVALIDDATA;
250 
251         if ((ret = avio_get_str16le(pb, len, name,
252                                     sizeof(name))) < len)
253             avio_skip(pb, len - ret);
254         avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pts,
255                            AV_NOPTS_VALUE, name);
256     }
257     align_position(pb, asf->offset, size);
258 
259     return 0;
260 }
261 
asf_read_metadata(AVFormatContext *s, const char *title, uint16_t len, unsigned char *ch, uint16_t buflen)262 static int asf_read_metadata(AVFormatContext *s, const char *title, uint16_t len,
263                              unsigned char *ch, uint16_t buflen)
264 {
265     AVIOContext *pb = s->pb;
266 
267     avio_get_str16le(pb, len, ch, buflen);
268     if (ch[0]) {
269         if (av_dict_set(&s->metadata, title, ch, 0) < 0)
270             av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
271     }
272 
273     return 0;
274 }
275 
asf_read_value(AVFormatContext *s, const uint8_t *name, uint16_t val_len, int type, AVDictionary **met)276 static int asf_read_value(AVFormatContext *s, const uint8_t *name,
277                           uint16_t val_len, int type, AVDictionary **met)
278 {
279     int ret;
280     uint8_t *value;
281     uint16_t buflen = 2 * val_len + 1;
282     AVIOContext *pb = s->pb;
283 
284     value = av_malloc(buflen);
285     if (!value)
286         return AVERROR(ENOMEM);
287     if (type == ASF_UNICODE) {
288         // get_asf_string reads UTF-16 and converts it to UTF-8 which needs longer buffer
289         if ((ret = get_asf_string(pb, val_len, value, buflen)) < 0)
290             goto failed;
291         if (av_dict_set(met, name, value, 0) < 0)
292             av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
293     } else {
294         char buf[256];
295         if (val_len > sizeof(buf)) {
296             ret = AVERROR_INVALIDDATA;
297             goto failed;
298         }
299         if ((ret = avio_read(pb, value, val_len)) < 0)
300             goto failed;
301         if (ret < 2 * val_len)
302             value[ret] = '\0';
303         else
304             value[2 * val_len - 1] = '\0';
305         snprintf(buf, sizeof(buf), "%s", value);
306         if (av_dict_set(met, name, buf, 0) < 0)
307             av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
308     }
309     av_freep(&value);
310 
311     return 0;
312 
313 failed:
314     av_freep(&value);
315     return ret;
316 }
asf_read_generic_value(AVIOContext *pb, int type, uint64_t *value)317 static int asf_read_generic_value(AVIOContext *pb, int type, uint64_t *value)
318 {
319 
320     switch (type) {
321     case ASF_BOOL:
322         *value = avio_rl16(pb);
323         break;
324     case ASF_DWORD:
325         *value = avio_rl32(pb);
326         break;
327     case ASF_QWORD:
328         *value = avio_rl64(pb);
329         break;
330     case ASF_WORD:
331         *value = avio_rl16(pb);
332         break;
333     default:
334         return AVERROR_INVALIDDATA;
335     }
336 
337     return 0;
338 }
339 
asf_set_metadata(AVFormatContext *s, const uint8_t *name, int type, AVDictionary **met)340 static int asf_set_metadata(AVFormatContext *s, const uint8_t *name,
341                             int type, AVDictionary **met)
342 {
343     AVIOContext *pb = s->pb;
344     uint64_t value;
345     char buf[32];
346     int ret;
347 
348     ret = asf_read_generic_value(pb, type, &value);
349     if (ret < 0)
350         return ret;
351 
352     snprintf(buf, sizeof(buf), "%"PRIu64, value);
353     if (av_dict_set(met, name, buf, 0) < 0)
354         av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
355 
356     return 0;
357 }
358 
process_metadata(AVFormatContext *s, const uint8_t *name, uint16_t name_len, uint16_t val_len, uint16_t type, AVDictionary **met)359 static int process_metadata(AVFormatContext *s, const uint8_t *name, uint16_t name_len,
360                             uint16_t val_len, uint16_t type, AVDictionary **met)
361 {
362     int ret;
363     ff_asf_guid guid;
364 
365     if (val_len) {
366         switch (type) {
367         case ASF_UNICODE:
368             asf_read_value(s, name, val_len, type, met);
369             break;
370         case ASF_BYTE_ARRAY:
371             if (ff_asf_handle_byte_array(s, name, val_len) > 0)
372                 asf_read_value(s, name, val_len, type, met);
373             break;
374         case ASF_GUID:
375             ff_get_guid(s->pb, &guid);
376             break;
377         default:
378             if ((ret = asf_set_metadata(s, name, type, met)) < 0)
379                 return ret;
380             break;
381         }
382     }
383 
384     return 0;
385 }
386 
asf_read_ext_content(AVFormatContext *s, const GUIDParseTable *g)387 static int asf_read_ext_content(AVFormatContext *s, const GUIDParseTable *g)
388 {
389     ASFContext *asf  = s->priv_data;
390     AVIOContext *pb  = s->pb;
391     uint64_t size    = avio_rl64(pb);
392     uint16_t nb_desc = avio_rl16(pb);
393     int i, ret;
394 
395     for (i = 0; i < nb_desc; i++) {
396         uint16_t name_len, type, val_len;
397         uint8_t *name = NULL;
398 
399         name_len = avio_rl16(pb);
400         if (!name_len)
401             return AVERROR_INVALIDDATA;
402         name = av_malloc(name_len);
403         if (!name)
404             return AVERROR(ENOMEM);
405         avio_get_str16le(pb, name_len, name,
406                          name_len);
407         type    = avio_rl16(pb);
408         // BOOL values are 16 bits long in the Metadata Object
409         // but 32 bits long in the Extended Content Description Object
410         if (type == ASF_BOOL)
411             type = ASF_DWORD;
412         val_len = avio_rl16(pb);
413 
414         ret = process_metadata(s, name, name_len, val_len, type, &s->metadata);
415         av_freep(&name);
416         if (ret < 0)
417             return ret;
418     }
419 
420     align_position(pb, asf->offset, size);
421     return 0;
422 }
423 
find_stream(AVFormatContext *s, uint16_t st_num)424 static AVStream *find_stream(AVFormatContext *s, uint16_t st_num)
425 {
426     AVStream *st = NULL;
427     ASFContext *asf = s->priv_data;
428     int i;
429 
430     for (i = 0; i < asf->nb_streams; i++) {
431         if (asf->asf_st[i]->stream_index == st_num) {
432             st = s->streams[asf->asf_st[i]->index];
433             break;
434         }
435     }
436 
437     return st;
438 }
439 
asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *name, int type)440 static int asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *name, int type)
441 {
442     ASFContext *asf   = s->priv_data;
443     AVIOContext *pb   = s->pb;
444     uint64_t value = 0;
445     int ret;
446 
447     ret = asf_read_generic_value(pb, type, &value);
448     if (ret < 0)
449         return ret;
450 
451     if (st_num < ASF_MAX_STREAMS) {
452         if (!strcmp(name, "AspectRatioX"))
453             asf->asf_sd[st_num].aspect_ratio.num = value;
454         else
455             asf->asf_sd[st_num].aspect_ratio.den = value;
456     }
457     return 0;
458 }
459 
asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)460 static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)
461 {
462     ASFContext *asf   = s->priv_data;
463     AVIOContext *pb   = s->pb;
464     uint64_t size     = avio_rl64(pb);
465     uint16_t nb_recs  = avio_rl16(pb); // number of records in the Description Records list
466     int i, ret;
467 
468     for (i = 0; i < nb_recs; i++) {
469         uint16_t name_len, buflen, type, val_len, st_num;
470         uint8_t *name = NULL;
471 
472         avio_skip(pb, 2); // skip reserved field
473         st_num   = avio_rl16(pb);
474         name_len = avio_rl16(pb);
475         buflen   = 2 * name_len + 1;
476         if (!name_len)
477             break;
478         type     = avio_rl16(pb);
479         val_len  = avio_rl32(pb);
480         name     = av_malloc(buflen);
481         if (!name)
482             return AVERROR(ENOMEM);
483         avio_get_str16le(pb, name_len, name,
484                          buflen);
485         if (!strcmp(name, "AspectRatioX") || !strcmp(name, "AspectRatioY")) {
486             ret = asf_store_aspect_ratio(s, st_num, name, type);
487             if (ret < 0) {
488                 av_freep(&name);
489                 break;
490             }
491         } else {
492             if (st_num < ASF_MAX_STREAMS) {
493                 if ((ret = process_metadata(s, name, name_len, val_len, type,
494                                             st_num ? &asf->asf_sd[st_num].asf_met
495                                                    : &s->metadata)) < 0) {
496                     av_freep(&name);
497                     break;
498                 }
499             }
500         }
501         av_freep(&name);
502     }
503 
504     align_position(pb, asf->offset, size);
505     return 0;
506 }
507 
asf_read_content_desc(AVFormatContext *s, const GUIDParseTable *g)508 static int asf_read_content_desc(AVFormatContext *s, const GUIDParseTable *g)
509 {
510     ASFContext *asf = s->priv_data;
511     AVIOContext *pb = s->pb;
512     int i;
513     static const char *const titles[] =
514     { "Title", "Author", "Copyright", "Description", "Rate" };
515     uint16_t len[5], buflen[5] = { 0 };
516     uint8_t *ch;
517     uint64_t size = avio_rl64(pb);
518 
519     for (i = 0; i < 5; i++) {
520         len[i]  = avio_rl16(pb);
521         // utf8 string should be <= 2 * utf16 string, extra byte for the terminator
522         buflen[i]  = 2 * len[i] + 1;
523     }
524 
525     for (i = 0; i < 5; i++) {
526         ch = av_malloc(buflen[i]);
527         if (!ch)
528             return(AVERROR(ENOMEM));
529         asf_read_metadata(s, titles[i], len[i], ch, buflen[i]);
530         av_freep(&ch);
531     }
532     align_position(pb, asf->offset, size);
533 
534     return 0;
535 }
536 
asf_read_properties(AVFormatContext *s, const GUIDParseTable *g)537 static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g)
538 {
539     ASFContext *asf = s->priv_data;
540     AVIOContext *pb = s->pb;
541     time_t creation_time;
542 
543     avio_rl64(pb); // read object size
544     avio_skip(pb, 16); // skip File ID
545     avio_skip(pb, 8);  // skip File size
546     creation_time = avio_rl64(pb);
547     if (!(asf->b_flags & ASF_FLAG_BROADCAST)) {
548         struct tm tmbuf;
549         struct tm *tm;
550         char buf[64];
551 
552         // creation date is in 100 ns units from 1 Jan 1601, conversion to s
553         creation_time /= 10000000;
554         // there are 11644473600 seconds between 1 Jan 1601 and 1 Jan 1970
555         creation_time -= 11644473600;
556         tm = gmtime_r(&creation_time, &tmbuf);
557         if (tm) {
558             if (!strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm))
559                 buf[0] = '\0';
560         } else
561             buf[0] = '\0';
562         if (buf[0]) {
563             if (av_dict_set(&s->metadata, "creation_time", buf, 0) < 0)
564                 av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
565         }
566     }
567     asf->nb_packets  = avio_rl64(pb);
568     asf->duration    = avio_rl64(pb) / 10000; // stream duration
569     avio_skip(pb, 8); // skip send duration
570     asf->preroll     = avio_rl64(pb);
571     asf->duration   -= asf->preroll;
572     asf->b_flags     = avio_rl32(pb);
573     avio_skip(pb, 4); // skip minimal packet size
574     asf->packet_size  = avio_rl32(pb);
575     avio_skip(pb, 4); // skip max_bitrate
576 
577     return 0;
578 }
579 
parse_video_info(AVFormatContext *avfmt, AVIOContext *pb, AVStream *st)580 static int parse_video_info(AVFormatContext *avfmt, AVIOContext *pb, AVStream *st)
581 {
582     uint16_t size_asf; // ASF-specific Format Data size
583     uint32_t size_bmp; // BMP_HEADER-specific Format Data size
584     unsigned int tag;
585 
586     st->codecpar->width  = avio_rl32(pb);
587     st->codecpar->height = avio_rl32(pb);
588     avio_skip(pb, 1); // skip reserved flags
589     size_asf = avio_rl16(pb);
590     tag = ff_get_bmp_header(pb, st, &size_bmp);
591     st->codecpar->codec_tag = tag;
592     st->codecpar->codec_id  = ff_codec_get_id(ff_codec_bmp_tags, tag);
593     size_bmp = FFMAX(size_asf, size_bmp);
594 
595     if (size_bmp > BMP_HEADER_SIZE) {
596         int ret = ff_get_extradata(avfmt, st->codecpar, pb, size_bmp - BMP_HEADER_SIZE);
597 
598         if (ret < 0)
599             return ret;
600     }
601     return 0;
602 }
603 
asf_read_stream_properties(AVFormatContext *s, const GUIDParseTable *g)604 static int asf_read_stream_properties(AVFormatContext *s, const GUIDParseTable *g)
605 {
606     ASFContext *asf = s->priv_data;
607     AVIOContext *pb = s->pb;
608     uint64_t size;
609     uint32_t err_data_len, ts_data_len; // type specific data length
610     uint16_t flags;
611     ff_asf_guid stream_type;
612     enum AVMediaType type;
613     int i, ret;
614     uint8_t stream_index;
615     AVStream *st;
616     ASFStream *asf_st;
617 
618     // ASF file must not contain more than 128 streams according to the specification
619     if (asf->nb_streams >= ASF_MAX_STREAMS)
620         return AVERROR_INVALIDDATA;
621 
622     size = avio_rl64(pb);
623     ff_get_guid(pb, &stream_type);
624     if (!ff_guidcmp(&stream_type, &ff_asf_audio_stream))
625         type = AVMEDIA_TYPE_AUDIO;
626     else if (!ff_guidcmp(&stream_type, &ff_asf_video_stream))
627         type = AVMEDIA_TYPE_VIDEO;
628     else if (!ff_guidcmp(&stream_type, &ff_asf_jfif_media))
629         type = AVMEDIA_TYPE_VIDEO;
630     else if (!ff_guidcmp(&stream_type, &ff_asf_command_stream))
631         type = AVMEDIA_TYPE_DATA;
632     else if (!ff_guidcmp(&stream_type,
633                          &ff_asf_ext_stream_embed_stream_header))
634         type = AVMEDIA_TYPE_UNKNOWN;
635     else
636         return AVERROR_INVALIDDATA;
637 
638     ff_get_guid(pb, &stream_type); // error correction type
639     avio_skip(pb, 8); // skip the time offset
640     ts_data_len      = avio_rl32(pb);
641     err_data_len     = avio_rl32(pb);
642     flags            = avio_rl16(pb); // bit 15 - Encrypted Content
643 
644     stream_index = flags & ASF_STREAM_NUM;
645     for (i = 0; i < asf->nb_streams; i++)
646         if (stream_index == asf->asf_st[i]->stream_index) {
647             av_log(s, AV_LOG_WARNING,
648                    "Duplicate stream found, this stream will be ignored.\n");
649             align_position(pb, asf->offset, size);
650             return 0;
651         }
652 
653     st = avformat_new_stream(s, NULL);
654     if (!st)
655         return AVERROR(ENOMEM);
656     avpriv_set_pts_info(st, 32, 1, 1000); // pts should be dword, in milliseconds
657     st->codecpar->codec_type = type;
658     asf->asf_st[asf->nb_streams] = av_mallocz(sizeof(*asf_st));
659     if (!asf->asf_st[asf->nb_streams])
660         return AVERROR(ENOMEM);
661     asf_st                       = asf->asf_st[asf->nb_streams];
662     asf->nb_streams++;
663     asf_st->stream_index         = stream_index;
664     asf_st->index                = st->index;
665     asf_st->indexed              = 0;
666     st->id                       = flags & ASF_STREAM_NUM;
667     asf_st->pkt.data_size        = 0;
668     asf_st->pkt.avpkt = av_packet_alloc();
669     if (!asf_st->pkt.avpkt)
670         return AVERROR(ENOMEM);
671     avio_skip(pb, 4); // skip reserved field
672 
673     switch (type) {
674     case AVMEDIA_TYPE_AUDIO:
675         asf_st->type = AVMEDIA_TYPE_AUDIO;
676         if ((ret = ff_get_wav_header(s, pb, st->codecpar, ts_data_len, 0)) < 0)
677             return ret;
678         break;
679     case AVMEDIA_TYPE_VIDEO:
680         asf_st->type = AVMEDIA_TYPE_VIDEO;
681         if ((ret = parse_video_info(s, pb, st)) < 0)
682             return ret;
683         break;
684     default:
685         avio_skip(pb, ts_data_len);
686         break;
687     }
688 
689     if (err_data_len) {
690         if (type == AVMEDIA_TYPE_AUDIO) {
691             uint8_t span = avio_r8(pb);
692             if (span > 1) {
693                 asf_st->span              = span;
694                 asf_st->virtual_pkt_len   = avio_rl16(pb);
695                 asf_st->virtual_chunk_len = avio_rl16(pb);
696                 if (!asf_st->virtual_chunk_len || !asf_st->virtual_pkt_len)
697                     return AVERROR_INVALIDDATA;
698                 avio_skip(pb, err_data_len - 5);
699             } else
700                 avio_skip(pb, err_data_len - 1);
701         } else
702             avio_skip(pb, err_data_len);
703     }
704 
705     align_position(pb, asf->offset, size);
706 
707     return 0;
708 }
709 
set_language(AVFormatContext *s, const char *rfc1766, AVDictionary **met)710 static void set_language(AVFormatContext *s, const char *rfc1766, AVDictionary **met)
711 {
712     // language abbr should contain at least 2 chars
713     if (rfc1766 && strlen(rfc1766) > 1) {
714         const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
715         const char *iso6392       = ff_convert_lang_to(primary_tag,
716                                                        AV_LANG_ISO639_2_BIBL);
717         if (iso6392)
718             if (av_dict_set(met, "language", iso6392, 0) < 0)
719                 av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
720     }
721 }
722 
asf_read_ext_stream_properties(AVFormatContext *s, const GUIDParseTable *g)723 static int asf_read_ext_stream_properties(AVFormatContext *s, const GUIDParseTable *g)
724 {
725     ASFContext *asf = s->priv_data;
726     AVIOContext *pb = s->pb;
727     AVStream *st    = NULL;
728     ff_asf_guid guid;
729     uint16_t nb_st_name, nb_pay_exts, st_num, lang_idx;
730     int i, ret;
731     uint32_t bitrate;
732     uint64_t start_time, end_time, time_per_frame;
733     uint64_t size = avio_rl64(pb);
734 
735     start_time = avio_rl64(pb);
736     end_time   = avio_rl64(pb);
737     bitrate    = avio_rl32(pb);
738     avio_skip(pb, 28); // skip some unused values
739     st_num     = avio_rl16(pb);
740     st_num    &= ASF_STREAM_NUM;
741     lang_idx   = avio_rl16(pb); // Stream Language ID Index
742     if (lang_idx >= ASF_MAX_STREAMS)
743         return AVERROR_INVALIDDATA;
744     for (i = 0; i < asf->nb_streams; i++) {
745         if (st_num == asf->asf_st[i]->stream_index) {
746             st                       = s->streams[asf->asf_st[i]->index];
747             asf->asf_st[i]->lang_idx = lang_idx;
748             break;
749         }
750     }
751     time_per_frame = avio_rl64(pb); // average time per frame
752     if (st) {
753         st->start_time           = start_time;
754         st->duration             = end_time - start_time;
755         st->codecpar->bit_rate   = bitrate;
756         st->avg_frame_rate.num   = 10000000;
757         st->avg_frame_rate.den   = time_per_frame;
758     }
759     nb_st_name = avio_rl16(pb);
760     nb_pay_exts   = avio_rl16(pb);
761     for (i = 0; i < nb_st_name; i++) {
762         uint16_t len;
763 
764         avio_rl16(pb); // Language ID Index
765         len = avio_rl16(pb);
766         avio_skip(pb, len);
767     }
768 
769     for (i = 0; i < nb_pay_exts; i++) {
770         uint32_t len;
771         avio_skip(pb, 16); // Extension System ID
772         avio_skip(pb, 2);  // Extension Data Size
773         len = avio_rl32(pb);
774         avio_skip(pb, len);
775     }
776 
777     if ((ret = ff_get_guid(pb, &guid)) < 0) {
778         align_position(pb, asf->offset, size);
779 
780         return 0;
781     }
782 
783     g = find_guid(guid);
784     if (g && !(strcmp(g->name, "Stream Properties"))) {
785         if ((ret = g->read_object(s, g)) < 0)
786             return ret;
787     }
788 
789     align_position(pb, asf->offset, size);
790     return 0;
791 }
792 
asf_read_language_list(AVFormatContext *s, const GUIDParseTable *g)793 static int asf_read_language_list(AVFormatContext *s, const GUIDParseTable *g)
794 {
795     ASFContext *asf   = s->priv_data;
796     AVIOContext *pb   = s->pb;
797     int i, ret;
798     uint64_t size     = avio_rl64(pb);
799     uint16_t nb_langs = avio_rl16(pb);
800 
801     if (nb_langs < ASF_MAX_STREAMS) {
802         for (i = 0; i < nb_langs; i++) {
803             size_t len;
804             len = avio_r8(pb);
805             if (!len)
806                 len = 6;
807             if ((ret = get_asf_string(pb, len, asf->asf_sd[i].langs,
808                                       sizeof(asf->asf_sd[i].langs))) < 0) {
809                 return ret;
810             }
811         }
812     }
813 
814     align_position(pb, asf->offset, size);
815     return 0;
816 }
817 
818 // returns data object offset when reading this object for the first time
asf_read_data(AVFormatContext *s, const GUIDParseTable *g)819 static int asf_read_data(AVFormatContext *s, const GUIDParseTable *g)
820 {
821     ASFContext *asf = s->priv_data;
822     AVIOContext *pb = s->pb;
823     uint64_t size   = asf->data_size = avio_rl64(pb);
824     int i;
825 
826     if (!asf->data_reached) {
827         asf->data_reached       = 1;
828         asf->data_offset        = asf->offset;
829     }
830 
831     for (i = 0; i < asf->nb_streams; i++) {
832         if (!(asf->b_flags & ASF_FLAG_BROADCAST))
833             s->streams[i]->duration = asf->duration;
834     }
835     asf->nb_mult_left           = 0;
836     asf->sub_left               = 0;
837     asf->state                  = PARSE_PACKET_HEADER;
838     asf->return_subpayload      = 0;
839     asf->packet_size_internal   = 0;
840     avio_skip(pb, 16); // skip File ID
841     size = avio_rl64(pb); // Total Data Packets
842     if (size != asf->nb_packets)
843         av_log(s, AV_LOG_WARNING,
844                "Number of Packets from File Properties Object is not equal to Total"
845                "Datapackets value! num of packets %"PRIu64" total num %"PRIu64".\n",
846                size, asf->nb_packets);
847     avio_skip(pb, 2); // skip reserved field
848     asf->first_packet_offset = avio_tell(pb);
849     if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !(asf->b_flags & ASF_FLAG_BROADCAST))
850         align_position(pb, asf->offset, asf->data_size);
851 
852     return 0;
853 }
854 
asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g)855 static int asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g)
856 {
857     ASFContext *asf = s->priv_data;
858     AVIOContext *pb = s->pb;
859     AVStream *st    = NULL;
860     uint64_t interval; // index entry time interval in 100 ns units, usually it's 1s
861     uint32_t pkt_num, nb_entries;
862     int32_t prev_pkt_num = -1;
863     int i;
864     int64_t offset;
865     uint64_t size = avio_rl64(pb);
866 
867     // simple index objects should be ordered by stream number, this loop tries to find
868     // the first not indexed video stream
869     for (i = 0; i < asf->nb_streams; i++) {
870         if ((asf->asf_st[i]->type == AVMEDIA_TYPE_VIDEO) && !asf->asf_st[i]->indexed) {
871             asf->asf_st[i]->indexed = 1;
872             st = s->streams[asf->asf_st[i]->index];
873             break;
874         }
875     }
876     if (!st) {
877         avio_skip(pb, size - 24); // if there's no video stream, skip index object
878         return 0;
879     }
880     avio_skip(pb, 16); // skip File ID
881     interval = avio_rl64(pb);
882     avio_skip(pb, 4);
883     nb_entries = avio_rl32(pb);
884     for (i = 0; i < nb_entries; i++) {
885         pkt_num = avio_rl32(pb);
886         offset = avio_skip(pb, 2);
887         if (offset < 0) {
888             av_log(s, AV_LOG_ERROR, "Skipping failed in asf_read_simple_index.\n");
889             return offset;
890         }
891         if (prev_pkt_num != pkt_num) {
892             av_add_index_entry(st, asf->first_packet_offset + asf->packet_size *
893                                pkt_num, av_rescale(interval, i, 10000),
894                                asf->packet_size, 0, AVINDEX_KEYFRAME);
895             prev_pkt_num = pkt_num;
896         }
897     }
898     asf->is_simple_index = 1;
899     align_position(pb, asf->offset, size);
900 
901     return 0;
902 }
903 
904 static const GUIDParseTable gdef[] = {
905     { "Data",                         { 0x75, 0xB2, 0x26, 0x36, 0x66, 0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_data, 1 },
906     { "Simple Index",                 { 0x33, 0x00, 0x08, 0x90, 0xE5, 0xB1, 0x11, 0xCF, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB }, asf_read_simple_index, 1 },
907     { "Content Description",          { 0x75, 0xB2, 0x26, 0x33, 0x66 ,0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_content_desc, 1 },
908     { "Extended Content Description", { 0xD2, 0xD0, 0xA4, 0x40, 0xE3, 0x07, 0x11, 0xD2, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5e, 0xA8, 0x50 }, asf_read_ext_content, 1 },
909     { "Stream Bitrate Properties",    { 0x7B, 0xF8, 0x75, 0xCE, 0x46, 0x8D, 0x11, 0xD1, 0x8D, 0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2 }, asf_read_unknown, 1 },
910     { "File Properties",              { 0x8C, 0xAB, 0xDC, 0xA1, 0xA9, 0x47, 0x11, 0xCF, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_properties, 1 },
911     { "Header Extension",             { 0x5F, 0xBF, 0x03, 0xB5, 0xA9, 0x2E, 0x11, 0xCF, 0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_unknown, 0 },
912     { "Stream Properties",            { 0xB7, 0xDC, 0x07, 0x91, 0xA9, 0xB7, 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_stream_properties, 1 },
913     { "Codec List",                   { 0x86, 0xD1, 0x52, 0x40, 0x31, 0x1D, 0x11, 0xD0, 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }, asf_read_unknown, 1 },
914     { "Marker",                       { 0xF4, 0x87, 0xCD, 0x01, 0xA9, 0x51, 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, asf_read_marker, 1 },
915     { "Script Command",               { 0x1E, 0xFB, 0x1A, 0x30, 0x0B, 0x62, 0x11, 0xD0, 0xA3, 0x9B, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }, asf_read_unknown, 1 },
916     { "Language List",                { 0x7C, 0x43, 0x46, 0xa9, 0xef, 0xe0, 0x4B, 0xFC, 0xB2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85 }, asf_read_language_list, 1},
917     { "Padding",                      { 0x18, 0x06, 0xD4, 0x74, 0xCA, 0xDF, 0x45, 0x09, 0xA4, 0xBA, 0x9A, 0xAB, 0xCB, 0x96, 0xAA, 0xE8 }, asf_read_unknown, 1 },
918     { "DRMv1 Header",                 { 0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
919     { "DRMv2 Header",                 { 0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22, 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9c }, asf_read_unknown, 1 },
920     { "Index",                        { 0xD6, 0xE2, 0x29, 0xD3, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
921     { "Media Object Index",           { 0xFE, 0xB1, 0x03, 0xF8, 0x12, 0xAD, 0x4C, 0x64, 0x84, 0x0F, 0x2A, 0x1D, 0x2F, 0x7A, 0xD4, 0x8C }, asf_read_unknown, 1 },
922     { "Timecode Index",               { 0x3C, 0xB7, 0x3F, 0xD0, 0x0C, 0x4A, 0x48, 0x03, 0x95, 0x3D, 0xED, 0xF7, 0xB6, 0x22, 0x8F, 0x0C }, asf_read_unknown, 0 },
923     { "Bitrate_Mutual_Exclusion",     { 0xD6, 0xE2, 0x29, 0xDC, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
924     { "Error Correction",             { 0x75, 0xB2, 0x26, 0x35, 0x66, 0x8E, 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, asf_read_unknown, 1 },
925     { "Content Branding",             { 0x22, 0x11, 0xB3, 0xFA, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
926     { "Content Encryption",           { 0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
927     { "Extended Content Encryption",  { 0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22, 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9C }, asf_read_unknown, 1 },
928     { "Digital Signature",            { 0x22, 0x11, 0xB3, 0xFC, 0xBD, 0x23, 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E }, asf_read_unknown, 1 },
929     { "Extended Stream Properties",   { 0x14, 0xE6, 0xA5, 0xCB, 0xC6, 0x72, 0x43, 0x32, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A }, asf_read_ext_stream_properties, 1 },
930     { "Advanced Mutual Exclusion",    { 0xA0, 0x86, 0x49, 0xCF, 0x47, 0x75, 0x46, 0x70, 0x8A, 0x16, 0x6E, 0x35, 0x35, 0x75, 0x66, 0xCD }, asf_read_unknown, 1 },
931     { "Group Mutual Exclusion",       { 0xD1, 0x46, 0x5A, 0x40, 0x5A, 0x79, 0x43, 0x38, 0xB7, 0x1B, 0xE3, 0x6B, 0x8F, 0xD6, 0xC2, 0x49 }, asf_read_unknown, 1},
932     { "Stream Prioritization",        { 0xD4, 0xFE, 0xD1, 0x5B, 0x88, 0xD3, 0x45, 0x4F, 0x81, 0xF0, 0xED, 0x5C, 0x45, 0x99, 0x9E, 0x24 }, asf_read_unknown, 1 },
933     { "Bandwidth Sharing Object",     { 0xA6, 0x96, 0x09, 0xE6, 0x51, 0x7B, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
934     { "Metadata",                     { 0xC5, 0xF8, 0xCB, 0xEA, 0x5B, 0xAF, 0x48, 0x77, 0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA }, asf_read_metadata_obj, 1 },
935     { "Metadata Library",             { 0x44, 0x23, 0x1C, 0x94, 0x94, 0x98, 0x49, 0xD1, 0xA1, 0x41, 0x1D, 0x13, 0x4E, 0x45, 0x70, 0x54 }, asf_read_metadata_obj, 1 },
936     { "Audio Spread",                 { 0xBF, 0xC3, 0xCD, 0x50, 0x61, 0x8F, 0x11, 0xCF, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 }, asf_read_unknown, 1 },
937     { "Index Parameters",             { 0xD6, 0xE2, 0x29, 0xDF, 0x35, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
938     { "Content Encryption System Windows Media DRM Network Devices",
939                                       { 0x7A, 0x07, 0x9B, 0xB6, 0xDA, 0XA4, 0x4e, 0x12, 0xA5, 0xCA, 0x91, 0xD3, 0x8D, 0xC1, 0x1A, 0x8D }, asf_read_unknown, 1 },
940     { "Mutex Language",               { 0xD6, 0xE2, 0x2A, 0x00, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
941     { "Mutex Bitrate",                { 0xD6, 0xE2, 0x2A, 0x01, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
942     { "Mutex Unknown",                { 0xD6, 0xE2, 0x2A, 0x02, 0x25, 0xDA, 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE }, asf_read_unknown, 1 },
943     { "Bandwidth Sharing Exclusive",  { 0xAF, 0x60, 0x60, 0xAA, 0x51, 0x97, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
944     { "Bandwidth Sharing Partial",    { 0xAF, 0x60, 0x60, 0xAB, 0x51, 0x97, 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9 }, asf_read_unknown, 1 },
945     { "Payload Extension System Timecode", { 0x39, 0x95, 0x95, 0xEC, 0x86, 0x67, 0x4E, 0x2D, 0x8F, 0xDB, 0x98, 0x81, 0x4C, 0xE7, 0x6C, 0x1E }, asf_read_unknown, 1 },
946     { "Payload Extension System File Name", { 0xE1, 0x65, 0xEC, 0x0E, 0x19, 0xED, 0x45, 0xD7, 0xB4, 0xA7, 0x25, 0xCB, 0xD1, 0xE2, 0x8E, 0x9B }, asf_read_unknown, 1 },
947     { "Payload Extension System Content Type", { 0xD5, 0x90, 0xDC, 0x20, 0x07, 0xBC, 0x43, 0x6C, 0x9C, 0xF7, 0xF3, 0xBB, 0xFB, 0xF1, 0xA4, 0xDC }, asf_read_unknown, 1 },
948     { "Payload Extension System Pixel Aspect Ratio", { 0x1, 0x1E, 0xE5, 0x54, 0xF9, 0xEA, 0x4B, 0xC8, 0x82, 0x1A, 0x37, 0x6B, 0x74, 0xE4, 0xC4, 0xB8 }, asf_read_unknown, 1 },
949     { "Payload Extension System Sample Duration", { 0xC6, 0xBD, 0x94, 0x50, 0x86, 0x7F, 0x49, 0x07, 0x83, 0xA3, 0xC7, 0x79, 0x21, 0xB7, 0x33, 0xAD }, asf_read_unknown, 1 },
950     { "Payload Extension System Encryption Sample ID", { 0x66, 0x98, 0xB8, 0x4E, 0x0A, 0xFA, 0x43, 0x30, 0xAE, 0xB2, 0x1C, 0x0A, 0x98, 0xD7, 0xA4, 0x4D }, asf_read_unknown, 1 },
951     { "Payload Extension System Degradable JPEG", { 0x00, 0xE1, 0xAF, 0x06, 0x7B, 0xEC, 0x11, 0xD1, 0xA5, 0x82, 0x00, 0xC0, 0x4F, 0xC2, 0x9C, 0xFB }, asf_read_unknown, 1 },
952 };
953 
954 #define READ_LEN(flag, name, len)            \
955     do {                                     \
956         if ((flag) == name ## IS_BYTE)       \
957             len = avio_r8(pb);               \
958         else if ((flag) == name ## IS_WORD)  \
959             len = avio_rl16(pb);             \
960         else if ((flag) == name ## IS_DWORD) \
961             len = avio_rl32(pb);             \
962         else                                 \
963             len = 0;                         \
964     } while(0)
965 
asf_read_subpayload(AVFormatContext *s, AVPacket *pkt, int is_header)966 static int asf_read_subpayload(AVFormatContext *s, AVPacket *pkt, int is_header)
967 {
968     ASFContext *asf = s->priv_data;
969     AVIOContext *pb = s->pb;
970     uint8_t sub_len;
971     int ret, i;
972 
973     if (is_header) {
974         asf->dts_delta = avio_r8(pb);
975         if (asf->nb_mult_left) {
976             asf->mult_sub_len = avio_rl16(pb); // total
977         }
978         asf->sub_header_offset = avio_tell(pb);
979         asf->nb_sub = 0;
980         asf->sub_left = 1;
981     }
982     sub_len = avio_r8(pb);
983     if ((ret = av_get_packet(pb, pkt, sub_len)) < 0) // each subpayload is entire frame
984         return ret;
985     for (i = 0; i < asf->nb_streams; i++) {
986         if (asf->stream_index == asf->asf_st[i]->stream_index) {
987             pkt->stream_index  = asf->asf_st[i]->index;
988             break;
989         }
990     }
991     asf->return_subpayload = 1;
992     if (!sub_len)
993         asf->return_subpayload = 0;
994 
995     if (sub_len)
996         asf->nb_sub++;
997     pkt->dts = asf->sub_dts + (asf->nb_sub - 1) * asf->dts_delta - asf->preroll;
998     if (asf->nb_mult_left && (avio_tell(pb) >=
999                               (asf->sub_header_offset + asf->mult_sub_len))) {
1000         asf->sub_left = 0;
1001         asf->nb_mult_left--;
1002     }
1003     if (avio_tell(pb) >= asf->packet_offset + asf->packet_size - asf->pad_len) {
1004         asf->sub_left = 0;
1005         if (!asf->nb_mult_left) {
1006             avio_skip(pb, asf->pad_len);
1007             if (avio_tell(pb) != asf->packet_offset + asf->packet_size) {
1008                 if (!asf->packet_size)
1009                     return AVERROR_INVALIDDATA;
1010                 av_log(s, AV_LOG_WARNING,
1011                        "Position %"PRId64" wrong, should be %"PRId64"\n",
1012                        avio_tell(pb), asf->packet_offset + asf->packet_size);
1013                 avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
1014             }
1015         }
1016     }
1017 
1018     return 0;
1019 }
1020 
reset_packet(ASFPacket *asf_pkt)1021 static void reset_packet(ASFPacket *asf_pkt)
1022 {
1023     asf_pkt->size_left = 0;
1024     asf_pkt->data_size = 0;
1025     asf_pkt->duration  = 0;
1026     asf_pkt->flags     = 0;
1027     asf_pkt->dts       = 0;
1028     av_packet_unref(asf_pkt->avpkt);
1029 }
1030 
asf_read_replicated_data(AVFormatContext *s, ASFPacket *asf_pkt)1031 static int asf_read_replicated_data(AVFormatContext *s, ASFPacket *asf_pkt)
1032 {
1033     ASFContext *asf = s->priv_data;
1034     AVIOContext *pb = s->pb;
1035     int ret, data_size;
1036 
1037     if (!asf_pkt->data_size) {
1038         data_size = avio_rl32(pb); // read media object size
1039         if (data_size <= 0)
1040             return AVERROR_INVALIDDATA;
1041         if ((ret = av_new_packet(asf_pkt->avpkt, data_size)) < 0)
1042             return ret;
1043         asf_pkt->data_size = asf_pkt->size_left = data_size;
1044     } else
1045         avio_skip(pb, 4); // reading of media object size is already done
1046     asf_pkt->dts = avio_rl32(pb); // read presentation time
1047     if (asf->rep_data_len >= 8)
1048         avio_skip(pb, asf->rep_data_len - 8); // skip replicated data
1049 
1050     return 0;
1051 }
1052 
asf_read_multiple_payload(AVFormatContext *s, AVPacket *pkt, ASFPacket *asf_pkt)1053 static int asf_read_multiple_payload(AVFormatContext *s, AVPacket *pkt,
1054                                  ASFPacket *asf_pkt)
1055 {
1056     ASFContext *asf = s->priv_data;
1057     AVIOContext *pb = s->pb;
1058     uint16_t pay_len;
1059     unsigned char *p;
1060     int ret;
1061     int skip = 0;
1062 
1063     // if replicated length is 1, subpayloads are present
1064     if (asf->rep_data_len == 1) {
1065         asf->sub_left = 1;
1066         asf->state = READ_MULTI_SUB;
1067         pkt->flags = asf_pkt->flags;
1068         if ((ret = asf_read_subpayload(s, pkt, 1)) < 0)
1069             return ret;
1070     } else {
1071         if (asf->rep_data_len)
1072             if ((ret = asf_read_replicated_data(s, asf_pkt)) < 0)
1073                 return ret;
1074         pay_len = avio_rl16(pb); // payload length should be WORD
1075         if (pay_len > asf->packet_size) {
1076             av_log(s, AV_LOG_ERROR,
1077                    "Error: invalid data packet size, pay_len %"PRIu16", "
1078                    "asf->packet_size %"PRIu32", offset %"PRId64".\n",
1079                    pay_len, asf->packet_size, avio_tell(pb));
1080             return AVERROR_INVALIDDATA;
1081         }
1082         p = asf_pkt->avpkt->data + asf_pkt->data_size - asf_pkt->size_left;
1083         if (pay_len > asf_pkt->size_left) {
1084             av_log(s, AV_LOG_ERROR,
1085                    "Error: invalid buffer size, pay_len %d, data size left %d.\n",
1086             pay_len, asf_pkt->size_left);
1087             skip = pay_len - asf_pkt->size_left;
1088             pay_len = asf_pkt->size_left;
1089         }
1090         if (asf_pkt->size_left <= 0)
1091             return AVERROR_INVALIDDATA;
1092         if ((ret = avio_read(pb, p, pay_len)) < 0)
1093             return ret;
1094         if (s->key && s->keylen == 20)
1095             ff_asfcrypt_dec(s->key, p, ret);
1096         avio_skip(pb, skip);
1097         asf_pkt->size_left -= pay_len;
1098         asf->nb_mult_left--;
1099     }
1100 
1101     return 0;
1102 }
1103 
asf_read_single_payload(AVFormatContext *s, ASFPacket *asf_pkt)1104 static int asf_read_single_payload(AVFormatContext *s, ASFPacket *asf_pkt)
1105 {
1106     ASFContext *asf = s->priv_data;
1107     AVIOContext *pb = s->pb;
1108     int64_t  offset;
1109     uint64_t size;
1110     unsigned char *p;
1111     int ret, data_size;
1112 
1113     if (!asf_pkt->data_size) {
1114         data_size = avio_rl32(pb); // read media object size
1115         if (data_size <= 0)
1116             return AVERROR_EOF;
1117         if ((ret = av_new_packet(asf_pkt->avpkt, data_size)) < 0)
1118             return ret;
1119         asf_pkt->data_size = asf_pkt->size_left = data_size;
1120     } else
1121         avio_skip(pb, 4); // skip media object size
1122     asf_pkt->dts = avio_rl32(pb); // read presentation time
1123     if (asf->rep_data_len >= 8)
1124         avio_skip(pb, asf->rep_data_len - 8); // skip replicated data
1125     offset = avio_tell(pb);
1126 
1127     // size of the payload - size of the packet without header and padding
1128     if (asf->packet_size_internal)
1129         size = asf->packet_size_internal - offset + asf->packet_offset - asf->pad_len;
1130     else
1131         size = asf->packet_size - offset + asf->packet_offset - asf->pad_len;
1132     if (size > asf->packet_size) {
1133         av_log(s, AV_LOG_ERROR,
1134                "Error: invalid data packet size, offset %"PRId64".\n",
1135                avio_tell(pb));
1136         return AVERROR_INVALIDDATA;
1137     }
1138     p = asf_pkt->avpkt->data + asf_pkt->data_size - asf_pkt->size_left;
1139     if (size > asf_pkt->size_left || asf_pkt->size_left <= 0)
1140         return AVERROR_INVALIDDATA;
1141     if (asf_pkt->size_left > size)
1142         asf_pkt->size_left -= size;
1143     else
1144         asf_pkt->size_left = 0;
1145     if ((ret = avio_read(pb, p, size)) < 0)
1146         return ret;
1147     if (s->key && s->keylen == 20)
1148             ff_asfcrypt_dec(s->key, p, ret);
1149     if (asf->packet_size_internal)
1150         avio_skip(pb, asf->packet_size - asf->packet_size_internal);
1151     avio_skip(pb, asf->pad_len); // skip padding
1152 
1153     return 0;
1154 }
1155 
asf_read_payload(AVFormatContext *s, AVPacket *pkt)1156 static int asf_read_payload(AVFormatContext *s, AVPacket *pkt)
1157 {
1158     ASFContext *asf = s->priv_data;
1159     AVIOContext *pb = s->pb;
1160     int ret, i;
1161     ASFPacket *asf_pkt = NULL;
1162 
1163     if (!asf->sub_left) {
1164         uint32_t off_len, media_len;
1165         uint8_t stream_num;
1166 
1167         stream_num = avio_r8(pb);
1168         asf->stream_index = stream_num & ASF_STREAM_NUM;
1169         for (i = 0; i < asf->nb_streams; i++) {
1170             if (asf->stream_index == asf->asf_st[i]->stream_index) {
1171                 asf_pkt               = &asf->asf_st[i]->pkt;
1172                 asf_pkt->stream_index = asf->asf_st[i]->index;
1173                 break;
1174             }
1175         }
1176         if (!asf_pkt) {
1177             if (asf->packet_offset + asf->packet_size <= asf->data_offset + asf->data_size) {
1178                 if (!asf->packet_size) {
1179                     av_log(s, AV_LOG_ERROR, "Invalid packet size 0.\n");
1180                     return AVERROR_INVALIDDATA;
1181                 }
1182                 avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
1183                 av_log(s, AV_LOG_WARNING, "Skipping the stream with the invalid stream index %d.\n",
1184                        asf->stream_index);
1185                 return AVERROR(EAGAIN);
1186             } else
1187                 return AVERROR_INVALIDDATA;
1188         }
1189 
1190         if (stream_num >> 7)
1191             asf_pkt->flags |= AV_PKT_FLAG_KEY;
1192         READ_LEN(asf->prop_flags & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE,
1193                  ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_, media_len);
1194         READ_LEN(asf->prop_flags & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE,
1195                  ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_, off_len);
1196         READ_LEN(asf->prop_flags & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE,
1197                  ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_, asf->rep_data_len);
1198         if (asf_pkt->size_left && (asf_pkt->frame_num != media_len)) {
1199             av_log(s, AV_LOG_WARNING, "Unfinished frame will be ignored\n");
1200             reset_packet(asf_pkt);
1201         }
1202         asf_pkt->frame_num = media_len;
1203         asf->sub_dts = off_len;
1204         if (asf->nb_mult_left) {
1205             if ((ret = asf_read_multiple_payload(s, pkt, asf_pkt)) < 0)
1206                 return ret;
1207         } else if (asf->rep_data_len == 1) {
1208             asf->sub_left = 1;
1209             asf->state    = READ_SINGLE;
1210             pkt->flags    = asf_pkt->flags;
1211             if ((ret = asf_read_subpayload(s, pkt, 1)) < 0)
1212                 return ret;
1213         } else {
1214             if ((ret = asf_read_single_payload(s, asf_pkt)) < 0)
1215                 return ret;
1216         }
1217     } else {
1218         for (i = 0; i <= asf->nb_streams; i++) {
1219             if (asf->stream_index == asf->asf_st[i]->stream_index) {
1220                 asf_pkt = &asf->asf_st[i]->pkt;
1221                 break;
1222             }
1223         }
1224         if (!asf_pkt)
1225             return AVERROR_INVALIDDATA;
1226         pkt->flags         = asf_pkt->flags;
1227         pkt->dts           = asf_pkt->dts;
1228         pkt->stream_index  = asf->asf_st[i]->index;
1229         if ((ret = asf_read_subpayload(s, pkt, 0)) < 0) // read subpayload without its header
1230             return ret;
1231     }
1232 
1233     return 0;
1234 }
1235 
asf_read_packet_header(AVFormatContext *s)1236 static int asf_read_packet_header(AVFormatContext *s)
1237 {
1238     ASFContext *asf = s->priv_data;
1239     AVIOContext *pb = s->pb;
1240     uint64_t size;
1241     uint32_t av_unused seq;
1242     unsigned char error_flags, len_flags, pay_flags;
1243 
1244     asf->packet_offset = avio_tell(pb);
1245     if (asf->packet_offset > INT64_MAX/2)
1246         asf->packet_offset = 0;
1247     error_flags = avio_r8(pb); // read Error Correction Flags
1248     if (error_flags & ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT) {
1249         if (!(error_flags & ASF_ERROR_CORRECTION_LENGTH_TYPE)) {
1250             size = error_flags & ASF_PACKET_ERROR_CORRECTION_DATA_SIZE;
1251             avio_skip(pb, size);
1252         }
1253         len_flags       = avio_r8(pb);
1254     } else
1255         len_flags = error_flags;
1256     asf->prop_flags = avio_r8(pb);
1257     READ_LEN(len_flags & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE,
1258              ASF_PPI_FLAG_PACKET_LENGTH_FIELD_, asf->packet_size_internal);
1259     READ_LEN(len_flags & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE,
1260              ASF_PPI_FLAG_SEQUENCE_FIELD_, seq);
1261     READ_LEN(len_flags & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE,
1262              ASF_PPI_FLAG_PADDING_LENGTH_FIELD_, asf->pad_len );
1263     asf->send_time = avio_rl32(pb); // send time
1264     avio_skip(pb, 2); // skip duration
1265     if (len_flags & ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT) { // Multiple Payloads present
1266         pay_flags = avio_r8(pb);
1267         asf->nb_mult_left = (pay_flags & ASF_NUM_OF_PAYLOADS);
1268     }
1269 
1270     return 0;
1271 }
1272 
asf_deinterleave(AVFormatContext *s, ASFPacket *asf_pkt, int st_num)1273 static int asf_deinterleave(AVFormatContext *s, ASFPacket *asf_pkt, int st_num)
1274 {
1275     ASFContext *asf    = s->priv_data;
1276     ASFStream *asf_st  = asf->asf_st[st_num];
1277     unsigned char *p   = asf_pkt->avpkt->data;
1278     uint16_t pkt_len   = asf->asf_st[st_num]->virtual_pkt_len;
1279     uint16_t chunk_len = asf->asf_st[st_num]->virtual_chunk_len;
1280     int nchunks        = pkt_len / chunk_len;
1281     uint8_t *data;
1282     int pos = 0, j, l, ret;
1283 
1284 
1285     data = av_malloc(asf_pkt->data_size + AV_INPUT_BUFFER_PADDING_SIZE);
1286     if (!data)
1287         return AVERROR(ENOMEM);
1288     memset(data + asf_pkt->data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1289 
1290     while (asf_pkt->data_size >= asf_st->span * pkt_len + pos) {
1291         if (pos >= asf_pkt->data_size) {
1292             break;
1293         }
1294         for (l = 0; l < pkt_len; l++) {
1295             if (pos >= asf_pkt->data_size) {
1296                 break;
1297             }
1298             for (j = 0; j < asf_st->span; j++) {
1299                 if ((pos + chunk_len) >= asf_pkt->data_size)
1300                     break;
1301                 memcpy(data + pos,
1302                        p + (j * nchunks + l) * chunk_len,
1303                        chunk_len);
1304                 pos += chunk_len;
1305             }
1306         }
1307         p += asf_st->span * pkt_len;
1308         if (p > asf_pkt->avpkt->data + asf_pkt->data_size)
1309             break;
1310     }
1311     av_packet_unref(asf_pkt->avpkt);
1312     ret = av_packet_from_data(asf_pkt->avpkt, data, asf_pkt->data_size);
1313     if (ret < 0)
1314         av_free(data);
1315 
1316     return ret;
1317 }
1318 
asf_read_packet(AVFormatContext *s, AVPacket *pkt)1319 static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
1320 {
1321     ASFContext *asf = s->priv_data;
1322     AVIOContext *pb = s->pb;
1323     int ret, i;
1324 
1325     if ((avio_tell(pb) >= asf->data_offset + asf->data_size) &&
1326         !(asf->b_flags & ASF_FLAG_BROADCAST))
1327         return AVERROR_EOF;
1328     while (!pb->eof_reached) {
1329         if (asf->state == PARSE_PACKET_HEADER) {
1330             asf_read_packet_header(s);
1331             if (pb->eof_reached)
1332                 break;
1333             if (!asf->nb_mult_left)
1334                 asf->state = READ_SINGLE;
1335             else
1336                 asf->state = READ_MULTI;
1337         }
1338         ret = asf_read_payload(s, pkt);
1339         if (ret == AVERROR(EAGAIN)) {
1340             asf->state = PARSE_PACKET_HEADER;
1341             continue;
1342         }
1343         else if (ret < 0)
1344             return ret;
1345 
1346         switch (asf->state) {
1347         case READ_SINGLE:
1348             if (!asf->sub_left)
1349                 asf->state = PARSE_PACKET_HEADER;
1350             break;
1351         case READ_MULTI_SUB:
1352             if (!asf->sub_left && !asf->nb_mult_left) {
1353                 asf->state = PARSE_PACKET_HEADER;
1354                 if (!asf->return_subpayload &&
1355                     (avio_tell(pb) <= asf->packet_offset +
1356                      asf->packet_size - asf->pad_len))
1357                     avio_skip(pb, asf->pad_len); // skip padding
1358                 if (asf->packet_offset + asf->packet_size > avio_tell(pb))
1359                     avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
1360             } else if (!asf->sub_left)
1361                 asf->state = READ_MULTI;
1362             break;
1363         case READ_MULTI:
1364             if (!asf->nb_mult_left) {
1365                 asf->state = PARSE_PACKET_HEADER;
1366                 if (!asf->return_subpayload &&
1367                     (avio_tell(pb) <= asf->packet_offset +
1368                      asf->packet_size - asf->pad_len))
1369                     avio_skip(pb, asf->pad_len); // skip padding
1370                 if (asf->packet_offset + asf->packet_size > avio_tell(pb))
1371                     avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
1372             }
1373             break;
1374         }
1375         if (asf->return_subpayload) {
1376             asf->return_subpayload = 0;
1377             return 0;
1378         }
1379         for (i = 0; i < asf->nb_streams; i++) {
1380             ASFPacket *asf_pkt = &asf->asf_st[i]->pkt;
1381             if (asf_pkt && !asf_pkt->size_left && asf_pkt->data_size) {
1382                 if (asf->asf_st[i]->span > 1 &&
1383                     asf->asf_st[i]->type == AVMEDIA_TYPE_AUDIO)
1384                     if ((ret = asf_deinterleave(s, asf_pkt, i)) < 0)
1385                         return ret;
1386                 av_packet_move_ref(pkt, asf_pkt->avpkt);
1387                 pkt->stream_index  = asf->asf_st[i]->index;
1388                 pkt->flags         = asf_pkt->flags;
1389                 pkt->dts           = asf_pkt->dts - asf->preroll;
1390                 asf_pkt->data_size = 0;
1391                 asf_pkt->frame_num = 0;
1392                 return 0;
1393             }
1394         }
1395     }
1396 
1397     if (pb->eof_reached)
1398         return AVERROR_EOF;
1399 
1400     return 0;
1401 }
1402 
asf_read_close(AVFormatContext *s)1403 static int asf_read_close(AVFormatContext *s)
1404 {
1405     ASFContext *asf = s->priv_data;
1406     int i;
1407 
1408     for (i = 0; i < ASF_MAX_STREAMS; i++) {
1409         av_dict_free(&asf->asf_sd[i].asf_met);
1410         if (i < asf->nb_streams) {
1411             av_packet_free(&asf->asf_st[i]->pkt.avpkt);
1412             av_freep(&asf->asf_st[i]);
1413         }
1414     }
1415 
1416     asf->nb_streams = 0;
1417     return 0;
1418 }
1419 
reset_packet_state(AVFormatContext *s)1420 static void reset_packet_state(AVFormatContext *s)
1421 {
1422     ASFContext *asf        = s->priv_data;
1423     int i;
1424 
1425     asf->state             = PARSE_PACKET_HEADER;
1426     asf->offset            = 0;
1427     asf->return_subpayload = 0;
1428     asf->sub_left          = 0;
1429     asf->sub_header_offset = 0;
1430     asf->packet_offset     = asf->first_packet_offset;
1431     asf->pad_len           = 0;
1432     asf->rep_data_len      = 0;
1433     asf->dts_delta         = 0;
1434     asf->mult_sub_len      = 0;
1435     asf->nb_mult_left      = 0;
1436     asf->nb_sub            = 0;
1437     asf->prop_flags        = 0;
1438     asf->sub_dts           = 0;
1439     for (i = 0; i < asf->nb_streams; i++) {
1440         ASFPacket *pkt = &asf->asf_st[i]->pkt;
1441         reset_packet(pkt);
1442     }
1443 }
1444 
1445 /*
1446  * Find a timestamp for the requested position within the payload
1447  * where the pos (position) is the offset inside the Data Object.
1448  * When position is not on the packet boundary, asf_read_timestamp tries
1449  * to find the closest packet offset after this position. If this packet
1450  * is a key frame, this packet timestamp is read and an index entry is created
1451  * for the packet. If this packet belongs to the requested stream,
1452  * asf_read_timestamp upgrades pos to the packet beginning offset and
1453  * returns this packet's dts. So returned dts is the dts of the first key frame with
1454  * matching stream number after given position.
1455  */
asf_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit)1456 static int64_t asf_read_timestamp(AVFormatContext *s, int stream_index,
1457                                   int64_t *pos, int64_t pos_limit)
1458 {
1459     ASFContext *asf = s->priv_data;
1460     int64_t pkt_pos = *pos, pkt_offset, dts = AV_NOPTS_VALUE, data_end;
1461     AVPacket *pkt = av_packet_alloc();
1462     int n;
1463 
1464     if (!pkt)
1465         return AVERROR(ENOMEM);
1466 
1467     data_end = asf->data_offset + asf->data_size;
1468 
1469     n = (pkt_pos - asf->first_packet_offset + asf->packet_size - 1) /
1470         asf->packet_size;
1471     n = av_clip(n, 0, ((data_end - asf->first_packet_offset) / asf->packet_size - 1));
1472     pkt_pos = asf->first_packet_offset +  n * asf->packet_size;
1473 
1474     avio_seek(s->pb, pkt_pos, SEEK_SET);
1475     pkt_offset = pkt_pos;
1476 
1477     reset_packet_state(s);
1478     while (avio_tell(s->pb) < data_end) {
1479 
1480         int i, ret, st_found;
1481 
1482         pkt_offset = avio_tell(s->pb);
1483         if ((ret = asf_read_packet(s, pkt)) < 0) {
1484             av_packet_free(&pkt);
1485             dts = AV_NOPTS_VALUE;
1486             return ret;
1487         }
1488         // ASFPacket may contain fragments of packets belonging to different streams,
1489         // pkt_offset is the offset of the first fragment within it.
1490         if ((pkt_offset >= (pkt_pos + asf->packet_size)))
1491             pkt_pos += asf->packet_size;
1492         for (i = 0; i < asf->nb_streams; i++) {
1493             ASFStream *st = asf->asf_st[i];
1494 
1495             st_found = 0;
1496             if (pkt->flags & AV_PKT_FLAG_KEY) {
1497                 dts = pkt->dts;
1498                 if (dts) {
1499                     av_add_index_entry(s->streams[pkt->stream_index], pkt_pos,
1500                                        dts, pkt->size, 0, AVINDEX_KEYFRAME);
1501                     if (stream_index == st->index) {
1502                         st_found = 1;
1503                         break;
1504                     }
1505                 }
1506             }
1507         }
1508         if (st_found)
1509             break;
1510         av_packet_unref(pkt);
1511     }
1512     *pos = pkt_pos;
1513 
1514     av_packet_free(&pkt);
1515     return dts;
1516 }
1517 
asf_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)1518 static int asf_read_seek(AVFormatContext *s, int stream_index,
1519                          int64_t timestamp, int flags)
1520 {
1521     ASFContext *asf = s->priv_data;
1522     AVStream *const st = s->streams[stream_index];
1523     FFStream *const sti = ffstream(st);
1524     int idx, ret;
1525 
1526     if (sti->nb_index_entries && asf->is_simple_index) {
1527         idx = av_index_search_timestamp(st, timestamp, flags);
1528         if (idx < 0 || idx >= sti->nb_index_entries)
1529             return AVERROR_INVALIDDATA;
1530         avio_seek(s->pb, sti->index_entries[idx].pos, SEEK_SET);
1531     } else {
1532         if ((ret = ff_seek_frame_binary(s, stream_index, timestamp, flags)) < 0)
1533             return ret;
1534     }
1535 
1536     reset_packet_state(s);
1537 
1538     return 0;
1539 }
1540 
find_guid(ff_asf_guid guid)1541 static const GUIDParseTable *find_guid(ff_asf_guid guid)
1542 {
1543     int j, ret;
1544     const GUIDParseTable *g;
1545 
1546     swap_guid(guid);
1547     g = gdef;
1548     for (j = 0; j < FF_ARRAY_ELEMS(gdef); j++) {
1549         if (!(ret = memcmp(guid, g->guid, sizeof(g->guid))))
1550             return g;
1551         g++;
1552     }
1553 
1554     return NULL;
1555 }
1556 
detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t size)1557 static int detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t size)
1558 {
1559     ASFContext *asf = s->priv_data;
1560     AVIOContext *pb = s->pb;
1561     const GUIDParseTable *g = NULL;
1562     ff_asf_guid guid;
1563     int ret;
1564 
1565     if (offset > INT64_MAX - size)
1566         return AVERROR_INVALIDDATA;
1567 
1568     while (avio_tell(pb) <= offset + size) {
1569         if (avio_tell(pb) == asf->offset)
1570             break;
1571         asf->offset = avio_tell(pb);
1572         if ((ret = ff_get_guid(pb, &guid)) < 0)
1573             return ret;
1574         g = find_guid(guid);
1575         if (g) {
1576             if ((ret = g->read_object(s, g)) < 0)
1577                 return ret;
1578         } else {
1579             GUIDParseTable g2;
1580 
1581             g2.name         = "Unknown";
1582             g2.is_subobject = 1;
1583             asf_read_unknown(s, &g2);
1584         }
1585     }
1586 
1587     return 0;
1588 }
1589 
asf_read_header(AVFormatContext *s)1590 static int asf_read_header(AVFormatContext *s)
1591 {
1592     ASFContext *asf         = s->priv_data;
1593     AVIOContext *pb         = s->pb;
1594     const GUIDParseTable *g = NULL;
1595     ff_asf_guid guid;
1596     int i, ret;
1597     uint64_t size;
1598 
1599     asf->preroll         = 0;
1600     asf->is_simple_index = 0;
1601     ff_get_guid(pb, &guid);
1602     if (ff_guidcmp(&guid, &ff_asf_header))
1603         return AVERROR_INVALIDDATA;
1604     avio_skip(pb, 8); // skip header object size
1605     avio_skip(pb, 6); // skip number of header objects and 2 reserved bytes
1606     asf->data_reached = 0;
1607 
1608     /* 1  is here instead of pb->eof_reached because (when not streaming), Data are skipped
1609      * for the first time,
1610      * Index object is processed and got eof and then seeking back to the Data is performed.
1611      */
1612     while (1) {
1613         // for the cases when object size is invalid
1614         if (avio_tell(pb) == asf->offset)
1615             break;
1616         asf->offset = avio_tell(pb);
1617         if ((ret = ff_get_guid(pb, &guid)) < 0) {
1618             if (ret == AVERROR_EOF && asf->data_reached)
1619                 break;
1620             else
1621                 goto failed;
1622         }
1623         g = find_guid(guid);
1624         if (g) {
1625             asf->unknown_offset = asf->offset;
1626             asf->is_header = 1;
1627             if ((ret = g->read_object(s, g)) < 0)
1628                 goto failed;
1629         } else {
1630             size = avio_rl64(pb);
1631             align_position(pb, asf->offset, size);
1632         }
1633         if (asf->data_reached &&
1634             (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
1635              (asf->b_flags & ASF_FLAG_BROADCAST)))
1636             break;
1637     }
1638 
1639     if (!asf->data_reached) {
1640         av_log(s, AV_LOG_ERROR, "Data Object was not found.\n");
1641         ret = AVERROR_INVALIDDATA;
1642         goto failed;
1643     }
1644     if (pb->seekable & AVIO_SEEKABLE_NORMAL)
1645         avio_seek(pb, asf->first_packet_offset, SEEK_SET);
1646 
1647     for (i = 0; i < asf->nb_streams; i++) {
1648         const char *rfc1766 = asf->asf_sd[asf->asf_st[i]->lang_idx].langs;
1649         AVStream *st        = s->streams[asf->asf_st[i]->index];
1650         set_language(s, rfc1766, &st->metadata);
1651     }
1652 
1653     for (i = 0; i < ASF_MAX_STREAMS; i++) {
1654         AVStream *st = NULL;
1655 
1656         st = find_stream(s, i);
1657         if (st) {
1658             av_dict_copy(&st->metadata, asf->asf_sd[i].asf_met, AV_DICT_IGNORE_SUFFIX);
1659             if (asf->asf_sd[i].aspect_ratio.num > 0 && asf->asf_sd[i].aspect_ratio.den > 0) {
1660                 st->sample_aspect_ratio.num = asf->asf_sd[i].aspect_ratio.num;
1661                 st->sample_aspect_ratio.den = asf->asf_sd[i].aspect_ratio.den;
1662             }
1663         }
1664     }
1665 
1666     return 0;
1667 
1668 failed:
1669     asf_read_close(s);
1670     return ret;
1671 }
1672 
1673 const AVInputFormat ff_asf_o_demuxer = {
1674     .name           = "asf_o",
1675     .long_name      = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
1676     .priv_data_size = sizeof(ASFContext),
1677     .read_probe     = asf_probe,
1678     .read_header    = asf_read_header,
1679     .read_packet    = asf_read_packet,
1680     .read_close     = asf_read_close,
1681     .read_timestamp = asf_read_timestamp,
1682     .read_seek      = asf_read_seek,
1683     .flags          = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
1684 };
1685