diff --git a/media/base/vp9_profile.cc b/media/base/vp9_profile.cc index cfecc5e545..abf2502fc8 100644 --- a/media/base/vp9_profile.cc +++ b/media/base/vp9_profile.cc @@ -24,6 +24,8 @@ std::string VP9ProfileToString(VP9Profile profile) { switch (profile) { case VP9Profile::kProfile0: return "0"; + case VP9Profile::kProfile1: + return "1"; case VP9Profile::kProfile2: return "2"; } @@ -38,6 +40,8 @@ absl::optional StringToVP9Profile(const std::string& str) { switch (i.value()) { case 0: return VP9Profile::kProfile0; + case 1: + return VP9Profile::kProfile1; case 2: return VP9Profile::kProfile2; default: diff --git a/media/base/vp9_profile.h b/media/base/vp9_profile.h index e2bbf19005..e47204fede 100644 --- a/media/base/vp9_profile.h +++ b/media/base/vp9_profile.h @@ -24,6 +24,7 @@ extern RTC_EXPORT const char kVP9FmtpProfileId[]; enum class VP9Profile { kProfile0, + kProfile1, kProfile2, }; diff --git a/media/engine/internal_decoder_factory.cc b/media/engine/internal_decoder_factory.cc index e68bb369b5..d512b731af 100644 --- a/media/engine/internal_decoder_factory.cc +++ b/media/engine/internal_decoder_factory.cc @@ -44,7 +44,7 @@ std::vector InternalDecoderFactory::GetSupportedFormats() const { std::vector formats; formats.push_back(SdpVideoFormat(cricket::kVp8CodecName)); - for (const SdpVideoFormat& format : SupportedVP9Codecs()) + for (const SdpVideoFormat& format : SupportedVP9DecoderCodecs()) formats.push_back(format); for (const SdpVideoFormat& h264_format : SupportedH264Codecs()) formats.push_back(h264_format); diff --git a/media/engine/internal_decoder_factory_unittest.cc b/media/engine/internal_decoder_factory_unittest.cc index 705933d439..61be5e72df 100644 --- a/media/engine/internal_decoder_factory_unittest.cc +++ b/media/engine/internal_decoder_factory_unittest.cc @@ -13,6 +13,7 @@ #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "media/base/media_constants.h" +#include "media/base/vp9_profile.h" #include "modules/video_coding/codecs/av1/libaom_av1_decoder.h" #include "test/gmock.h" #include "test/gtest.h" @@ -30,6 +31,26 @@ TEST(InternalDecoderFactory, TestVP8) { EXPECT_TRUE(decoder); } +#ifdef RTC_ENABLE_VP9 +TEST(InternalDecoderFactory, TestVP9Profile0) { + InternalDecoderFactory factory; + std::unique_ptr decoder = + factory.CreateVideoDecoder(SdpVideoFormat( + cricket::kVp9CodecName, + {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}})); + EXPECT_TRUE(decoder); +} + +TEST(InternalDecoderFactory, TestVP9Profile1) { + InternalDecoderFactory factory; + std::unique_ptr decoder = + factory.CreateVideoDecoder(SdpVideoFormat( + cricket::kVp9CodecName, + {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile1)}})); + EXPECT_TRUE(decoder); +} +#endif // RTC_ENABLE_VP9 + TEST(InternalDecoderFactory, Av1) { InternalDecoderFactory factory; if (kIsLibaomAv1DecoderSupported) { diff --git a/modules/video_coding/codecs/vp9/include/vp9.h b/modules/video_coding/codecs/vp9/include/vp9.h index 8091cacec9..7cf1c2ebd1 100644 --- a/modules/video_coding/codecs/vp9/include/vp9.h +++ b/modules/video_coding/codecs/vp9/include/vp9.h @@ -25,6 +25,10 @@ namespace webrtc { // negotiate in SDP, in order of preference. std::vector SupportedVP9Codecs(); +// Returns a vector with all supported internal VP9 decode profiles in order of +// preference. These will be availble for receive-only connections. +std::vector SupportedVP9DecoderCodecs(); + class VP9Encoder : public VideoEncoder { public: // Deprecated. Returns default implementation using VP9 Profile 0. diff --git a/modules/video_coding/codecs/vp9/vp9.cc b/modules/video_coding/codecs/vp9/vp9.cc index 527bce7729..9b0585c059 100644 --- a/modules/video_coding/codecs/vp9/vp9.cc +++ b/modules/video_coding/codecs/vp9/vp9.cc @@ -39,6 +39,22 @@ std::vector SupportedVP9Codecs() { cricket::kVp9CodecName, {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile2)}})); } + + return supported_formats; +#else + return std::vector(); +#endif +} + +std::vector SupportedVP9DecoderCodecs() { +#ifdef RTC_ENABLE_VP9 + std::vector supported_formats = SupportedVP9Codecs(); + // The WebRTC internal decoder supports VP9 profile 1. However, there's + // currently no way of sending VP9 profile 1 using the internal encoder. + // It would require extended support for I444, I422, and I440 buffers. + supported_formats.push_back(SdpVideoFormat( + cricket::kVp9CodecName, + {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile1)}})); return supported_formats; #else return std::vector(); diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index 8230ba3a18..3ac46f627e 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -516,6 +516,11 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, config_->g_profile = 0; config_->g_input_bit_depth = 8; break; + case VP9Profile::kProfile1: + // Encoding of profile 1 is not implemented. It would require extended + // support for I444, I422, and I440 buffers. + RTC_NOTREACHED(); + break; case VP9Profile::kProfile2: img_fmt = VPX_IMG_FMT_I42016; bits_for_storage = 16; @@ -973,6 +978,10 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, raw_->stride[VPX_PLANE_V] = i420_buffer->StrideV(); break; } + case VP9Profile::kProfile1: { + RTC_NOTREACHED(); + break; + } case VP9Profile::kProfile2: { // We can inject kI010 frames directly for encode. All other formats // should be converted to it.