Adds use of SurfaceLayerBridge into WebMediaPlayerMS.
This CL allows for WebMediaPlayerMS to create a SurfaceLayerBridge and
interface with it in order to use a Surface for video playback.
Bug: 746182
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I39174499a7e659eeeef13a81f8f5679d5f73425a
Reviewed-on: https://chromium-review.googlesource.com/1087587
Reviewed-by: Frank Liberato <[email protected]>
Reviewed-by: Emircan Uysaler <[email protected]>
Commit-Queue: CJ DiMeglio <[email protected]>
Cr-Commit-Position: refs/heads/master@{#582346}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f055d73..0d3bdea 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2874,6 +2874,10 @@
flag_descriptions::kUseSurfaceLayerForVideoName,
flag_descriptions::kUseSurfaceLayerForVideoDescription, kOsAll,
FEATURE_VALUE_TYPE(media::kUseSurfaceLayerForVideo)},
+ {"enable-surfaces-for-videos-ms",
+ flag_descriptions::kUseSurfaceLayerForVideoMSName,
+ flag_descriptions::kUseSurfaceLayerForVideoMSDescription, kOsAll,
+ FEATURE_VALUE_TYPE(media::kUseSurfaceLayerForVideoMS)},
#if defined(OS_CHROMEOS)
{"quick-unlock-pin", flag_descriptions::kQuickUnlockPinName,
flag_descriptions::kQuickUnlockPinDescription, kOsCrOS,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 7202b08a9..5fb5141 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1159,6 +1159,11 @@
const char kUseSurfaceLayerForVideoDescription[] =
"Enable compositing onto a Surface instead of a VideoLayer "
"for videos.";
+const char kUseSurfaceLayerForVideoMSName[] =
+ "Enable the use of SurfaceLayer objects for media stream videos.";
+const char kUseSurfaceLayerForVideoMSDescription[] =
+ "Enable compositing onto a Surface instead of a VideoLayer "
+ "for media stream videos.";
const char kNewUsbBackendName[] = "Enable new USB backend";
const char kNewUsbBackendDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 129eaa9..7984625b 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -720,6 +720,9 @@
extern const char kUseSurfaceLayerForVideoName[];
extern const char kUseSurfaceLayerForVideoDescription[];
+extern const char kUseSurfaceLayerForVideoMSName[];
+extern const char kUseSurfaceLayerForVideoMSDescription[];
+
extern const char kNewUsbBackendName[];
extern const char kNewUsbBackendDescription[];
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc
index fe25c6b..a594229 100644
--- a/content/renderer/media/media_factory.cc
+++ b/content/renderer/media/media_factory.cc
@@ -153,6 +153,20 @@
features::IsAshInBrowserProcess();
}
+bool MediaFactory::VideoSurfaceLayerEnabledForMS() {
+ // LayoutTests do not support SurfaceLayer by default at the moment.
+ // See https://crbug.com/838128
+ content::RenderThreadImpl* render_thread =
+ content::RenderThreadImpl::current();
+ if (render_thread && render_thread->layout_test_mode() &&
+ !render_thread->LayoutTestModeUsesDisplayCompositorPixelDump()) {
+ return false;
+ }
+
+ return base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideoMS) &&
+ features::IsAshInBrowserProcess();
+}
+
MediaFactory::MediaFactory(
RenderFrameImpl* render_frame,
media::RequestRoutingTokenCallback request_routing_token_cb)
@@ -214,7 +228,7 @@
GetWebMediaStreamFromWebMediaPlayerSource(source);
if (!web_stream.IsNull())
return CreateWebMediaPlayerForMediaStream(client, sink_id, security_origin,
- web_frame);
+ web_frame, layer_tree_view);
// If |source| was not a MediaStream, it must be a URL.
// TODO(guidou): Fix this when support for other srcObject types is added.
@@ -507,7 +521,8 @@
blink::WebMediaPlayerClient* client,
const blink::WebString& sink_id,
const blink::WebSecurityOrigin& security_origin,
- blink::WebLocalFrame* frame) {
+ blink::WebLocalFrame* frame,
+ blink::WebLayerTreeView* layer_tree_view) {
RenderThreadImpl* const render_thread = RenderThreadImpl::current();
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
@@ -516,6 +531,7 @@
compositor_task_runner =
render_frame_->GetTaskRunner(blink::TaskType::kInternalMediaRealTime);
+ DCHECK(layer_tree_view);
return new WebMediaPlayerMS(
frame, client, GetWebMediaPlayerDelegate(),
std::make_unique<RenderMediaLog>(
@@ -524,7 +540,9 @@
CreateMediaStreamRendererFactory(), render_thread->GetIOTaskRunner(),
compositor_task_runner, render_thread->GetMediaThreadTaskRunner(),
render_thread->GetWorkerTaskRunner(), render_thread->GetGpuFactories(),
- sink_id);
+ sink_id,
+ base::BindOnce(&blink::WebSurfaceLayerBridge::Create, layer_tree_view),
+ VideoSurfaceLayerEnabledForMS());
}
media::RendererWebMediaPlayerDelegate*
diff --git a/content/renderer/media/media_factory.h b/content/renderer/media/media_factory.h
index 7c4ea97..bbb8837e 100644
--- a/content/renderer/media/media_factory.h
+++ b/content/renderer/media/media_factory.h
@@ -74,6 +74,10 @@
// Helper function returning whether VideoSurfaceLayer should be enabled.
static bool VideoSurfaceLayerEnabled();
+ // Helper function returning whether VideoSurfaceLayer should be enabled for
+ // MediaStreams.
+ static bool VideoSurfaceLayerEnabledForMS();
+
// Create a MediaFactory to assist the |render_frame| with media tasks.
// |request_routing_token_cb| bound to |render_frame| IPC functions for
// obtaining overlay tokens.
@@ -122,7 +126,8 @@
blink::WebMediaPlayerClient* client,
const blink::WebString& sink_id,
const blink::WebSecurityOrigin& security_origin,
- blink::WebLocalFrame* frame);
+ blink::WebLocalFrame* frame,
+ blink::WebLayerTreeView* layer_tree_view);
// Returns the media delegate for WebMediaPlayer usage. If
// |media_player_delegate_| is NULL, one is created.
diff --git a/content/renderer/media/stream/webmediaplayer_ms.cc b/content/renderer/media/stream/webmediaplayer_ms.cc
index bf6ffa5..d071c391 100644
--- a/content/renderer/media/stream/webmediaplayer_ms.cc
+++ b/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/public/platform/web_media_player_source.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/public/platform/web_surface_layer_bridge.h"
#include "third_party/blink/public/web/web_local_frame.h"
namespace {
@@ -262,7 +263,9 @@
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
scoped_refptr<base::TaskRunner> worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories,
- const blink::WebString& sink_id)
+ const blink::WebString& sink_id,
+ CreateSurfaceLayerBridgeCB create_bridge_callback,
+ bool surface_layer_for_video_enabled)
: frame_(frame),
network_state_(WebMediaPlayer::kNetworkStateEmpty),
ready_state_(WebMediaPlayer::kReadyStateHaveNothing),
@@ -282,7 +285,9 @@
initial_audio_output_device_id_(sink_id.Utf8()),
volume_(1.0),
volume_multiplier_(1.0),
- should_play_upon_shown_(false) {
+ should_play_upon_shown_(false),
+ create_bridge_callback_(std::move(create_bridge_callback)),
+ surface_layer_for_video_enabled_(surface_layer_for_video_enabled) {
DVLOG(1) << __func__;
DCHECK(client);
DCHECK(delegate_);
@@ -301,8 +306,10 @@
// Destruct compositor resources in the proper order.
get_client()->SetCcLayer(nullptr);
- if (video_layer_)
+ if (video_layer_) {
+ DCHECK(!surface_layer_for_video_enabled_);
video_layer_->StopUsingProvider();
+ }
if (frame_deliverer_)
io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
@@ -418,6 +425,27 @@
return blink::WebMediaPlayer::LoadTiming::kImmediate;
}
+void WebMediaPlayerMS::OnWebLayerUpdated() {}
+
+void WebMediaPlayerMS::RegisterContentsLayer(cc::Layer* layer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(bridge_);
+
+ bridge_->SetContentsOpaque(opaque_);
+ client_->SetCcLayer(layer);
+}
+
+void WebMediaPlayerMS::UnregisterContentsLayer(cc::Layer* layer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // |client_| will unregister its cc::Layer if given a nullptr.
+ client_->SetCcLayer(nullptr);
+}
+
+void WebMediaPlayerMS::OnSurfaceIdUpdated(viz::SurfaceId surface_id) {
+ // TODO(apacible): Add implementation. See http://crbug/746182.
+ NOTIMPLEMENTED();
+}
+
void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) {
Reload();
}
@@ -1013,6 +1041,15 @@
bool is_opaque) {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (surface_layer_for_video_enabled_) {
+ DCHECK(!bridge_);
+
+ bridge_ = std::move(create_bridge_callback_)
+ .Run(this, compositor_->GetUpdateSubmissionStateCallback());
+ bridge_->CreateSurfaceLayer();
+ }
+
SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData);
@@ -1023,9 +1060,17 @@
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
- // Opacity can be changed during the session without resetting
- // |video_layer_|.
- video_layer_->SetContentsOpaque(is_opaque);
+ opaque_ = is_opaque;
+
+ if (!bridge_) {
+ // Opacity can be changed during the session without resetting
+ // |video_layer_|.
+ video_layer_->SetContentsOpaque(opaque_);
+ } else {
+ DCHECK(bridge_);
+
+ bridge_->SetContentsOpaque(opaque_);
+ }
}
void WebMediaPlayerMS::OnRotationChanged(media::VideoRotation video_rotation,
@@ -1033,16 +1078,22 @@
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
video_rotation_ = video_rotation;
+ opaque_ = is_opaque;
- // Keep the old |video_layer_| alive until SetCcLayer() is called with a new
- // pointer, as it may use the pointer from the last call.
- auto new_video_layer =
- cc::VideoLayer::Create(compositor_.get(), video_rotation);
- new_video_layer->SetContentsOpaque(is_opaque);
+ if (!bridge_) {
+ // Keep the old |video_layer_| alive until SetCcLayer() is called with a new
+ // pointer, as it may use the pointer from the last call.
+ auto new_video_layer =
+ cc::VideoLayer::Create(compositor_.get(), video_rotation);
+ new_video_layer->SetContentsOpaque(is_opaque);
- get_client()->SetCcLayer(new_video_layer.get());
+ get_client()->SetCcLayer(new_video_layer.get());
- video_layer_ = std::move(new_video_layer);
+ video_layer_ = std::move(new_video_layer);
+ } else if (bridge_->GetCcLayer()) {
+ // TODO(lethalantidote): Handle rotation.
+ bridge_->SetContentsOpaque(opaque_);
+ }
}
void WebMediaPlayerMS::RepaintInternal() {
diff --git a/content/renderer/media/stream/webmediaplayer_ms.h b/content/renderer/media/stream/webmediaplayer_ms.h
index 8c0b492f..1857e62 100644
--- a/content/renderer/media/stream/webmediaplayer_ms.h
+++ b/content/renderer/media/stream/webmediaplayer_ms.h
@@ -21,6 +21,7 @@
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_stream.h"
+#include "third_party/blink/public/platform/web_surface_layer_bridge.h"
namespace blink {
class WebLocalFrame;
@@ -44,6 +45,11 @@
}
namespace content {
+using CreateSurfaceLayerBridgeCB =
+ base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
+ blink::WebSurfaceLayerBridgeObserver*,
+ cc::UpdateSubmissionStateCB)>;
+
class MediaStreamAudioRenderer;
class MediaStreamRendererFactory;
class MediaStreamVideoRenderer;
@@ -66,6 +72,7 @@
: public blink::WebMediaStreamObserver,
public blink::WebMediaPlayer,
public media::WebMediaPlayerDelegate::Observer,
+ public blink::WebSurfaceLayerBridgeObserver,
public base::SupportsWeakPtr<WebMediaPlayerMS> {
public:
// Construct a WebMediaPlayerMS with reference to the client, and
@@ -82,7 +89,9 @@
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
scoped_refptr<base::TaskRunner> worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories,
- const blink::WebString& sink_id);
+ const blink::WebString& sink_id,
+ CreateSurfaceLayerBridgeCB create_bridge_callback,
+ bool surface_layer_for_video_enabled_);
~WebMediaPlayerMS() override;
@@ -91,6 +100,12 @@
const blink::WebMediaPlayerSource& source,
CORSMode cors_mode) override;
+ // WebSurfaceLayerBridgeObserver implementation.
+ void OnWebLayerUpdated() override;
+ void RegisterContentsLayer(cc::Layer* layer) override;
+ void UnregisterContentsLayer(cc::Layer* layer) override;
+ void OnSurfaceIdUpdated(viz::SurfaceId surface_id) override;
+
// Playback controls.
void Play() override;
void Pause() override;
@@ -306,6 +321,18 @@
blink::WebString current_video_track_id_;
blink::WebString current_audio_track_id_;
+ CreateSurfaceLayerBridgeCB create_bridge_callback_;
+
+ // Whether the use of a surface layer instead of a video layer is enabled.
+ bool surface_layer_for_video_enabled_ = false;
+
+ // Owns the weblayer and obtains/maintains SurfaceIds for
+ // kUseSurfaceLayerForVideo feature.
+ std::unique_ptr<blink::WebSurfaceLayerBridge> bridge_;
+
+ // Whether the video is known to be opaque or not.
+ bool opaque_ = true;
+
DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerMS);
};
diff --git a/content/renderer/media/stream/webmediaplayer_ms_compositor.h b/content/renderer/media/stream/webmediaplayer_ms_compositor.h
index 002b4c4..921b0bb 100644
--- a/content/renderer/media/stream/webmediaplayer_ms_compositor.h
+++ b/content/renderer/media/stream/webmediaplayer_ms_compositor.h
@@ -16,6 +16,7 @@
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
+#include "cc/layers/surface_layer.h"
#include "cc/layers/video_frame_provider.h"
#include "content/common/content_export.h"
#include "media/base/media_log.h"
@@ -62,6 +63,11 @@
const blink::WebMediaStream& web_stream,
const base::WeakPtr<WebMediaPlayerMS>& player);
+ // Can be called from any thread.
+ cc::UpdateSubmissionStateCB GetUpdateSubmissionStateCallback() {
+ return update_submission_state_callback_;
+ }
+
void EnqueueFrame(scoped_refptr<media::VideoFrame> frame);
// Statistical data
@@ -182,6 +188,8 @@
std::map<base::TimeDelta, base::TimeTicks> timestamps_to_clock_times_;
+ cc::UpdateSubmissionStateCB update_submission_state_callback_;
+
// |current_frame_lock_| protects |current_frame_|, |rendering_frame_buffer_|,
// |dropped_frame_count_|, and |render_started_|.
base::Lock current_frame_lock_;
diff --git a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
index 8f01703e..89994de8 100644
--- a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
+++ b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -26,6 +26,9 @@
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
+using ::testing::Return;
+using ::testing::StrictMock;
+
namespace content {
enum class FrameType {
@@ -35,6 +38,16 @@
MIN_TYPE = TEST_BRAKE
};
+class MockSurfaceLayerBridge : public blink::WebSurfaceLayerBridge {
+ public:
+ MOCK_CONST_METHOD0(GetCcLayer, cc::Layer*());
+ MOCK_CONST_METHOD0(GetFrameSinkId, const viz::FrameSinkId&());
+ MOCK_CONST_METHOD0(GetSurfaceId, const viz::SurfaceId&());
+ MOCK_METHOD1(SetContentsOpaque, void(bool));
+ MOCK_METHOD0(CreateSurfaceLayer, void());
+ MOCK_METHOD0(ClearSurfaceId, void());
+};
+
using TestFrame = std::pair<FrameType, scoped_refptr<media::VideoFrame>>;
static const int kOddSizeOffset = 3;
@@ -493,26 +506,20 @@
: render_factory_(new MockRenderFactory(message_loop_.task_runner(),
&message_loop_controller_)),
gpu_factories_(new media::MockGpuVideoAcceleratorFactories(nullptr)),
- player_(new WebMediaPlayerMS(
- nullptr,
- this,
- &delegate_,
- std::make_unique<media::MediaLog>(),
- std::unique_ptr<MediaStreamRendererFactory>(render_factory_),
- message_loop_.task_runner(),
- message_loop_.task_runner(),
- message_loop_.task_runner(),
- message_loop_.task_runner(),
- gpu_factories_.get(),
- blink::WebString())),
+ surface_layer_bridge_(
+ std::make_unique<StrictMock<MockSurfaceLayerBridge>>()),
layer_set_(false),
rendering_(false),
- background_rendering_(false) {}
+ background_rendering_(false) {
+ surface_layer_bridge_ptr_ = surface_layer_bridge_.get();
+ }
~WebMediaPlayerMSTest() override {
player_.reset();
base::RunLoop().RunUntilIdle();
}
+ void InitializeWebMediaPlayerMS(bool enable_surface_layer_for_video);
+
MockMediaStreamVideoRenderer* LoadAndGetFrameProvider(bool algorithm_enabled);
// Implementation of WebMediaPlayerClient
@@ -608,6 +615,12 @@
MOCK_METHOD1(CheckSizeChanged, void(gfx::Size));
MOCK_CONST_METHOD0(CouldPlayIfEnoughData, bool());
+ std::unique_ptr<blink::WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge(
+ blink::WebSurfaceLayerBridgeObserver*,
+ cc::UpdateSubmissionStateCB) {
+ return std::move(surface_layer_bridge_);
+ }
+
base::MessageLoop message_loop_;
MockRenderFactory* render_factory_;
std::unique_ptr<media::MockGpuVideoAcceleratorFactories> gpu_factories_;
@@ -618,6 +631,8 @@
cc::Layer* layer_;
bool is_audio_element_ = false;
std::vector<base::OnceClosure> frame_ready_cbs_;
+ std::unique_ptr<StrictMock<MockSurfaceLayerBridge>> surface_layer_bridge_;
+ StrictMock<MockSurfaceLayerBridge>* surface_layer_bridge_ptr_ = nullptr;
private:
// Main function trying to ask WebMediaPlayerMS to submit a frame for
@@ -629,6 +644,19 @@
bool background_rendering_;
};
+void WebMediaPlayerMSTest::InitializeWebMediaPlayerMS(
+ bool enable_surface_layer_for_video) {
+ player_ = std::make_unique<WebMediaPlayerMS>(
+ nullptr, this, &delegate_, std::make_unique<media::MediaLog>(),
+ std::unique_ptr<MediaStreamRendererFactory>(render_factory_),
+ message_loop_.task_runner(), message_loop_.task_runner(),
+ message_loop_.task_runner(), message_loop_.task_runner(),
+ gpu_factories_.get(), blink::WebString(),
+ base::BindRepeating(&WebMediaPlayerMSTest::CreateMockSurfaceLayerBridge,
+ base::Unretained(this)),
+ enable_surface_layer_for_video);
+}
+
MockMediaStreamVideoRenderer* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
bool algorithm_enabled) {
EXPECT_FALSE(!!render_factory_->provider()) << "There should not be a "
@@ -742,6 +770,7 @@
}
TEST_F(WebMediaPlayerMSTest, NoDataDuringLoadForVideo) {
+ InitializeWebMediaPlayerMS(false);
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata))
.Times(0);
@@ -759,6 +788,7 @@
}
TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudio) {
+ InitializeWebMediaPlayerMS(false);
is_audio_element_ = true;
scoped_refptr<MediaStreamAudioRenderer> audio_renderer(
new MockMediaStreamAudioRenderer());
@@ -785,6 +815,7 @@
}
TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudioOnly) {
+ InitializeWebMediaPlayerMS(false);
render_factory_->set_support_video_renderer(false);
scoped_refptr<MediaStreamAudioRenderer> audio_renderer(
new MockMediaStreamAudioRenderer());
@@ -802,6 +833,8 @@
// and verifies that they are produced by WebMediaPlayerMS in appropriate
// order.
+ InitializeWebMediaPlayerMS(false);
+
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
@@ -832,6 +865,8 @@
// This tests sends a broken frame to WebMediaPlayerMS, and verifies
// OnSourceError function works as expected.
+ InitializeWebMediaPlayerMS(false);
+
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
const int kBrokenFrame = static_cast<int>(FrameType::BROKEN_FRAME);
@@ -859,6 +894,7 @@
}
TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
+ InitializeWebMediaPlayerMS(false);
const bool opaque_frame = testing::get<0>(GetParam());
const bool odd_size_frame = testing::get<1>(GetParam());
// In the middle of this test, WebMediaPlayerMS::pause will be called, and we
@@ -900,6 +936,7 @@
}
TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
+ InitializeWebMediaPlayerMS(false);
const bool opaque_frame = testing::get<0>(GetParam());
const bool odd_size_frame = testing::get<1>(GetParam());
// Similary to PlayAndPause test above, this one focuses on testing that
@@ -959,6 +996,7 @@
// During this test, we check that when we send rotated video frames, it applies
// to player's natural size.
TEST_F(WebMediaPlayerMSTest, RotationChange) {
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
@@ -999,6 +1037,7 @@
// During this test, we check that web layer changes opacity according to the
// given frames.
TEST_F(WebMediaPlayerMSTest, OpacityChange) {
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
// Push one opaque frame.
@@ -1043,6 +1082,7 @@
// WebMediaPlayerMS without an explicit notification. We should expect that
// WebMediaPlayerMS can digest old frames, rather than piling frames up and
// explode.
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
@@ -1091,6 +1131,7 @@
// During this test, the frame size of the input changes.
// We need to make sure, when sizeChanged() gets called, new size should be
// returned by GetCurrentSize().
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
@@ -1119,6 +1160,7 @@
// Tests that GpuMemoryBufferVideoFramePool is called in the expected sequence.
// TODO(https://crbug.com/831327): Flaky under load / CPU scheduling delays.
TEST_F(WebMediaPlayerMSTest, DISABLED_CreateHardwareFrames) {
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
SetGpuMemoryBufferVideoForTesting();
@@ -1156,6 +1198,7 @@
// TODO(https://crbug.com/831327): Flaky under load / CPU scheduling delays.
TEST_F(WebMediaPlayerMSTest,
DISABLED_StopsCreatingHardwareFramesWhenHiddenOrClosed) {
+ InitializeWebMediaPlayerMS(false);
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
SetGpuMemoryBufferVideoForTesting();
@@ -1213,6 +1256,7 @@
#if defined(OS_ANDROID)
TEST_F(WebMediaPlayerMSTest, HiddenPlayerTests) {
+ InitializeWebMediaPlayerMS(false);
LoadAndGetFrameProvider(true);
// Hidden status should not affect playback.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 7361893..4610d85 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -325,6 +325,10 @@
const base::Feature kUseSurfaceLayerForVideo{"UseSurfaceLayerForVideo",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Use SurfaceLayer instead of VideoLayer for MediaStream.
+const base::Feature kUseSurfaceLayerForVideoMS{
+ "UseSurfaceLayerForVideoMS", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enable VA-API hardware encode acceleration for VP8.
const base::Feature kVaapiVP8Encoder{"VaapiVP8Encoder",
base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 967fd507..6be16b7 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -138,6 +138,7 @@
MEDIA_EXPORT extern const base::Feature kVideoBlitColorAccuracy;
MEDIA_EXPORT extern const base::Feature kUnifiedAutoplay;
MEDIA_EXPORT extern const base::Feature kUseSurfaceLayerForVideo;
+MEDIA_EXPORT extern const base::Feature kUseSurfaceLayerForVideoMS;
MEDIA_EXPORT extern const base::Feature kUseModernMediaControls;
#if defined(OS_ANDROID)
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index 12694a6..330194f 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -879,10 +879,7 @@
// Whether the use of a surface layer instead of a video layer is enabled.
bool surface_layer_for_video_enabled_ = false;
- base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
- blink::WebSurfaceLayerBridgeObserver*,
- cc::UpdateSubmissionStateCB)>
- create_bridge_callback_;
+ CreateSurfaceLayerBridgeCB create_bridge_callback_;
base::CancelableOnceCallback<void(base::TimeTicks)> frame_time_report_cb_;
diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc
index 0436885..42317de1 100644
--- a/media/blink/webmediaplayer_params.cc
+++ b/media/blink/webmediaplayer_params.cc
@@ -28,9 +28,7 @@
bool enable_instant_source_buffer_gc,
bool embedded_media_experience_enabled,
mojom::MediaMetricsProviderPtr metrics_provider,
- base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
- blink::WebSurfaceLayerBridgeObserver*,
- cc::UpdateSubmissionStateCB)> create_bridge_callback,
+ CreateSurfaceLayerBridgeCB create_bridge_callback,
scoped_refptr<viz::ContextProvider> context_provider,
bool use_surface_layer_for_video)
: defer_load_cb_(defer_load_cb),
diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h
index 0793f19..21b132e 100644
--- a/media/blink/webmediaplayer_params.h
+++ b/media/blink/webmediaplayer_params.h
@@ -37,6 +37,11 @@
namespace media {
+using CreateSurfaceLayerBridgeCB =
+ base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
+ blink::WebSurfaceLayerBridgeObserver*,
+ cc::UpdateSubmissionStateCB)>;
+
class SwitchableAudioRendererSink;
// Holds parameters for constructing WebMediaPlayerImpl without having
@@ -81,9 +86,7 @@
bool enable_instant_source_buffer_gc,
bool embedded_media_experience_enabled,
mojom::MediaMetricsProviderPtr metrics_provider,
- base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
- blink::WebSurfaceLayerBridgeObserver*,
- cc::UpdateSubmissionStateCB)> bridge_callback,
+ CreateSurfaceLayerBridgeCB bridge_callback,
scoped_refptr<viz::ContextProvider> context_provider,
bool use_surface_layer_for_video);
@@ -153,10 +156,7 @@
return request_routing_token_cb_;
}
- base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
- blink::WebSurfaceLayerBridgeObserver*,
- cc::UpdateSubmissionStateCB)>
- create_bridge_callback() {
+ CreateSurfaceLayerBridgeCB create_bridge_callback() {
return std::move(create_bridge_callback_);
}
@@ -187,10 +187,7 @@
bool enable_instant_source_buffer_gc_;
const bool embedded_media_experience_enabled_;
mojom::MediaMetricsProviderPtr metrics_provider_;
- base::OnceCallback<std::unique_ptr<blink::WebSurfaceLayerBridge>(
- blink::WebSurfaceLayerBridgeObserver*,
- cc::UpdateSubmissionStateCB)>
- create_bridge_callback_;
+ CreateSurfaceLayerBridgeCB create_bridge_callback_;
scoped_refptr<viz::ContextProvider> context_provider_;
bool use_surface_layer_for_video_;
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 2ae0bac..3c50b505 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -29505,6 +29505,7 @@
<int value="1689183477" label="enable-merge-key-char-events"/>
<int value="1690837904" label="save-previous-document-resources"/>
<int value="1691568199" label="AndroidSpellCheckerNonLowEnd:disabled"/>
+ <int value="1694562245" label="UseSurfaceLayerForVideoMS:disabled"/>
<int value="1694766748"
label="AutofillRestrictUnownedFieldsToFormlessCheckout:enabled"/>
<int value="1694798717" label="NewNetErrorPageUI:enabled"/>
@@ -29591,6 +29592,7 @@
<int value="1862207743" label="enable-android-spellchecker"/>
<int value="1863622457" label="WebAuthentication:enabled"/>
<int value="1865068568" label="disable-audio-support-for-desktop-share"/>
+ <int value="1865702649" label="UseSurfaceLayerForVideoMS:enabled"/>
<int value="1865799183" label="javascript-harmony"/>
<int value="1865963858" label="tls13-variant"/>
<int value="1866079109" label="team-drives"/>