mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00
Add codec name H265 to support H265 in WebRTC
Bug: webrtc:13485 Change-Id: I352b15a65867f0d56fc8e9a9e03081bd3258108e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/316283 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40773}
This commit is contained in:
parent
9596002743
commit
ae82df718c
45 changed files with 217 additions and 8 deletions
4
BUILD.gn
4
BUILD.gn
|
@ -302,6 +302,10 @@ config("common_config") {
|
||||||
defines += [ "RTC_ENABLE_VP9" ]
|
defines += [ "RTC_ENABLE_VP9" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_use_h265) {
|
||||||
|
defines += [ "RTC_ENABLE_H265" ]
|
||||||
|
}
|
||||||
|
|
||||||
if (rtc_include_dav1d_in_internal_decoder_factory) {
|
if (rtc_include_dav1d_in_internal_decoder_factory) {
|
||||||
defines += [ "RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY" ]
|
defines += [ "RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY" ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,10 @@ std::unique_ptr<VideoRtpDepacketizer> CreateDepacketizer(
|
||||||
return std::make_unique<VideoRtpDepacketizerAv1>();
|
return std::make_unique<VideoRtpDepacketizerAv1>();
|
||||||
case RtpVideoFrameAssembler::kGeneric:
|
case RtpVideoFrameAssembler::kGeneric:
|
||||||
return std::make_unique<VideoRtpDepacketizerGeneric>();
|
return std::make_unique<VideoRtpDepacketizerGeneric>();
|
||||||
|
case RtpVideoFrameAssembler::kH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement VideoRtpDepacketizerH265
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -52,7 +52,7 @@ class RtpVideoFrameAssembler {
|
||||||
// FrameVector is just a vector-like type of std::unique_ptr<EncodedFrame>.
|
// FrameVector is just a vector-like type of std::unique_ptr<EncodedFrame>.
|
||||||
// The vector type may change without notice.
|
// The vector type may change without notice.
|
||||||
using FrameVector = absl::InlinedVector<AssembledFrame, 3>;
|
using FrameVector = absl::InlinedVector<AssembledFrame, 3>;
|
||||||
enum PayloadFormat { kRaw, kH264, kVp8, kVp9, kAv1, kGeneric };
|
enum PayloadFormat { kRaw, kH264, kVp8, kVp9, kAv1, kGeneric, kH265 };
|
||||||
|
|
||||||
explicit RtpVideoFrameAssembler(PayloadFormat payload_format);
|
explicit RtpVideoFrameAssembler(PayloadFormat payload_format);
|
||||||
RtpVideoFrameAssembler(const RtpVideoFrameAssembler& other) = delete;
|
RtpVideoFrameAssembler(const RtpVideoFrameAssembler& other) = delete;
|
||||||
|
|
|
@ -89,6 +89,9 @@ class PacketBuilder {
|
||||||
case PayloadFormat::kAv1: {
|
case PayloadFormat::kAv1: {
|
||||||
return kVideoCodecAV1;
|
return kVideoCodecAV1;
|
||||||
}
|
}
|
||||||
|
case PayloadFormat::kH265: {
|
||||||
|
return kVideoCodecH265;
|
||||||
|
}
|
||||||
case PayloadFormat::kGeneric: {
|
case PayloadFormat::kGeneric: {
|
||||||
return kVideoCodecGeneric;
|
return kVideoCodecGeneric;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ enum VideoCodecType {
|
||||||
kVideoCodecAV1,
|
kVideoCodecAV1,
|
||||||
kVideoCodecH264,
|
kVideoCodecH264,
|
||||||
kVideoCodecMultiplex,
|
kVideoCodecMultiplex,
|
||||||
|
kVideoCodecH265,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/video_codecs/av1_profile.h"
|
#include "api/video_codecs/av1_profile.h"
|
||||||
#include "api/video_codecs/h264_profile_level_id.h"
|
#include "api/video_codecs/h264_profile_level_id.h"
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
#include "api/video_codecs/h265_profile_tier_level.h"
|
||||||
|
#endif
|
||||||
#include "api/video_codecs/video_codec.h"
|
#include "api/video_codecs/video_codec.h"
|
||||||
#include "api/video_codecs/vp9_profile.h"
|
#include "api/video_codecs/vp9_profile.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
@ -61,6 +64,10 @@ bool IsSameCodecSpecific(const SdpVideoFormat& format1,
|
||||||
return VP9IsSameProfile(format1.parameters, format2.parameters);
|
return VP9IsSameProfile(format1.parameters, format2.parameters);
|
||||||
case kVideoCodecAV1:
|
case kVideoCodecAV1:
|
||||||
return AV1IsSameProfile(format1.parameters, format2.parameters);
|
return AV1IsSameProfile(format1.parameters, format2.parameters);
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
case kVideoCodecH265:
|
||||||
|
return H265IsSameProfileTierLevel(format1.parameters, format2.parameters);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,18 @@ TEST(SdpVideoFormatTest, SameCodecNameNoParameters) {
|
||||||
EXPECT_TRUE(Sdp("VP8").IsSameCodec(Sdp("vp8")));
|
EXPECT_TRUE(Sdp("VP8").IsSameCodec(Sdp("vp8")));
|
||||||
EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("vp9")));
|
EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("vp9")));
|
||||||
EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("Av1")));
|
EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("Av1")));
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
EXPECT_TRUE(Sdp("H265").IsSameCodec(Sdp("h265")));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SdpVideoFormatTest, DifferentCodecNameNoParameters) {
|
TEST(SdpVideoFormatTest, DifferentCodecNameNoParameters) {
|
||||||
EXPECT_FALSE(Sdp("H264").IsSameCodec(Sdp("VP8")));
|
EXPECT_FALSE(Sdp("H264").IsSameCodec(Sdp("VP8")));
|
||||||
EXPECT_FALSE(Sdp("VP8").IsSameCodec(Sdp("VP9")));
|
EXPECT_FALSE(Sdp("VP8").IsSameCodec(Sdp("VP9")));
|
||||||
EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("VP8")));
|
EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("VP8")));
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp("VP8")));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SdpVideoFormatTest, SameCodecNameSameParameters) {
|
TEST(SdpVideoFormatTest, SameCodecNameSameParameters) {
|
||||||
|
@ -50,6 +56,17 @@ TEST(SdpVideoFormatTest, SameCodecNameSameParameters) {
|
||||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
|
.IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
|
||||||
EXPECT_TRUE(Sdp("AV1", Params{{"profile", "2"}})
|
EXPECT_TRUE(Sdp("AV1", Params{{"profile", "2"}})
|
||||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
EXPECT_TRUE(Sdp("H265").IsSameCodec(Sdp(
|
||||||
|
"H265",
|
||||||
|
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "93"}})));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
Sdp("H265",
|
||||||
|
Params{{"profile-id", "2"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||||
|
.IsSameCodec(Sdp("H265", Params{{"profile-id", "2"},
|
||||||
|
{"tier-flag", "0"},
|
||||||
|
{"level-id", "93"}})));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SdpVideoFormatTest, SameCodecNameDifferentParameters) {
|
TEST(SdpVideoFormatTest, SameCodecNameDifferentParameters) {
|
||||||
|
@ -69,6 +86,35 @@ TEST(SdpVideoFormatTest, SameCodecNameDifferentParameters) {
|
||||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
|
.IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
|
||||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "1"}})
|
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "1"}})
|
||||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||||
|
"H265",
|
||||||
|
Params{{"profile-id", "0"}, {"tier-flag", "0"}, {"level-id", "93"}})));
|
||||||
|
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||||
|
"H265",
|
||||||
|
Params{{"profile-id", "1"}, {"tier-flag", "1"}, {"level-id", "93"}})));
|
||||||
|
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||||
|
"H265",
|
||||||
|
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "90"}})));
|
||||||
|
EXPECT_FALSE(
|
||||||
|
Sdp("H265",
|
||||||
|
Params{{"profile-id", "2"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||||
|
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||||
|
{"tier-flag", "0"},
|
||||||
|
{"level-id", "93"}})));
|
||||||
|
EXPECT_FALSE(
|
||||||
|
Sdp("H265",
|
||||||
|
Params{{"profile-id", "1"}, {"tier-flag", "1"}, {"level-id", "120"}})
|
||||||
|
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||||
|
{"tier-flag", "0"},
|
||||||
|
{"level-id", "120"}})));
|
||||||
|
EXPECT_FALSE(
|
||||||
|
Sdp("H265",
|
||||||
|
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||||
|
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||||
|
{"tier-flag", "0"},
|
||||||
|
{"level-id", "90"}})));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SdpVideoFormatTest, DifferentCodecNameSameParameters) {
|
TEST(SdpVideoFormatTest, DifferentCodecNameSameParameters) {
|
||||||
|
@ -86,6 +132,12 @@ TEST(SdpVideoFormatTest, DifferentCodecNameSameParameters) {
|
||||||
.IsSameCodec(Sdp("H264", Params{{"profile", "0"}})));
|
.IsSameCodec(Sdp("H264", Params{{"profile", "0"}})));
|
||||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "2"}})
|
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "2"}})
|
||||||
.IsSameCodec(Sdp("VP9", Params{{"profile", "2"}})));
|
.IsSameCodec(Sdp("VP9", Params{{"profile", "2"}})));
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
EXPECT_FALSE(Sdp("H265", Params{{"profile-id", "0"}})
|
||||||
|
.IsSameCodec(Sdp("H264", Params{{"profile-id", "0"}})));
|
||||||
|
EXPECT_FALSE(Sdp("H265", Params{{"profile-id", "2"}})
|
||||||
|
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SdpVideoFormatTest, H264PacketizationMode) {
|
TEST(SdpVideoFormatTest, H264PacketizationMode) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ constexpr char kPayloadNameAv1x[] = "AV1X";
|
||||||
constexpr char kPayloadNameH264[] = "H264";
|
constexpr char kPayloadNameH264[] = "H264";
|
||||||
constexpr char kPayloadNameGeneric[] = "Generic";
|
constexpr char kPayloadNameGeneric[] = "Generic";
|
||||||
constexpr char kPayloadNameMultiplex[] = "Multiplex";
|
constexpr char kPayloadNameMultiplex[] = "Multiplex";
|
||||||
|
constexpr char kPayloadNameH265[] = "H265";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool VideoCodecVP8::operator==(const VideoCodecVP8& other) const {
|
bool VideoCodecVP8::operator==(const VideoCodecVP8& other) const {
|
||||||
|
@ -126,6 +127,8 @@ const char* CodecTypeToPayloadString(VideoCodecType type) {
|
||||||
return kPayloadNameMultiplex;
|
return kPayloadNameMultiplex;
|
||||||
case kVideoCodecGeneric:
|
case kVideoCodecGeneric:
|
||||||
return kPayloadNameGeneric;
|
return kPayloadNameGeneric;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
return kPayloadNameH265;
|
||||||
}
|
}
|
||||||
RTC_CHECK_NOTREACHED();
|
RTC_CHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
@ -142,6 +145,8 @@ VideoCodecType PayloadStringToCodecType(const std::string& name) {
|
||||||
return kVideoCodecH264;
|
return kVideoCodecH264;
|
||||||
if (absl::EqualsIgnoreCase(name, kPayloadNameMultiplex))
|
if (absl::EqualsIgnoreCase(name, kPayloadNameMultiplex))
|
||||||
return kVideoCodecMultiplex;
|
return kVideoCodecMultiplex;
|
||||||
|
if (absl::EqualsIgnoreCase(name, kPayloadNameH265))
|
||||||
|
return kVideoCodecH265;
|
||||||
return kVideoCodecGeneric;
|
return kVideoCodecGeneric;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,10 @@ void VideoDecoderSoftwareFallbackWrapper::UpdateFallbackDecoderHistograms() {
|
||||||
RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Multiplex",
|
RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Multiplex",
|
||||||
hw_decoded_frames_since_last_fallback_);
|
hw_decoded_frames_since_last_fallback_);
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "H265",
|
||||||
|
hw_decoded_frames_since_last_fallback_);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info,
|
||||||
case kVideoCodecGeneric:
|
case kVideoCodecGeneric:
|
||||||
rtp->codec = kVideoCodecGeneric;
|
rtp->codec = kVideoCodecGeneric;
|
||||||
return;
|
return;
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement H265 codec specific info
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -341,6 +342,9 @@ void RtpPayloadParams::SetGeneric(const CodecSpecificInfo* codec_specific_info,
|
||||||
return;
|
return;
|
||||||
case VideoCodecType::kVideoCodecMultiplex:
|
case VideoCodecType::kVideoCodecMultiplex:
|
||||||
return;
|
return;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement H265 to generic descriptor.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_NOTREACHED() << "Unsupported codec.";
|
RTC_DCHECK_NOTREACHED() << "Unsupported codec.";
|
||||||
}
|
}
|
||||||
|
@ -402,6 +406,7 @@ absl::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
|
||||||
}
|
}
|
||||||
case VideoCodecType::kVideoCodecAV1:
|
case VideoCodecType::kVideoCodecAV1:
|
||||||
case VideoCodecType::kVideoCodecH264:
|
case VideoCodecType::kVideoCodecH264:
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
case VideoCodecType::kVideoCodecMultiplex:
|
case VideoCodecType::kVideoCodecMultiplex:
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,8 @@ rtclog2::FrameDecodedEvents::Codec ConvertToProtoFormat(VideoCodecType codec) {
|
||||||
case VideoCodecType::kVideoCodecMultiplex:
|
case VideoCodecType::kVideoCodecMultiplex:
|
||||||
// This codec type is afaik not used.
|
// This codec type is afaik not used.
|
||||||
return rtclog2::FrameDecodedEvents::CODEC_UNKNOWN;
|
return rtclog2::FrameDecodedEvents::CODEC_UNKNOWN;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
return rtclog2::FrameDecodedEvents::CODEC_H265;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
return rtclog2::FrameDecodedEvents::CODEC_UNKNOWN;
|
return rtclog2::FrameDecodedEvents::CODEC_UNKNOWN;
|
||||||
|
|
|
@ -339,6 +339,7 @@ message FrameDecodedEvents {
|
||||||
CODEC_VP9 = 3;
|
CODEC_VP9 = 3;
|
||||||
CODEC_AV1 = 4;
|
CODEC_AV1 = 4;
|
||||||
CODEC_H264 = 5;
|
CODEC_H264 = 5;
|
||||||
|
CODEC_H265 = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// required
|
// required
|
||||||
|
|
|
@ -261,6 +261,8 @@ VideoCodecType GetRuntimeCodecType(rtclog2::FrameDecodedEvents::Codec codec) {
|
||||||
return VideoCodecType::kVideoCodecAV1;
|
return VideoCodecType::kVideoCodecAV1;
|
||||||
case rtclog2::FrameDecodedEvents::CODEC_H264:
|
case rtclog2::FrameDecodedEvents::CODEC_H264:
|
||||||
return VideoCodecType::kVideoCodecH264;
|
return VideoCodecType::kVideoCodecH264;
|
||||||
|
case rtclog2::FrameDecodedEvents::CODEC_H265:
|
||||||
|
return VideoCodecType::kVideoCodecH265;
|
||||||
case rtclog2::FrameDecodedEvents::CODEC_UNKNOWN:
|
case rtclog2::FrameDecodedEvents::CODEC_UNKNOWN:
|
||||||
RTC_LOG(LS_ERROR) << "Unknown codec type. Assuming "
|
RTC_LOG(LS_ERROR) << "Unknown codec type. Assuming "
|
||||||
"VideoCodecType::kVideoCodecMultiplex";
|
"VideoCodecType::kVideoCodecMultiplex";
|
||||||
|
|
|
@ -169,11 +169,11 @@ std::unique_ptr<RtcEventFrameDecoded> EventGenerator::NewFrameDecodedEvent(
|
||||||
constexpr int kMaxHeight = 8640;
|
constexpr int kMaxHeight = 8640;
|
||||||
constexpr int kMinWidth = 16;
|
constexpr int kMinWidth = 16;
|
||||||
constexpr int kMinHeight = 16;
|
constexpr int kMinHeight = 16;
|
||||||
constexpr int kNumCodecTypes = 5;
|
constexpr int kNumCodecTypes = 6;
|
||||||
|
|
||||||
constexpr VideoCodecType kCodecList[kNumCodecTypes] = {
|
constexpr VideoCodecType kCodecList[kNumCodecTypes] = {
|
||||||
kVideoCodecGeneric, kVideoCodecVP8, kVideoCodecVP9, kVideoCodecAV1,
|
kVideoCodecGeneric, kVideoCodecVP8, kVideoCodecVP9,
|
||||||
kVideoCodecH264};
|
kVideoCodecAV1, kVideoCodecH264, kVideoCodecH265};
|
||||||
const int64_t render_time_ms =
|
const int64_t render_time_ms =
|
||||||
rtc::TimeMillis() + prng_.Rand(kMinRenderDelayMs, kMaxRenderDelayMs);
|
rtc::TimeMillis() + prng_.Rand(kMinRenderDelayMs, kMaxRenderDelayMs);
|
||||||
const int width = prng_.Rand(kMinWidth, kMaxWidth);
|
const int width = prng_.Rand(kMinWidth, kMaxWidth);
|
||||||
|
|
|
@ -33,6 +33,9 @@ std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
|
||||||
return std::make_unique<VideoRtpDepacketizerVp9>();
|
return std::make_unique<VideoRtpDepacketizerVp9>();
|
||||||
case kVideoCodecAV1:
|
case kVideoCodecAV1:
|
||||||
return std::make_unique<VideoRtpDepacketizerAv1>();
|
return std::make_unique<VideoRtpDepacketizerAv1>();
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement VideoRtpDepacketizerH265.
|
||||||
|
return nullptr;
|
||||||
case kVideoCodecGeneric:
|
case kVideoCodecGeneric:
|
||||||
case kVideoCodecMultiplex:
|
case kVideoCodecMultiplex:
|
||||||
return std::make_unique<VideoRtpDepacketizerGeneric>();
|
return std::make_unique<VideoRtpDepacketizerGeneric>();
|
||||||
|
|
|
@ -57,6 +57,7 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
|
||||||
return std::make_unique<RtpPacketizerAv1>(
|
return std::make_unique<RtpPacketizerAv1>(
|
||||||
payload, limits, rtp_video_header.frame_type,
|
payload, limits, rtp_video_header.frame_type,
|
||||||
rtp_video_header.is_last_frame_in_picture);
|
rtp_video_header.is_last_frame_in_picture);
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement RtpPacketizerH265.
|
||||||
default: {
|
default: {
|
||||||
return std::make_unique<RtpPacketizerGeneric>(payload, limits,
|
return std::make_unique<RtpPacketizerGeneric>(payload, limits,
|
||||||
rtp_video_header);
|
rtp_video_header);
|
||||||
|
|
|
@ -92,6 +92,10 @@ bool IsBaseLayer(const RTPVideoHeader& video_header) {
|
||||||
// TODO(kron): Implement logic for H264 once WebRTC supports temporal
|
// TODO(kron): Implement logic for H264 once WebRTC supports temporal
|
||||||
// layers for H264.
|
// layers for H264.
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement logic for H265 once WebRTC
|
||||||
|
// supports temporal layers for H265.
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,9 @@ VideoFrameMetadata RTPVideoHeader::GetAsMetadata() const {
|
||||||
metadata.SetRTPVideoHeaderCodecSpecifics(
|
metadata.SetRTPVideoHeaderCodecSpecifics(
|
||||||
absl::get<RTPVideoHeaderH264>(video_type_header));
|
absl::get<RTPVideoHeaderH264>(video_type_header));
|
||||||
break;
|
break;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Codec-specifics are not supported for this codec.
|
// Codec-specifics are not supported for this codec.
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -93,6 +93,9 @@ int MultiplexEncoderAdapter::InitEncode(
|
||||||
key_frame_interval_ = video_codec.H264()->keyFrameInterval;
|
key_frame_interval_ = video_codec.H264()->keyFrameInterval;
|
||||||
video_codec.H264()->keyFrameInterval = 0;
|
video_codec.H264()->keyFrameInterval = 0;
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,9 @@ std::string CodecSpecificToString(const VideoCodec& codec) {
|
||||||
ss << "\nnum_temporal_layers: "
|
ss << "\nnum_temporal_layers: "
|
||||||
<< static_cast<int>(codec.H264().numberOfTemporalLayers);
|
<< static_cast<int>(codec.H264().numberOfTemporalLayers);
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +249,9 @@ void VideoCodecTestFixtureImpl::Config::SetCodecSettings(
|
||||||
codec_settings.H264()->numberOfTemporalLayers =
|
codec_settings.H264()->numberOfTemporalLayers =
|
||||||
static_cast<uint8_t>(num_temporal_layers);
|
static_cast<uint8_t>(num_temporal_layers);
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,10 @@ void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
|
||||||
_codecSpecificInfo.codecType = kVideoCodecAV1;
|
_codecSpecificInfo.codecType = kVideoCodecAV1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kVideoCodecH265: {
|
||||||
|
_codecSpecificInfo.codecType = kVideoCodecH265;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
_codecSpecificInfo.codecType = kVideoCodecGeneric;
|
_codecSpecificInfo.codecType = kVideoCodecGeneric;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,6 +29,7 @@ constexpr uint8_t kVp8Header[kCodecTypeBytesCount] = {'V', 'P', '8', '0'};
|
||||||
constexpr uint8_t kVp9Header[kCodecTypeBytesCount] = {'V', 'P', '9', '0'};
|
constexpr uint8_t kVp9Header[kCodecTypeBytesCount] = {'V', 'P', '9', '0'};
|
||||||
constexpr uint8_t kAv1Header[kCodecTypeBytesCount] = {'A', 'V', '0', '1'};
|
constexpr uint8_t kAv1Header[kCodecTypeBytesCount] = {'A', 'V', '0', '1'};
|
||||||
constexpr uint8_t kH264Header[kCodecTypeBytesCount] = {'H', '2', '6', '4'};
|
constexpr uint8_t kH264Header[kCodecTypeBytesCount] = {'H', '2', '6', '4'};
|
||||||
|
constexpr uint8_t kH265Header[kCodecTypeBytesCount] = {'H', '2', '6', '5'};
|
||||||
|
|
||||||
// RTP standard required 90kHz clock rate.
|
// RTP standard required 90kHz clock rate.
|
||||||
constexpr int32_t kRtpClockRateHz = 90000;
|
constexpr int32_t kRtpClockRateHz = 90000;
|
||||||
|
@ -192,6 +193,9 @@ absl::optional<VideoCodecType> IvfFileReader::ParseCodecType(uint8_t* buffer,
|
||||||
if (memcmp(&buffer[start_pos], kH264Header, kCodecTypeBytesCount) == 0) {
|
if (memcmp(&buffer[start_pos], kH264Header, kCodecTypeBytesCount) == 0) {
|
||||||
return VideoCodecType::kVideoCodecH264;
|
return VideoCodecType::kVideoCodecH264;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&buffer[start_pos], kH265Header, kCodecTypeBytesCount) == 0) {
|
||||||
|
return VideoCodecType::kVideoCodecH265;
|
||||||
|
}
|
||||||
has_error_ = true;
|
has_error_ = true;
|
||||||
RTC_LOG(LS_ERROR) << "Unknown codec type: "
|
RTC_LOG(LS_ERROR) << "Unknown codec type: "
|
||||||
<< std::string(
|
<< std::string(
|
||||||
|
|
|
@ -92,6 +92,12 @@ bool IvfFileWriter::WriteHeader() {
|
||||||
ivf_header[10] = '6';
|
ivf_header[10] = '6';
|
||||||
ivf_header[11] = '4';
|
ivf_header[11] = '4';
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
ivf_header[8] = 'H';
|
||||||
|
ivf_header[9] = '2';
|
||||||
|
ivf_header[10] = '6';
|
||||||
|
ivf_header[11] = '5';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// For unknown codec type use **** code. You can specify actual payload
|
// For unknown codec type use **** code. You can specify actual payload
|
||||||
// format when playing the video with ffplay: ffplay -f H263 file.ivf
|
// format when playing the video with ffplay: ffplay -f H263 file.ivf
|
||||||
|
|
|
@ -36,6 +36,8 @@ absl::optional<uint32_t> QpParser::Parse(VideoCodecType codec_type,
|
||||||
}
|
}
|
||||||
} else if (codec_type == kVideoCodecH264) {
|
} else if (codec_type == kVideoCodecH264) {
|
||||||
return h264_parsers_[spatial_idx].Parse(frame_data, frame_size);
|
return h264_parsers_[spatial_idx].Parse(frame_data, frame_size);
|
||||||
|
} else if (codec_type == kVideoCodecH265) {
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
}
|
}
|
||||||
|
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
|
|
|
@ -94,6 +94,9 @@ int SimulcastUtility::NumberOfTemporalLayers(const VideoCodec& codec,
|
||||||
case kVideoCodecH264:
|
case kVideoCodecH264:
|
||||||
num_temporal_layers = codec.H264().numberOfTemporalLayers;
|
num_temporal_layers = codec.H264().numberOfTemporalLayers;
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,9 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
|
||||||
kMaxTemporalStreams);
|
kMaxTemporalStreams);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// TODO(pbos): Support encoder_settings codec-agnostically.
|
// TODO(pbos): Support encoder_settings codec-agnostically.
|
||||||
RTC_DCHECK(!config.encoder_specific_settings)
|
RTC_DCHECK(!config.encoder_specific_settings)
|
||||||
|
|
|
@ -159,6 +159,8 @@ absl::optional<VideoEncoder::QpThresholds> GetThresholds(
|
||||||
low = config.vp9.GetQpLow();
|
low = config.vp9.GetQpLow();
|
||||||
high = config.vp9.GetQpHigh();
|
high = config.vp9.GetQpHigh();
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use H264 QP thresholds for now.
|
||||||
case kVideoCodecH264:
|
case kVideoCodecH264:
|
||||||
low = config.h264.GetQpLow();
|
low = config.h264.GetQpLow();
|
||||||
high = config.h264.GetQpHigh();
|
high = config.h264.GetQpHigh();
|
||||||
|
@ -194,6 +196,8 @@ int GetFps(VideoCodecType type,
|
||||||
case kVideoCodecVP8:
|
case kVideoCodecVP8:
|
||||||
fps = config->vp8.GetFps();
|
fps = config->vp8.GetFps();
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
fps = config->vp9.GetFps();
|
fps = config->vp9.GetFps();
|
||||||
break;
|
break;
|
||||||
|
@ -226,6 +230,8 @@ absl::optional<int> GetKbps(
|
||||||
case kVideoCodecVP8:
|
case kVideoCodecVP8:
|
||||||
kbps = config->vp8.GetKbps();
|
kbps = config->vp8.GetKbps();
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
kbps = config->vp9.GetKbps();
|
kbps = config->vp9.GetKbps();
|
||||||
break;
|
break;
|
||||||
|
@ -259,6 +265,8 @@ absl::optional<int> GetKbpsRes(
|
||||||
case kVideoCodecVP8:
|
case kVideoCodecVP8:
|
||||||
kbps_res = config->vp8.GetKbpsRes();
|
kbps_res = config->vp8.GetKbpsRes();
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
kbps_res = config->vp9.GetKbpsRes();
|
kbps_res = config->vp9.GetKbpsRes();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -94,6 +94,8 @@ absl::optional<DataRate> GetExperimentalMinVideoBitrate(VideoCodecType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case kVideoCodecVP8:
|
case kVideoCodecVP8:
|
||||||
return min_bitrate_vp8.GetOptional();
|
return min_bitrate_vp8.GetOptional();
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
return min_bitrate_vp9.GetOptional();
|
return min_bitrate_vp9.GetOptional();
|
||||||
case kVideoCodecAV1:
|
case kVideoCodecAV1:
|
||||||
|
|
|
@ -81,6 +81,8 @@ QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type) {
|
||||||
return GetThresholds(settings->vp8_low, settings->vp8_high, kMaxVp8Qp);
|
return GetThresholds(settings->vp8_low, settings->vp8_high, kMaxVp8Qp);
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
return GetThresholds(settings->vp9_low, settings->vp9_high, kMaxVp9Qp);
|
return GetThresholds(settings->vp9_low, settings->vp9_high, kMaxVp9Qp);
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use H264 QP thresholds for now.
|
||||||
case kVideoCodecH264:
|
case kVideoCodecH264:
|
||||||
return GetThresholds(settings->h264_low, settings->h264_high, kMaxH264Qp);
|
return GetThresholds(settings->h264_low, settings->h264_high, kMaxH264Qp);
|
||||||
case kVideoCodecGeneric:
|
case kVideoCodecGeneric:
|
||||||
|
|
|
@ -430,7 +430,8 @@ bool Convert(std::string inputfile,
|
||||||
{VideoCodecType::kVideoCodecVP9, "VP9"},
|
{VideoCodecType::kVideoCodecVP9, "VP9"},
|
||||||
{VideoCodecType::kVideoCodecAV1, "AV1"},
|
{VideoCodecType::kVideoCodecAV1, "AV1"},
|
||||||
{VideoCodecType::kVideoCodecH264, "H264"},
|
{VideoCodecType::kVideoCodecH264, "H264"},
|
||||||
{VideoCodecType::kVideoCodecMultiplex, "MULTIPLEX"}};
|
{VideoCodecType::kVideoCodecMultiplex, "MULTIPLEX"},
|
||||||
|
{VideoCodecType::kVideoCodecH265, "H265"}};
|
||||||
|
|
||||||
fprintf(output,
|
fprintf(output,
|
||||||
"FRAME_DECODED %" PRId64 " render_time=%" PRId64
|
"FRAME_DECODED %" PRId64 " render_time=%" PRId64
|
||||||
|
|
|
@ -295,7 +295,9 @@ class TestVideoEncoderFactoryWrapper final {
|
||||||
RTC_LOG(LS_WARNING) << "Failed to configure svc bitrates for av1.";
|
RTC_LOG(LS_WARNING) << "Failed to configure svc bitrates for av1.";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RTC_CHECK_NOTREACHED();
|
RTC_CHECK_NOTREACHED();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -267,6 +267,8 @@ class DecoderIvfFileWriter : public test::FakeDecoder {
|
||||||
video_codec_type_ = VideoCodecType::kVideoCodecH264;
|
video_codec_type_ = VideoCodecType::kVideoCodecH264;
|
||||||
} else if (codec == "AV1") {
|
} else if (codec == "AV1") {
|
||||||
video_codec_type_ = VideoCodecType::kVideoCodecAV1;
|
video_codec_type_ = VideoCodecType::kVideoCodecAV1;
|
||||||
|
} else if (codec == "H265") {
|
||||||
|
video_codec_type_ = VideoCodecType::kVideoCodecH265;
|
||||||
} else {
|
} else {
|
||||||
RTC_LOG(LS_ERROR) << "Unsupported video codec " << codec;
|
RTC_LOG(LS_ERROR) << "Unsupported video codec " << codec;
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
|
|
@ -255,6 +255,13 @@ absl::optional<uint8_t> VideoDecoderWrapper::ParseQP(
|
||||||
qp = h264_bitstream_parser_.GetLastSliceQp();
|
qp = h264_bitstream_parser_.GetLastSliceQp();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
case kVideoCodecH265:
|
||||||
|
h265_bitstream_parser_.ParseBitstream(buffer);
|
||||||
|
qp = h265_bitstream_parser_.GetLastSliceQp().value_or(-1);
|
||||||
|
success = (qp >= 0);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break; // Default is to not provide QP.
|
break; // Default is to not provide QP.
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "api/video_codecs/video_decoder.h"
|
#include "api/video_codecs/video_decoder.h"
|
||||||
#include "common_video/h264/h264_bitstream_parser.h"
|
#include "common_video/h264/h264_bitstream_parser.h"
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
#include "common_video/h265/h265_bitstream_parser.h"
|
||||||
|
#endif
|
||||||
#include "rtc_base/race_checker.h"
|
#include "rtc_base/race_checker.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
#include "sdk/android/src/jni/jni_helpers.h"
|
#include "sdk/android/src/jni/jni_helpers.h"
|
||||||
|
@ -96,6 +99,10 @@ class VideoDecoderWrapper : public VideoDecoder {
|
||||||
bool initialized_ RTC_GUARDED_BY(decoder_thread_checker_);
|
bool initialized_ RTC_GUARDED_BY(decoder_thread_checker_);
|
||||||
H264BitstreamParser h264_bitstream_parser_
|
H264BitstreamParser h264_bitstream_parser_
|
||||||
RTC_GUARDED_BY(decoder_thread_checker_);
|
RTC_GUARDED_BY(decoder_thread_checker_);
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
H265BitstreamParser h265_bitstream_parser_
|
||||||
|
RTC_GUARDED_BY(decoder_thread_checker_);
|
||||||
|
#endif
|
||||||
|
|
||||||
DecodedImageCallback* callback_ RTC_GUARDED_BY(callback_race_checker_);
|
DecodedImageCallback* callback_ RTC_GUARDED_BY(callback_race_checker_);
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,8 @@ VideoEncoderWrapper::GetScalingSettingsInternal(JNIEnv* jni) const {
|
||||||
return VideoEncoder::ScalingSettings(kLowVp9QpThreshold,
|
return VideoEncoder::ScalingSettings(kLowVp9QpThreshold,
|
||||||
kHighVp9QpThreshold);
|
kHighVp9QpThreshold);
|
||||||
}
|
}
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use H264 QP thresholds for now.
|
||||||
case kVideoCodecH264: {
|
case kVideoCodecH264: {
|
||||||
// Same as in h264_encoder_impl.cc.
|
// Same as in h264_encoder_impl.cc.
|
||||||
static const int kLowH264QpThreshold = 24;
|
static const int kLowH264QpThreshold = 24;
|
||||||
|
@ -355,6 +357,13 @@ int VideoEncoderWrapper::ParseQp(rtc::ArrayView<const uint8_t> buffer) {
|
||||||
qp = h264_bitstream_parser_.GetLastSliceQp().value_or(-1);
|
qp = h264_bitstream_parser_.GetLastSliceQp().value_or(-1);
|
||||||
success = (qp >= 0);
|
success = (qp >= 0);
|
||||||
break;
|
break;
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
case kVideoCodecH265:
|
||||||
|
h265_bitstream_parser_.ParseBitstream(buffer);
|
||||||
|
qp = h265_bitstream_parser_.GetLastSliceQp().value_or(-1);
|
||||||
|
success = (qp >= 0);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default: // Default is to not provide QP.
|
default: // Default is to not provide QP.
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/h264/h264_bitstream_parser.h"
|
#include "common_video/h264/h264_bitstream_parser.h"
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
#include "common_video/h265/h265_bitstream_parser.h"
|
||||||
|
#endif
|
||||||
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
||||||
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
|
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
|
@ -103,6 +106,9 @@ class VideoEncoderWrapper : public VideoEncoder {
|
||||||
VideoCodec codec_settings_;
|
VideoCodec codec_settings_;
|
||||||
EncoderInfo encoder_info_;
|
EncoderInfo encoder_info_;
|
||||||
H264BitstreamParser h264_bitstream_parser_;
|
H264BitstreamParser h264_bitstream_parser_;
|
||||||
|
#ifdef RTC_ENABLE_H265
|
||||||
|
H265BitstreamParser h265_bitstream_parser_;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fills frame dependencies in codec-agnostic format.
|
// Fills frame dependencies in codec-agnostic format.
|
||||||
ScalableVideoControllerNoLayering svc_controller_;
|
ScalableVideoControllerNoLayering svc_controller_;
|
||||||
|
|
|
@ -120,6 +120,9 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
||||||
reader.CopyTo(
|
reader.CopyTo(
|
||||||
&video_header.video_type_header.emplace<RTPVideoHeaderH264>());
|
&video_header.video_type_header.emplace<RTPVideoHeaderH264>());
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485)
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ uint8_t CodecTypeToPayloadType(VideoCodecType codec_type) {
|
||||||
return VideoTestConstants::kPayloadTypeVP9;
|
return VideoTestConstants::kPayloadTypeVP9;
|
||||||
case VideoCodecType::kVideoCodecH264:
|
case VideoCodecType::kVideoCodecH264:
|
||||||
return VideoTestConstants::kPayloadTypeH264;
|
return VideoTestConstants::kPayloadTypeH264;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
return VideoTestConstants::kPayloadTypeH265;
|
||||||
default:
|
default:
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
@ -66,6 +68,8 @@ std::string CodecTypeToCodecName(VideoCodecType codec_type) {
|
||||||
return cricket::kVp9CodecName;
|
return cricket::kVp9CodecName;
|
||||||
case VideoCodecType::kVideoCodecH264:
|
case VideoCodecType::kVideoCodecH264:
|
||||||
return cricket::kH264CodecName;
|
return cricket::kH264CodecName;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
return cricket::kH265CodecName;
|
||||||
default:
|
default:
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
@ -203,6 +207,7 @@ CreateEncoderSpecificSettings(VideoStreamConfig config) {
|
||||||
return CreateVp9SpecificSettings(config);
|
return CreateVp9SpecificSettings(config);
|
||||||
case Codec::kVideoCodecGeneric:
|
case Codec::kVideoCodecGeneric:
|
||||||
case Codec::kVideoCodecAV1:
|
case Codec::kVideoCodecAV1:
|
||||||
|
case Codec::kVideoCodecH265:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case Codec::kVideoCodecMultiplex:
|
case Codec::kVideoCodecMultiplex:
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
|
|
@ -148,6 +148,9 @@ std::unique_ptr<VideoDecoder> IvfVideoFrameGenerator::CreateVideoDecoder(
|
||||||
if (codec_type == VideoCodecType::kVideoCodecAV1) {
|
if (codec_type == VideoCodecType::kVideoCodecAV1) {
|
||||||
return CreateDav1dDecoder();
|
return CreateDav1dDecoder();
|
||||||
}
|
}
|
||||||
|
if (codec_type == VideoCodecType::kVideoCodecH265) {
|
||||||
|
// TODO(bugs.webrtc.org/13485): implement H265 decoder
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ class VideoTestConstants {
|
||||||
kRtxRedPayloadType = 99,
|
kRtxRedPayloadType = 99,
|
||||||
kVideoSendPayloadType = 100,
|
kVideoSendPayloadType = 100,
|
||||||
kAudioSendPayloadType = 103,
|
kAudioSendPayloadType = 103,
|
||||||
|
kPayloadTypeH265 = 117,
|
||||||
kRedPayloadType = 118,
|
kRedPayloadType = 118,
|
||||||
kUlpfecPayloadType = 119,
|
kUlpfecPayloadType = 119,
|
||||||
kFlexfecPayloadType = 120,
|
kFlexfecPayloadType = 120,
|
||||||
|
|
|
@ -266,6 +266,12 @@ void EncoderOvershootDetector::UpdateHistograms() {
|
||||||
RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "H264",
|
RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "H264",
|
||||||
average_overshoot_percent);
|
average_overshoot_percent);
|
||||||
break;
|
break;
|
||||||
|
case VideoCodecType::kVideoCodecH265:
|
||||||
|
RTC_HISTOGRAMS_COUNTS_10000(index, rmse_histogram_prefix + "H265",
|
||||||
|
bitrate_rmse);
|
||||||
|
RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "H265",
|
||||||
|
average_overshoot_percent);
|
||||||
|
break;
|
||||||
case VideoCodecType::kVideoCodecGeneric:
|
case VideoCodecType::kVideoCodecGeneric:
|
||||||
case VideoCodecType::kVideoCodecMultiplex:
|
case VideoCodecType::kVideoCodecMultiplex:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -35,6 +35,8 @@ static std::string CodecTypeToHistogramSuffix(VideoCodecType codec) {
|
||||||
return "Av1";
|
return "Av1";
|
||||||
case kVideoCodecH264:
|
case kVideoCodecH264:
|
||||||
return "H264";
|
return "H264";
|
||||||
|
case kVideoCodecH265:
|
||||||
|
return "H265";
|
||||||
case kVideoCodecGeneric:
|
case kVideoCodecGeneric:
|
||||||
return "Generic";
|
return "Generic";
|
||||||
case kVideoCodecMultiplex:
|
case kVideoCodecMultiplex:
|
||||||
|
@ -275,6 +277,8 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{VideoCodecType::kVideoCodecAV1, false},
|
{VideoCodecType::kVideoCodecAV1, false},
|
||||||
{VideoCodecType::kVideoCodecAV1, true},
|
{VideoCodecType::kVideoCodecAV1, true},
|
||||||
{VideoCodecType::kVideoCodecH264, false},
|
{VideoCodecType::kVideoCodecH264, false},
|
||||||
{VideoCodecType::kVideoCodecH264, true}}));
|
{VideoCodecType::kVideoCodecH264, true},
|
||||||
|
{VideoCodecType::kVideoCodecH265, false},
|
||||||
|
{VideoCodecType::kVideoCodecH265, true}}));
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum HistogramCodecType {
|
||||||
kVideoVp9 = 2,
|
kVideoVp9 = 2,
|
||||||
kVideoH264 = 3,
|
kVideoH264 = 3,
|
||||||
kVideoAv1 = 4,
|
kVideoAv1 = 4,
|
||||||
|
kVideoH265 = 5,
|
||||||
kVideoMax = 64,
|
kVideoMax = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +77,8 @@ HistogramCodecType PayloadNameToHistogramCodecType(
|
||||||
return kVideoH264;
|
return kVideoH264;
|
||||||
case kVideoCodecAV1:
|
case kVideoCodecAV1:
|
||||||
return kVideoAv1;
|
return kVideoAv1;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
return kVideoH265;
|
||||||
default:
|
default:
|
||||||
return kVideoUnknown;
|
return kVideoUnknown;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,9 @@ bool RequiresEncoderReset(const VideoCodec& prev_send_codec,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement new send codec H265
|
||||||
|
[[fallthrough]];
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1351,6 +1353,7 @@ void VideoStreamEncoder::ReconfigureEncoder() {
|
||||||
// TODO(sprang): Add a better way to disable frame dropping.
|
// TODO(sprang): Add a better way to disable frame dropping.
|
||||||
num_layers = codec.simulcastStream[0].numberOfTemporalLayers;
|
num_layers = codec.simulcastStream[0].numberOfTemporalLayers;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO(bugs.webrtc.org/13485): Implement H265 temporal layer
|
||||||
num_layers = 1;
|
num_layers = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8822,6 +8822,9 @@ class VideoStreamEncoderWithRealEncoderTest
|
||||||
mock_encoder_factory_for_multiplex_.get(), SdpVideoFormat("VP8"),
|
mock_encoder_factory_for_multiplex_.get(), SdpVideoFormat("VP8"),
|
||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
|
case kVideoCodecH265:
|
||||||
|
// TODO(bugs.webrtc.org/13485): Use a fake encoder
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RTC_DCHECK_NOTREACHED();
|
RTC_DCHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue