diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index f85da12ed..c23f61892 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 7.0 Changelog
+* v7.0, 2025-12-06, Merge [#4604](https://github.com/ossrs/srs/pull/4604): DVR: Fix HEVC mp4 recording error. v7.0.135 (#4604)
* v7.0, 2025-12-06, SRT: Fix peer_idle_timeout not applied to publishers and players. v7.0.134 (#4600)
* v7.0, 2025-12-04, SRT: Enable tlpktdrop by default to prevent 100% CPU usage. v7.0.133 (#4587)
* v7.0, 2025-12-03, AI: WebRTC: Fix audio-only WHIP publish without SSRC. v7.0.132 (#4570)
@@ -148,6 +149,7 @@ The changelog for SRS.
## SRS 6.0 Changelog
+* v6.0, 2025-12-06, Merge [#4605](https://github.com/ossrs/srs/pull/4605): DVR: Fix HEVC mp4 recording error. v6.0.185 (#4605)
* v6.0, 2025-12-03, Merge [#4588](https://github.com/ossrs/srs/pull/4588): RTMP: Ignore FMLE start packet after flash publish. v6.0.184 (#4588)
* v6.0, 2025-10-17, Merge [#4534](https://github.com/ossrs/srs/pull/4534): HLS: Fix a iterator bug in hls_ctx cleanup function. v6.0.182 (#4534)
* v6.0, 2025-10-14, Disable sanitizer by default to fix memory leak. (#4364) v6.0.181
diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp
index 1f34e7481..daddadf0c 100644
--- a/trunk/src/core/srs_core_version6.hpp
+++ b/trunk/src/core/srs_core_version6.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 6
#define VERSION_MINOR 0
-#define VERSION_REVISION 182
+#define VERSION_REVISION 185
#endif
diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp
index d43806662..48a1d2fc3 100644
--- a/trunk/src/core/srs_core_version7.hpp
+++ b/trunk/src/core/srs_core_version7.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
-#define VERSION_REVISION 134
+#define VERSION_REVISION 135
#endif
\ No newline at end of file
diff --git a/trunk/src/kernel/srs_kernel_packet.cpp b/trunk/src/kernel/srs_kernel_packet.cpp
index dfc8481b0..fb27161b9 100644
--- a/trunk/src/kernel/srs_kernel_packet.cpp
+++ b/trunk/src/kernel/srs_kernel_packet.cpp
@@ -643,6 +643,12 @@ srs_error_t SrsFormat::video_avc_demux(SrsBuffer *stream, int64_t timestamp)
// ignore info frame without error,
// @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909
if (video_->frame_type_ == SrsVideoAvcFrameTypeVideoInfoFrame) {
+ // For non-ext header Video Info Frame, try to read packet type from stream if available
+ if (!is_ext_header && stream->left() > 0) {
+ packet_type = (SrsVideoAvcFrameTrait)stream->read_1bytes();
+ }
+
+ video_->avc_packet_type_ = packet_type;
srs_warn("avc ignore the info frame");
return err;
}
diff --git a/trunk/src/utest/srs_utest_manual_kernel.cpp b/trunk/src/utest/srs_utest_manual_kernel.cpp
index a0c0003ad..c73fd9de7 100644
--- a/trunk/src/utest/srs_utest_manual_kernel.cpp
+++ b/trunk/src/utest/srs_utest_manual_kernel.cpp
@@ -4326,6 +4326,85 @@ VOID TEST(KernelCodecTest, VideoFrameH264_BFrameDetection_EdgeCases)
}
}
+VOID TEST(KernelCodecTest, VideoFrameVideoInfoFrameHandling)
+{
+ srs_error_t err;
+
+ // Test both AVC and HEVC video codecs
+ SrsFormat format;
+ HELPER_EXPECT_SUCCESS(format.initialize());
+
+ // Test 1: AVC Video Info Frame handling with additional NALU data
+ {
+ // AVC Video Info Frame
+ // Frame type 5 (Video Info Frame) | Codec ID 7 (AVC)
+ uint8_t avc_video_info_frame[] = {
+ 0x57, // Frame type 5 (Video Info Frame) | Codec ID 7 (AVC)
+ 0x01, // AVC packet type 1 (NALU)
+ 0x00, 0x00, 0x00, // Composition time 0
+ // NALU data (mock IDR frame)
+ 0x00, 0x00, 0x00, 0x01, // NAL unit start code
+ 0x65, 0x88, 0x84, 0x00 // IDR NALU (mock data)
+ };
+
+ // Call on_video with AVC video info frame - should not return error
+ err = format.on_video(2000, (char *)avc_video_info_frame, sizeof(avc_video_info_frame));
+ EXPECT_TRUE(err == NULL) << "Failed to handle AVC Video Info Frame with NALU data";
+
+ // Verify avc_packet_type_ is correctly set to SrsVideoAvcFrameTraitNALU (1)
+ EXPECT_TRUE(format.video_ != NULL) << "Video packet should be initialized after on_video call";
+ EXPECT_EQ(format.video_->avc_packet_type_, SrsVideoAvcFrameTraitNALU)
+ << "Expected avc_packet_type_ to be SrsVideoAvcFrameTraitNALU (1), got "
+ << format.video_->avc_packet_type_;
+
+ srs_freep(err);
+ }
+
+ // Test 2: HEVC Video Info Frame handling with coded frames
+ {
+ // HEVC Video Info Frame (enhanced RTMP format)
+ uint8_t hevc_video_info_frame[] = {
+ 0xD1, // Frame type 5 (Video Info Frame) | Extended header flag (0x80) | Packet type 1
+ 0x68, 0x76, 0x63, 0x31, // 'hvc1' FourCC (HEVC)
+ 0x00, 0x00, 0x00 // Composition time 0 (for coded frames packet type)
+ };
+
+ // Call on_video with HEVC video info frame - should not return error
+ err = format.on_video(4000, (char *)hevc_video_info_frame, sizeof(hevc_video_info_frame));
+ EXPECT_TRUE(err == NULL) << "Failed to handle HEVC Video Info Frame with coded frames";
+
+ // Verify avc_packet_type_ is correctly set to SrsVideoHEVCFrameTraitPacketTypeCodedFrames (1)
+ EXPECT_TRUE(format.video_ != NULL) << "Video packet should be initialized after on_video call";
+ EXPECT_EQ(format.video_->avc_packet_type_, SrsVideoHEVCFrameTraitPacketTypeCodedFrames)
+ << "Expected avc_packet_type_ to be SrsVideoHEVCFrameTraitPacketTypeCodedFrames (1), got "
+ << format.video_->avc_packet_type_;
+
+ srs_freep(err);
+ }
+
+ // Test 3: HEVC Video Info Frame handling with coded frames X (optimized zero composition time)
+ {
+ // HEVC Video Info Frame with coded frames X (optimized)
+ uint8_t hevc_video_info_frame[] = {
+ 0xD3, // Frame type 5 (Video Info Frame) | Extended header flag (0x80) | Packet type 3 (coded frames X)
+ 0x68, 0x76, 0x63, 0x31 // 'hvc1' FourCC (HEVC)
+ // No composition time field for coded frames X (implied to be zero)
+ };
+
+ // Call on_video with HEVC video info frame - should not return error
+ err = format.on_video(7000, (char *)hevc_video_info_frame, sizeof(hevc_video_info_frame));
+ EXPECT_TRUE(err == NULL) << "Failed to handle HEVC Video Info Frame with coded frames X";
+
+ // Verify avc_packet_type_ is correctly set to SrsVideoHEVCFrameTraitPacketTypeCodedFramesX (3)
+ EXPECT_TRUE(format.video_ != NULL) << "Video packet should be initialized after on_video call";
+ EXPECT_EQ(format.video_->avc_packet_type_, SrsVideoHEVCFrameTraitPacketTypeCodedFramesX)
+ << "Expected avc_packet_type_ to be SrsVideoHEVCFrameTraitPacketTypeCodedFramesX (3), got "
+ << format.video_->avc_packet_type_;
+
+ srs_freep(err);
+ }
+}
+
VOID TEST(KernelCodecTest, VideoFrameH265)
{
srs_error_t err;