xref: /aosp_15_r20/external/webrtc/modules/video_coding/codecs/vp9/vp9.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 
15 #include "absl/container/inlined_vector.h"
16 #include "api/transport/field_trial_based_config.h"
17 #include "api/video_codecs/scalability_mode.h"
18 #include "api/video_codecs/sdp_video_format.h"
19 #include "api/video_codecs/vp9_profile.h"
20 #include "modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h"
21 #include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h"
22 #include "modules/video_coding/svc/create_scalability_structure.h"
23 #include "rtc_base/checks.h"
24 #include "vpx/vp8cx.h"
25 #include "vpx/vp8dx.h"
26 #include "vpx/vpx_codec.h"
27 
28 namespace webrtc {
29 
SupportedVP9Codecs(bool add_scalability_modes)30 std::vector<SdpVideoFormat> SupportedVP9Codecs(bool add_scalability_modes) {
31 #ifdef RTC_ENABLE_VP9
32   // Profile 2 might not be available on some platforms until
33   // https://bugs.chromium.org/p/webm/issues/detail?id=1544 is solved.
34   static bool vpx_supports_high_bit_depth =
35       (vpx_codec_get_caps(vpx_codec_vp9_cx()) & VPX_CODEC_CAP_HIGHBITDEPTH) !=
36           0 &&
37       (vpx_codec_get_caps(vpx_codec_vp9_dx()) & VPX_CODEC_CAP_HIGHBITDEPTH) !=
38           0;
39 
40   absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
41   if (add_scalability_modes) {
42     for (const auto scalability_mode : kAllScalabilityModes) {
43       if (ScalabilityStructureConfig(scalability_mode).has_value()) {
44         scalability_modes.push_back(scalability_mode);
45       }
46     }
47   }
48   std::vector<SdpVideoFormat> supported_formats{SdpVideoFormat(
49       cricket::kVp9CodecName,
50       {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}},
51       scalability_modes)};
52   if (vpx_supports_high_bit_depth) {
53     supported_formats.push_back(SdpVideoFormat(
54         cricket::kVp9CodecName,
55         {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile2)}},
56         scalability_modes));
57   }
58 
59   return supported_formats;
60 #else
61   return std::vector<SdpVideoFormat>();
62 #endif
63 }
64 
SupportedVP9DecoderCodecs()65 std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs() {
66 #ifdef RTC_ENABLE_VP9
67   std::vector<SdpVideoFormat> supported_formats = SupportedVP9Codecs();
68   // The WebRTC internal decoder supports VP9 profile 1 and 3. However, there's
69   // currently no way of sending VP9 profile 1 or 3 using the internal encoder.
70   // It would require extended support for I444, I422, and I440 buffers.
71   supported_formats.push_back(SdpVideoFormat(
72       cricket::kVp9CodecName,
73       {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile1)}}));
74   supported_formats.push_back(SdpVideoFormat(
75       cricket::kVp9CodecName,
76       {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile3)}}));
77   return supported_formats;
78 #else
79   return std::vector<SdpVideoFormat>();
80 #endif
81 }
82 
Create()83 std::unique_ptr<VP9Encoder> VP9Encoder::Create() {
84 #ifdef RTC_ENABLE_VP9
85   return std::make_unique<LibvpxVp9Encoder>(cricket::VideoCodec(),
86                                             LibvpxInterface::Create(),
87                                             FieldTrialBasedConfig());
88 #else
89   RTC_DCHECK_NOTREACHED();
90   return nullptr;
91 #endif
92 }
93 
Create(const cricket::VideoCodec & codec)94 std::unique_ptr<VP9Encoder> VP9Encoder::Create(
95     const cricket::VideoCodec& codec) {
96 #ifdef RTC_ENABLE_VP9
97   return std::make_unique<LibvpxVp9Encoder>(codec, LibvpxInterface::Create(),
98                                             FieldTrialBasedConfig());
99 #else
100   RTC_DCHECK_NOTREACHED();
101   return nullptr;
102 #endif
103 }
104 
SupportsScalabilityMode(ScalabilityMode scalability_mode)105 bool VP9Encoder::SupportsScalabilityMode(ScalabilityMode scalability_mode) {
106   return ScalabilityStructureConfig(scalability_mode).has_value();
107 }
108 
Create()109 std::unique_ptr<VP9Decoder> VP9Decoder::Create() {
110 #ifdef RTC_ENABLE_VP9
111   return std::make_unique<LibvpxVp9Decoder>();
112 #else
113   RTC_DCHECK_NOTREACHED();
114   return nullptr;
115 #endif
116 }
117 
118 }  // namespace webrtc
119