Skip to content

Commit

Permalink
WebRTC HEVC RFC 7798 RTP Payload Format Implementation
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=258794

Reviewed by Youenn Fablet.

The current WebRTC HEVC is using generic packetization instead of RFC 7789 Packetization.
So this is about implementing the RFC 7798 Packetization.

Fix HEVC depacketizer issues. (WebKit#185)
Enalbing low latency mode for RTC (WebKit#169)
Enable HEVC support. (WebKit#165)
Fix out-of-bounds write in H265VpsSpsPpsTracker (WebKit#163)
Apply fix bitstream logic to RtpVideoStreamReceiver2 (WebKit#142)
Add missing CODEC_H265 switch case (WebKit#136)
Add HEVC support for iOS/Android (WebKit#68)
H265 packetization_mode setting fix (WebKit#53)
Add H.265 QP parsing logic (WebKit#47)

This patch is extracted from following Open WebRTC Toolkit code changes:
<open-webrtc-toolkit/owt-deps-webrtc#185>
<open-webrtc-toolkit/owt-deps-webrtc#169>
<open-webrtc-toolkit/owt-deps-webrtc#165>
<open-webrtc-toolkit/owt-deps-webrtc#163>
<open-webrtc-toolkit/owt-deps-webrtc#142>
<open-webrtc-toolkit/owt-deps-webrtc#136>
<open-webrtc-toolkit/owt-deps-webrtc#68>
<open-webrtc-toolkit/owt-deps-webrtc#53>
<open-webrtc-toolkit/owt-deps-webrtc#47>

co-authoured by:
taste1981 <jianlin.qiu@intel.com>
jianjunz <jianjun.zhu@intel.com>
Cyril Lashkevich <notorca@gmail.com>
Piasy <xz4215@gmail.com>
ShiJinCheng <874042641@qq.com>
Andreas Unterhuber <andreas.unterhuber@keepinmind.info>
dong-heun <63987238+dong-heun@users.noreply.github.com>

* Source/ThirdParty/libwebrtc/Configurations/libwebrtc.xcconfig:
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video/video_codec_type.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video_codecs/video_codec.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video_codecs/video_codec.h:
(webrtc::VideoCodecH265::operator!= const):
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video_codecs/video_encoder.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/api/video_codecs/video_encoder.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/call/rtp_payload_params.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_pps_parser.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_pps_parser.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_sps_parser.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_sps_parser.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_vps_parser.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_vps_parser.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/media/base/media_constants.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/media/base/media_constants.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/internal_decoder_factory.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.h:
(webrtc::RtpPacketizerH265::PacketUnit::PacketUnit):
(webrtc::VideoRtpDepacketizerH265::~VideoRtpDepacketizerH265): Deleted.
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_video_header.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/h265/include/h265_globals.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/encoded_frame.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/h265_vps_sps_pps_tracker.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/h265_vps_sps_pps_tracker.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/include/video_codec_interface.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/packet_buffer.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/experiments/min_video_bitrate_experiment.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/nalu_rewriter.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/nalu_rewriter.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/test/scenario/video_stream.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/test/video_codec_settings.h:
(webrtc::test::CodecSettings):
* Source/ThirdParty/libwebrtc/Source/webrtc/video/config/video_encoder_config.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/config/video_encoder_config.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/encoder_overshoot_detector.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/rtp_video_stream_receiver2.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/rtp_video_stream_receiver2.h:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/send_statistics_proxy.cc:
* Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc:
* Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/267677@main
  • Loading branch information
xingri authored and Mark Lam committed Sep 6, 2023
1 parent bee8623 commit 93eb48d
Show file tree
Hide file tree
Showing 47 changed files with 1,306 additions and 720 deletions.
Expand Up @@ -61,7 +61,7 @@ INSTALLHDRS_SCRIPT_PHASE = YES;
WARNING_CFLAGS = -Wno-deprecated-declarations $(inherited);

// FIXME: Set WEBRTC_USE_BUILTIN_ISAC_FIX and WEBRTC_USE_BUILTIN_ISAC_FLOAT for iOS and Mac
GCC_PREPROCESSOR_DEFINITIONS = GTEST_RELATIVE_PATH WEBRTC_OPUS_SUPPORT_120MS_PTIME=0 WEBRTC_POSIX WEBRTC_MAC SSL_USE_OPENSSL FEATURE_ENABLE_SSL HAVE_SRTP HAVE_NETINET_IN_H HAVE_OPENSSL_SSL_H SCTP_PROCESS_LEVEL_LOCKS SCTP_SIMPLE_ALLOCATOR SCTP_USE_OPENSSL_SHA1 __Userspace__ HAVE_SA_LEN HAVE_SCONN_LEN __APPLE_USE_RFC_2292 __Userspace_os_Darwin NON_WINDOWS_DEFINE HAVE_WEBRTC_VIDEO HAVE_WEBRTC_VOICE WEBRTC_INTELLIGIBILITY_ENHANCER=0 WEBRTC_APM_DEBUG_DUMP=0 WEBRTC_NS_FLOAT WEBRTC_USE_BUILTIN_OPUS WEBRTC_CODEC_OPUS WEBRTC_CODEC_ISAC WEBRTC_CODEC_RED HAVE_STDINT_H HAVE_STDLIB_H HAVE_UINT64_T OPENSSL HAVE_CONFIG_H WEBRTC_WEBKIT_BUILD HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE HAVE_SCTP WEBRTC_CODEC_G711 WEBRTC_CODEC_G722 WEBRTC_OPUS_VARIABLE_COMPLEXITY=0 WEBRTC_USE_BUILTIN_ISAC_FIX=1 WEBRTC_USE_BUILTIN_ISAC_FLOAT=0 USE_BUILTIN_SW_CODECS WEBRTC_WEBKIT_BUILD RTC_ENABLE_VP9 NO_MAIN_THREAD_WRAPPING RTC_DISABLE_TRACE_EVENTS WEBRTC_HAVE_SCTP WEBRTC_EXCLUDE_TRANSIENT_SUPPRESSOR WEBRTC_HAVE_DCSCTP $(inherited);
GCC_PREPROCESSOR_DEFINITIONS = GTEST_RELATIVE_PATH WEBRTC_OPUS_SUPPORT_120MS_PTIME=0 WEBRTC_POSIX WEBRTC_MAC SSL_USE_OPENSSL FEATURE_ENABLE_SSL HAVE_SRTP HAVE_NETINET_IN_H HAVE_OPENSSL_SSL_H SCTP_PROCESS_LEVEL_LOCKS SCTP_SIMPLE_ALLOCATOR SCTP_USE_OPENSSL_SHA1 __Userspace__ HAVE_SA_LEN HAVE_SCONN_LEN __APPLE_USE_RFC_2292 __Userspace_os_Darwin NON_WINDOWS_DEFINE HAVE_WEBRTC_VIDEO HAVE_WEBRTC_VOICE WEBRTC_INTELLIGIBILITY_ENHANCER=0 WEBRTC_APM_DEBUG_DUMP=0 WEBRTC_NS_FLOAT WEBRTC_USE_H265 WEBRTC_USE_BUILTIN_OPUS WEBRTC_CODEC_OPUS WEBRTC_CODEC_ISAC WEBRTC_CODEC_RED HAVE_STDINT_H HAVE_STDLIB_H HAVE_UINT64_T OPENSSL HAVE_CONFIG_H WEBRTC_WEBKIT_BUILD HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE HAVE_SCTP WEBRTC_CODEC_G711 WEBRTC_CODEC_G722 WEBRTC_OPUS_VARIABLE_COMPLEXITY=0 WEBRTC_USE_BUILTIN_ISAC_FIX=1 WEBRTC_USE_BUILTIN_ISAC_FLOAT=0 USE_BUILTIN_SW_CODECS WEBRTC_WEBKIT_BUILD RTC_ENABLE_VP9 NO_MAIN_THREAD_WRAPPING RTC_DISABLE_TRACE_EVENTS WEBRTC_HAVE_SCTP WEBRTC_EXCLUDE_TRANSIENT_SUPPRESSOR WEBRTC_HAVE_DCSCTP $(inherited);

GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*] = $(inherited) WEBRTC_USE_VTB_HARDWARE_ENCODER $(GCC_PREPROCESSOR_DEFINITIONS_$(WK_IS_CATALYST));
GCC_PREPROCESSOR_DEFINITIONS_YES = WEBRTC_MAC_CATALYST WEBRTC_IOS;
Expand Down
Expand Up @@ -21,9 +21,7 @@ enum VideoCodecType {
kVideoCodecVP9,
kVideoCodecAV1,
kVideoCodecH264,
#ifndef DISABLE_H265
kVideoCodecH265,
#endif
kVideoCodecMultiplex,
};

Expand Down
Expand Up @@ -26,7 +26,7 @@ constexpr char kPayloadNameAv1[] = "AV1";
// needed.
constexpr char kPayloadNameAv1x[] = "AV1X";
constexpr char kPayloadNameH264[] = "H264";
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
constexpr char kPayloadNameH265[] = "H265";
#endif
constexpr char kPayloadNameGeneric[] = "Generic";
Expand Down Expand Up @@ -55,6 +55,15 @@ bool VideoCodecH264::operator==(const VideoCodecH264& other) const {
numberOfTemporalLayers == other.numberOfTemporalLayers);
}

bool VideoCodecH265::operator==(const VideoCodecH265& other) const {
return (frameDroppingOn == other.frameDroppingOn &&
keyFrameInterval == other.keyFrameInterval &&
vpsLen == other.vpsLen && spsLen == other.spsLen &&
ppsLen == other.ppsLen &&
(spsLen == 0 || memcmp(spsData, other.spsData, spsLen) == 0) &&
(ppsLen == 0 || memcmp(ppsData, other.ppsData, ppsLen) == 0));
}

VideoCodec::VideoCodec()
: codecType(kVideoCodecGeneric),
width(0),
Expand Down Expand Up @@ -105,6 +114,18 @@ const VideoCodecH264& VideoCodec::H264() const {
return codec_specific_.H264;
}

#ifdef WEBRTC_USE_H265
VideoCodecH265* VideoCodec::H265() {
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
return &codec_specific_.H265;
}

const VideoCodecH265& VideoCodec::H265() const {
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
return codec_specific_.H265;
}
#endif

const char* CodecTypeToPayloadString(VideoCodecType type) {
switch (type) {
case kVideoCodecVP8:
Expand All @@ -115,7 +136,7 @@ const char* CodecTypeToPayloadString(VideoCodecType type) {
return kPayloadNameAv1;
case kVideoCodecH264:
return kPayloadNameH264;
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
case kVideoCodecH265:
return kPayloadNameH265;
#endif
Expand All @@ -137,7 +158,7 @@ VideoCodecType PayloadStringToCodecType(const std::string& name) {
return kVideoCodecAV1;
if (absl::EqualsIgnoreCase(name, kPayloadNameH264))
return kVideoCodecH264;
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
if (absl::EqualsIgnoreCase(name, kPayloadNameH265))
return kVideoCodecH265;
#endif
Expand Down
Expand Up @@ -97,6 +97,21 @@ struct VideoCodecH264 {
uint8_t numberOfTemporalLayers;
};

struct VideoCodecH265 {
bool operator==(const VideoCodecH265& other) const;
bool operator!=(const VideoCodecH265& other) const {
return !(*this == other);
}
bool frameDroppingOn;
int keyFrameInterval;
const uint8_t* vpsData;
size_t vpsLen;
const uint8_t* spsData;
size_t spsLen;
const uint8_t* ppsData;
size_t ppsLen;
};

// Translates from name of codec to codec type and vice versa.
RTC_EXPORT const char* CodecTypeToPayloadString(VideoCodecType type);
RTC_EXPORT VideoCodecType PayloadStringToCodecType(const std::string& name);
Expand All @@ -105,6 +120,7 @@ union VideoCodecUnion {
VideoCodecVP8 VP8;
VideoCodecVP9 VP9;
VideoCodecH264 H264;
VideoCodecH265 H265;
};

enum class VideoCodecMode { kRealtimeVideo, kScreensharing };
Expand Down Expand Up @@ -193,6 +209,8 @@ class RTC_EXPORT VideoCodec {
const VideoCodecVP9& VP9() const;
VideoCodecH264* H264();
const VideoCodecH264& H264() const;
VideoCodecH265* H265();
const VideoCodecH265& H265() const;

private:
// TODO(hta): Consider replacing the union with a pointer type.
Expand Down
Expand Up @@ -167,7 +167,7 @@ void VideoDecoderSoftwareFallbackWrapper::UpdateFallbackDecoderHistograms() {
RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "H264",
hw_decoded_frames_since_last_fallback_);
break;
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
case kVideoCodecH265:
RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "H265",
hw_decoded_frames_since_last_fallback_);
Expand Down
Expand Up @@ -58,6 +58,23 @@ VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
return h264_settings;
}

#ifdef WEBRTC_USE_H265
VideoCodecH265 VideoEncoder::GetDefaultH265Settings() {
VideoCodecH265 h265_settings;
memset(&h265_settings, 0, sizeof(h265_settings));

// h265_settings.profile = kProfileBase;
h265_settings.frameDroppingOn = true;
h265_settings.keyFrameInterval = 3000;
h265_settings.spsData = nullptr;
h265_settings.spsLen = 0;
h265_settings.ppsData = nullptr;
h265_settings.ppsLen = 0;

return h265_settings;
}
#endif

VideoEncoder::ScalingSettings::ScalingSettings() = default;

VideoEncoder::ScalingSettings::ScalingSettings(KOff) : ScalingSettings() {}
Expand Down
Expand Up @@ -338,6 +338,9 @@ class RTC_EXPORT VideoEncoder {
static VideoCodecVP8 GetDefaultVp8Settings();
static VideoCodecVP9 GetDefaultVp9Settings();
static VideoCodecH264 GetDefaultH264Settings();
#ifdef WEBRTC_USE_H265
static VideoCodecH265 GetDefaultH265Settings();
#endif

virtual ~VideoEncoder() {}

Expand Down
Expand Up @@ -96,12 +96,11 @@ void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info,
info.codecSpecific.H264.packetization_mode;
return;
}
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
case kVideoCodecH265: {
auto& h265_header = rtp->video_type_header.emplace<RTPVideoHeaderH265>();
h265_header.packetization_mode =
info.codecSpecific.H265.packetization_mode;
rtp->simulcastIdx = spatial_index.value_or(0);
return;
}
#endif
Expand Down Expand Up @@ -348,7 +347,7 @@ void RtpPayloadParams::SetGeneric(const CodecSpecificInfo* codec_specific_info,
is_keyframe, rtp_video_header);
}
return;
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
case VideoCodecType::kVideoCodecH265:
// FIXME: Implement H265 to generic descriptor.
return;
Expand Down Expand Up @@ -416,7 +415,7 @@ absl::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
}
case VideoCodecType::kVideoCodecAV1:
case VideoCodecType::kVideoCodecH264:
#ifndef DISABLE_H265
#ifdef WEBRTC_USE_H265
case VideoCodecType::kVideoCodecH265:
#endif
case VideoCodecType::kVideoCodecMultiplex:
Expand Down
Expand Up @@ -10,100 +10,50 @@

#include "common_video/h265/h265_common.h"

#include "common_video/h264/h264_common.h"

namespace webrtc {
namespace H265 {

const uint8_t kNaluTypeMask = 0x7E;

std::vector<H264::NaluIndex> FindNaluIndices(const uint8_t* buffer,
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size) {
// This is sorta like Boyer-Moore, but with only the first optimization step:
// given a 3-byte sequence we're looking at, if the 3rd byte isn't 1 or 0,
// skip ahead to the next 3-byte sequence. 0s and 1s are relatively rare, so
// this will skip the majority of reads/checks.
std::vector<H264::NaluIndex> sequences;
if (buffer_size < kNaluShortStartSequenceSize)
return sequences;

const size_t end = buffer_size - kNaluShortStartSequenceSize;
for (size_t i = 0; i < end;) {
if (buffer[i + 2] > 1) {
i += 3;
} else if (buffer[i + 2] == 1 && buffer[i + 1] == 0 && buffer[i] == 0) {
// We found a start sequence, now check if it was a 3 of 4 byte one.
H264::NaluIndex index = {i, i + 3, 0};
if (index.start_offset > 0 && buffer[index.start_offset - 1] == 0)
--index.start_offset;

// Update length of previous entry.
auto it = sequences.rbegin();
if (it != sequences.rend())
it->payload_size = index.start_offset - it->payload_start_offset;

sequences.push_back(index);

i += 3;
} else {
++i;
}
std::vector<H264::NaluIndex> indices =
H264::FindNaluIndices(buffer, buffer_size);
std::vector<NaluIndex> results;
for (auto& index : indices) {
results.push_back(
{index.start_offset, index.payload_start_offset, index.payload_size});
}

// Update length of last entry, if any.
auto it = sequences.rbegin();
if (it != sequences.rend())
it->payload_size = buffer_size - it->payload_start_offset;

return sequences;
return results;
}

NaluType ParseNaluType(uint8_t data) {
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
}

std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
std::vector<uint8_t> out;
out.reserve(length);

for (size_t i = 0; i < length;) {
// Be careful about over/underflow here. byte_length_ - 3 can underflow, and
// i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
// above, and that expression will produce the number of bytes left in
// the stream including the byte at i.
if (length - i >= 3 && !data[i] && !data[i + 1] && data[i + 2] == 3) {
// Two rbsp bytes.
out.push_back(data[i++]);
out.push_back(data[i++]);
// Skip the emulation byte.
i++;
} else {
// Single rbsp byte.
out.push_back(data[i++]);
}
}
return out;
return H264::ParseRbsp(data, length);
}

void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination) {
static const uint8_t kZerosInStartSequence = 2;
static const uint8_t kEmulationByte = 0x03u;
size_t num_consecutive_zeros = 0;
destination->EnsureCapacity(destination->size() + length);
H264::WriteRbsp(bytes, length, destination);
}

for (size_t i = 0; i < length; ++i) {
uint8_t byte = bytes[i];
if (byte <= kEmulationByte &&
num_consecutive_zeros >= kZerosInStartSequence) {
// Need to escape.
destination->AppendData(kEmulationByte);
num_consecutive_zeros = 0;
}
destination->AppendData(byte);
if (byte == 0) {
++num_consecutive_zeros;
} else {
num_consecutive_zeros = 0;
}
uint32_t Log2(uint32_t value) {
uint32_t result = 0;
// If value is not a power of two an additional bit is required
// to account for the ceil() of log2() below.
if ((value & (value - 1)) != 0) {
++result;
}
while (value > 0) {
value >>= 1;
++result;
}

return result;
}

} // namespace H265
Expand Down
Expand Up @@ -14,7 +14,6 @@
#include <memory>
#include <vector>

#include "common_video/h264/h264_common.h"
#include "rtc_base/buffer.h"

namespace webrtc {
Expand All @@ -28,8 +27,8 @@ const size_t kNaluLongStartSequenceSize = 4;
// not the first NALU of an access unit or an SPS or PPS block.
const size_t kNaluShortStartSequenceSize = 3;

// The size of the NALU type byte (1).
const size_t kNaluTypeSize = 1;
// The size of the NALU type byte (2).
const size_t kNaluTypeSize = 2;

enum NaluType : uint8_t {
kTrailN = 0,
Expand Down Expand Up @@ -57,10 +56,19 @@ enum NaluType : uint8_t {
kFU = 49
};

enum SliceType : uint8_t { kP = 0, kB = 1, kI = 2, kSp = 3, kSi = 4 };
enum SliceType : uint8_t { kB = 0, kP = 1, kI = 2 };

struct NaluIndex {
// Start index of NALU, including start sequence.
size_t start_offset;
// Start index of NALU payload, typically type header.
size_t payload_start_offset;
// Length of NALU payload, in bytes, counting from payload_start_offset.
size_t payload_size;
};

// Returns a vector of the NALU indices in the given buffer.
std::vector<H264::NaluIndex> FindNaluIndices(const uint8_t* buffer,
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size);

// Get the NAL type from the header byte immediately following start sequence.
Expand All @@ -86,6 +94,8 @@ std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length);
// bytes in order to escape any data the could be interpreted as a start
// sequence.
void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination);

uint32_t Log2(uint32_t value);
} // namespace H265
} // namespace webrtc

Expand Down

0 comments on commit 93eb48d

Please sign in to comment.