+ int64_t start_pos = avio_tell(s->pb);
+ int64_t start = 0, end = 0;
+ struct tm timeinfo;
+
+ if (!s->pb->seekable)
+ return 0;
+
+ avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET);
+ if (avio_rl32(s->pb) == MKTAG('d','h','a','v')) {
+ int seek_back = avio_rl32(s->pb);
+
+ avio_seek(s->pb, -seek_back, SEEK_CUR);
+ read_chunk(s);
+ get_timeinfo(dhav->date, &timeinfo);
+ end = av_timegm(&timeinfo) * 1000LL;
+ } else {
+ avio_seek(s->pb, start_pos, SEEK_SET);
+ return 0;
+ }
+
+ avio_seek(s->pb, start_pos, SEEK_SET);
+
+ read_chunk(s);
+ get_timeinfo(dhav->date, &timeinfo);
+ start = av_timegm(&timeinfo) * 1000LL;
+
+ avio_seek(s->pb, start_pos, SEEK_SET);
+
+ return end - start;
+}
+
+static int dhav_read_header(AVFormatContext *s)
+{
+ DHAVContext *dhav = s->priv_data;
+ uint8_t signature[5];
+
+ ffio_ensure_seekback(s->pb, 5);
+ avio_read(s->pb, signature, sizeof(signature));
+ if (!memcmp(signature, "DAHUA", 5)) {
+ avio_skip(s->pb, 0x400 - 5);
+ dhav->last_good_pos = avio_tell(s->pb);
+ } else {
+ if (!memcmp(signature, "DHAV", 4)) {
+ avio_seek(s->pb, -5, SEEK_CUR);
+ dhav->last_good_pos = avio_tell(s->pb);
+ } else if (s->pb->seekable) {
+ avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET);
+ while (avio_rl32(s->pb) == MKTAG('d','h','a','v')) {
+ int seek_back;
+
+ seek_back = avio_rl32(s->pb) + 8;
+ dhav->last_good_pos = avio_tell(s->pb);
+ avio_seek(s->pb, -seek_back, SEEK_CUR);
+ }
+ avio_seek(s->pb, dhav->last_good_pos, SEEK_SET);
+ }
+ }