1 /*
2 * Copyright (c) 2015 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
12 #include "modules/video_coding/codecs/h264/include/h264.h"
13
14 #include <memory>
15 #include <string>
16
17 #include "absl/types/optional.h"
18 #include "api/video_codecs/sdp_video_format.h"
19 #include "media/base/media_constants.h"
20
21 #if defined(WEBRTC_USE_H264)
22 #include "modules/video_coding/codecs/h264/h264_decoder_impl.h"
23 #include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
24 #endif
25
26 #include "rtc_base/checks.h"
27 #include "rtc_base/logging.h"
28
29 namespace webrtc {
30
31 namespace {
32
33 #if defined(WEBRTC_USE_H264)
34 bool g_rtc_use_h264 = true;
35 #endif
36
37 // If H.264 OpenH264/FFmpeg codec is supported.
IsH264CodecSupported()38 bool IsH264CodecSupported() {
39 #if defined(WEBRTC_USE_H264)
40 return g_rtc_use_h264;
41 #else
42 return false;
43 #endif
44 }
45
46 } // namespace
47
CreateH264Format(H264::Profile profile,H264::Level level,const std::string & packetization_mode)48 SdpVideoFormat CreateH264Format(H264::Profile profile,
49 H264::Level level,
50 const std::string& packetization_mode) {
51 const absl::optional<std::string> profile_string =
52 H264::ProfileLevelIdToString(H264::ProfileLevelId(profile, level));
53 RTC_CHECK(profile_string);
54 return SdpVideoFormat(
55 cricket::kH264CodecName,
56 {{cricket::kH264FmtpProfileLevelId, *profile_string},
57 {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
58 {cricket::kH264FmtpPacketizationMode, packetization_mode}});
59 }
60
DisableRtcUseH264()61 void DisableRtcUseH264() {
62 #if defined(WEBRTC_USE_H264)
63 g_rtc_use_h264 = false;
64 #endif
65 }
66
SupportedH264Codecs()67 std::vector<SdpVideoFormat> SupportedH264Codecs() {
68 if (!IsH264CodecSupported())
69 return std::vector<SdpVideoFormat>();
70 // We only support encoding Constrained Baseline Profile (CBP), but the
71 // decoder supports more profiles. We can list all profiles here that are
72 // supported by the decoder and that are also supersets of CBP, i.e. the
73 // decoder for that profile is required to be able to decode CBP. This means
74 // we can encode and send CBP even though we negotiated a potentially
75 // higher profile. See the H264 spec for more information.
76 //
77 // We support both packetization modes 0 (mandatory) and 1 (optional,
78 // preferred).
79 return {
80 CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "1"),
81 CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "0"),
82 CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1, "1"),
83 CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1,
84 "0")};
85 }
86
Create(const cricket::VideoCodec & codec)87 std::unique_ptr<H264Encoder> H264Encoder::Create(
88 const cricket::VideoCodec& codec) {
89 RTC_DCHECK(H264Encoder::IsSupported());
90 #if defined(WEBRTC_USE_H264)
91 RTC_CHECK(g_rtc_use_h264);
92 RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
93 return std::make_unique<H264EncoderImpl>(codec);
94 #else
95 RTC_NOTREACHED();
96 return nullptr;
97 #endif
98 }
99
IsSupported()100 bool H264Encoder::IsSupported() {
101 return IsH264CodecSupported();
102 }
103
Create()104 std::unique_ptr<H264Decoder> H264Decoder::Create() {
105 RTC_DCHECK(H264Decoder::IsSupported());
106 #if defined(WEBRTC_USE_H264)
107 RTC_CHECK(g_rtc_use_h264);
108 RTC_LOG(LS_INFO) << "Creating H264DecoderImpl.";
109 return std::make_unique<H264DecoderImpl>();
110 #else
111 RTC_NOTREACHED();
112 return nullptr;
113 #endif
114 }
115
IsSupported()116 bool H264Decoder::IsSupported() {
117 return IsH264CodecSupported();
118 }
119
120 } // namespace webrtc
121