webrtc/modules/video_coding/codecs/h264/h264.cc
Magnus Jedvert 8deb818086 Support more H264 profiles for internal software codec
Care should be taken when landing this, because it will affect users of
WebRTC. I'm thinking primarily of Chromium. Chromium will start to
support High profile and Baseline profile using SW codecs with this CL.
Clients who do SDP munging without looking at the H264 profile might
switch from Constrained Baseline to High profile with this change.

Bug: webrtc:8317
Change-Id: Idca3a6b761a66d9e521b913b850c6ae14381f1f4
Reviewed-on: https://webrtc-review.googlesource.com/6341
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20190}
2017-10-06 14:28:44 +00:00

106 lines
3.1 KiB
C++

/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*
*/
#include "modules/video_coding/codecs/h264/include/h264.h"
#include "api/video_codecs/sdp_video_format.h"
#include "media/base/h264_profile_level_id.h"
#if defined(WEBRTC_USE_H264)
#include "modules/video_coding/codecs/h264/h264_decoder_impl.h"
#include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
#endif
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
namespace webrtc {
namespace {
#if defined(WEBRTC_USE_H264)
bool g_rtc_use_h264 = true;
#endif
// If H.264 OpenH264/FFmpeg codec is supported.
bool IsH264CodecSupported() {
#if defined(WEBRTC_USE_H264)
return g_rtc_use_h264;
#else
return false;
#endif
}
SdpVideoFormat CreateH264Format(H264::Profile profile, H264::Level level) {
const rtc::Optional<std::string> profile_string =
H264::ProfileLevelIdToString(H264::ProfileLevelId(profile, level));
RTC_CHECK(profile_string);
return SdpVideoFormat(cricket::kH264CodecName,
{{cricket::kH264FmtpProfileLevelId, *profile_string},
{cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
{cricket::kH264FmtpPacketizationMode, "1"}});
}
} // namespace
void DisableRtcUseH264() {
#if defined(WEBRTC_USE_H264)
g_rtc_use_h264 = false;
#endif
}
std::vector<SdpVideoFormat> SupportedH264Codecs() {
if (!IsH264CodecSupported())
return std::vector<SdpVideoFormat>();
// We only support encoding Constrained Baseline Profile (CBP), but the
// decoder supports more profiles. We can list all profiles here that are
// supported by the decoder and that are also supersets of CBP, i.e. the
// decoder for that profile is required to be able to decode CBP. This means
// we can encode and send CBP even though we negotiated a potentially
// higher profile. See the H264 spec for more information.
return {CreateH264Format(H264::kProfileHigh, H264::kLevel3_1),
CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1),
CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1)};
}
H264Encoder* H264Encoder::Create(const cricket::VideoCodec& codec) {
RTC_DCHECK(H264Encoder::IsSupported());
#if defined(WEBRTC_USE_H264)
RTC_CHECK(g_rtc_use_h264);
LOG(LS_INFO) << "Creating H264EncoderImpl.";
return new H264EncoderImpl(codec);
#else
RTC_NOTREACHED();
return nullptr;
#endif
}
bool H264Encoder::IsSupported() {
return IsH264CodecSupported();
}
H264Decoder* H264Decoder::Create() {
RTC_DCHECK(H264Decoder::IsSupported());
#if defined(WEBRTC_USE_H264)
RTC_CHECK(g_rtc_use_h264);
LOG(LS_INFO) << "Creating H264DecoderImpl.";
return new H264DecoderImpl();
#else
RTC_NOTREACHED();
return nullptr;
#endif
}
bool H264Decoder::IsSupported() {
return IsH264CodecSupported();
}
} // namespace webrtc