vp9.cc (3622B)
1 /* 2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/video_coding/codecs/vp9/include/vp9.h" 12 13 #include <memory> 14 #include <vector> 15 16 #include "absl/base/nullability.h" 17 #include "absl/container/inlined_vector.h" 18 #include "api/environment/environment.h" 19 #include "api/video_codecs/scalability_mode.h" 20 #include "api/video_codecs/sdp_video_format.h" 21 #include "api/video_codecs/video_encoder.h" 22 #include "modules/video_coding/codecs/interface/libvpx_interface.h" 23 #include "modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h" 24 #include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h" 25 #include "modules/video_coding/svc/create_scalability_structure.h" 26 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 27 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 28 #include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h" 29 30 namespace webrtc { 31 32 std::vector<SdpVideoFormat> SupportedVP9Codecs(bool add_scalability_modes) { 33 #ifdef RTC_ENABLE_VP9 34 // Profile 2 might not be available on some platforms until 35 // https://bugs.chromium.org/p/webm/issues/detail?id=1544 is solved. 36 static bool vpx_supports_high_bit_depth = 37 (vpx_codec_get_caps(vpx_codec_vp9_cx()) & VPX_CODEC_CAP_HIGHBITDEPTH) != 38 0 && 39 (vpx_codec_get_caps(vpx_codec_vp9_dx()) & VPX_CODEC_CAP_HIGHBITDEPTH) != 40 0; 41 42 absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes; 43 if (add_scalability_modes) { 44 for (const auto scalability_mode : kAllScalabilityModes) { 45 if (ScalabilityStructureConfig(scalability_mode).has_value()) { 46 scalability_modes.push_back(scalability_mode); 47 } 48 } 49 } 50 std::vector<SdpVideoFormat> supported_formats{ 51 SdpVideoFormat(SdpVideoFormat::VP9Profile0(), scalability_modes)}; 52 if (vpx_supports_high_bit_depth) { 53 supported_formats.push_back( 54 SdpVideoFormat(SdpVideoFormat::VP9Profile2(), scalability_modes)); 55 } 56 57 return supported_formats; 58 #else 59 return std::vector<SdpVideoFormat>(); 60 #endif 61 } 62 63 std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs() { 64 #ifdef RTC_ENABLE_VP9 65 std::vector<SdpVideoFormat> supported_formats = SupportedVP9Codecs(); 66 // The WebRTC internal decoder supports VP9 profile 1 and 3. However, there's 67 // currently no way of sending VP9 profile 1 or 3 using the internal encoder. 68 // It would require extended support for I444, I422, and I440 buffers. 69 supported_formats.push_back(SdpVideoFormat::VP9Profile1()); 70 supported_formats.push_back(SdpVideoFormat::VP9Profile3()); 71 return supported_formats; 72 #else 73 return std::vector<SdpVideoFormat>(); 74 #endif 75 } 76 77 absl_nonnull std::unique_ptr<VideoEncoder> CreateVp9Encoder( 78 const Environment& env, 79 Vp9EncoderSettings settings) { 80 #ifdef RTC_ENABLE_VP9 81 return std::make_unique<LibvpxVp9Encoder>(env, settings, 82 LibvpxInterface::Create()); 83 #else 84 RTC_CHECK_NOTREACHED(); 85 #endif 86 } 87 88 bool VP9Encoder::SupportsScalabilityMode(ScalabilityMode scalability_mode) { 89 return ScalabilityStructureConfig(scalability_mode).has_value(); 90 } 91 92 std::unique_ptr<VP9Decoder> VP9Decoder::Create() { 93 #ifdef RTC_ENABLE_VP9 94 return std::make_unique<LibvpxVp9Decoder>(); 95 #else 96 RTC_DCHECK_NOTREACHED(); 97 return nullptr; 98 #endif 99 } 100 101 } // namespace webrtc