Message ID | 20201024003225.216806-1-mike@keeley.net.nz |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel] avformat/dhav: also support ZLAV packets | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
LGTM On Sat, Oct 24, 2020 at 2:32 AM Michael Keeley <mike@keeley.net.nz> wrote: > Some DVRs (e.g. D7008FH made by Zhuhai Ltd) 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@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 21a4be731b..8e289733e2 100644 > --- a/Changelog > +++ b/Changelog > @@ -37,6 +37,7 @@ version <next>: > - Cintel RAW decoder > - VDPAU accelerated VP9 10/12bit decoding > - afreqshift and aphaseshift filters > +- Add ZLAV format to DHAV demuxer > > > version 4.3: > diff --git a/libavformat/dhav.c b/libavformat/dhav.c > index 79afe9be03..e2f3c40065 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) != 0 && memcmp(p->buf, "ZLAV", 4) != 0) > 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) == 0 || memcmp(signature, > "ZLAV", 4) == 0) { > 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 86e0a232ee..7853068649 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 62 > +#define LIBAVFORMAT_VERSION_MINOR 63 > #define LIBAVFORMAT_VERSION_MICRO 100 > > #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, > \ > -- > 2.25.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Hi Michael, > On Oct 24, 2020, at 8:32 AM, Michael Keeley <mike@keeley.net.nz> wrote: > > Some DVRs (e.g. D7008FH made by Zhuhai Ltd) output the same format .dav file, > but use ZLAV/zlav tags to delimit the packets instead of DHAV/dhav. Zhuhai Ltd doesn't look like the real company name. I didn't find much information about D7008FH. Could you share more informations so I can help figure out the product model and vendor? Of course, if such information matters. > > Signed-off-by: Michael Keeley <mike@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 21a4be731b..8e289733e2 100644 > --- a/Changelog > +++ b/Changelog > @@ -37,6 +37,7 @@ version <next>: > - Cintel RAW decoder > - VDPAU accelerated VP9 10/12bit decoding > - afreqshift and aphaseshift filters > +- Add ZLAV format to DHAV demuxer > > > version 4.3: > diff --git a/libavformat/dhav.c b/libavformat/dhav.c > index 79afe9be03..e2f3c40065 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) != 0 && memcmp(p->buf, "ZLAV", 4) != 0) > 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) == 0 || memcmp(signature, "ZLAV", 4) == 0) { > 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 86e0a232ee..7853068649 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 62 > +#define LIBAVFORMAT_VERSION_MINOR 63 > #define LIBAVFORMAT_VERSION_MICRO 100 > > #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ > -- > 2.25.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Hi Zhao, > > Some DVRs (e.g. D7008FH made by Zhuhai Ltd) output the same format > .dav file, > > but use ZLAV/zlav tags to delimit the packets instead of DHAV/dhav. > > Zhuhai Ltd doesn't look like the real company name. I didn't find much > information > about D7008FH. Could you share more informations so I can help figure > out the product > model and vendor? Of course, if such information matters. > I own this product, and I have attached the PDF manual for the device. There is no branding on the device itself, except for the model number on a sticker underneath. I googled the model number and found this manual. The company name is actually iSmart Cities (Zhuhai) Limited, I just assumed Zhuhai was the Chinese company name (based on the ZL tag prefix Zhuhai Ltd -> ZL). But looking closer, I see that's just the city name, whoops! Of course, this doesn't affect the code, happy to supply more information if you want it. Mike.
> > On Oct 25, 2020, at 7:58 AM, Michael Keeley <mike@keeley.net.nz> wrote: > > Hi Zhao, > >>> Some DVRs (e.g. D7008FH made by Zhuhai Ltd) output the same format >> .dav file, >>> but use ZLAV/zlav tags to delimit the packets instead of DHAV/dhav. >> >> Zhuhai Ltd doesn't look like the real company name. I didn't find much >> information >> about D7008FH. Could you share more informations so I can help figure >> out the product >> model and vendor? Of course, if such information matters. >> > > I own this product, and I have attached the PDF manual for the device. There is no branding on the device itself, except for the model number on a sticker underneath. > I googled the model number and found this manual. The company name is actually iSmart Cities (Zhuhai) Limited, I just assumed Zhuhai was the Chinese company name (based on the ZL tag prefix Zhuhai Ltd -> ZL). > But looking closer, I see that's just the city name, whoops! Yes, city names are not allowed to be registered as branding names now in China. > > Of course, this doesn't affect the code, happy to supply more information if you want it. Thank you, this information may help identify or reverse engineer similar device. > > Mike. > > <D7008FH Manual.pdf>_______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel> > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".
> -----Original Message----- > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf > Of Paul B Mahol > Sent: Saturday, 24 October 2020 9:03 pm > To: FFmpeg development discussions and patches > Cc: Michael Keeley > Subject: Re: [FFmpeg-devel] [PATCH] avformat/dhav: also support ZLAV > packets > > LGTM > Thanks for the feedback. Is there anything more I need to do here, or will someone merge it? Cheers, Mike. > On Sat, Oct 24, 2020 at 2:32 AM Michael Keeley <mike@keeley.net.nz> > wrote: > > > Some DVRs (e.g. D7008FH made by Zhuhai Ltd) 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@keeley.net.nz> > > --- > > Changelog | 1 + > > libavformat/dhav.c | 31 ++++++++++++++++++++++--------- > > libavformat/version.h | 2 +- > > 3 files changed, 24 insertions(+), 10 deletions(-) > > <snip>
On Sat, Oct 24, 2020 at 13:32:25 +1300, Michael Keeley wrote: > - if (memcmp(p->buf, "DHAV", 4)) > + if (memcmp(p->buf, "DHAV", 4) != 0 && memcmp(p->buf, "ZLAV", 4) != 0) The "!= 0" isn't necessary. > - if (!memcmp(signature, "DHAV", 4)) { > + if (memcmp(signature, "DHAV", 4) == 0 || memcmp(signature, "ZLAV", 4) == 0) { Also here, ffmpeg prefers the "!memcmp()" style. Moritz
diff --git a/Changelog b/Changelog index 21a4be731b..8e289733e2 100644 --- a/Changelog +++ b/Changelog @@ -37,6 +37,7 @@ version <next>: - Cintel RAW decoder - VDPAU accelerated VP9 10/12bit decoding - afreqshift and aphaseshift filters +- Add ZLAV format to DHAV demuxer version 4.3: diff --git a/libavformat/dhav.c b/libavformat/dhav.c index 79afe9be03..e2f3c40065 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) != 0 && memcmp(p->buf, "ZLAV", 4) != 0) 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) == 0 || memcmp(signature, "ZLAV", 4) == 0) { 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 86e0a232ee..7853068649 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 62 +#define LIBAVFORMAT_VERSION_MINOR 63 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
Some DVRs (e.g. D7008FH made by Zhuhai Ltd) 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@keeley.net.nz> --- Changelog | 1 + libavformat/dhav.c | 31 ++++++++++++++++++++++--------- libavformat/version.h | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-)