Add decoder support for VP9 profile 1 I444

libvpx already supports VP9 profile 1. Add code to enable SDP negotiation of receiving VP9 profile 1.

Bug: webrtc:11555
Change-Id: I35d12d159a1414aac744f202331d3a9c4a84f5af
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176322
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31509}
This commit is contained in:
Johannes Kron
2020-06-11 13:41:06 +02:00
committed by Commit Bot
parent b64ecd9960
commit 7ff6355b88
7 changed files with 56 additions and 1 deletions

View File

@ -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<VP9Profile> StringToVP9Profile(const std::string& str) {
switch (i.value()) {
case 0:
return VP9Profile::kProfile0;
case 1:
return VP9Profile::kProfile1;
case 2:
return VP9Profile::kProfile2;
default:

View File

@ -24,6 +24,7 @@ extern RTC_EXPORT const char kVP9FmtpProfileId[];
enum class VP9Profile {
kProfile0,
kProfile1,
kProfile2,
};

View File

@ -44,7 +44,7 @@ std::vector<SdpVideoFormat> InternalDecoderFactory::GetSupportedFormats()
const {
std::vector<SdpVideoFormat> 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);

View File

@ -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<VideoDecoder> decoder =
factory.CreateVideoDecoder(SdpVideoFormat(
cricket::kVp9CodecName,
{{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}}));
EXPECT_TRUE(decoder);
}
TEST(InternalDecoderFactory, TestVP9Profile1) {
InternalDecoderFactory factory;
std::unique_ptr<VideoDecoder> decoder =
factory.CreateVideoDecoder(SdpVideoFormat(
cricket::kVp9CodecName,
{{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile1)}}));
EXPECT_TRUE(decoder);
}
#endif // RTC_ENABLE_VP9
TEST(InternalDecoderFactory, Av1) {
InternalDecoderFactory factory;
if (kIsLibaomAv1DecoderSupported) {

View File

@ -25,6 +25,10 @@ namespace webrtc {
// negotiate in SDP, in order of preference.
std::vector<SdpVideoFormat> 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<SdpVideoFormat> SupportedVP9DecoderCodecs();
class VP9Encoder : public VideoEncoder {
public:
// Deprecated. Returns default implementation using VP9 Profile 0.

View File

@ -39,6 +39,22 @@ std::vector<SdpVideoFormat> SupportedVP9Codecs() {
cricket::kVp9CodecName,
{{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile2)}}));
}
return supported_formats;
#else
return std::vector<SdpVideoFormat>();
#endif
}
std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs() {
#ifdef RTC_ENABLE_VP9
std::vector<SdpVideoFormat> 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<SdpVideoFormat>();

View File

@ -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.