Commit 8dfac453 authored by Thomas Guilbert's avatar Thomas Guilbert Committed by Commit Bot

Add OnRemotePlayStateChange to RendererClient

There is no way for a FlingingRenderer (which corresponds 1:1 with a
video playing remotely on a cast device) to signal to WMPI that an
external device has paused/resumed the video.

This CL adds the necessary plumbing for FlingingRenderer to send state
changes back to media::Pipeline, via the RendererClient interface.

Two follow up CLs are planned: adding OnRemotePlayStateChange to
Pipeline::Client, and adding the logic to keep WMPI's play/pause state
in sync with the externally playing video.

Bug: 790766
Change-Id: I85bb77d85000d7913bc9e7f52048daf527e1c8c7
Reviewed-on: https://chromium-review.googlesource.com/c/1412806Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Commit-Queue: Thomas Guilbert <tguilbert@chromium.org>
Auto-Submit: Thomas Guilbert <tguilbert@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625423}
parent 34fbd242
......@@ -9,6 +9,7 @@
#include "base/time/time.h"
#include "base/version.h"
#include "media/base/media_controller.h"
#include "media/base/mock_filters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -27,20 +28,6 @@ class MockMediaController : public media::MediaController {
MOCK_METHOD1(Seek, void(base::TimeDelta));
};
class MockRendererClient : public media::RendererClient {
public:
MOCK_METHOD1(OnError, void(media::PipelineStatus));
MOCK_METHOD0(OnEnded, void());
MOCK_METHOD1(OnStatisticsUpdate, void(const media::PipelineStatistics&));
MOCK_METHOD1(OnBufferingStateChange, void(media::BufferingState));
MOCK_METHOD1(OnWaiting, void(media::WaitingReason));
MOCK_METHOD1(OnAudioConfigChange, void(const media::AudioDecoderConfig&));
MOCK_METHOD1(OnVideoConfigChange, void(const media::VideoDecoderConfig&));
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
};
class MockFlingingController : public media::FlingingController {
public:
explicit MockFlingingController(media::MediaController* media_controller)
......@@ -72,7 +59,7 @@ class FlingingRendererTest : public testing::Test {
}
protected:
NiceMock<MockRendererClient> renderer_client_;
NiceMock<media::MockRendererClient> renderer_client_;
std::unique_ptr<MockMediaController> media_controller_;
StrictMock<MockFlingingController>* flinging_controller_;
std::unique_ptr<FlingingRenderer> renderer_;
......
......@@ -173,4 +173,10 @@ void MediaPlayerRendererClient::OnDurationChange(base::TimeDelta duration) {
client_->OnDurationChange(duration);
}
void MediaPlayerRendererClient::OnRemotePlayStateChange(
media::MediaStatus::State state) {
// Only used with the FlingingRenderer.
NOTREACHED();
}
} // namespace content
......@@ -68,6 +68,7 @@ class CONTENT_EXPORT MediaPlayerRendererClient : public media::Renderer,
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
void OnDurationChange(base::TimeDelta duration) override;
void OnRemotePlayStateChange(media::MediaStatus::State state) override;
// Called on |compositor_task_runner_| whenever |stream_texture_wrapper_| has
// a new frame.
......
......@@ -24,6 +24,7 @@
#include "media/base/encryption_scheme.h"
#include "media/base/hdr_metadata.h"
#include "media/base/media_log_event.h"
#include "media/base/media_status.h"
#include "media/base/output_device_info.h"
#include "media/base/overlay_info.h"
#include "media/base/pipeline_status.h"
......@@ -110,6 +111,9 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::HdcpVersion,
IPC_ENUM_TRAITS_MAX_VALUE(media::MediaLogEvent::Type,
media::MediaLogEvent::TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(media::MediaStatus::State,
media::MediaStatus::State::STATE_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(media::OutputDeviceStatus,
media::OUTPUT_DEVICE_STATUS_MAX)
......
......@@ -16,7 +16,14 @@ namespace media {
// TODO(https://crbug.com/820277): Deduplicate media_router::MediaStatus.
struct MEDIA_EXPORT MediaStatus {
public:
enum class State { UNKNOWN, PLAYING, PAUSED, BUFFERING, STOPPED };
enum class State {
UNKNOWN,
PLAYING,
PAUSED,
BUFFERING,
STOPPED,
STATE_MAX = STOPPED,
};
MediaStatus();
MediaStatus(const MediaStatus& other);
......
......@@ -263,6 +263,7 @@ class MockRendererClient : public RendererClient {
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
};
class MockVideoRenderer : public VideoRenderer {
......
......@@ -138,6 +138,7 @@ class PipelineImpl::RendererWrapper : public DemuxerHost,
void OnVideoNaturalSizeChange(const gfx::Size& size) final;
void OnVideoOpacityChange(bool opaque) final;
void OnDurationChange(base::TimeDelta duration) final;
void OnRemotePlayStateChange(MediaStatus::State state) final;
// Common handlers for notifications from renderers and demuxer.
void OnPipelineError(PipelineStatus error);
......@@ -767,6 +768,13 @@ void PipelineImpl::RendererWrapper::OnDurationChange(base::TimeDelta duration) {
SetDuration(duration);
}
void PipelineImpl::RendererWrapper::OnRemotePlayStateChange(
MediaStatus::State state) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
// TODO(tguilbert): post change to Pipeline
}
void PipelineImpl::RendererWrapper::OnPipelineError(PipelineStatus error) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!";
......
......@@ -7,6 +7,7 @@
#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/media_status.h"
#include "media/base/pipeline_status.h"
#include "media/base/video_decoder_config.h"
#include "media/base/waiting.h"
......@@ -49,6 +50,12 @@ class RendererClient {
// Executed when video metadata is first read, and whenever it changes.
// Only used when we are using a URL demuxer (e.g. for MediaPlayerRenderer).
virtual void OnDurationChange(base::TimeDelta duration) = 0;
// Executed when the status of a video playing remotely is changed, without
// the change originating from the media::Pipeline that owns |this|.
// Only used with the FlingingRenderer, when an external device play/pauses
// videos, and WMPI needs to be updated accordingly.
virtual void OnRemotePlayStateChange(media::MediaStatus::State state) = 0;
};
} // namespace media
......
......@@ -282,6 +282,11 @@ void MojoRenderer::OnDurationChange(base::TimeDelta duration) {
client_->OnDurationChange(duration);
}
void MojoRenderer::OnRemotePlayStateChange(media::MediaStatus::State state) {
DVLOG(2) << __func__ << ": state" << (int)state;
client_->OnRemotePlayStateChange(state);
}
void MojoRenderer::OnVideoOpacityChange(bool opaque) {
DVLOG(2) << __func__ << ": " << opaque;
DCHECK(task_runner_->BelongsToCurrentThread());
......
......@@ -85,6 +85,7 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
void OnWaiting(WaitingReason reason) override;
void OnStatisticsUpdate(const PipelineStatistics& stats) override;
void OnDurationChange(base::TimeDelta duration) override;
void OnRemotePlayStateChange(media::MediaStatus::State state) override;
// Binds |remote_renderer_| to the mojo message pipe. Can be called multiple
// times. If an error occurs during connection, OnConnectionError will be
......
......@@ -78,6 +78,10 @@ enum EncryptionMode;
[Native]
enum MediaContainerName;
// See media/base/media_status.h for description.
[Native]
enum MediaStatusState;
// This defines a mojo transport format for media::EncryptionPattern
// See media/base/encryption_pattern.h for description.
struct EncryptionPattern {
......
......@@ -15,6 +15,7 @@ public_headers = [
"//media/base/encryption_scheme.h",
"//media/base/hdr_metadata.h",
"//media/base/media_log_event.h",
"//media/base/media_status.h",
"//media/base/output_device_info.h",
"//media/base/pipeline_status.h",
"//media/base/sample_format.h",
......@@ -57,4 +58,5 @@ type_mappings = [
"media.mojom.WaitingReason=media::WaitingReason",
"media.mojom.WatchTimeKey=media::WatchTimeKey",
"media.mojom.EncryptionPattern=media::EncryptionPattern",
"media.mojom.MediaStatusState=media::MediaStatus::State",
]
......@@ -94,4 +94,10 @@ interface RendererClient {
// Executed the first time the metadata is updated, and whenever the duration
// changes.
OnDurationChange(mojo_base.mojom.TimeDelta duration);
// Executed whenever a renderer receives notification of a status change that
// was not originated by its owner.
// Only used with the FlingingRenderer (when external devices play/pause the
// video playing remotely).
OnRemotePlayStateChange(MediaStatusState state);
};
......@@ -108,6 +108,7 @@ class MockRendererClient : public mojom::RendererClient {
void(const media::PipelineStatistics& stats));
MOCK_METHOD1(OnWaiting, void(WaitingReason));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
private:
DISALLOW_COPY_AND_ASSIGN(MockRendererClient);
......
......@@ -195,6 +195,10 @@ void MojoRendererService::OnDurationChange(base::TimeDelta duration) {
client_->OnDurationChange(duration);
}
void MojoRendererService::OnRemotePlayStateChange(MediaStatus::State state) {
client_->OnRemotePlayStateChange(state);
}
void MojoRendererService::OnVideoOpacityChange(bool opaque) {
DVLOG(2) << __func__ << "(" << opaque << ")";
client_->OnVideoOpacityChange(opaque);
......
......@@ -92,6 +92,7 @@ class MEDIA_MOJO_EXPORT MojoRendererService : public mojom::Renderer,
void OnVideoNaturalSizeChange(const gfx::Size& size) final;
void OnVideoOpacityChange(bool opaque) final;
void OnDurationChange(base::TimeDelta duration) final;
void OnRemotePlayStateChange(MediaStatus::State state) final;
// Called when the MediaResourceShim is ready to go (has a config,
// pipe handle, etc) and can be handed off to a renderer for use.
......
......@@ -92,6 +92,7 @@ class RendererClientImpl final : public RendererClient {
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size& size));
MOCK_METHOD1(OnVideoOpacityChange, void(bool opaque));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
void DelegateOnStatisticsUpdate(const PipelineStatistics& stats) {
stats_ = stats;
......
......@@ -326,5 +326,10 @@ void Receiver::OnDurationChange(base::TimeDelta duration) {
rpc_broker_->SendMessageToRemote(std::move(rpc));
}
void Receiver::OnRemotePlayStateChange(MediaStatus::State state) {
// Only used with the FlingingRenderer.
NOTREACHED();
}
} // namespace remoting
} // namespace media
......@@ -41,6 +41,7 @@ class Receiver final : public RendererClient {
void OnVideoNaturalSizeChange(const gfx::Size& size) override;
void OnVideoOpacityChange(bool opaque) override;
void OnDurationChange(base::TimeDelta duration) override;
void OnRemotePlayStateChange(MediaStatus::State state) override;
void OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message);
void OnReceivedBuffer(DemuxerStream::Type type,
......
......@@ -194,6 +194,7 @@ class AudioRendererImplTest : public ::testing::Test, public RendererClient {
MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
MOCK_METHOD1(OnVideoOpacityChange, void(bool));
MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
void InitializeRenderer(DemuxerStream* demuxer_stream,
const PipelineStatusCB& pipeline_status_cb) {
......
......@@ -72,6 +72,10 @@ class RendererImpl::RendererClientInternal final : public RendererClient {
// the DemuxerHost interface.
NOTREACHED();
}
void OnRemotePlayStateChange(MediaStatus::State state) override {
// Only used with FlingingRenderer.
NOTREACHED();
}
private:
DemuxerStream::Type type_;
......
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