diff --git a/media/engine/webrtcvideoengine_unittest.cc b/media/engine/webrtcvideoengine_unittest.cc index 974f479380..7fc5924c92 100644 --- a/media/engine/webrtcvideoengine_unittest.cc +++ b/media/engine/webrtcvideoengine_unittest.cc @@ -564,8 +564,19 @@ TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) { cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec( const std::string& name) { for (const cricket::VideoCodec& engine_codec : engine_.codecs()) { - if (CodecNamesEq(name, engine_codec.name)) - return engine_codec; + if (!CodecNamesEq(name, engine_codec.name)) + continue; + // The tests only use H264 Constrained Baseline. Make sure we don't return + // an internal H264 codec from the engine with a different H264 profile. + if (CodecNamesEq(name.c_str(), kH264CodecName)) { + const rtc::Optional profile_level_id = + webrtc::H264::ParseSdpProfileLevelId(engine_codec.params); + if (profile_level_id->profile != + webrtc::H264::kProfileConstrainedBaseline) { + continue; + } + } + return engine_codec; } // This point should never be reached. ADD_FAILURE() << "Unrecognized codec name: " << name; diff --git a/modules/video_coding/DEPS b/modules/video_coding/DEPS index af1a6e7f98..a02ed634ae 100644 --- a/modules/video_coding/DEPS +++ b/modules/video_coding/DEPS @@ -1,6 +1,4 @@ include_rules = [ - "+third_party/ffmpeg", - "+third_party/openh264", "+vpx", "+call", "+common_video", @@ -17,7 +15,4 @@ specific_include_rules = { "+media/engine", "+sdk", ], - ".*h264\.h": [ - "+media/base/codec.h" - ], } diff --git a/modules/video_coding/codecs/h264/DEPS b/modules/video_coding/codecs/h264/DEPS new file mode 100644 index 0000000000..4e110917d8 --- /dev/null +++ b/modules/video_coding/codecs/h264/DEPS @@ -0,0 +1,5 @@ +include_rules = [ + "+third_party/ffmpeg", + "+third_party/openh264", + "+media/base", +] diff --git a/modules/video_coding/codecs/h264/h264.cc b/modules/video_coding/codecs/h264/h264.cc index c24162d890..d7ed3b42e8 100644 --- a/modules/video_coding/codecs/h264/h264.cc +++ b/modules/video_coding/codecs/h264/h264.cc @@ -12,6 +12,7 @@ #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" @@ -29,7 +30,7 @@ namespace { bool g_rtc_use_h264 = true; #endif -// If any H.264 codec is supported (iOS HW or OpenH264/FFmpeg). +// If H.264 OpenH264/FFmpeg codec is supported. bool IsH264CodecSupported() { #if defined(WEBRTC_USE_H264) return g_rtc_use_h264; @@ -38,6 +39,16 @@ bool IsH264CodecSupported() { #endif } +SdpVideoFormat CreateH264Format(H264::Profile profile, H264::Level level) { + const rtc::Optional 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() { @@ -49,15 +60,15 @@ void DisableRtcUseH264() { std::vector SupportedH264Codecs() { if (!IsH264CodecSupported()) return std::vector(); - std::vector codecs; - - codecs.push_back(SdpVideoFormat( - cricket::kH264CodecName, {{cricket::kH264FmtpProfileLevelId, - cricket::kH264ProfileLevelConstrainedBaseline}, - {cricket::kH264FmtpLevelAsymmetryAllowed, "1"}, - {cricket::kH264FmtpPacketizationMode, "1"}})); - - return codecs; + // 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) {