blob: b03dc533b6ab103d24b7f2116a3784eccbdf6d0d [file]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/cast_streaming/renderer/playback_command_forwarding_renderer.h"
#include "base/notreached.h"
namespace cast_streaming {
PlaybackCommandForwardingRenderer::PlaybackCommandForwardingRenderer(
std::unique_ptr<media::Renderer> renderer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojo::PendingReceiver<media::mojom::Renderer> pending_renderer_controls)
: real_renderer_(std::move(renderer)),
pending_renderer_controls_(std::move(pending_renderer_controls)),
task_runner_(std::move(task_runner)),
weak_factory_(this) {
DCHECK(real_renderer_);
DCHECK(pending_renderer_controls_);
}
PlaybackCommandForwardingRenderer::~PlaybackCommandForwardingRenderer() =
default;
void PlaybackCommandForwardingRenderer::Initialize(
media::MediaResource* media_resource,
media::RendererClient* client,
media::PipelineStatusCallback init_cb) {
DCHECK(!init_cb_);
init_cb_ = std::move(init_cb);
real_renderer_->Initialize(
media_resource, client,
base::BindOnce(&PlaybackCommandForwardingRenderer::
OnRealRendererInitializationComplete,
weak_factory_.GetWeakPtr()));
}
void PlaybackCommandForwardingRenderer::SetCdm(media::CdmContext* cdm_context,
CdmAttachedCB cdm_attached_cb) {
// CDM should not be set for current mirroring use cases.
NOTREACHED();
}
void PlaybackCommandForwardingRenderer::SetLatencyHint(
absl::optional<base::TimeDelta> latency_hint) {
// Not relevant for current mirroring use cases.
}
void PlaybackCommandForwardingRenderer::Flush(base::OnceClosure flush_cb) {}
void PlaybackCommandForwardingRenderer::StartPlayingFrom(base::TimeDelta time) {
DCHECK(task_runner_->BelongsToCurrentThread());
}
void PlaybackCommandForwardingRenderer::SetPlaybackRate(double playback_rate) {
DCHECK(task_runner_->BelongsToCurrentThread());
}
void PlaybackCommandForwardingRenderer::SetVolume(float volume) {}
base::TimeDelta PlaybackCommandForwardingRenderer::GetMediaTime() {
return real_renderer_->GetMediaTime();
}
void PlaybackCommandForwardingRenderer::OnRealRendererInitializationComplete(
media::PipelineStatus status) {
DCHECK(init_cb_);
DCHECK(!playback_controller_);
playback_controller_ = std::make_unique<PlaybackController>(
std::move(pending_renderer_controls_), task_runner_,
real_renderer_.get());
std::move(init_cb_).Run(status);
}
// NOTE: The mojo pipe CANNOT be bound to task runner |task_runner_| - this will
// result in runtime errors on the release branch due to an outdated mojo
// implementation. Calls must instead be bounced to the correct task runner in
// each receiver method.
// TODO(b/205307190): Bind the mojo pipe to the task runner directly.
PlaybackCommandForwardingRenderer::PlaybackController::PlaybackController(
mojo::PendingReceiver<media::mojom::Renderer> pending_renderer_controls,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
media::Renderer* real_renderer)
: real_renderer_(real_renderer),
task_runner_(std::move(task_runner)),
playback_controller_(this, std::move(pending_renderer_controls)),
weak_factory_(this) {
DCHECK(real_renderer_);
DCHECK(task_runner_);
}
PlaybackCommandForwardingRenderer::PlaybackController::~PlaybackController() =
default;
void PlaybackCommandForwardingRenderer::PlaybackController::Initialize(
::mojo::PendingAssociatedRemote<media::mojom::RendererClient> client,
absl::optional<
std::vector<::mojo::PendingRemote<::media::mojom::DemuxerStream>>>
streams,
media::mojom::MediaUrlParamsPtr media_url_params,
InitializeCallback callback) {
NOTIMPLEMENTED();
std::move(callback).Run(false);
}
void PlaybackCommandForwardingRenderer::PlaybackController::Flush(
FlushCallback callback) {
NOTIMPLEMENTED();
std::move(callback).Run();
}
void PlaybackCommandForwardingRenderer::PlaybackController::StartPlayingFrom(
::base::TimeDelta time) {
if (!task_runner_->BelongsToCurrentThread()) {
task_runner_->PostTask(
FROM_HERE, base::BindOnce(&PlaybackCommandForwardingRenderer::
PlaybackController::StartPlayingFrom,
weak_factory_.GetWeakPtr(), time));
return;
}
real_renderer_->StartPlayingFrom(time);
}
void PlaybackCommandForwardingRenderer::PlaybackController::SetPlaybackRate(
double playback_rate) {
if (!task_runner_->BelongsToCurrentThread()) {
task_runner_->PostTask(
FROM_HERE, base::BindOnce(&PlaybackCommandForwardingRenderer::
PlaybackController::SetPlaybackRate,
weak_factory_.GetWeakPtr(), playback_rate));
return;
}
real_renderer_->SetPlaybackRate(playback_rate);
}
void PlaybackCommandForwardingRenderer::PlaybackController::SetVolume(
float volume) {
NOTIMPLEMENTED();
}
void PlaybackCommandForwardingRenderer::PlaybackController::SetCdm(
const absl::optional<::base::UnguessableToken>& cdm_id,
SetCdmCallback callback) {
NOTIMPLEMENTED();
std::move(callback).Run(false);
}
} // namespace cast_streaming