blob: 4d44c7d5f0ae8117ac6269c6a124eaba61ed8ad6 [file] [log] [blame]
// Copyright 2017 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.
#ifndef MEDIA_REMOTING_RECEIVER_H_
#define MEDIA_REMOTING_RECEIVER_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/timer/timer.h"
#include "media/base/buffering_state.h"
#include "media/base/demuxer_stream.h"
#include "media/base/renderer.h"
#include "media/base/renderer_client.h"
#include "third_party/openscreen/src/cast/streaming/remoting.pb.h"
#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
namespace openscreen {
namespace cast {
class RpcMessenger;
}
} // namespace openscreen
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace media {
namespace remoting {
class ReceiverController;
// Receiver runs on a remote device, and forwards the information sent from a
// CourierRenderer to |renderer_|, which actually renders the media.
//
// Receiver implements media::Renderer to be able to work with
// WebMediaPlayerImpl. However, most of the APIs of media::Renderer are dummy
// functions, because the media playback of the remoting media is not controlled
// by the local pipeline of WMPI. It should be controlled by the remoting sender
// via RPC calls. When Receiver receives RPC calls, it will call the
// corresponding functions of |renderer_| to control the media playback of
// the remoting media.
class Receiver final : public Renderer, public RendererClient {
public:
Receiver(int rpc_handle,
int remote_handle,
ReceiverController* receiver_controller,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
std::unique_ptr<Renderer> renderer,
base::OnceCallback<void(int)> acquire_renderer_done_cb);
~Receiver() override;
// Renderer implementation
void Initialize(MediaResource* media_resource,
RendererClient* client,
PipelineStatusCallback init_cb) override;
void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
void Flush(base::OnceClosure flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(double playback_rate) override;
void SetVolume(float volume) override;
base::TimeDelta GetMediaTime() override;
// RendererClient implementation.
void OnError(PipelineStatus status) override;
void OnEnded() override;
void OnStatisticsUpdate(const PipelineStatistics& stats) override;
void OnBufferingStateChange(BufferingState state,
BufferingStateChangeReason reason) override;
void OnWaiting(WaitingReason reason) override;
void OnAudioConfigChange(const AudioDecoderConfig& config) override;
void OnVideoConfigChange(const VideoDecoderConfig& config) override;
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
void OnVideoFrameRateChange(absl::optional<int>) override;
// Used to set |remote_handle_| after Receiver is created, because the remote
// handle might be received after Receiver is created.
void SetRemoteHandle(int remote_handle);
base::WeakPtr<Receiver> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
private:
// Send RPC message on |main_task_runner_|.
void SendRpcMessageOnMainThread(
std::unique_ptr<openscreen::cast::RpcMessage> message);
// Callback function when RPC message is received.
void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message);
// RPC message handlers.
void RpcInitialize(std::unique_ptr<openscreen::cast::RpcMessage> message);
void RpcSetPlaybackRate(
std::unique_ptr<openscreen::cast::RpcMessage> message);
void RpcFlushUntil(std::unique_ptr<openscreen::cast::RpcMessage> message);
void RpcStartPlayingFrom(
std::unique_ptr<openscreen::cast::RpcMessage> message);
void RpcSetVolume(std::unique_ptr<openscreen::cast::RpcMessage> message);
void ShouldInitializeRenderer();
void OnRendererInitialized(PipelineStatus status);
void VerifyAcquireRendererDone();
void OnFlushDone();
// Periodically send the UpdateTime RPC message to update the media time.
void ScheduleMediaTimeUpdates();
void SendMediaTimeUpdate();
// The callback function to call when |this| is initialized.
PipelineStatusCallback init_cb_;
// Indicates whether |this| received RPC_R_INITIALIZE message or not.
bool rpc_initialize_received_ = false;
// Owns by the WebMediaPlayerImpl instance.
MediaResource* demuxer_ = nullptr;
// The handle of |this| for listening RPC messages.
const int rpc_handle_;
// The CourierRenderer handle on sender side. |remote_handle_| could be set
// through the ctor or SetRemoteHandle().
int remote_handle_;
ReceiverController* const receiver_controller_; // Outlives this class.
openscreen::cast::RpcMessenger* const rpc_messenger_; // Outlives this class.
// Calling SendMessageCallback() of |rpc_messenger_| should be on main thread.
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// Media tasks should run on media thread.
const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
// |renderer_| is the real renderer to render media.
std::unique_ptr<Renderer> renderer_;
// The callback function to send RPC_ACQUIRE_RENDERER_DONE.
base::OnceCallback<void(int)> acquire_renderer_done_cb_;
// The timer to periodically update the media time.
base::RepeatingTimer time_update_timer_;
base::WeakPtrFactory<Receiver> weak_factory_{this};
};
} // namespace remoting
} // namespace media
#endif // MEDIA_REMOTING_RECEIVER_H_