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