From 922683ddf5797641acf7b7163b18f76bd8a2019f Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Wed, 6 Aug 2025 22:10:12 +0900 Subject: [PATCH 1/2] nalu 1 --- api/crypto/frame_crypto_transformer.cc | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/api/crypto/frame_crypto_transformer.cc b/api/crypto/frame_crypto_transformer.cc index 88c394ef10..227202cf71 100644 --- a/api/crypto/frame_crypto_transformer.cc +++ b/api/crypto/frame_crypto_transformer.cc @@ -32,6 +32,7 @@ #include "absl/types/variant.h" #include "api/array_view.h" #include "common_video/h264/h264_common.h" +#include "common_video/h265/h265_common.h" #include "modules/rtp_rtcp/source/rtp_format_h264.h" #include "rtc_base/byte_buffer.h" #include "rtc_base/logging.h" @@ -96,6 +97,41 @@ inline bool FrameIsH264(webrtc::TransformableFrameInterface* frame, } } +inline bool FrameIsH265(webrtc::TransformableFrameInterface* frame, + webrtc::FrameCryptorTransformer::MediaType type) { + switch (type) { + case webrtc::FrameCryptorTransformer::MediaType::kVideoFrame: { + auto videoFrame = + static_cast(frame); + return videoFrame->header().codec == + webrtc::VideoCodecType::kVideoCodecH265; + } + default: + return false; + } +} + +inline bool IsH265SliceNalu(webrtc::H265::NaluType nalu_type) { + // VCL NALUs (Video Coding Layer) - slice segments + // Based on H.265 spec and matches TypeScript logic in naluUtils.ts + return nalu_type == webrtc::H265::NaluType::kTrailN || + nalu_type == webrtc::H265::NaluType::kTrailR || + nalu_type == webrtc::H265::NaluType::kTsaN || + nalu_type == webrtc::H265::NaluType::kTsaR || + nalu_type == webrtc::H265::NaluType::kStsaN || + nalu_type == webrtc::H265::NaluType::kStsaR || + nalu_type == webrtc::H265::NaluType::kRadlN || + nalu_type == webrtc::H265::NaluType::kRadlR || + nalu_type == static_cast(8) || // RASL_N + nalu_type == static_cast(9) || // RASL_R + nalu_type == webrtc::H265::NaluType::kBlaWLp || + nalu_type == webrtc::H265::NaluType::kBlaWRadl || + nalu_type == webrtc::H265::NaluType::kBlaNLp || + nalu_type == webrtc::H265::NaluType::kIdrWRadl || + nalu_type == webrtc::H265::NaluType::kIdrNLp || + nalu_type == webrtc::H265::NaluType::kCra; +} + inline bool NeedsRbspUnescaping(const uint8_t* frameData, size_t frameSize) { for (size_t i = 0; i < frameSize - 3; ++i) { if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) @@ -163,6 +199,27 @@ uint8_t get_unencrypted_bytes(webrtc::TransformableFrameInterface* frame, break; } } + } else if (videoFrame->header().codec == + webrtc::VideoCodecType::kVideoCodecH265) { + rtc::ArrayView data_in = frame->GetData(); + std::vector nalu_indices = + webrtc::H265::FindNaluIndices(data_in); + + int idx = 0; + for (const auto& index : nalu_indices) { + const uint8_t* slice = data_in.data() + index.payload_start_offset; + webrtc::H265::NaluType nalu_type = + webrtc::H265::ParseNaluType(slice[0]); + if (IsH265SliceNalu(nalu_type)) { + // H.265 has a 2-byte NALU header, so unencrypted bytes = offset + header size + unencrypted_bytes = index.payload_start_offset + webrtc::H265::kNaluHeaderSize; + RTC_LOG(LS_INFO) + << "H265 NonParameterSetNalu::payload_size: " << index.payload_size + << ", nalu_type " << static_cast(nalu_type) << ", NaluIndex [" << idx++ + << "] offset: " << index.payload_start_offset << ", unencrypted_bytes: " << unencrypted_bytes; + return unencrypted_bytes; + } + } } break; } @@ -413,6 +470,9 @@ void FrameCryptorTransformer::encryptFrame( if (FrameIsH264(frame.get(), type_)) { H264::WriteRbsp(data_without_header.data(), data_without_header.size(), &data_out); + } else if (FrameIsH265(frame.get(), type_)) { + H265::WriteRbsp(data_without_header.data(), data_without_header.size(), + &data_out); } else { data_out.AppendData(data_without_header); RTC_CHECK_EQ(data_out.size(), frame_header.size() + @@ -561,6 +621,10 @@ void FrameCryptorTransformer::decryptFrame( NeedsRbspUnescaping(encrypted_buffer.data(), encrypted_buffer.size())) { encrypted_buffer.SetData( H264::ParseRbsp(encrypted_buffer.data(), encrypted_buffer.size())); + } else if (FrameIsH265(frame.get(), type_) && + NeedsRbspUnescaping(encrypted_buffer.data(), encrypted_buffer.size())) { + encrypted_buffer.SetData( + H265::ParseRbsp(encrypted_buffer.data(), encrypted_buffer.size())); } rtc::Buffer encrypted_payload(encrypted_buffer.size() - ivLength - 2); From a61694d06c3aa07078700f7532140adbf8d1cdf4 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Wed, 6 Aug 2025 22:31:16 +0900 Subject: [PATCH 2/2] clean up 1 --- api/crypto/frame_crypto_transformer.cc | 5 ++--- common_video/h265/h265_common.h | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/crypto/frame_crypto_transformer.cc b/api/crypto/frame_crypto_transformer.cc index 227202cf71..d96b3152a4 100644 --- a/api/crypto/frame_crypto_transformer.cc +++ b/api/crypto/frame_crypto_transformer.cc @@ -113,7 +113,6 @@ inline bool FrameIsH265(webrtc::TransformableFrameInterface* frame, inline bool IsH265SliceNalu(webrtc::H265::NaluType nalu_type) { // VCL NALUs (Video Coding Layer) - slice segments - // Based on H.265 spec and matches TypeScript logic in naluUtils.ts return nalu_type == webrtc::H265::NaluType::kTrailN || nalu_type == webrtc::H265::NaluType::kTrailR || nalu_type == webrtc::H265::NaluType::kTsaN || @@ -122,8 +121,8 @@ inline bool IsH265SliceNalu(webrtc::H265::NaluType nalu_type) { nalu_type == webrtc::H265::NaluType::kStsaR || nalu_type == webrtc::H265::NaluType::kRadlN || nalu_type == webrtc::H265::NaluType::kRadlR || - nalu_type == static_cast(8) || // RASL_N - nalu_type == static_cast(9) || // RASL_R + nalu_type == webrtc::H265::NaluType::kRaslN || + nalu_type == webrtc::H265::NaluType::kRaslR || nalu_type == webrtc::H265::NaluType::kBlaWLp || nalu_type == webrtc::H265::NaluType::kBlaWRadl || nalu_type == webrtc::H265::NaluType::kBlaNLp || diff --git a/common_video/h265/h265_common.h b/common_video/h265/h265_common.h index 7bba7f84a7..745b5ea5a1 100644 --- a/common_video/h265/h265_common.h +++ b/common_video/h265/h265_common.h @@ -43,6 +43,8 @@ enum NaluType : uint8_t { kStsaR = 5, kRadlN = 6, kRadlR = 7, + kRaslN = 8, + kRaslR = 9, kBlaWLp = 16, kBlaWRadl = 17, kBlaNLp = 18,