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