The branch, master has been updated
       via  e02e6d54b04aaed3a500e55fd53da6dd411074d8 (commit)
       via  dcddb2bf08f5fa6af655938a3a0d3cd2200fd8c9 (commit)
      from  db0b86a4adf3ffe592ea70e756d615e89138eee0 (commit)


- Log -----------------------------------------------------------------
commit e02e6d54b04aaed3a500e55fd53da6dd411074d8
Author:     Zhao Zhili <[email protected]>
AuthorDate: Sun Sep 14 18:14:10 2025 +0800
Commit:     Zhao Zhili <[email protected]>
CommitDate: Sun Sep 21 17:42:19 2025 +0800

    tests/fate/demux: add hxvs test case

diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index a2cb45aa7e..ad1046a453 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -54,6 +54,9 @@ fate-flv-demux: CMD = ffprobe_demux 
$(TARGET_SAMPLES)/flv/Enigma_Principles_of_L
 FATE_SAMPLES_DEMUX-$(call FRAMECRC, GIF,, GIF_PARSER) += fate-gif-demux
 fate-gif-demux: CMD = framecrc -i 
$(TARGET_SAMPLES)/gif/Newtons_cradle_animation_book_2.gif -c:v copy
 
+FATE_SAMPLES_DEMUX-$(call FRAMECRC, HXVS, HEVC, EXTRACT_EXTRADATA_BSF) += 
fate-hxvs-demux
+fate-hxvs-demux: CMD = framecrc -i 
$(TARGET_SAMPLES)/hxvs/A231130_171422_171436.bin -c copy -t 3
+
 FATE_SAMPLES_DEMUX-$(call FRAMECRC, IFF) += fate-iff-demux
 fate-iff-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iff-anim/Hammer2.sndanim 
-c:v copy -c:a copy
 
diff --git a/tests/ref/fate/hxvs-demux b/tests/ref/fate/hxvs-demux
new file mode 100644
index 0000000000..c72628ace7
--- /dev/null
+++ b/tests/ref/fate/hxvs-demux
@@ -0,0 +1,197 @@
+#extradata 0:       88, 0x61e61071
+#tb 0: 1/1000
+#media_type 0: video
+#codec_id 0: hevc
+#dimensions 0: 2560x1920
+#sar 0: 0/1
+#tb 1: 1/1000
+#media_type 1: audio
+#codec_id 1: pcm_alaw
+#sample_rate 1: 8000
+#channel_layout_name 1: mono
+1,          0,          0,       20,      160, 0x8a615ea0
+1,         20,         20,       20,      160, 0xd37063a0
+1,         40,         40,       20,      160, 0xb53b7520
+1,         60,         60,       20,      160, 0x7c3b75a0
+1,         80,         80,       20,      160, 0x1a7f6d20
+1,        100,        100,       20,      160, 0xf48e7120
+1,        120,        120,       20,      160, 0x41e16520
+1,        140,        140,       20,      160, 0x7dac70a0
+1,        160,        160,       20,      160, 0x2f8e6ba0
+1,        180,        180,       20,      160, 0xe4d26420
+1,        200,        200,       20,      160, 0xd7526220
+1,        220,        220,       20,      160, 0x3ce16520
+0,        225,        225,       80,    23267, 0x356a00c4
+1,        240,        240,       20,      160, 0xabf06a20
+1,        260,        260,       20,      160, 0xdd8e6f20
+1,        280,        280,       20,      160, 0x76ac70a0
+1,        300,        300,       20,      160, 0x559d70a0
+0,        305,        305,       80,    96910, 0x221584d7, F=0x0
+0,        305,        385,       80,    45582, 0x459e018f
+1,        320,        320,       20,      160, 0xcff06920
+1,        340,        340,       20,      160, 0x2b7f6920
+1,        360,        360,       20,      160, 0x8e3b72a0
+1,        380,        380,       20,      160, 0x96ac6ca0
+0,        385,        465,       80,    29130, 0xfa158ab8, F=0x0
+1,        400,        400,       20,      160, 0xfa0e7120
+1,        420,        420,       20,      160, 0x64bb73a0
+1,        440,        440,       20,      160, 0x93ff6aa0
+1,        460,        460,       20,      160, 0x22597b20
+0,        465,        545,       80,    24585, 0x1e849e4b, F=0x0
+1,        480,        480,       20,      160, 0xd71d71a0
+1,        500,        500,       20,      160, 0x3f3b7220
+1,        520,        520,       20,      160, 0x938e7120
+1,        540,        540,       20,      160, 0x19ac74a0
+0,        545,        625,       80,    12727, 0x6df49132, F=0x0
+1,        560,        560,       20,      160, 0xf78e70a0
+1,        580,        580,       20,      160, 0xb8ac74a0
+1,        600,        600,       20,      160, 0x86d97c20
+1,        620,        620,       20,      160, 0x654a7a20
+0,        625,        705,       80,    16230, 0x46a44bf5
+1,        640,        640,       20,      160, 0xb69d7320
+1,        660,        660,       20,      160, 0x722c7220
+1,        680,        680,       20,      160, 0x976161a0
+1,        700,        700,       20,      160, 0xc3ff65a0
+0,        705,        785,       80,      270, 0x22e4706a, F=0x0
+1,        720,        720,       20,      160, 0x099d70a0
+1,        740,        740,       20,      160, 0x41bb7320
+1,        760,        760,       20,      160, 0x71bb78a0
+1,        780,        780,       20,      160, 0xcf1d7020
+0,        785,        865,       80,     1688, 0x16a723d0, F=0x0
+1,        800,        800,       20,      160, 0x978e6ea0
+1,        820,        820,       20,      160, 0x0e7069a0
+1,        840,        840,       20,      160, 0xba265a8a
+1,        860,        860,       20,      160, 0xc3a65e16
+0,        865,        945,       80,     4818, 0x03555171, F=0x0
+1,        880,        880,       20,      160, 0xb84a5c6d
+1,        900,        900,       20,      160, 0x80ba5f86
+1,        920,        920,       20,      160, 0x4a16611c
+1,        940,        940,       20,      160, 0x2dc364a0
+0,        945,       1025,       80,     4640, 0x8a1e0a78, F=0x0
+1,        960,        960,       20,      160, 0xe52d6091
+1,        980,        980,       20,      160, 0x801d6da0
+1,       1000,       1000,       20,      160, 0x239d73a0
+1,       1020,       1020,       20,      160, 0xa28e7020
+0,       1025,       1105,       80,     5487, 0xb388a312, F=0x0
+1,       1040,       1040,       20,      160, 0xbc5268a0
+1,       1060,       1060,       20,      160, 0xc72c7220
+1,       1080,       1080,       20,      160, 0xe14a79a0
+1,       1100,       1100,       20,      160, 0x853b71a0
+0,       1105,       1185,       80,     9139, 0xffedec30, F=0x0
+1,       1120,       1120,       20,      160, 0x919d6fa0
+1,       1140,       1140,       20,      160, 0x59706720
+1,       1160,       1160,       20,      160, 0x017f6920
+1,       1180,       1180,       20,      160, 0xb01d72a0
+0,       1185,       1265,       80,      756, 0x556d70d5, F=0x0
+1,       1200,       1200,       20,      160, 0xcd0e7320
+1,       1220,       1220,       20,      160, 0x3dff6da0
+1,       1240,       1240,       20,      160, 0x6cd06115
+1,       1260,       1260,       20,      160, 0xcc345f9e
+0,       1265,       1345,       80,     3243, 0x20224c97, F=0x0
+1,       1280,       1280,       20,      160, 0x06436220
+1,       1300,       1300,       20,      160, 0x410e63a0
+1,       1320,       1320,       20,      160, 0x161d6ea0
+1,       1340,       1340,       20,      160, 0xb5bb78a0
+0,       1345,       1425,       80,     8431, 0x4b7c45e1, F=0x0
+1,       1360,       1360,       20,      160, 0x899d74a0
+1,       1380,       1380,       20,      160, 0x48bb75a0
+1,       1400,       1400,       20,      160, 0x0c3b6fa0
+1,       1420,       1420,       20,      160, 0x4eca7920
+0,       1425,       1505,       80,     3313, 0x7555594d, F=0x0
+1,       1440,       1440,       20,      160, 0x188e6b20
+1,       1460,       1460,       20,      160, 0x108e7020
+1,       1480,       1480,       20,      160, 0x417f7120
+1,       1500,       1500,       20,      160, 0x9dca79a0
+0,       1505,       1585,       80,    11529, 0x2ad94990, F=0x0
+1,       1520,       1520,       20,      160, 0x449d6f20
+1,       1540,       1540,       20,      160, 0x0c8e6ca0
+1,       1560,       1560,       20,      160, 0x174a79a0
+1,       1580,       1580,       20,      160, 0xfed97fa0
+0,       1585,       1665,       80,      402, 0x4804b096, F=0x0
+1,       1600,       1600,       20,      160, 0x291d6f20
+1,       1620,       1620,       20,      160, 0x481d6e20
+1,       1640,       1640,       20,      160, 0x67bb7720
+1,       1660,       1660,       20,      160, 0x77d97920
+0,       1665,       1745,       80,     1105, 0x146732d3, F=0x0
+1,       1680,       1680,       20,      160, 0xd00e6e20
+1,       1700,       1700,       20,      160, 0x928e6920
+1,       1720,       1720,       20,      160, 0x4b3b71a0
+1,       1740,       1740,       20,      160, 0xbe9d7320
+0,       1745,       1825,       80,     1644, 0x335e273b, F=0x0
+1,       1760,       1760,       20,      160, 0x908e7020
+1,       1780,       1780,       20,      160, 0xf52c75a0
+1,       1800,       1800,       20,      160, 0x5d687f20
+1,       1820,       1820,       20,      160, 0x37597b20
+0,       1825,       1905,       80,    10631, 0x1932ae14, F=0x0
+1,       1840,       1840,       20,      160, 0x202c7620
+1,       1860,       1860,       20,      160, 0x594a77a0
+1,       1880,       1880,       20,      160, 0x58ca7ba0
+1,       1900,       1900,       20,      160, 0x54bb7820
+0,       1905,       1985,       80,     5253, 0x97ac4e85, F=0x0
+1,       1920,       1920,       20,      160, 0x1a3b76a0
+1,       1940,       1940,       20,      160, 0x0d3b76a0
+1,       1960,       1960,       20,      160, 0x94bb7720
+1,       1980,       1980,       20,      160, 0x48597e20
+0,       1985,       2065,       80,     3917, 0x95109a5b, F=0x0
+1,       2000,       2000,       20,      160, 0x5e4a7820
+1,       2020,       2020,       20,      160, 0xf3687ea0
+1,       2040,       2040,       20,      160, 0x96bb7920
+1,       2060,       2060,       20,      160, 0x35d97b20
+0,       2065,       2145,       80,     5097, 0x3905f533, F=0x0
+1,       2080,       2080,       20,      160, 0x423b7620
+1,       2100,       2100,       20,      160, 0x9d3b7720
+1,       2120,       2120,       20,      160, 0x373b77a0
+1,       2140,       2140,       20,      160, 0xdbca7ba0
+0,       2145,       2225,       80,    13858, 0xe92a0e09, F=0x0
+1,       2160,       2160,       20,      160, 0xf07f6f20
+1,       2180,       2180,       20,      160, 0x233b6da0
+1,       2200,       2200,       20,      160, 0xa97f7520
+1,       2220,       2220,       20,      160, 0x24966020
+0,       2225,       2305,       80,     1266, 0xb6ac78dd, F=0x0
+1,       2240,       2240,       20,      160, 0x35ac7320
+1,       2260,       2260,       20,      160, 0x3eac7420
+1,       2280,       2280,       20,      160, 0x681d74a0
+1,       2300,       2300,       20,      160, 0xc8ac73a0
+0,       2305,       2385,       80,     1452, 0xbec3c1c7, F=0x0
+1,       2320,       2320,       20,      160, 0x741d6fa0
+1,       2340,       2340,       20,      160, 0x80ff66a0
+1,       2360,       2360,       20,      160, 0x92ff6c20
+1,       2380,       2380,       20,      160, 0x7bbb78a0
+0,       2385,       2465,       80,      746, 0x00d06534, F=0x0
+1,       2400,       2400,       20,      160, 0x7e0e6d20
+1,       2420,       2420,       20,      160, 0x8cbb72a0
+1,       2440,       2440,       20,      160, 0x446f669d
+1,       2460,       2460,       20,      160, 0xe0b45ca0
+0,       2465,       2545,       80,      882, 0x36d3ad81, F=0x0
+1,       2480,       2480,       20,      160, 0x957f6ea0
+1,       2500,       2500,       20,      160, 0x122c6fa0
+1,       2520,       2520,       20,      160, 0x1bbb7720
+1,       2540,       2540,       20,      160, 0x31e164a0
+0,       2545,       2625,       80,      969, 0x4549d4c1, F=0x0
+1,       2560,       2560,       20,      160, 0x0d3b74a0
+1,       2580,       2580,       20,      160, 0x0dac75a0
+1,       2600,       2600,       20,      160, 0xc73b78a0
+1,       2620,       2620,       20,      160, 0xceca78a0
+0,       2625,       2705,       80,      736, 0x9f84568c, F=0x0
+1,       2640,       2640,       20,      160, 0xe1ff6ba0
+1,       2660,       2660,       20,      160, 0xc1597ba0
+1,       2680,       2680,       20,      160, 0x62d97c20
+1,       2700,       2700,       20,      160, 0x554a7320
+0,       2705,       2785,       80,      886, 0xf157a913, F=0x0
+1,       2720,       2720,       20,      160, 0x31616920
+1,       2740,       2740,       20,      160, 0x3c526820
+1,       2760,       2760,       20,      160, 0x935268a0
+1,       2780,       2780,       20,      160, 0xa04a7ba0
+0,       2785,       2865,       80,      944, 0x3cf2c38d, F=0x0
+1,       2800,       2800,       20,      160, 0xf91d7220
+1,       2820,       2820,       20,      160, 0xe29d7020
+1,       2840,       2840,       20,      160, 0xb31d75a0
+1,       2860,       2860,       20,      160, 0x253b7920
+0,       2865,       2945,       80,     1313, 0x147a786a, F=0x0
+1,       2880,       2880,       20,      160, 0x678e6ea0
+1,       2900,       2900,       20,      160, 0xb53b78a0
+1,       2920,       2920,       20,      160, 0x4f597c20
+1,       2940,       2940,       20,      160, 0xd3ac7720
+0,       2945,       3025,       80,     1901, 0xdbf8a5f4, F=0x0
+1,       2960,       2960,       20,      160, 0xd9f06020
+1,       2980,       2980,       20,      160, 0x649d6ca0

commit dcddb2bf08f5fa6af655938a3a0d3cd2200fd8c9
Author:     Zhao Zhili <[email protected]>
AuthorDate: Sun Sep 14 01:47:12 2025 +0800
Commit:     Zhao Zhili <[email protected]>
CommitDate: Sun Sep 21 17:42:19 2025 +0800

    avformat: add hxvs demuxer

diff --git a/Changelog b/Changelog
index 88e1ce6659..997ff3b0b6 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@ version <next>:
 - ffprobe -codec option
 - EXIF Metadata Parsing
 - gfxcapture: Windows.Graphics.Capture based window/monitor capture
+- hxvs demuxer for HXVS/HXVT IP camera format
 
 
 version 8.0:
diff --git a/configure b/configure
index 8def62a5d9..98de8e5dff 100755
--- a/configure
+++ b/configure
@@ -3753,6 +3753,7 @@ gxf_muxer_select="pcm_rechunk_bsf"
 hds_muxer_select="flv_muxer"
 hls_demuxer_select="aac_demuxer ac3_demuxer adts_header ac3_parser 
eac3_demuxer mov_demuxer mpegts_demuxer"
 hls_muxer_select="mov_muxer mpegts_muxer"
+hxvs_demuxer_select="h264_parser hevc_parser"
 iamf_demuxer_select="iamfdec"
 iamf_muxer_select="iamfenc"
 image2_alias_pix_demuxer_select="image2_demuxer"
diff --git a/libavformat/Makefile b/libavformat/Makefile
index ab5551a735..0171f1c480 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -268,6 +268,7 @@ OBJS-$(CONFIG_EVC_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_HLS_DEMUXER)               += hls.o hls_sample_encryption.o
 OBJS-$(CONFIG_HLS_MUXER)                 += hlsenc.o hlsplaylist.o
 OBJS-$(CONFIG_HNM_DEMUXER)               += hnm.o
+OBJS-$(CONFIG_HXVS_DEMUXER)              += hxvs.o
 OBJS-$(CONFIG_IAMF_DEMUXER)              += iamfdec.o
 OBJS-$(CONFIG_IAMF_MUXER)                += iamfenc.o
 OBJS-$(CONFIG_ICO_DEMUXER)               += icodec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index e39eab8e85..3a025da3db 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -216,6 +216,7 @@ extern const FFOutputFormat ff_hevc_muxer;
 extern const FFInputFormat  ff_hls_demuxer;
 extern const FFOutputFormat ff_hls_muxer;
 extern const FFInputFormat  ff_hnm_demuxer;
+extern const FFInputFormat  ff_hxvs_demuxer;
 extern const FFInputFormat  ff_iamf_demuxer;
 extern const FFOutputFormat ff_iamf_muxer;
 extern const FFInputFormat  ff_ico_demuxer;
diff --git a/libavformat/hxvs.c b/libavformat/hxvs.c
new file mode 100644
index 0000000000..ed827c8d97
--- /dev/null
+++ b/libavformat/hxvs.c
@@ -0,0 +1,340 @@
+/*
+ * HXVS/HXVT IP camera format
+ *
+ * Copyright (c) 2025 Zhao Zhili <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+
+#include "avio_internal.h"
+#include "demux.h"
+#include "internal.h"
+
+/*
+ * Ref
+ * https://code.videolan.org/videolan/vlc/-/blob/master/modules/demux/hx.c
+ * https://github.com/francescovannini/ipcam26Xconvert/tree/main
+ */
+
+/* H.264
+ *
+ * uint32_t tag;
+ * uint32_t width;
+ * uint32_t height;
+ * uint8_t padding[4];
+ */
+#define HXVS    MKTAG('H', 'X', 'V', 'S')
+
+/* H.265
+ *
+ * Same as HXVS.
+ */
+#define HXVT    MKTAG('H', 'X', 'V', 'T')
+
+/* video frame
+ *
+ * uint32_t tag;
+ * uint32_t bytes
+ * uint32_t timestamp;
+ * uint32_t flags;
+ * ------------------
+ * uint8_t data[bytes]
+ *
+ * Note: each HXVF contains a single NALU or slice, not a frame.
+ */
+#define HXVF    MKTAG('H', 'X', 'V', 'F')
+
+/* audio frame
+ *
+ * uint32_t tag;
+ * uint32_t bytes
+ * uint32_t timestamp;
+ * uint32_t flags;
+ * ------------------
+ * uint8_t data[bytes]
+ *
+ * Note: The first four bytes of data is fake start code and NALU type,
+ * which should be skipped.
+ */
+#define HXAF    MKTAG('H', 'X', 'A', 'F')
+
+/* RAP frame index
+ *
+ * uint32_t tag;
+ * uint32_t bytes
+ * uint32_t duration;
+ * uint32_t flags;
+ */
+#define HXFI    MKTAG('H', 'X', 'F', 'I')
+
+#define HXFI_TABLE_SIZE  200000
+#define HXFI_TABLE_COUNT (200000 / 8)
+
+typedef struct HxvsContext {
+    int video_index;
+    int audio_index;
+} HxvsContext;
+
+static int hxvs_probe(const AVProbeData *p)
+{
+    uint32_t flag = 0;
+    uint32_t bytes;
+
+    for (size_t i = 0; i < p->buf_size; ) {
+        uint32_t tag = AV_RL32(&p->buf[i]);
+
+        // first four bytes must begin with HXVS/HXVT
+        if (i == 0) {
+            if (tag != HXVS && tag != HXVT)
+                return 0;
+            flag |= 1;
+            i += 16;
+            continue;
+        }
+
+        // Got RAP index at the end
+        if (tag == HXFI) {
+            if (flag == 7)
+                return AVPROBE_SCORE_MAX;
+            break;
+        }
+
+        i += 4;
+        if (tag == HXVF || tag == HXAF) {
+            bytes = AV_RL32(&p->buf[i]);
+            i += 12 + bytes;
+            flag |= (tag == HXVF) ? 2 : 4;
+            continue;
+        }
+
+        return 0;
+    }
+
+    // Get audio and video
+    if (flag == 7)
+        return AVPROBE_SCORE_EXTENSION + 10;
+    // Get video only
+    if (flag == 3)
+        return AVPROBE_SCORE_EXTENSION + 2;
+
+    return 0;
+}
+
+static int hxvs_create_video_stream(AVFormatContext *s, enum AVCodecID 
codec_id)
+{
+    HxvsContext *ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVStream *vt = avformat_new_stream(s, NULL);
+    if (!vt)
+        return AVERROR(ENOMEM);
+
+    vt->id = 0;
+    vt->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+    vt->codecpar->codec_id = codec_id;
+    vt->codecpar->width = avio_rl32(pb);
+    vt->codecpar->height = avio_rl32(pb);
+    avpriv_set_pts_info(vt, 32, 1, 1000);
+    ffstream(vt)->need_parsing = AVSTREAM_PARSE_FULL;
+    ctx->video_index = vt->index;
+
+    // skip padding
+    avio_skip(pb, 4);
+
+    return 0;
+}
+
+static int hxvs_create_audio_stream(AVFormatContext *s)
+{
+    HxvsContext *ctx = s->priv_data;
+    AVStream *at = avformat_new_stream(s, NULL);
+    if (!at)
+        return AVERROR(ENOMEM);
+
+    at->id = 1;
+    at->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+    at->codecpar->codec_id = AV_CODEC_ID_PCM_ALAW;
+    at->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
+    at->codecpar->sample_rate = 8000;
+    avpriv_set_pts_info(at, 32, 1, 1000);
+    ctx->audio_index = at->index;
+
+    return 0;
+}
+
+static int hxvs_build_index(AVFormatContext *s)
+{
+    HxvsContext *ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    int64_t size = avio_size(pb);
+    if (size < 0)
+        return size;
+    // Don't return error when HXFI is missing
+    int64_t pos = avio_seek(pb, size -(HXFI_TABLE_SIZE + 16), SEEK_SET);
+    if (pos < 0)
+        return 0;
+
+    uint32_t tag = avio_rl32(pb);
+    if (tag != HXFI)
+        return 0;
+    avio_skip(pb, 4);
+    AVStream *st = s->streams[ctx->video_index];
+    st->duration = avio_rl32(pb);
+    avio_skip(pb, 4);
+
+    FFStream *const sti = ffstream(st);
+    uint32_t prev_time;
+    for (int i = 0; i < HXFI_TABLE_COUNT; i++) {
+        uint32_t offset = avio_rl32(pb);
+        // pts = first_frame_pts + time
+        uint32_t time = avio_rl32(pb);
+        av_log(s, AV_LOG_TRACE, "%s/%d: offset %u, time %u\n",
+               av_fourcc2str(HXAF), i, offset, time);
+        if (!offset)
+            break;
+
+        if (!i) {
+            // Get first frame timestamp
+            int64_t save_pos = avio_tell(pb);
+            pos = avio_seek(pb, offset, SEEK_SET);
+            if (pos < 0)
+                return pos;
+            tag = avio_rl32(pb);
+            if (tag != HXVF) {
+                av_log(s, AV_LOG_ERROR, "invalid tag %s at pos %u\n",
+                       av_fourcc2str(tag), offset);
+                return AVERROR_INVALIDDATA;
+            }
+            avio_skip(pb, 4);
+            // save first frame timestamp to stream start_time
+            st->start_time = avio_rl32(pb);
+            pos = avio_seek(pb, save_pos, SEEK_SET);
+            if (pos < 0)
+                return pos;
+        } else if (time == prev_time) {
+            // hxvs put SPS, PPS and slice into separate entries with same 
timestamp.
+            // Only record the first entry.
+            continue;
+        }
+        prev_time = time;
+        int ret = ff_add_index_entry(&sti->index_entries,
+                                     &sti->nb_index_entries,
+                                     &sti->index_entries_allocated_size,
+                                     offset, st->start_time + time,
+                                     0, 0, AVINDEX_KEYFRAME);
+        if (ret < 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+static int hxvs_read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    uint32_t tag = avio_rl32(pb);
+    enum AVCodecID codec_id;
+
+    if (tag == HXVS) {
+        codec_id = AV_CODEC_ID_H264;
+    } else if (tag == HXVT) {
+        codec_id = AV_CODEC_ID_HEVC;
+    } else {
+        av_log(s, AV_LOG_ERROR, "Unknown tag %s\n", av_fourcc2str(tag));
+        return AVERROR_INVALIDDATA;
+    }
+
+    int ret = hxvs_create_video_stream(s, codec_id);
+    if (ret < 0)
+        return ret;
+
+    ret = hxvs_create_audio_stream(s);
+    if (ret < 0)
+        return ret;
+
+    if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
+        int64_t pos = avio_tell(pb);
+        if (pos < 0)
+            return pos;
+
+        ret = hxvs_build_index(s);
+        if (ret < 0)
+            return ret;
+
+        pos = avio_seek(pb, pos, SEEK_SET);
+        if (pos < 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+static int hxvs_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    HxvsContext *ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int64_t pos = avio_tell(pb);
+    uint32_t tag = avio_rl32(pb);
+    uint32_t bytes;
+    int ret;
+
+    if (avio_feof(pb) || (tag == HXFI))
+        return AVERROR_EOF;
+
+    if (tag != HXVF && tag != HXAF)
+        return AVERROR_INVALIDDATA;
+
+    bytes = avio_rl32(pb);
+    if (bytes < 4)
+        return AVERROR_INVALIDDATA;
+
+    uint32_t timestamp = avio_rl32(pb);
+    int key_flag = 0;
+    int index;
+    if (tag == HXVF) {
+        if (avio_rl32(pb) == 1)
+            key_flag = AV_PKT_FLAG_KEY;
+        index = ctx->video_index;
+    } else {
+        avio_skip(pb, 8);
+        index = ctx->audio_index;
+        bytes -= 4;
+    }
+
+    ret = av_get_packet(pb, pkt, bytes);
+    if (ret < 0)
+        return ret;
+    pkt->pts = timestamp;
+    pkt->pos = pos;
+    pkt->stream_index = index;
+    pkt->flags |= key_flag;
+
+    return 0;
+}
+
+const FFInputFormat ff_hxvs_demuxer = {
+    .p.name         = "hxvs",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("HXVF/HXVS IP camera format"),
+    .p.extensions   = "264,265",
+    .p.flags        = AVFMT_GENERIC_INDEX,
+    .read_probe     = hxvs_probe,
+    .read_header    = hxvs_read_header,
+    .read_packet    = hxvs_read_packet,
+    .priv_data_size = sizeof(HxvsContext),
+};
diff --git a/libavformat/version.h b/libavformat/version.h
index 384cbd49cc..4bde82abb4 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,8 +31,8 @@
 
 #include "version_major.h"
 
-#define LIBAVFORMAT_VERSION_MINOR   5
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MINOR   6
+#define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \

-----------------------------------------------------------------------

Summary of changes:
 Changelog                 |   1 +
 configure                 |   1 +
 libavformat/Makefile      |   1 +
 libavformat/allformats.c  |   1 +
 libavformat/hxvs.c        | 340 ++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/version.h     |   4 +-
 tests/fate/demux.mak      |   3 +
 tests/ref/fate/hxvs-demux | 197 +++++++++++++++++++++++++++
 8 files changed, 546 insertions(+), 2 deletions(-)
 create mode 100644 libavformat/hxvs.c
 create mode 100644 tests/ref/fate/hxvs-demux


hooks/post-receive
-- 

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to