[FFmpeg-devel] [PATCH v2] avformat/dhav: also support ZLAV packets

Michael Keeley mike at keeley.net.nz
Sun Nov 8 11:41:43 EET 2020


Some DVRs (e.g. D7008FH made by iSmart Cities (Zhuhai) Limited) output the same format .dav file,
but use ZLAV/zlav tags to delimit the packets instead of DHAV/dhav.

Signed-off-by: Michael Keeley <mike at keeley.net.nz>
---
 Changelog             |  1 +
 libavformat/dhav.c    | 31 ++++++++++++++++++++++---------
 libavformat/version.h |  2 +-
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/Changelog b/Changelog
index 0ea1901bbe..a56216543d 100644
--- a/Changelog
+++ b/Changelog
@@ -41,6 +41,7 @@ version <next>:
 - LEGO Racers ALP (.tun & .pcm) muxer
 - AV1 VAAPI decoder
 - adenorm filter
+- Add ZLAV format to DHAV demuxer
 
 
 version 4.3:
diff --git a/libavformat/dhav.c b/libavformat/dhav.c
index 53deaff77e..40c2cc78b0 100644
--- a/libavformat/dhav.c
+++ b/libavformat/dhav.c
@@ -1,5 +1,5 @@
 /*
- * DHAV demuxer
+ * DHAV/ZLAV demuxer
  *
  * Copyright (c) 2018 Paul B Mahol
  *
@@ -57,7 +57,7 @@ static int dhav_probe(const AVProbeData *p)
     if (!memcmp(p->buf, "DAHUA", 5))
         return AVPROBE_SCORE_MAX;
 
-    if (memcmp(p->buf, "DHAV", 4))
+    if (memcmp(p->buf, "DHAV", 4) && memcmp(p->buf, "ZLAV", 4))
         return 0;
 
     if (p->buf[4] == 0xf0 ||
@@ -163,6 +163,19 @@ static int parse_ext(AVFormatContext *s, int length)
     return 0;
 }
 
+static int read_start_tag(AVIOContext *pb)
+{
+    unsigned int start_tag = avio_rl32(pb);
+    return start_tag == MKTAG('D','H','A','V') || start_tag == MKTAG('Z','L','A','V');
+}
+
+static int read_end_tag(AVIOContext *pb)
+{
+    unsigned int end_tag = avio_rl32(pb);
+    return end_tag == MKTAG('d','h','a','v') || end_tag == MKTAG('z','l','a','v');
+}
+
+
 static int read_chunk(AVFormatContext *s)
 {
     DHAVContext *dhav = s->priv_data;
@@ -173,11 +186,11 @@ static int read_chunk(AVFormatContext *s)
     if (avio_feof(s->pb))
         return AVERROR_EOF;
 
-    if (avio_rl32(s->pb) != MKTAG('D','H','A','V')) {
+    if (!read_start_tag(s->pb)) {
         dhav->last_good_pos += 0x8000;
         avio_seek(s->pb, dhav->last_good_pos, SEEK_SET);
 
-        while (avio_rl32(s->pb) != MKTAG('D','H','A','V')) {
+        while (!read_start_tag(s->pb)) {
             if (avio_feof(s->pb))
                 return AVERROR_EOF;
             dhav->last_good_pos += 0x8000;
@@ -247,7 +260,7 @@ static int64_t get_duration(AVFormatContext *s)
         return 0;
 
     avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET);
-    if (avio_rl32(s->pb) == MKTAG('d','h','a','v')) {
+    if (read_end_tag(s->pb)) {
         int seek_back = avio_rl32(s->pb);
 
         avio_seek(s->pb, -seek_back, SEEK_CUR);
@@ -281,12 +294,12 @@ static int dhav_read_header(AVFormatContext *s)
         avio_skip(s->pb, 0x400 - 5);
         dhav->last_good_pos = avio_tell(s->pb);
     } else {
-        if (!memcmp(signature, "DHAV", 4)) {
+        if (!memcmp(signature, "DHAV", 4) || !memcmp(signature, "ZLAV", 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')) {
+            while (read_end_tag(s->pb)) {
                 int seek_back;
 
                 seek_back = avio_rl32(s->pb) + 8;
@@ -409,7 +422,7 @@ retry:
     stream_index = dhav->type == 0xf0 ? dhav->audio_stream_index : dhav->video_stream_index;
     if (stream_index < 0) {
         avio_skip(s->pb, ret);
-        if (avio_rl32(s->pb) == MKTAG('d','h','a','v'))
+        if (read_end_tag(s->pb))
             avio_skip(s->pb, 4);
         goto retry;
     }
@@ -425,7 +438,7 @@ retry:
     if (pkt->stream_index >= 0)
         pkt->pts = get_pts(s, pkt->stream_index);
     pkt->pos = dhav->last_good_pos;
-    if (avio_rl32(s->pb) == MKTAG('d','h','a','v'))
+    if (read_end_tag(s->pb))
         avio_skip(s->pb, 4);
 
     return ret;
diff --git a/libavformat/version.h b/libavformat/version.h
index ddcca9ae50..b43193bcb1 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
 // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
 // Also please add any ticket numbers that you believe might be affected here
 #define LIBAVFORMAT_VERSION_MAJOR  58
-#define LIBAVFORMAT_VERSION_MINOR  64
+#define LIBAVFORMAT_VERSION_MINOR  65
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-- 
2.25.1



More information about the ffmpeg-devel mailing list