Hello FFmpeg developers, Iv'e noticed some DAV files containing a 0xff's padding in between DHAV chunks. This is possible when the Dahua DVR device generates a DAV file which is concatenated from 2 different DAV files kept on the device hard drive.
Here <https://www98.zippyshare.com/v/SjZCQwuv/file.html> is a 30 seconds sample DAV file with such concatenation. The current code (master) fails to parse frame at 11:00:12 (clock on frame) as it incorrectly skips valid DHAV chunks in the file after detecting the padding. Proposing a possible patch for this issue (git formatted patch is attached). Will like to hear your thoughts and insights. Thank you -- Idan Freiberg Mobile: +972-52-2925213
From 89a7678883d061f3601b6260a2be5dc3471a76a9 Mon Sep 17 00:00:00 2001 From: Idan Freiberg <i...@tokagroup.com> Date: Wed, 13 Jan 2021 13:55:48 +0200 Subject: [PATCH] avformat/dhav: Fix incorrect non-DHAV chunk skipping logic DAV files may contain a variable length padding in between chunks filled with 0xff bytes. The current skipping logic is incorrect as it may skip over DHAV chunks not appearing sequentially in the file. We now look for the 'DHAV' tag using a byte-by-byte search in order to handle such situations. Also the dhav->last_good_pos field will not be updated while skipping unrecognized data. --- libavformat/dhav.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/libavformat/dhav.c b/libavformat/dhav.c index 00e0d8476e..6a6c235e65 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -173,18 +173,9 @@ static int read_chunk(AVFormatContext *s) if (avio_feof(s->pb)) return AVERROR_EOF; - if (avio_rl32(s->pb) != MKTAG('D','H','A','V') && dhav->last_good_pos < INT64_MAX - 0x8000) { - 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')) { - if (avio_feof(s->pb) || dhav->last_good_pos >= INT64_MAX - 0x8000) - return AVERROR_EOF; - dhav->last_good_pos += 0x8000; - ret = avio_skip(s->pb, 0x8000 - 4); - if (ret < 0) - return ret; - } + while (avio_r8(s->pb) != 'D' || avio_r8(s->pb) != 'H' || avio_r8(s->pb) != 'A' || avio_r8(s->pb) != 'V') { + if (avio_feof(s->pb)) + return AVERROR_EOF; } start = avio_tell(s->pb) - 4; -- 2.29.2
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".