blob: 93d4750b8e568c54ebb2dfcbd38da5075d548692 [file] [log] [blame]
Zeke Chin71f6f442015-06-29 14:34:58 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020012#include "modules/video_coding/codecs/h264/include/h264.h"
Zeke Chin71f6f442015-06-29 14:34:58 -070013
Magnus Jedvert849b3ae2017-09-29 17:54:09 +020014#include "api/video_codecs/sdp_video_format.h"
Magnus Jedvert8deb8182017-10-05 13:13:32 +020015#include "media/base/h264_profile_level_id.h"
Magnus Jedvert849b3ae2017-09-29 17:54:09 +020016
hbos9dc59282016-02-03 05:09:37 -080017#if defined(WEBRTC_USE_H264)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/video_coding/codecs/h264/h264_decoder_impl.h"
19#include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
hbosbab934b2016-01-27 01:36:03 -080020#endif
Zeke Chin71f6f442015-06-29 14:34:58 -070021
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/checks.h"
23#include "rtc_base/logging.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010024#include "rtc_base/ptr_util.h"
Zeke Chin71f6f442015-06-29 14:34:58 -070025
26namespace webrtc {
27
hbos9dc59282016-02-03 05:09:37 -080028namespace {
29
30#if defined(WEBRTC_USE_H264)
31bool g_rtc_use_h264 = true;
32#endif
33
Magnus Jedvert8deb8182017-10-05 13:13:32 +020034// If H.264 OpenH264/FFmpeg codec is supported.
Magnus Jedvert849b3ae2017-09-29 17:54:09 +020035bool IsH264CodecSupported() {
36#if defined(WEBRTC_USE_H264)
37 return g_rtc_use_h264;
38#else
39 return false;
40#endif
41}
42
Taylor Brandstetter28deb902018-05-30 14:56:50 -070043SdpVideoFormat CreateH264Format(H264::Profile profile,
44 H264::Level level,
45 const std::string& packetization_mode) {
Danil Chapovalov0040b662018-06-18 10:48:16 +020046 const absl::optional<std::string> profile_string =
Magnus Jedvert8deb8182017-10-05 13:13:32 +020047 H264::ProfileLevelIdToString(H264::ProfileLevelId(profile, level));
48 RTC_CHECK(profile_string);
Taylor Brandstetter28deb902018-05-30 14:56:50 -070049 return SdpVideoFormat(
50 cricket::kH264CodecName,
51 {{cricket::kH264FmtpProfileLevelId, *profile_string},
52 {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
53 {cricket::kH264FmtpPacketizationMode, packetization_mode}});
Magnus Jedvert8deb8182017-10-05 13:13:32 +020054}
55
hbos9dc59282016-02-03 05:09:37 -080056} // namespace
57
58void DisableRtcUseH264() {
59#if defined(WEBRTC_USE_H264)
60 g_rtc_use_h264 = false;
61#endif
62}
63
Magnus Jedvert849b3ae2017-09-29 17:54:09 +020064std::vector<SdpVideoFormat> SupportedH264Codecs() {
65 if (!IsH264CodecSupported())
66 return std::vector<SdpVideoFormat>();
Magnus Jedvert8deb8182017-10-05 13:13:32 +020067 // We only support encoding Constrained Baseline Profile (CBP), but the
68 // decoder supports more profiles. We can list all profiles here that are
69 // supported by the decoder and that are also supersets of CBP, i.e. the
70 // decoder for that profile is required to be able to decode CBP. This means
71 // we can encode and send CBP even though we negotiated a potentially
72 // higher profile. See the H264 spec for more information.
Taylor Brandstetter28deb902018-05-30 14:56:50 -070073 //
74 // We support both packetization modes 0 (mandatory) and 1 (optional,
75 // preferred).
76 return {
77 CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "1"),
78 CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "0"),
79 CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1, "1"),
80 CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1,
81 "0")};
Zeke Chin71f6f442015-06-29 14:34:58 -070082}
83
Magnus Jedvert46a27652017-11-13 14:10:02 +010084std::unique_ptr<H264Encoder> H264Encoder::Create(
85 const cricket::VideoCodec& codec) {
henrikg91d6ede2015-09-17 00:24:34 -070086 RTC_DCHECK(H264Encoder::IsSupported());
hbos9dc59282016-02-03 05:09:37 -080087#if defined(WEBRTC_USE_H264)
88 RTC_CHECK(g_rtc_use_h264);
Mirko Bonadei675513b2017-11-09 11:09:25 +010089 RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
Magnus Jedvert46a27652017-11-13 14:10:02 +010090 return rtc::MakeUnique<H264EncoderImpl>(codec);
Zeke Chin71f6f442015-06-29 14:34:58 -070091#else
92 RTC_NOTREACHED();
93 return nullptr;
94#endif
95}
96
97bool H264Encoder::IsSupported() {
98 return IsH264CodecSupported();
99}
100
Magnus Jedvert46a27652017-11-13 14:10:02 +0100101std::unique_ptr<H264Decoder> H264Decoder::Create() {
henrikg91d6ede2015-09-17 00:24:34 -0700102 RTC_DCHECK(H264Decoder::IsSupported());
hbos9dc59282016-02-03 05:09:37 -0800103#if defined(WEBRTC_USE_H264)
104 RTC_CHECK(g_rtc_use_h264);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100105 RTC_LOG(LS_INFO) << "Creating H264DecoderImpl.";
Magnus Jedvert46a27652017-11-13 14:10:02 +0100106 return rtc::MakeUnique<H264DecoderImpl>();
Zeke Chin71f6f442015-06-29 14:34:58 -0700107#else
108 RTC_NOTREACHED();
109 return nullptr;
110#endif
111}
112
113bool H264Decoder::IsSupported() {
114 return IsH264CodecSupported();
115}
116
117} // namespace webrtc