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