Commit 4d10d214 authored by magjed's avatar magjed Committed by Commit Bot

Reland of RTCVideoEncoder: Report H264 profile information to WebRTC (patchset...

Reland of RTCVideoEncoder: Report H264 profile information to WebRTC (patchset #1 id:1 of https://codereview.chromium.org/2973253002/ )

Reason for revert:
Update test to still use HW version of H264.

Original issue's description:
> Revert of TCVideoEncoder: Report H264 profile information to WebRTC (patchset #1 id:190001 of https://codereview.chromium.org/2548443002/ )
>
> Reason for revert:
> Reverting this since it's causing multiple perf regression on mac, looks like HW encode/decode might get disabled.
>
> Original issue's description:
> > Reland of RTCVideoEncoder: Report H264 profile information to WebRTC (patchset #1 id:1 of https://codereview.chromium.org/2521923002/ )
> >
> > Reason for revert:
> > Try again.
> >
> > Original issue's description:
> > > Revert of RTCVideoEncoder: Report H264 profile information to WebRTC (patchset #3 id:60001 of https://codereview.chromium.org/2499973002/ )
> > >
> > > Reason for revert:
> > > Causes these tests to fail on chromium.webrtc bots for Win and Mac:
> > > WebRtcPerfBrowserTest.MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsH264
> > > WebRtcVideoQualityBrowserTests/WebRtcVideoQualityBrowserTest.MANUAL_TestVideoQualityH264
> > > https://build.chromium.org/p/chromium.webrtc/builders/Win8%20Tester/builds/30367
> > > https://build.chromium.org/p/chromium.webrtc/builders/Mac%20Tester/builds/62661
> > >
> > > Original issue's description:
> > > > RTCVideoEncoder: Report H264 profile information to WebRTC
> > > >
> > > > This CL updates RTCVideoEncoderFactory to report cricket::VideoCodecs
> > > > instead of WebRtcVideoEncoderFactory::VideoCodecs. The H264 profile
> > > > information is added to the cricket::VideoCodec so that WebRTC receives
> > > > this information. Also, the mapping between media::VideoCodecProfiles
> > > > and cricket::VideoCodecs is cached so that we can send the
> > > > media::VideoCodecProfile to RTCVideoEncoder instead of having to deal
> > > > with webrtc::VideoCodecType.
> > > >
> > > > BUG=webrtc:6337
> > > >
> > > > Committed: https://crrev.com/510eddede44cb4b67c8f17fdd68cefb780a668c5
> > > > Cr-Commit-Position: refs/heads/master@{#433508}
> > >
> > > TBR=emircan@chromium.org,posciak@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:6337
> > >
> > > Committed: https://crrev.com/c2564bc627cb950b124ac8e41bc5fd3187f7ad9c
> > > Cr-Commit-Position: refs/heads/master@{#433828}
> >
> > TBR=emircan@chromium.org,posciak@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=688541,735959
> >
> > Review-Url: https://codereview.chromium.org/2548443002
> > Cr-Commit-Position: refs/heads/master@{#484874}
> > Committed: https://chromium.googlesource.com/chromium/src/+/829b1d57525c3c6549d18a2c85a96527d59ea5e9
>
> TBR=emircan@chromium.org,magjed@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=688541,735959
>
> Review-Url: https://codereview.chromium.org/2973253002
> Cr-Commit-Position: refs/heads/master@{#484960}
> Committed: https://chromium.googlesource.com/chromium/src/+/df6e5a5c7e7c665603f9619930a1d7106b55160d

TBR=emircan@chromium.org,niklase@chromium.org,phoglund@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=688541,735959

Review-Url: https://codereview.chromium.org/2985263002
Cr-Commit-Position: refs/heads/master@{#491338}
parent 507ddcc2
...@@ -52,6 +52,7 @@ class WebRtcBrowserTest : public WebRtcTestBase { ...@@ -52,6 +52,7 @@ class WebRtcBrowserTest : public WebRtcTestBase {
void RunsAudioVideoWebRTCCallInTwoTabs( void RunsAudioVideoWebRTCCallInTwoTabs(
const std::string& video_codec = WebRtcTestBase::kUseDefaultVideoCodec, const std::string& video_codec = WebRtcTestBase::kUseDefaultVideoCodec,
bool prefer_hw_video_codec = false,
const std::string& offer_cert_keygen_alg = const std::string& offer_cert_keygen_alg =
WebRtcTestBase::kUseDefaultCertKeygen, WebRtcTestBase::kUseDefaultCertKeygen,
const std::string& answer_cert_keygen_alg = const std::string& answer_cert_keygen_alg =
...@@ -62,8 +63,8 @@ class WebRtcBrowserTest : public WebRtcTestBase { ...@@ -62,8 +63,8 @@ class WebRtcBrowserTest : public WebRtcTestBase {
SetupPeerconnectionWithLocalStream(right_tab_, answer_cert_keygen_alg); SetupPeerconnectionWithLocalStream(right_tab_, answer_cert_keygen_alg);
if (!video_codec.empty()) { if (!video_codec.empty()) {
SetDefaultVideoCodec(left_tab_, video_codec); SetDefaultVideoCodec(left_tab_, video_codec, prefer_hw_video_codec);
SetDefaultVideoCodec(right_tab_, video_codec); SetDefaultVideoCodec(right_tab_, video_codec, prefer_hw_video_codec);
} }
NegotiateCall(left_tab_, right_tab_); NegotiateCall(left_tab_, right_tab_);
...@@ -137,7 +138,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, ...@@ -137,7 +138,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
"(test \"OK\")"; "(test \"OK\")";
return; return;
} }
RunsAudioVideoWebRTCCallInTwoTabs("H264"); RunsAudioVideoWebRTCCallInTwoTabs("H264", true /* prefer_hw_video_codec */);
} }
#endif // BUILDFLAG(RTC_USE_H264) #endif // BUILDFLAG(RTC_USE_H264)
...@@ -160,15 +161,15 @@ IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, TestWebAudioMediaStream) { ...@@ -160,15 +161,15 @@ IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, TestWebAudioMediaStream) {
IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerRsa) { RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerRsa) {
RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec,
kKeygenAlgorithmRsa, false /* prefer_hw_video_codec */,
kKeygenAlgorithmRsa); kKeygenAlgorithmRsa, kKeygenAlgorithmRsa);
} }
IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerEcdsa) { RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerEcdsa) {
RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, RunsAudioVideoWebRTCCallInTwoTabs(
kKeygenAlgorithmEcdsa, WebRtcTestBase::kUseDefaultVideoCodec, false /* prefer_hw_video_codec */,
kKeygenAlgorithmEcdsa); kKeygenAlgorithmEcdsa, kKeygenAlgorithmEcdsa);
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
...@@ -186,15 +187,15 @@ IN_PROC_BROWSER_TEST_F( ...@@ -186,15 +187,15 @@ IN_PROC_BROWSER_TEST_F(
IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerEcdsa) { RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerEcdsa) {
RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec,
kKeygenAlgorithmRsa, false /* prefer_hw_video_codec */,
kKeygenAlgorithmEcdsa); kKeygenAlgorithmRsa, kKeygenAlgorithmEcdsa);
} }
IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerRsa) { RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerRsa) {
RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec,
kKeygenAlgorithmEcdsa, false /* prefer_hw_video_codec */,
kKeygenAlgorithmRsa); kKeygenAlgorithmEcdsa, kKeygenAlgorithmRsa);
} }
IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
......
...@@ -559,11 +559,13 @@ void WebRtcTestBase::SetDefaultAudioCodec( ...@@ -559,11 +559,13 @@ void WebRtcTestBase::SetDefaultAudioCodec(
"setDefaultAudioCodec('" + audio_codec + "')", tab)); "setDefaultAudioCodec('" + audio_codec + "')", tab));
} }
void WebRtcTestBase::SetDefaultVideoCodec( void WebRtcTestBase::SetDefaultVideoCodec(content::WebContents* tab,
content::WebContents* tab, const std::string& video_codec,
const std::string& video_codec) const { bool prefer_hw_codec) const {
EXPECT_EQ("ok", ExecuteJavascript( EXPECT_EQ("ok",
"setDefaultVideoCodec('" + video_codec + "')", tab)); ExecuteJavascript("setDefaultVideoCodec('" + video_codec + "'," +
(prefer_hw_codec ? "true" : "false") + ")",
tab));
} }
void WebRtcTestBase::EnableOpusDtx(content::WebContents* tab) const { void WebRtcTestBase::EnableOpusDtx(content::WebContents* tab) const {
......
...@@ -193,8 +193,13 @@ class WebRtcTestBase : public InProcessBrowserTest { ...@@ -193,8 +193,13 @@ class WebRtcTestBase : public InProcessBrowserTest {
// Change the default audio/video codec in the offer SDP. // Change the default audio/video codec in the offer SDP.
void SetDefaultAudioCodec(content::WebContents* tab, void SetDefaultAudioCodec(content::WebContents* tab,
const std::string& audio_codec) const; const std::string& audio_codec) const;
// |prefer_hw_codec| controls if the first or last codec with name
// |video_codec| should be selected. External video codecs are currently at
// the end of the SDP list. This parameter only matters if there are multiple
// codecs with the same name, which can be the case for H264.
void SetDefaultVideoCodec(content::WebContents* tab, void SetDefaultVideoCodec(content::WebContents* tab,
const std::string& video_codec) const; const std::string& video_codec,
bool prefer_hw_codec = false) const;
// Add 'usedtx=1' to the offer SDP. // Add 'usedtx=1' to the offer SDP.
void EnableOpusDtx(content::WebContents* tab) const; void EnableOpusDtx(content::WebContents* tab) const;
......
...@@ -114,7 +114,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase { ...@@ -114,7 +114,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase {
} }
void RunsAudioVideoCall60SecsAndLogsInternalMetrics( void RunsAudioVideoCall60SecsAndLogsInternalMetrics(
const std::string& video_codec) { const std::string& video_codec,
bool prefer_hw_video_codec) {
ASSERT_TRUE(test::HasReferenceFilesInCheckout()); ASSERT_TRUE(test::HasReferenceFilesInCheckout());
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
...@@ -131,8 +132,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase { ...@@ -131,8 +132,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase {
SetupPeerconnectionWithLocalStream(right_tab); SetupPeerconnectionWithLocalStream(right_tab);
if (!video_codec.empty()) { if (!video_codec.empty()) {
SetDefaultVideoCodec(left_tab, video_codec); SetDefaultVideoCodec(left_tab, video_codec, prefer_hw_video_codec);
SetDefaultVideoCodec(right_tab, video_codec); SetDefaultVideoCodec(right_tab, video_codec, prefer_hw_video_codec);
} }
NegotiateCall(left_tab, right_tab); NegotiateCall(left_tab, right_tab);
...@@ -179,8 +180,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase { ...@@ -179,8 +180,8 @@ class WebRtcInternalsPerfBrowserTest : public WebRtcTestBase {
SetupPeerconnectionWithoutLocalStream(right_tab); SetupPeerconnectionWithoutLocalStream(right_tab);
if (!video_codec.empty()) { if (!video_codec.empty()) {
SetDefaultVideoCodec(left_tab, video_codec); SetDefaultVideoCodec(left_tab, video_codec, false /* prefer_hw_codec */);
SetDefaultVideoCodec(right_tab, video_codec); SetDefaultVideoCodec(right_tab, video_codec, false /* prefer_hw_codec */);
} }
if (opus_dtx) { if (opus_dtx) {
EnableOpusDtx(left_tab); EnableOpusDtx(left_tab);
...@@ -228,14 +229,16 @@ IN_PROC_BROWSER_TEST_F( ...@@ -228,14 +229,16 @@ IN_PROC_BROWSER_TEST_F(
WebRtcInternalsPerfBrowserTest, WebRtcInternalsPerfBrowserTest,
MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp8) { MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp8) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioVideoCall60SecsAndLogsInternalMetrics("VP8"); RunsAudioVideoCall60SecsAndLogsInternalMetrics(
"VP8", false /* prefer_hw_video_codec */);
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcInternalsPerfBrowserTest, WebRtcInternalsPerfBrowserTest,
MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp9) { MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetricsVp9) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioVideoCall60SecsAndLogsInternalMetrics("VP9"); RunsAudioVideoCall60SecsAndLogsInternalMetrics(
"VP9", false /* prefer_hw_video_codec */);
} }
#if BUILDFLAG(RTC_USE_H264) #if BUILDFLAG(RTC_USE_H264)
...@@ -252,7 +255,8 @@ IN_PROC_BROWSER_TEST_F( ...@@ -252,7 +255,8 @@ IN_PROC_BROWSER_TEST_F(
"\"OK\")"; "\"OK\")";
return; return;
} }
RunsAudioVideoCall60SecsAndLogsInternalMetrics("H264"); RunsAudioVideoCall60SecsAndLogsInternalMetrics(
"H264", true /* prefer_hw_video_codec */);
} }
#endif // BUILDFLAG(RTC_USE_H264) #endif // BUILDFLAG(RTC_USE_H264)
......
...@@ -88,7 +88,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase { ...@@ -88,7 +88,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase {
} }
void StartCall(const std::string& audio_codec, void StartCall(const std::string& audio_codec,
const std::string& video_codec) { const std::string& video_codec,
bool prefer_hw_video_codec) {
ASSERT_TRUE(test::HasReferenceFilesInCheckout()); ASSERT_TRUE(test::HasReferenceFilesInCheckout());
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
...@@ -103,8 +104,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase { ...@@ -103,8 +104,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase {
SetupPeerconnectionWithLocalStream(right_tab_); SetupPeerconnectionWithLocalStream(right_tab_);
SetDefaultAudioCodec(left_tab_, audio_codec); SetDefaultAudioCodec(left_tab_, audio_codec);
SetDefaultAudioCodec(right_tab_, audio_codec); SetDefaultAudioCodec(right_tab_, audio_codec);
SetDefaultVideoCodec(left_tab_, video_codec); SetDefaultVideoCodec(left_tab_, video_codec, prefer_hw_video_codec);
SetDefaultVideoCodec(right_tab_, video_codec); SetDefaultVideoCodec(right_tab_, video_codec, prefer_hw_video_codec);
CreateDataChannel(left_tab_, "data"); CreateDataChannel(left_tab_, "data");
CreateDataChannel(right_tab_, "data"); CreateDataChannel(right_tab_, "data");
NegotiateCall(left_tab_, right_tab_); NegotiateCall(left_tab_, right_tab_);
...@@ -121,9 +122,23 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase { ...@@ -121,9 +122,23 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase {
HangUp(right_tab_); HangUp(right_tab_);
} }
void RunsAudioAndVideoCallCollectingMetrics( void RunsAudioAndVideoCallCollectingMetricsWithAudioCodec(
const std::string& audio_codec, const std::string& video_codec) { const std::string& audio_codec) {
StartCall(audio_codec, video_codec); RunsAudioAndVideoCallCollectingMetrics(audio_codec, kUseDefaultVideoCodec,
false /* prefer_hw_video_codec */);
}
void RunsAudioAndVideoCallCollectingMetricsWithVideoCodec(
const std::string& video_codec,
bool prefer_hw_video_codec) {
RunsAudioAndVideoCallCollectingMetrics(kUseDefaultAudioCodec, video_codec,
prefer_hw_video_codec);
}
void RunsAudioAndVideoCallCollectingMetrics(const std::string& audio_codec,
const std::string& video_codec,
bool prefer_hw_video_codec) {
StartCall(audio_codec, video_codec, prefer_hw_video_codec);
// Call for 60 seconds so that values may stabilize, bandwidth ramp up, etc. // Call for 60 seconds so that values may stabilize, bandwidth ramp up, etc.
test::SleepInJavascript(left_tab_, 60000); test::SleepInJavascript(left_tab_, 60000);
...@@ -199,7 +214,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase { ...@@ -199,7 +214,8 @@ class WebRtcStatsPerfBrowserTest : public WebRtcTestBase {
GetStatsVariation variation) { GetStatsVariation variation) {
EXPECT_TRUE(base::TimeTicks::IsHighResolution()); EXPECT_TRUE(base::TimeTicks::IsHighResolution());
StartCall(kUseDefaultAudioCodec, kUseDefaultVideoCodec); StartCall(kUseDefaultAudioCodec, kUseDefaultVideoCodec,
false /* prefer_hw_video_codec */);
double invocation_time = 0.0; double invocation_time = 0.0;
switch (variation) { switch (variation) {
...@@ -234,49 +250,51 @@ IN_PROC_BROWSER_TEST_F( ...@@ -234,49 +250,51 @@ IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_opus) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_opus) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics("opus", kUseDefaultVideoCodec); RunsAudioAndVideoCallCollectingMetricsWithAudioCodec("opus");
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_ISAC) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_ISAC) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics("ISAC", kUseDefaultVideoCodec); RunsAudioAndVideoCallCollectingMetricsWithAudioCodec("ISAC");
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_G722) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_G722) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics("G722", kUseDefaultVideoCodec); RunsAudioAndVideoCallCollectingMetricsWithAudioCodec("G722");
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_PCMU) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_PCMU) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics("PCMU", kUseDefaultVideoCodec); RunsAudioAndVideoCallCollectingMetricsWithAudioCodec("PCMU");
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_PCMA) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_AudioCodec_PCMA) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics("PCMA", kUseDefaultVideoCodec); RunsAudioAndVideoCallCollectingMetricsWithAudioCodec("PCMA");
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_VideoCodec_VP8) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_VideoCodec_VP8) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics(kUseDefaultAudioCodec, "VP8"); RunsAudioAndVideoCallCollectingMetricsWithVideoCodec(
"VP8", false /* prefer_hw_video_codec */);
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
WebRtcStatsPerfBrowserTest, WebRtcStatsPerfBrowserTest,
MANUAL_RunsAudioAndVideoCallCollectingMetrics_VideoCodec_VP9) { MANUAL_RunsAudioAndVideoCallCollectingMetrics_VideoCodec_VP9) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
RunsAudioAndVideoCallCollectingMetrics(kUseDefaultAudioCodec, "VP9"); RunsAudioAndVideoCallCollectingMetricsWithVideoCodec(
"VP9", false /* prefer_hw_video_codec */);
} }
#if BUILDFLAG(RTC_USE_H264) #if BUILDFLAG(RTC_USE_H264)
...@@ -293,7 +311,8 @@ IN_PROC_BROWSER_TEST_F( ...@@ -293,7 +311,8 @@ IN_PROC_BROWSER_TEST_F(
"\"OK\")"; "\"OK\")";
return; return;
} }
RunsAudioAndVideoCallCollectingMetrics(kUseDefaultAudioCodec, "H264"); RunsAudioAndVideoCallCollectingMetricsWithVideoCodec(
"H264", true /* prefer_hw_video_codec */);
} }
#endif // BUILDFLAG(RTC_USE_H264) #endif // BUILDFLAG(RTC_USE_H264)
......
...@@ -259,7 +259,8 @@ class WebRtcVideoQualityBrowserTest : public WebRtcTestBase, ...@@ -259,7 +259,8 @@ class WebRtcVideoQualityBrowserTest : public WebRtcTestBase,
return true; return true;
} }
void TestVideoQuality(const std::string& video_codec) { void TestVideoQuality(const std::string& video_codec,
bool prefer_hw_video_codec) {
ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 150) ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 150)
<< "This is a long-running test; you must specify " << "This is a long-running test; you must specify "
"--ui-test-action-max-timeout to have a value of at least 150000."; "--ui-test-action-max-timeout to have a value of at least 150000.";
...@@ -279,8 +280,8 @@ class WebRtcVideoQualityBrowserTest : public WebRtcTestBase, ...@@ -279,8 +280,8 @@ class WebRtcVideoQualityBrowserTest : public WebRtcTestBase,
SetupPeerconnectionWithLocalStream(right_tab); SetupPeerconnectionWithLocalStream(right_tab);
if (!video_codec.empty()) { if (!video_codec.empty()) {
SetDefaultVideoCodec(left_tab, video_codec); SetDefaultVideoCodec(left_tab, video_codec, prefer_hw_video_codec);
SetDefaultVideoCodec(right_tab, video_codec); SetDefaultVideoCodec(right_tab, video_codec, prefer_hw_video_codec);
} }
NegotiateCall(left_tab, right_tab); NegotiateCall(left_tab, right_tab);
...@@ -346,13 +347,13 @@ INSTANTIATE_TEST_CASE_P( ...@@ -346,13 +347,13 @@ INSTANTIATE_TEST_CASE_P(
IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
MANUAL_TestVideoQualityVp8) { MANUAL_TestVideoQualityVp8) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
TestVideoQuality("VP8"); TestVideoQuality("VP8", false /* prefer_hw_video_codec */);
} }
IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
MANUAL_TestVideoQualityVp9) { MANUAL_TestVideoQualityVp9) {
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
TestVideoQuality("VP9"); TestVideoQuality("VP9", false /* prefer_hw_video_codec */);
} }
#if BUILDFLAG(RTC_USE_H264) #if BUILDFLAG(RTC_USE_H264)
...@@ -367,7 +368,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, ...@@ -367,7 +368,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest,
"(test \"OK\")"; "(test \"OK\")";
return; return;
} }
TestVideoQuality("H264"); TestVideoQuality("H264", true /* prefer_hw_video_codec */);
} }
#endif // BUILDFLAG(RTC_USE_H264) #endif // BUILDFLAG(RTC_USE_H264)
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
* See |setSdpDefaultCodec|. * See |setSdpDefaultCodec|.
*/ */
function setSdpDefaultAudioCodec(sdp, codec) { function setSdpDefaultAudioCodec(sdp, codec) {
return setSdpDefaultCodec(sdp, 'audio', codec); return setSdpDefaultCodec(sdp, 'audio', codec, false /* preferHwCodec */);
} }
/** /**
* See |setSdpDefaultCodec|. * See |setSdpDefaultCodec|.
*/ */
function setSdpDefaultVideoCodec(sdp, codec) { function setSdpDefaultVideoCodec(sdp, codec, preferHwCodec) {
return setSdpDefaultCodec(sdp, 'video', codec); return setSdpDefaultCodec(sdp, 'video', codec, preferHwCodec);
} }
/** /**
...@@ -55,14 +55,17 @@ function setOpusDtxEnabled(sdp) { ...@@ -55,14 +55,17 @@ function setOpusDtxEnabled(sdp) {
/** /**
* Returns a modified version of |sdp| where the |codec| has been promoted to be * Returns a modified version of |sdp| where the |codec| has been promoted to be
* the default codec, i.e. the codec whose ID is first in the list of codecs on * the default codec, i.e. the codec whose ID is first in the list of codecs on
* the 'm=|type|' line, where |type| is 'audio' or 'video'. * the 'm=|type|' line, where |type| is 'audio' or 'video'. If |preferHwCodec|
* is true, it will select the last codec with the given name, and if false, it
* will select the first codec with the given name, because HW codecs are listed
* after SW codecs in the SDP list.
* @private * @private
*/ */
function setSdpDefaultCodec(sdp, type, codec) { function setSdpDefaultCodec(sdp, type, codec, preferHwCodec) {
var sdpLines = splitSdpLines(sdp); var sdpLines = splitSdpLines(sdp);
// Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'. // Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'.
var codecId = findRtpmapId(sdpLines, codec); var codecId = findRtpmapId(sdpLines, codec, preferHwCodec);
if (codecId === null) { if (codecId === null) {
failure('setSdpDefaultCodec', failure('setSdpDefaultCodec',
'Unknown ID for |codec| = \'' + codec + '\'.'); 'Unknown ID for |codec| = \'' + codec + '\'.');
...@@ -129,13 +132,15 @@ function getSdpDefaultCodec(sdp, type) { ...@@ -129,13 +132,15 @@ function getSdpDefaultCodec(sdp, type) {
/** /**
* Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of
* the specified name, returning its ID as an int if found, or null otherwise. * the specified name, returning its ID as an int if found, or null otherwise.
* |codec| is the case-sensitive name of the codec. * |codec| is the case-sensitive name of the codec. If |lastInstance|
* is true, it will return the last such ID, and if false, it will return the
* first such ID.
* For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is
* 'VP8', this function returns 100. * 'VP8', this function returns 100.
* @private * @private
*/ */
function findRtpmapId(sdpLines, codec) { function findRtpmapId(sdpLines, codec, lastInstance) {
var lineNo = findRtpmapLine(sdpLines, codec); var lineNo = findRtpmapLine(sdpLines, codec, lastInstance);
if (lineNo === null) if (lineNo === null)
return null; return null;
// Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'. // Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'.
...@@ -163,27 +168,45 @@ function findRtpmapCodec(sdpLines, id) { ...@@ -163,27 +168,45 @@ function findRtpmapCodec(sdpLines, id) {
} }
/** /**
* Finds the first 'a=rtpmap:' line from |sdpLines| that contains |contains| and * Finds a 'a=rtpmap:' line from |sdpLines| that contains |contains| and returns
* returns its line index, or null if no such line was found. |contains| may be * its line index, or null if no such line was found. |contains| may be the
* the codec ID, codec name or bitrate. An 'a=rtpmap:' line looks like this: * codec ID, codec name or bitrate. If |lastInstance| is true, it will return
* 'a=rtpmap:<id> <codec>/<rate>'. * the last such line index, and if false, it will return the first such line
* index.
* An 'a=rtpmap:' line looks like this: 'a=rtpmap:<id> <codec>/<rate>'.
*/ */
function findRtpmapLine(sdpLines, contains) { function findRtpmapLine(sdpLines, contains, lastInstance) {
for (var i = 0; i < sdpLines.length; i++) { if (lastInstance === true) {
// Is 'a=rtpmap:' line containing |contains| string? for (var i = sdpLines.length - 1; i >= 0 ; i--) {
if (sdpLines[i].startsWith('a=rtpmap:') && if (isRtpmapLine(sdpLines[i], contains))
sdpLines[i].indexOf(contains) != -1) { return i;
// Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'. }
var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); } else {
if (!sdpLines[i].match(pattern)) for (var i = 0; i < sdpLines.length; i++) {
failure('findRtpmapLine', 'Unexpected "a=rtpmap:" pattern.'); if (isRtpmapLine(sdpLines[i], contains))
// Return line index. return i;
return i;
} }
} }
return null; return null;
} }
/**
* Returns true if |sdpLine| contains |contains| and is of pattern
* 'a=rtpmap:<id> <codec>/<rate>'.
*/
function isRtpmapLine(sdpLine, contains) {
// Is 'a=rtpmap:' line containing |contains| string?
if (sdpLine.startsWith('a=rtpmap:') &&
sdpLine.indexOf(contains) != -1) {
// Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'.
var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
if (!sdpLine.match(pattern))
failure('isRtpmapLine', 'Unexpected "a=rtpmap:" pattern.');
return true;
}
return false;
}
/** /**
* Finds the fmtp line in |sdpLines| for the given |codecId|, and returns its * Finds the fmtp line in |sdpLines| for the given |codecId|, and returns its
* line number. The line starts with 'a=fmtp:<codecId>'. * line number. The line starts with 'a=fmtp:<codecId>'.
......
...@@ -40,6 +40,12 @@ var gDefaultAudioCodec = null; ...@@ -40,6 +40,12 @@ var gDefaultAudioCodec = null;
*/ */
var gDefaultVideoCodec = null; var gDefaultVideoCodec = null;
/**
* Flag to indicate if HW or SW video codec is preferred.
* @private
*/
var gDefaultPreferHwVideoCodec = null;
/** /**
* Flag to indicate if Opus Dtx should be enabled. * Flag to indicate if Opus Dtx should be enabled.
* @private * @private
...@@ -122,9 +128,14 @@ function setDefaultAudioCodec(audioCodec) { ...@@ -122,9 +128,14 @@ function setDefaultAudioCodec(audioCodec) {
* video codec, e.g. the first one in the list on the 'm=video' SDP offer * video codec, e.g. the first one in the list on the 'm=video' SDP offer
* line. |videoCodec| is the case-sensitive codec name, e.g. 'VP8' or * line. |videoCodec| is the case-sensitive codec name, e.g. 'VP8' or
* 'H264'. * 'H264'.
* @param {bool} preferHwVideoCodec specifies what codec to use from the
* 'm=video' line when there are multiple codecs with the name |videoCodec|.
* If true, it will return the last codec with that name, and if false, it
* will return the first codec with that name.
*/ */
function setDefaultVideoCodec(videoCodec) { function setDefaultVideoCodec(videoCodec, preferHwVideoCodec) {
gDefaultVideoCodec = videoCodec; gDefaultVideoCodec = videoCodec;
gDefaultPreferHwVideoCodec = preferHwVideoCodec;
returnToTest('ok'); returnToTest('ok');
} }
...@@ -156,7 +167,8 @@ function createLocalOffer(constraints) { ...@@ -156,7 +167,8 @@ function createLocalOffer(constraints) {
} }
if (gDefaultVideoCodec !== null) { if (gDefaultVideoCodec !== null) {
localOffer.sdp = setSdpDefaultVideoCodec(localOffer.sdp, localOffer.sdp = setSdpDefaultVideoCodec(localOffer.sdp,
gDefaultVideoCodec); gDefaultVideoCodec,
gDefaultPreferHwVideoCodec);
} }
if (gOpusDtx) { if (gOpusDtx) {
localOffer.sdp = setOpusDtxEnabled(localOffer.sdp); localOffer.sdp = setOpusDtxEnabled(localOffer.sdp);
......
...@@ -775,6 +775,7 @@ target(link_target_type, "renderer") { ...@@ -775,6 +775,7 @@ target(link_target_type, "renderer") {
"//third_party/webrtc/api:video_frame_api", "//third_party/webrtc/api:video_frame_api",
"//third_party/webrtc/api/audio_codecs:builtin_audio_decoder_factory", "//third_party/webrtc/api/audio_codecs:builtin_audio_decoder_factory",
"//third_party/webrtc/api/audio_codecs:builtin_audio_encoder_factory", "//third_party/webrtc/api/audio_codecs:builtin_audio_encoder_factory",
"//third_party/webrtc/common_video:common_video",
"//third_party/webrtc/media:rtc_media", "//third_party/webrtc/media:rtc_media",
"//third_party/webrtc/media:rtc_media_base", "//third_party/webrtc/media:rtc_media_base",
"//third_party/webrtc/modules/audio_device", "//third_party/webrtc/modules/audio_device",
......
...@@ -47,25 +47,16 @@ struct RTCTimestamps { ...@@ -47,25 +47,16 @@ struct RTCTimestamps {
DISALLOW_IMPLICIT_CONSTRUCTORS(RTCTimestamps); DISALLOW_IMPLICIT_CONSTRUCTORS(RTCTimestamps);
}; };
// Translate from webrtc::VideoCodecType and webrtc::VideoCodec to webrtc::VideoCodecType ProfileToWebRtcVideoCodecType(
// media::VideoCodecProfile. media::VideoCodecProfile profile) {
media::VideoCodecProfile WebRTCVideoCodecToVideoCodecProfile( if (profile >= media::VP8PROFILE_MIN && profile <= media::VP8PROFILE_MAX) {
webrtc::VideoCodecType type, return webrtc::kVideoCodecVP8;
const webrtc::VideoCodec* codec_settings) { } else if (profile >= media::H264PROFILE_MIN &&
DCHECK_EQ(type, codec_settings->codecType); profile <= media::H264PROFILE_MAX) {
switch (type) { return webrtc::kVideoCodecH264;
case webrtc::kVideoCodecVP8:
return media::VP8PROFILE_ANY;
case webrtc::kVideoCodecVP9:
return media::VP9PROFILE_MIN;
case webrtc::kVideoCodecH264:
// TODO(magjed): WebRTC is only using Baseline profile for now. Update
// once http://crbug/webrtc/6337 is fixed.
return media::H264PROFILE_BASELINE;
default:
NOTREACHED() << "Unrecognized video codec type";
return media::VIDEO_CODEC_PROFILE_UNKNOWN;
} }
NOTREACHED() << "Invalid profile " << GetProfileName(profile);
return webrtc::kVideoCodecUnknown;
} }
// Populates struct webrtc::RTPFragmentationHeader for H264 codec. // Populates struct webrtc::RTPFragmentationHeader for H264 codec.
...@@ -798,12 +789,12 @@ void RTCVideoEncoder::Impl::ReturnEncodedImage( ...@@ -798,12 +789,12 @@ void RTCVideoEncoder::Impl::ReturnEncodedImage(
} }
RTCVideoEncoder::RTCVideoEncoder( RTCVideoEncoder::RTCVideoEncoder(
webrtc::VideoCodecType type, media::VideoCodecProfile profile,
media::GpuVideoAcceleratorFactories* gpu_factories) media::GpuVideoAcceleratorFactories* gpu_factories)
: video_codec_type_(type), : profile_(profile),
gpu_factories_(gpu_factories), gpu_factories_(gpu_factories),
gpu_task_runner_(gpu_factories->GetTaskRunner()) { gpu_task_runner_(gpu_factories->GetTaskRunner()) {
DVLOG(1) << __func__ << " codec type=" << type; DVLOG(1) << "RTCVideoEncoder(): profile=" << GetProfileName(profile);
} }
RTCVideoEncoder::~RTCVideoEncoder() { RTCVideoEncoder::~RTCVideoEncoder() {
...@@ -822,9 +813,7 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, ...@@ -822,9 +813,7 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
if (impl_) if (impl_)
Release(); Release();
impl_ = new Impl(gpu_factories_, video_codec_type_); impl_ = new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_));
const media::VideoCodecProfile profile = WebRTCVideoCodecToVideoCodecProfile(
impl_->video_codec_type(), codec_settings);
base::WaitableEvent initialization_waiter( base::WaitableEvent initialization_waiter(
base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::ResetPolicy::MANUAL,
...@@ -832,17 +821,14 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, ...@@ -832,17 +821,14 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
gpu_task_runner_->PostTask( gpu_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, impl_,
impl_,
gfx::Size(codec_settings->width, codec_settings->height), gfx::Size(codec_settings->width, codec_settings->height),
codec_settings->startBitrate, codec_settings->startBitrate, profile_, &initialization_waiter,
profile,
&initialization_waiter,
&initialization_retval)); &initialization_retval));
// webrtc::VideoEncoder expects this call to be synchronous. // webrtc::VideoEncoder expects this call to be synchronous.
initialization_waiter.Wait(); initialization_waiter.Wait();
RecordInitEncodeUMA(initialization_retval, profile); RecordInitEncodeUMA(initialization_retval, profile_);
return initialization_retval; return initialization_retval;
} }
......
...@@ -41,7 +41,7 @@ namespace content { ...@@ -41,7 +41,7 @@ namespace content {
class CONTENT_EXPORT RTCVideoEncoder class CONTENT_EXPORT RTCVideoEncoder
: NON_EXPORTED_BASE(public webrtc::VideoEncoder) { : NON_EXPORTED_BASE(public webrtc::VideoEncoder) {
public: public:
RTCVideoEncoder(webrtc::VideoCodecType type, RTCVideoEncoder(media::VideoCodecProfile profile,
media::GpuVideoAcceleratorFactories* gpu_factories); media::GpuVideoAcceleratorFactories* gpu_factories);
~RTCVideoEncoder() override; ~RTCVideoEncoder() override;
...@@ -65,8 +65,7 @@ class CONTENT_EXPORT RTCVideoEncoder ...@@ -65,8 +65,7 @@ class CONTENT_EXPORT RTCVideoEncoder
class Impl; class Impl;
friend class RTCVideoEncoder::Impl; friend class RTCVideoEncoder::Impl;
// The video codec type, as reported to WebRTC. const media::VideoCodecProfile profile_;
const webrtc::VideoCodecType video_codec_type_;
// Factory for creating VEAs, shared memory buffers, etc. // Factory for creating VEAs, shared memory buffers, etc.
media::GpuVideoAcceleratorFactories* gpu_factories_; media::GpuVideoAcceleratorFactories* gpu_factories_;
......
...@@ -11,23 +11,23 @@ ...@@ -11,23 +11,23 @@
#include "content/renderer/media/gpu/rtc_video_encoder.h" #include "content/renderer/media/gpu/rtc_video_encoder.h"
#include "media/gpu/ipc/client/gpu_video_encode_accelerator_host.h" #include "media/gpu/ipc/client/gpu_video_encode_accelerator_host.h"
#include "media/renderers/gpu_video_accelerator_factories.h" #include "media/renderers/gpu_video_accelerator_factories.h"
#include "media/video/video_encode_accelerator.h" #include "third_party/webrtc/common_video/h264/profile_level_id.h"
namespace content { namespace content {
namespace { namespace {
// Translate from media::VideoEncodeAccelerator::SupportedProfile to // Translate from media::VideoEncodeAccelerator::SupportedProfile to
// one or more instances of cricket::WebRtcVideoEncoderFactory::VideoCodec // cricket::WebRtcVideoEncoderFactory::VideoCodec, or return nothing if the
void VEAToWebRTCCodecs( // profile isn't supported.
std::vector<cricket::VideoCodec>* codecs, base::Optional<cricket::VideoCodec> VEAToWebRTCCodec(
const media::VideoEncodeAccelerator::SupportedProfile& profile) { const media::VideoEncodeAccelerator::SupportedProfile& profile) {
DCHECK_EQ(profile.max_framerate_denominator, 1U); DCHECK_EQ(profile.max_framerate_denominator, 1U);
if (profile.profile >= media::VP8PROFILE_MIN && if (profile.profile >= media::VP8PROFILE_MIN &&
profile.profile <= media::VP8PROFILE_MAX) { profile.profile <= media::VP8PROFILE_MAX) {
if (base::FeatureList::IsEnabled(features::kWebRtcHWVP8Encoding)) { if (base::FeatureList::IsEnabled(features::kWebRtcHWVP8Encoding)) {
codecs->push_back(cricket::VideoCodec("VP8")); return base::Optional<cricket::VideoCodec>(cricket::VideoCodec("VP8"));
} }
} else if (profile.profile >= media::H264PROFILE_MIN && } else if (profile.profile >= media::H264PROFILE_MIN &&
profile.profile <= media::H264PROFILE_MAX) { profile.profile <= media::H264PROFILE_MAX) {
...@@ -41,10 +41,41 @@ void VEAToWebRTCCodecs( ...@@ -41,10 +41,41 @@ void VEAToWebRTCCodecs(
#endif // BUILDFLAG(RTC_USE_H264) && !defined(MEDIA_DISABLE_FFMPEG) #endif // BUILDFLAG(RTC_USE_H264) && !defined(MEDIA_DISABLE_FFMPEG)
if (webrtc_h264_sw_enabled || if (webrtc_h264_sw_enabled ||
base::FeatureList::IsEnabled(features::kWebRtcHWH264Encoding)) { base::FeatureList::IsEnabled(features::kWebRtcHWH264Encoding)) {
// TODO(magjed): Propagate H264 profile information. webrtc::H264::Profile h264_profile;
codecs->push_back(cricket::VideoCodec("H264")); switch (profile.profile) {
case media::H264PROFILE_BASELINE:
h264_profile = webrtc::H264::kProfileBaseline;
break;
case media::H264PROFILE_MAIN:
h264_profile = webrtc::H264::kProfileMain;
break;
case media::H264PROFILE_HIGH:
h264_profile = webrtc::H264::kProfileHigh;
break;
default:
// Unsupported H264 profile in WebRTC.
return base::Optional<cricket::VideoCodec>();
}
const int width = profile.max_resolution.width();
const int height = profile.max_resolution.height();
const int fps = profile.max_framerate_numerator;
DCHECK_EQ(1u, profile.max_framerate_denominator);
const rtc::Optional<webrtc::H264::Level> h264_level =
webrtc::H264::SupportedLevel(width * height, fps);
const webrtc::H264::ProfileLevelId profile_level_id(
h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
cricket::VideoCodec codec("H264");
codec.SetParam(cricket::kH264FmtpProfileLevelId,
*webrtc::H264::ProfileLevelIdToString(profile_level_id));
codec.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
return base::Optional<cricket::VideoCodec>(codec);
} }
} }
return base::Optional<cricket::VideoCodec>();
} }
} // anonymous namespace } // anonymous namespace
...@@ -54,20 +85,36 @@ RTCVideoEncoderFactory::RTCVideoEncoderFactory( ...@@ -54,20 +85,36 @@ RTCVideoEncoderFactory::RTCVideoEncoderFactory(
: gpu_factories_(gpu_factories) { : gpu_factories_(gpu_factories) {
const media::VideoEncodeAccelerator::SupportedProfiles& profiles = const media::VideoEncodeAccelerator::SupportedProfiles& profiles =
gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles(); gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
for (const auto& profile : profiles) for (const auto& profile : profiles) {
VEAToWebRTCCodecs(&supported_codecs_, profile); base::Optional<cricket::VideoCodec> codec = VEAToWebRTCCodec(profile);
if (codec) {
supported_codecs_.push_back(std::move(*codec));
profiles_.push_back(profile.profile);
}
}
// There should be a 1:1 mapping between media::VideoCodecProfile and
// cricket::VideoCodec.
CHECK_EQ(profiles_.size(), supported_codecs_.size());
} }
RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {} RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {}
webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder( webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder(
const cricket::VideoCodec& codec) { const cricket::VideoCodec& codec) {
for (const cricket::VideoCodec& supported_codec : supported_codecs_) { for (size_t i = 0; i < supported_codecs_.size(); ++i) {
if (cricket::CodecNamesEq(codec.name, supported_codec.name)) { if (!cricket::CodecNamesEq(codec.name, supported_codecs_[i].name))
webrtc::VideoCodecType type = webrtc::PayloadNameToCodecType(codec.name) continue;
.value_or(webrtc::kVideoCodecUnknown); // Check H264 profile.
return new RTCVideoEncoder(type, gpu_factories_); using webrtc::H264::ParseSdpProfileLevelId;
if (cricket::CodecNamesEq(codec.name.c_str(), cricket::kH264CodecName) &&
ParseSdpProfileLevelId(codec.params)->profile !=
ParseSdpProfileLevelId(supported_codecs_[i].params)->profile) {
continue;
} }
// There should be a 1:1 mapping between media::VideoCodecProfile and
// cricket::VideoCodec.
CHECK_EQ(profiles_.size(), supported_codecs_.size());
return new RTCVideoEncoder(profiles_[i], gpu_factories_);
} }
return nullptr; return nullptr;
} }
......
...@@ -39,6 +39,9 @@ class CONTENT_EXPORT RTCVideoEncoderFactory ...@@ -39,6 +39,9 @@ class CONTENT_EXPORT RTCVideoEncoderFactory
media::GpuVideoAcceleratorFactories* gpu_factories_; media::GpuVideoAcceleratorFactories* gpu_factories_;
// List of supported cricket::WebRtcVideoEncoderFactory::VideoCodec. // List of supported cricket::WebRtcVideoEncoderFactory::VideoCodec.
// |profiles_| and |supported_codecs_| have the same length and the profile
// for |supported_codecs_[i]| is |profiles_[i]|.
std::vector<media::VideoCodecProfile> profiles_;
std::vector<cricket::VideoCodec> supported_codecs_; std::vector<cricket::VideoCodec> supported_codecs_;
DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory); DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory);
......
...@@ -113,7 +113,19 @@ class RTCVideoEncoderTest ...@@ -113,7 +113,19 @@ class RTCVideoEncoderTest
void CreateEncoder(webrtc::VideoCodecType codec_type) { void CreateEncoder(webrtc::VideoCodecType codec_type) {
DVLOG(3) << __func__; DVLOG(3) << __func__;
rtc_encoder_ = base::MakeUnique<RTCVideoEncoder>(codec_type, media::VideoCodecProfile media_profile;
switch (codec_type) {
case webrtc::kVideoCodecVP8:
media_profile = media::VP8PROFILE_ANY;
break;
case webrtc::kVideoCodecH264:
media_profile = media::H264PROFILE_BASELINE;
break;
default:
ADD_FAILURE() << "Unexpected codec type: " << codec_type;
media_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
}
rtc_encoder_ = base::MakeUnique<RTCVideoEncoder>(media_profile,
mock_gpu_factories_.get()); mock_gpu_factories_.get());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment