From b67ef7ae941408d3174819ab0caf32099d86f29a Mon Sep 17 00:00:00 2001 From: Jacob Su Date: Sat, 6 Dec 2025 15:23:28 +0800 Subject: [PATCH 1/3] Fix #4603: DVR hevc to mp4 error. --- trunk/src/kernel/srs_kernel_packet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/trunk/src/kernel/srs_kernel_packet.cpp b/trunk/src/kernel/srs_kernel_packet.cpp index dfc8481b0a..439af6409e 100644 --- a/trunk/src/kernel/srs_kernel_packet.cpp +++ b/trunk/src/kernel/srs_kernel_packet.cpp @@ -643,6 +643,7 @@ 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) { + video_->avc_packet_type_ = packet_type; srs_warn("avc ignore the info frame"); return err; } From 69f4a59735c5f88454f72baff086ad377e470271 Mon Sep 17 00:00:00 2001 From: Jacob Su Date: Sat, 6 Dec 2025 17:06:17 +0800 Subject: [PATCH 2/3] Add additional utest for video info frames. --- trunk/src/kernel/srs_kernel_packet.cpp | 5 ++ trunk/src/utest/srs_utest_manual_kernel.cpp | 79 +++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/trunk/src/kernel/srs_kernel_packet.cpp b/trunk/src/kernel/srs_kernel_packet.cpp index 439af6409e..fb27161b98 100644 --- a/trunk/src/kernel/srs_kernel_packet.cpp +++ b/trunk/src/kernel/srs_kernel_packet.cpp @@ -643,6 +643,11 @@ 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 a0c0003ad0..c73fd9de74 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; From 912663ad902581e86ee58713b991258344ecd119 Mon Sep 17 00:00:00 2001 From: OSSRS-AI Date: Sat, 6 Dec 2025 18:44:02 -0500 Subject: [PATCH 3/3] DVR: Fix HEVC mp4 recording error. v7.0.135 (#4604) --- trunk/doc/CHANGELOG.md | 2 ++ trunk/src/core/srs_core_version6.hpp | 2 +- trunk/src/core/srs_core_version7.hpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index f85da12ed9..c23f61892b 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 1f34e74817..daddadf0c4 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 d438066627..48a1d2fc35 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