Skip to content

Commit b434cc2

Browse files
authored
media: Refactor bypass bridge for StarboardRenderer (#11262)
Move the media bypass bridge logic out of the core MojoRenderer and MojoRendererService classes. This logic is now encapsulated within StarboardRendererClient and StarboardRendererWrapper. By moving InitializeWithBypassBridge to the StarboardRendererExtension mojom interface, this refactor keeps Starboard-specific optimizations separated from the generic Chromium Mojo media implementation. This improves code maintainability while preserving support for single-process media bypass. This PR also aligns the order of functions in StarboardRendererClient and StarboardRendererWrapper. Issue: 513254071
1 parent 8deb0f1 commit b434cc2

18 files changed

Lines changed: 659 additions & 306 deletions

media/mojo/clients/mojo_renderer.cc

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44

55
#include "media/mojo/clients/mojo_renderer.h"
66

7-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
8-
#include <atomic>
9-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
10-
#include <utility>
11-
127
#include "base/functional/bind.h"
138
#include "base/functional/callback_helpers.h"
149
#include "base/location.h"
@@ -24,36 +19,16 @@
2419
#include "media/mojo/common/media_type_converters.h"
2520
#include "media/renderers/video_overlay_factory.h"
2621

27-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
28-
#include "base/command_line.h"
29-
#include "base/feature_list.h"
30-
#include "media/base/media_switches.h"
31-
#endif
32-
3322
namespace media {
3423

35-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
36-
namespace {
37-
std::atomic<uint32_t> g_next_bypass_id{1};
38-
} // namespace
39-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
40-
4124
MojoRenderer::MojoRenderer(
4225
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
4326
std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
4427
VideoRendererSink* video_renderer_sink,
45-
mojo::PendingRemote<mojom::Renderer> remote_renderer
46-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
47-
,
48-
bool bypass_mojo_for_media
49-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
50-
)
28+
mojo::PendingRemote<mojom::Renderer> remote_renderer)
5129
: task_runner_(task_runner),
5230
video_overlay_factory_(std::move(video_overlay_factory)),
5331
video_renderer_sink_(video_renderer_sink),
54-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
55-
bypass_mojo_for_media_(bypass_mojo_for_media),
56-
#endif
5732
remote_renderer_pending_remote_(std::move(remote_renderer)),
5833
media_time_interpolator_(base::DefaultTickClock::GetInstance()) {
5934
DVLOG(1) << __func__;
@@ -63,13 +38,6 @@ MojoRenderer::~MojoRenderer() {
6338
DVLOG(1) << __func__;
6439
DCHECK(task_runner_->RunsTasksInCurrentSequence());
6540

66-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
67-
if (bypass_bridge_) {
68-
bypass_bridge_->Invalidate();
69-
BypassBridgeRegistry::Unregister(bypass_id_);
70-
}
71-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
72-
7341
CancelPendingCallbacks();
7442
}
7543

@@ -90,36 +58,6 @@ void MojoRenderer::Initialize(MediaResource* media_resource,
9058
media_resource_ = media_resource;
9159
init_cb_ = std::move(init_cb);
9260

93-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
94-
if ((base::FeatureList::IsEnabled(kCobaltBypassMojoForMedia)
95-
|| bypass_mojo_for_media_) &&
96-
base::CommandLine::ForCurrentProcess()->HasSwitch("single-process")) {
97-
98-
// Create the bypass bridge to manage shared state and callbacks.
99-
bypass_bridge_ = base::MakeRefCounted<MojoRendererBypassBridge>(
100-
task_runner_,
101-
base::BindRepeating(&MojoRenderer::OnTimeUpdate,
102-
weak_factory_.GetWeakPtr()),
103-
base::BindRepeating(&MojoRenderer::OnStatisticsUpdate,
104-
weak_factory_.GetWeakPtr()));
105-
// Set the actual streams in the bridge.
106-
DemuxerStream* audio_stream = media_resource_->GetFirstStream(
107-
DemuxerStream::AUDIO);
108-
DemuxerStream* video_stream = media_resource_->GetFirstStream(
109-
DemuxerStream::VIDEO);
110-
bypass_bridge_->SetStreams(audio_stream, video_stream);
111-
// Generate a unique ID and register the bridge.
112-
bypass_id_ = g_next_bypass_id.fetch_add(1);
113-
BypassBridgeRegistry::Register(bypass_id_, bypass_bridge_);
114-
BindRemoteRendererIfNeeded();
115-
remote_renderer_->InitializeWithBypassBridge(
116-
client_receiver_.BindNewEndpointAndPassRemote(),
117-
bypass_id_, base::BindOnce(&MojoRenderer::OnInitialized,
118-
base::Unretained(this), client));
119-
return;
120-
}
121-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
122-
12361
// Create mojom::DemuxerStream for each demuxer stream and bind its lifetime
12462
// to the pipe.
12563
std::vector<DemuxerStream*> streams = media_resource_->GetAllStreams();

media/mojo/clients/mojo_renderer.h

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
#include "mojo/public/cpp/bindings/pending_remote.h"
2424
#include "mojo/public/cpp/bindings/remote.h"
2525

26-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
27-
#include "media/mojo/common/starboard/mojo_renderer_bypass_bridge.h"
28-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
29-
3026
namespace media {
3127

3228
class MediaResource;
@@ -49,12 +45,7 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
4945
MojoRenderer(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
5046
std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
5147
VideoRendererSink* video_renderer_sink,
52-
mojo::PendingRemote<mojom::Renderer> remote_renderer
53-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
54-
,
55-
bool bypass_mojo_for_media = false
56-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
57-
);
48+
mojo::PendingRemote<mojom::Renderer> remote_renderer);
5849

5950
MojoRenderer(const MojoRenderer&) = delete;
6051
MojoRenderer& operator=(const MojoRenderer&) = delete;
@@ -74,13 +65,11 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
7465
base::TimeDelta GetMediaTime() override;
7566
RendererType GetRendererType() override;
7667

68+
private:
7769
#if BUILDFLAG(USE_STARBOARD_MEDIA)
78-
scoped_refptr<base::SequencedTaskRunner> task_runner() const {
79-
return task_runner_;
80-
}
70+
friend class StarboardRendererClient;
8171
#endif
8272

83-
private:
8473
// mojom::RendererClient implementation, dispatched on the |task_runner_|.
8574
void OnTimeUpdate(base::TimeDelta time,
8675
base::TimeDelta max_time,
@@ -137,12 +126,6 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
137126
// Client of |this| renderer passed in Initialize.
138127
raw_ptr<media::RendererClient> client_ = nullptr;
139128

140-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
141-
bool bypass_mojo_for_media_ = false;
142-
scoped_refptr<MojoRendererBypassBridge> bypass_bridge_;
143-
uint32_t bypass_id_ = 0;
144-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
145-
146129
// Mojo demuxer streams.
147130
// Owned by MojoRenderer instead of remote mojom::Renderer
148131
// because these demuxer streams need to be destroyed as soon as |this| is
@@ -176,10 +159,6 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
176159
media::TimeDeltaInterpolator media_time_interpolator_;
177160

178161
std::optional<PipelineStatistics> pending_stats_;
179-
180-
#if BUILDFLAG(USE_STARBOARD_MEDIA)
181-
base::WeakPtrFactory<MojoRenderer> weak_factory_{this};
182-
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
183162
};
184163

185164
} // namespace media

media/mojo/clients/mojo_renderer_factory.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ std::unique_ptr<MojoRenderer> MojoRendererFactory::CreateStarboardRenderer(
130130

131131
return std::make_unique<MojoRenderer>(
132132
media_task_runner, nullptr, video_renderer_sink,
133-
std::move(renderer_remote),
134-
config.experimental_features.GetBool(kMediaBypassMojoForMedia));
133+
std::move(renderer_remote));
135134
}
136135
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
137136

media/mojo/clients/mojo_renderer_wrapper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class MojoRendererWrapper : public Renderer {
3838
void SetVolume(float volume) override;
3939
base::TimeDelta GetMediaTime() override;
4040

41+
#if BUILDFLAG(USE_STARBOARD_MEDIA)
42+
protected:
43+
MojoRenderer* mojo_renderer() { return mojo_renderer_.get(); }
44+
#endif // BUILDFLAG(USE_STARBOARD_MEDIA)
45+
4146
private:
4247
std::unique_ptr<MojoRenderer> mojo_renderer_;
4348
};

media/mojo/clients/starboard/starboard_renderer_client.cc

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@
1414

1515
#include "media/mojo/clients/starboard/starboard_renderer_client.h"
1616

17+
#include <atomic>
18+
19+
#include "base/feature_list.h"
1720
#include "base/functional/bind.h"
1821
#include "base/time/time.h"
1922
#include "base/unguessable_token.h"
2023
#include "media/base/media_log.h"
2124
#include "media/base/media_resource.h"
25+
#include "media/base/media_switches.h"
2226
#include "media/base/video_frame.h"
2327
#include "media/mojo/clients/mojo_renderer.h"
2428
#include "media/renderers/video_overlay_factory.h"
2529
#include "media/video/gpu_video_accelerator_factories.h"
30+
#include "mojo/public/cpp/bindings/callback_helpers.h"
2631
#include "mojo/public/cpp/bindings/pending_receiver.h"
2732

2833
#if BUILDFLAG(IS_ANDROID)
@@ -31,6 +36,10 @@
3136

3237
namespace media {
3338

39+
namespace {
40+
std::atomic<uint32_t> g_next_bypass_id{1};
41+
} // namespace
42+
3443
StarboardRendererClient::StarboardRendererClient(
3544
const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
3645
std::unique_ptr<MediaLog> media_log,
@@ -45,7 +54,8 @@ StarboardRendererClient::StarboardRendererClient(
4554
,
4655
RequestOverlayInfoCB request_overlay_info_cb
4756
#endif // BUILDFLAG(IS_ANDROID)
48-
)
57+
,
58+
bool bypass_mojo_for_media)
4959
: MojoRendererWrapper(std::move(mojo_renderer)),
5060
media_task_runner_(media_task_runner),
5161
media_log_(std::move(media_log)),
@@ -60,7 +70,8 @@ StarboardRendererClient::StarboardRendererClient(
6070
,
6171
request_overlay_info_cb_(std::move(request_overlay_info_cb))
6272
#endif // BUILDFLAG(IS_ANDROID)
63-
{
73+
,
74+
bypass_mojo_for_media_(bypass_mojo_for_media) {
6475
DCHECK(media_task_runner_);
6576
DCHECK(video_renderer_sink_);
6677
DCHECK(video_overlay_factory_);
@@ -71,6 +82,11 @@ StarboardRendererClient::~StarboardRendererClient() {
7182
SetPlayingState(false);
7283
DCHECK(!video_renderer_sink_started_);
7384

85+
if (bypass_bridge_) {
86+
bypass_bridge_->Invalidate();
87+
BypassBridgeRegistry::Unregister(bypass_id_);
88+
}
89+
7490
#if BUILDFLAG(IS_ANDROID)
7591
if (request_overlay_info_cb_ && overlay_info_requested_) {
7692
request_overlay_info_cb_.Run(false, base::NullCallback());
@@ -334,6 +350,72 @@ void StarboardRendererClient::InitializeMojoRenderer(
334350
PipelineStatusCallback init_cb) {
335351
DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
336352
DCHECK(AreMojoPipesConnected());
353+
354+
if (base::FeatureList::IsEnabled(kCobaltBypassMojoForMedia) ||
355+
bypass_mojo_for_media_) {
356+
bypass_bridge_ = base::MakeRefCounted<MojoRendererBypassBridge>(
357+
media_task_runner_,
358+
base::BindRepeating(&StarboardRendererClient::OnTimeUpdateFromBridge,
359+
weak_factory_.GetWeakPtr()),
360+
base::BindRepeating(
361+
&StarboardRendererClient::OnStatisticsUpdateFromBridge,
362+
weak_factory_.GetWeakPtr()));
363+
DemuxerStream* audio_stream =
364+
media_resource->GetFirstStream(DemuxerStream::AUDIO);
365+
DemuxerStream* video_stream =
366+
media_resource->GetFirstStream(DemuxerStream::VIDEO);
367+
bypass_bridge_->SetStreams(audio_stream, video_stream);
368+
bypass_id_ = g_next_bypass_id.fetch_add(1);
369+
BypassBridgeRegistry::Register(bypass_id_, bypass_bridge_);
370+
renderer_extension_->InitializeWithBypassBridge(
371+
bypass_id_,
372+
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
373+
base::BindOnce(
374+
&StarboardRendererClient::OnExtensionBypassInitialized,
375+
weak_factory_.GetWeakPtr(), media_resource, client,
376+
std::move(init_cb)),
377+
false));
378+
return;
379+
}
380+
381+
MojoRendererWrapper::Initialize(media_resource, client, std::move(init_cb));
382+
}
383+
384+
void StarboardRendererClient::OnTimeUpdateFromBridge(
385+
base::TimeDelta time,
386+
base::TimeDelta max_time,
387+
base::TimeTicks capture_time) {
388+
DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
389+
if (mojo_renderer()) {
390+
mojo_renderer()->OnTimeUpdate(time, max_time, capture_time);
391+
}
392+
}
393+
394+
void StarboardRendererClient::OnStatisticsUpdateFromBridge(
395+
const PipelineStatistics& stats) {
396+
DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
397+
if (mojo_renderer()) {
398+
mojo_renderer()->OnStatisticsUpdate(stats);
399+
}
400+
}
401+
402+
void StarboardRendererClient::OnExtensionBypassInitialized(
403+
MediaResource* media_resource,
404+
RendererClient* client,
405+
PipelineStatusCallback init_cb,
406+
bool success) {
407+
DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
408+
if (!success) {
409+
if (bypass_bridge_) {
410+
bypass_bridge_->Invalidate();
411+
BypassBridgeRegistry::Unregister(bypass_id_);
412+
bypass_bridge_ = nullptr;
413+
}
414+
if (init_cb) {
415+
std::move(init_cb).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
416+
}
417+
return;
418+
}
337419
MojoRendererWrapper::Initialize(media_resource, client, std::move(init_cb));
338420
}
339421

media/mojo/clients/starboard/starboard_renderer_client.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "media/base/starboard/starboard_rendering_mode.h"
2727
#include "media/base/video_renderer_sink.h"
2828
#include "media/mojo/clients/mojo_renderer_wrapper.h"
29+
#include "media/mojo/common/starboard/mojo_renderer_bypass_bridge.h"
2930
#include "media/mojo/mojom/renderer_extensions.mojom.h"
3031
#include "media/starboard/starboard_callbacks.h"
3132
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -68,7 +69,8 @@ class MEDIA_EXPORT StarboardRendererClient
6869
,
6970
RequestOverlayInfoCB request_overlay_info_cb
7071
#endif // BUILDFLAG(IS_ANDROID)
71-
);
72+
,
73+
bool bypass_mojo_for_media = false);
7274

7375
StarboardRendererClient(const StarboardRendererClient&) = delete;
7476
StarboardRendererClient& operator=(const StarboardRendererClient&) = delete;
@@ -121,6 +123,14 @@ class MEDIA_EXPORT StarboardRendererClient
121123
void InitializeMojoRenderer(MediaResource* media_resource,
122124
RendererClient* client,
123125
PipelineStatusCallback init_cb);
126+
void OnTimeUpdateFromBridge(base::TimeDelta time,
127+
base::TimeDelta max_time,
128+
base::TimeTicks capture_time);
129+
void OnStatisticsUpdateFromBridge(const PipelineStatistics& stats);
130+
void OnExtensionBypassInitialized(MediaResource* media_resource,
131+
RendererClient* client,
132+
PipelineStatusCallback init_cb,
133+
bool success);
124134
void InitAndConstructMojoRenderer(mojom::CommandBufferIdPtr command_buffer_id,
125135
base::OnceClosure complete_cb);
126136
bool AreMojoPipesConnected() const {
@@ -152,6 +162,9 @@ class MEDIA_EXPORT StarboardRendererClient
152162
#if BUILDFLAG(IS_ANDROID)
153163
RequestOverlayInfoCB request_overlay_info_cb_;
154164
#endif // BUILDFLAG(IS_ANDROID)
165+
bool bypass_mojo_for_media_ = false;
166+
scoped_refptr<MojoRendererBypassBridge> bypass_bridge_;
167+
uint32_t bypass_id_ = 0;
155168

156169
mojo::Remote<RendererExtension> renderer_extension_;
157170

media/mojo/clients/starboard/starboard_renderer_client_factory.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ std::unique_ptr<Renderer> StarboardRendererClientFactory::CreateRenderer(
125125
,
126126
std::move(request_overlay_info_cb)
127127
#endif // BUILDFLAG(IS_ANDROID)
128-
);
128+
,
129+
config.experimental_features.GetBool(kMediaBypassMojoForMedia));
129130
}
130131

131132
} // namespace media

0 commit comments

Comments
 (0)