From 27b5d15320de6f1f756c4ce10f1389408ae321d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haibo=20Chen=28=E9=99=88=E6=B5=B7=E5=8D=9A=29?= <495810242@qq.com> Date: Thu, 10 Jul 2025 21:08:05 +0800 Subject: [PATCH] Fix H.264 B-frame detection logic to comply with specification. v5.0.224 (#4414) For H.264, only when the NAL Type is 1, 2, 3, or 4 is it possible for B-frames to be present; that is, non-IDR pictures and slice data. The current `SrsVideoFrame::parse_avc_bframe()` function uses incorrect logic to determine if a NALU can contain B-frames. The original implementation only checked for specific NALU types (IDR, SPS, PPS) to mark as non-B-frames, but this approach misses many other NALU types that cannot contain B-frames according to the H.264 specification. According to H.264 specification (ISO_IEC_14496-10-AVC-2012.pdf, Table 7-1), B-frames can **only** exist in these specific NALU types: - Type 1: Non-IDR coded slice (`SrsAvcNaluTypeNonIDR`) - Type 2: Coded slice data partition A (`SrsAvcNaluTypeDataPartitionA`) - Type 3: Coded slice data partition B (`SrsAvcNaluTypeDataPartitionB`) - Type 4: Coded slice data partition C (`SrsAvcNaluTypeDataPartitionC`) All other NALU types (IDR=5, SEI=6, SPS=7, PPS=8, AUD=9, etc.) cannot contain B-frames by definition. --------- Co-authored-by: Jacob Su Co-authored-by: winlin --- trunk/doc/CHANGELOG.md | 2 ++ trunk/src/core/srs_core_version5.hpp | 2 +- trunk/src/kernel/srs_kernel_codec.cpp | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index ae4389d8c..634590b79 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,8 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2025-07-10, Merge [#4414](https://github.com/ossrs/srs/pull/4414): Fix H.264 B-frame detection logic to comply with specification. v5.0.224 (#4414) +* v5.0, 2025-03-21, Merge [#4303](https://github.com/ossrs/srs/pull/4303): replace values with enums. v5.0.223 (#4303) * v5.0, 2025-03-20, Merge [#4305](https://github.com/ossrs/srs/pull/4305): free sample to prevent memory leak. v5.0.222 (#4305) * v5.0, 2025-03-18, Merge [#4302](https://github.com/ossrs/srs/pull/4302): update geekyeggo/delete-artifact to 5.0.0. v5.0.221 (#4302) * v5.0, 2025-02-20, Merge [#4253](https://github.com/ossrs/srs/pull/4253): fix typo about heartbeat. v5.0.220 (#4253) diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 0c6d8605f..3d4c536c4 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 222 +#define VERSION_REVISION 224 #endif diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index 1d45571e7..7c71638a9 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -611,7 +611,8 @@ srs_error_t SrsVideoFrame::parse_avc_b_frame(const SrsSample* sample, bool& is_b return srs_error_wrap(err, "parse avc nalu type error"); } - if (nalu_type != SrsAvcNaluTypeNonIDR && nalu_type != SrsAvcNaluTypeDataPartitionA && nalu_type != SrsAvcNaluTypeIDR) { + if (nalu_type != SrsAvcNaluTypeNonIDR && nalu_type != SrsAvcNaluTypeDataPartitionA + && nalu_type != SrsAvcNaluTypeDataPartitionB && nalu_type != SrsAvcNaluTypeDataPartitionC) { is_b_frame = false; return err; }