Quoting Alexandra Hájková (2015-03-26 10:06:07)
> +static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g)
>  {
> +    ASFContext *asf = s->priv_data;
>      AVIOContext *pb = s->pb;
> -    int len1, len2, len3, len4, len5;
> -
> -    len1 = avio_rl16(pb);
> -    len2 = avio_rl16(pb);
> -    len3 = avio_rl16(pb);
> -    len4 = avio_rl16(pb);
> -    len5 = avio_rl16(pb);
> -    get_tag(s, "title", 0, len1, 32);
> -    get_tag(s, "author", 0, len2, 32);
> -    get_tag(s, "copyright", 0, len3, 32);
> -    get_tag(s, "comment", 0, len4, 32);
> -    avio_skip(pb, len5);
> +    uint64_t creation_time;
> +    struct tm tmbuf;
> +    struct tm *tm;
> +    char buf[64] = {0};
> +
> +    avio_rl64(pb); // read object size
> +    avio_skip(pb, 16); // skip File ID
> +    avio_skip(pb, 8);  // skip File size
> +    creation_time = avio_rl64(pb);
> +    if (!(asf->b_flags & ASF_FLAG_BROADCAST)) {
> +        // creation date is in 100 ns units from 1 Jan 1601, conversion to s
> +        creation_time /= 10000000;
> +        // there are 11644473600 seconds between 1 Jan 1601 and 1 Jan 1970
> +        creation_time -= 11644473600;
> +        tm = gmtime_r(&creation_time, &tmbuf);
> +        if (tm) {
> +            if (!strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm))
> +                buf[0] = '\0';
> +        } else
> +            buf[0] = '\0';
> +        if (av_dict_set(&s->metadata, "creation_time", buf, 0) < 0)
> +        av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
> +    }
> +    asf->nb_packets  = avio_rl64(pb);
> +    asf->duration    = avio_rl64(pb) / 10000; // stream duration
> +    avio_skip(pb, 8); // skip send duration
> +    asf->preroll     = avio_rl64(pb);

The specs say that preroll must be applied to the duration as well.

> +// returns data object offset when reading this object for the first time
> +static int asf_read_data(AVFormatContext *s, const GUIDParseTable *g)
>  {
> -    AVIOContext *pb = s->pb;
>      ASFContext *asf = s->priv_data;
> -    int i, count, name_len, ret;
> -    char name[1024];
> +    AVIOContext *pb = s->pb;
> +    uint64_t size   = asf->data_size = avio_rl64(pb);
> +    int i;
>  
> -    avio_rl64(pb);            // reserved 16 bytes
> -    avio_rl64(pb);            // ...
> -    count = avio_rl32(pb);    // markers count
> -    avio_rl16(pb);            // reserved 2 bytes
> -    name_len = avio_rl16(pb); // name length
> -    for (i = 0; i < name_len; i++)
> -        avio_r8(pb); // skip the name
> -
> -    for (i = 0; i < count; i++) {
> -        int64_t pres_time;
> -        int name_len;
> -
> -        avio_rl64(pb);             // offset, 8 bytes
> -        pres_time = avio_rl64(pb); // presentation time
> -        pres_time -= asf->hdr.preroll * 10000;
> -        avio_rl16(pb);             // entry length
> -        avio_rl32(pb);             // send time
> -        avio_rl32(pb);             // flags
> -        name_len = avio_rl32(pb);  // name length
> -        if ((ret = avio_get_str16le(pb, name_len * 2, name,
> -                                    sizeof(name))) < name_len)
> -            avio_skip(pb, name_len - ret);
> -        avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pres_time,
> -                           AV_NOPTS_VALUE, name);
> +    if (!asf->data_reached && pb->seekable) {
> +        asf->data_reached       = 1;
> +        asf->data_offset  = asf->offset;
>      }
>  
> +    for (i = 0; i < asf->nb_streams; i++)
> +        s->streams[i]->duration = asf->duration;

This unconditionally overwrites the value that may already have been
set earlier. That is probably not a good idea.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to