зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1803368 - Plumb H264 configuration from sdp negotiation into libwebrtc. r=webrtc-reviewers,mjf
The plumbing for this was broken in https://hg.mozilla.org/mozilla-central/rev/f3fc736c62d289ba9d7be9ed01806de7b6c00855 This patch puts the config data into SdpVideoFormat::Parameters which gets passed into libwebrtc. Further down the line, these parameters will have to be picked up by encoders. Subsequent patches fixes this for WebrtcGmpVideoEncoder and WebrtcMediaDataEncoder. Differential Revision: https://phabricator.services.mozilla.com/D163470
This commit is contained in:
Родитель
7f88fb67c4
Коммит
fcb762f2ba
|
@ -30,6 +30,7 @@
|
|||
|
||||
// libwebrtc includes
|
||||
#include "api/transport/bitrate_settings.h"
|
||||
#include "api/video_codecs/h264_profile_level_id.h"
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "api/video_codecs/video_codec.h"
|
||||
#include "media/base/media_constants.h"
|
||||
|
@ -126,7 +127,8 @@ webrtc::VideoCodecType SupportedCodecType(webrtc::VideoCodecType aType) {
|
|||
// Call thread only.
|
||||
rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings>
|
||||
ConfigureVideoEncoderSettings(const VideoCodecConfig& aConfig,
|
||||
const WebrtcVideoConduit* aConduit) {
|
||||
const WebrtcVideoConduit* aConduit,
|
||||
webrtc::SdpVideoFormat::Parameters& aParameters) {
|
||||
bool is_screencast =
|
||||
aConduit->CodecMode() == webrtc::VideoCodecMode::kScreensharing;
|
||||
// No automatic resizing when using simulcast or screencast.
|
||||
|
@ -141,6 +143,25 @@ ConfigureVideoEncoderSettings(const VideoCodecConfig& aConfig,
|
|||
codec_default_denoising = !denoising;
|
||||
}
|
||||
|
||||
if (aConfig.mName == kH264CodecName) {
|
||||
aParameters[kH264FmtpPacketizationMode] =
|
||||
std::to_string(aConfig.mPacketizationMode);
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::setfill('0');
|
||||
ss << std::setw(2) << static_cast<uint32_t>(aConfig.mProfile);
|
||||
ss << std::setw(2) << static_cast<uint32_t>(aConfig.mConstraints);
|
||||
ss << std::setw(2) << static_cast<uint32_t>(aConfig.mLevel);
|
||||
std::string profileLevelId = ss.str();
|
||||
auto parsedProfileLevelId =
|
||||
webrtc::ParseH264ProfileLevelId(profileLevelId.c_str());
|
||||
MOZ_DIAGNOSTIC_ASSERT(parsedProfileLevelId);
|
||||
if (parsedProfileLevelId) {
|
||||
aParameters[kH264FmtpProfileLevelId] = profileLevelId;
|
||||
}
|
||||
}
|
||||
aParameters[kH264FmtpSpropParameterSets] = aConfig.mSpropParameterSets;
|
||||
}
|
||||
if (aConfig.mName == kVp8CodecName) {
|
||||
webrtc::VideoCodecVP8 vp8_settings =
|
||||
webrtc::VideoEncoder::GetDefaultVp8Settings();
|
||||
|
@ -628,15 +649,16 @@ void WebrtcVideoConduit::OnControlConfigChange() {
|
|||
|
||||
// XXX parse the encoded SPS/PPS data and set
|
||||
// spsData/spsLen/ppsData/ppsLen
|
||||
mEncoderConfig.video_format =
|
||||
webrtc::SdpVideoFormat(codecConfig->mName);
|
||||
mEncoderConfig.encoder_specific_settings =
|
||||
ConfigureVideoEncoderSettings(*codecConfig, this);
|
||||
ConfigureVideoEncoderSettings(
|
||||
*codecConfig, this, mEncoderConfig.video_format.parameters);
|
||||
|
||||
mEncoderConfig.codec_type = SupportedCodecType(
|
||||
webrtc::PayloadStringToCodecType(codecConfig->mName));
|
||||
MOZ_RELEASE_ASSERT(mEncoderConfig.codec_type !=
|
||||
webrtc::VideoCodecType::kVideoCodecGeneric);
|
||||
mEncoderConfig.video_format =
|
||||
webrtc::SdpVideoFormat(codecConfig->mName);
|
||||
|
||||
mEncoderConfig.content_type =
|
||||
mControl.mCodecMode.Ref() == webrtc::VideoCodecMode::kRealtimeVideo
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "WebrtcGmpVideoCodec.h"
|
||||
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "media/base/media_constants.h"
|
||||
#include "media/base/video_adapter.h"
|
||||
|
||||
#include "MockCall.h"
|
||||
|
@ -2235,4 +2236,57 @@ TEST_F(VideoConduitTest, TestExternalRemoteSsrcCollision) {
|
|||
Not(testing::AnyOf(0U, 1U)));
|
||||
}
|
||||
|
||||
TEST_F(VideoConduitTest, TestVideoConfigurationH264) {
|
||||
const int profileLevelId1 = 0x42E00D;
|
||||
const int profileLevelId2 = 0x64000C;
|
||||
const char* sprop1 = "foo bar";
|
||||
const char* sprop2 = "baz";
|
||||
|
||||
// Test that VideoConduit propagates H264 configuration data properly.
|
||||
// We do two tests:
|
||||
// - Test valid data in packetization mode 0 (SingleNALU)
|
||||
// - Test different valid data in packetization mode 1 (NonInterleaved)
|
||||
|
||||
{
|
||||
mControl.Update([&](auto& aControl) {
|
||||
aControl.mTransmitting = true;
|
||||
VideoCodecConfigH264 h264{};
|
||||
h264.packetization_mode = 0;
|
||||
h264.profile_level_id = profileLevelId1;
|
||||
strncpy(h264.sprop_parameter_sets, sprop1,
|
||||
sizeof(h264.sprop_parameter_sets) - 1);
|
||||
VideoCodecConfig codecConfig(97, "H264", EncodingConstraints(), &h264);
|
||||
codecConfig.mEncodings.emplace_back();
|
||||
aControl.mVideoSendCodec = Some(codecConfig);
|
||||
aControl.mVideoSendRtpRtcpConfig =
|
||||
Some(RtpRtcpConfig(webrtc::RtcpMode::kCompound));
|
||||
});
|
||||
|
||||
ASSERT_TRUE(Call()->mVideoSendEncoderConfig);
|
||||
auto& params = Call()->mVideoSendEncoderConfig->video_format.parameters;
|
||||
EXPECT_EQ(params[cricket::kH264FmtpPacketizationMode], "0");
|
||||
EXPECT_EQ(params[cricket::kH264FmtpProfileLevelId], "42e00d");
|
||||
EXPECT_EQ(params[cricket::kH264FmtpSpropParameterSets], sprop1);
|
||||
}
|
||||
|
||||
{
|
||||
mControl.Update([&](auto& aControl) {
|
||||
VideoCodecConfigH264 h264{};
|
||||
h264.packetization_mode = 1;
|
||||
h264.profile_level_id = profileLevelId2;
|
||||
strncpy(h264.sprop_parameter_sets, sprop2,
|
||||
sizeof(h264.sprop_parameter_sets) - 1);
|
||||
VideoCodecConfig codecConfig(126, "H264", EncodingConstraints(), &h264);
|
||||
codecConfig.mEncodings.emplace_back();
|
||||
aControl.mVideoSendCodec = Some(codecConfig);
|
||||
});
|
||||
|
||||
ASSERT_TRUE(Call()->mVideoSendEncoderConfig);
|
||||
auto& params = Call()->mVideoSendEncoderConfig->video_format.parameters;
|
||||
EXPECT_EQ(params[cricket::kH264FmtpPacketizationMode], "1");
|
||||
EXPECT_EQ(params[cricket::kH264FmtpProfileLevelId], "64000c");
|
||||
EXPECT_EQ(params[cricket::kH264FmtpSpropParameterSets], sprop2);
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace test.
|
||||
|
|
Загрузка…
Ссылка в новой задаче