1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROMECAST_MEDIA_SERVICE_CAST_RENDERER_H_ 6 #define CHROMECAST_MEDIA_SERVICE_CAST_RENDERER_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/memory/weak_ptr.h" 12 #include "base/no_destructor.h" 13 #include "base/optional.h" 14 #include "base/unguessable_token.h" 15 #include "chromecast/common/mojom/multiroom.mojom.h" 16 #include "chromecast/common/mojom/service_connector.mojom.h" 17 #include "chromecast/media/api/cma_backend_factory.h" 18 #include "chromecast/media/base/video_resolution_policy.h" 19 #include "chromecast/media/service/mojom/video_geometry_setter.mojom.h" 20 #include "media/base/renderer.h" 21 #include "media/base/waiting.h" 22 #include "media/mojo/mojom/cast_application_media_info_manager.mojom.h" 23 #include "media/mojo/mojom/frame_interface_factory.mojom.h" 24 #include "mojo/public/cpp/bindings/receiver.h" 25 #include "mojo/public/cpp/bindings/remote.h" 26 #include "ui/gfx/geometry/rect_f.h" 27 #include "ui/gfx/overlay_transform.h" 28 29 namespace base { 30 class SingleThreadTaskRunner; 31 } // namespace base 32 33 namespace chromecast { 34 class TaskRunnerImpl; 35 36 namespace media { 37 class BalancedMediaTaskRunnerFactory; 38 class CastCdmContext; 39 class MediaPipelineImpl; 40 class VideoGeometrySetterService; 41 class VideoModeSwitcher; 42 43 class CastRenderer : public ::media::Renderer, 44 public VideoResolutionPolicy::Observer, 45 public mojom::VideoGeometryChangeClient { 46 public: 47 // |frame_interfaces| provides interfaces tied to RenderFrameHost. 48 CastRenderer(CmaBackendFactory* backend_factory, 49 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 50 VideoModeSwitcher* video_mode_switcher, 51 VideoResolutionPolicy* video_resolution_policy, 52 const base::UnguessableToken& overlay_plane_id, 53 ::media::mojom::FrameInterfaceFactory* frame_interfaces); 54 ~CastRenderer() final; 55 // For CmaBackend implementation, CastRenderer must be connected to 56 // VideoGeometrySetterService. 57 void SetVideoGeometrySetterService( 58 VideoGeometrySetterService* video_geometry_setter_service); 59 60 // ::media::Renderer implementation. 61 void Initialize(::media::MediaResource* media_resource, 62 ::media::RendererClient* client, 63 ::media::PipelineStatusCallback init_cb) final; 64 void SetCdm(::media::CdmContext* cdm_context, 65 CdmAttachedCB cdm_attached_cb) final; 66 void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) final; 67 void Flush(base::OnceClosure flush_cb) final; 68 void StartPlayingFrom(base::TimeDelta time) final; 69 void SetPlaybackRate(double playback_rate) final; 70 void SetVolume(float volume) final; 71 base::TimeDelta GetMediaTime() final; 72 73 // VideoResolutionPolicy::Observer implementation. 74 void OnVideoResolutionPolicyChanged() override; 75 76 // mojom::VideoGeometryChangeClient implementation. 77 void OnVideoGeometryChange(const gfx::RectF& rect_f, 78 gfx::OverlayTransform transform) final; 79 80 // TODO(guohuideng): For now we use a global callback to gain access to 81 // VideoPlaneController so CastRenderer can set the video geometry. We 82 // should separate the SetGeometry from VideoPlaneController and get rid 83 // of this callback. see b/79266094. 84 using OverlayCompositedCallback = 85 base::RepeatingCallback<void(const gfx::RectF&, gfx::OverlayTransform)>; 86 static void SetOverlayCompositedCallback(const OverlayCompositedCallback& cb); 87 88 private: 89 enum Stream { STREAM_AUDIO, STREAM_VIDEO }; 90 void OnSubscribeToVideoGeometryChange(::media::MediaResource* media_resource, 91 ::media::RendererClient* client); 92 void OnApplicationMediaInfoReceived( 93 ::media::MediaResource* media_resource, 94 ::media::RendererClient* client, 95 ::media::mojom::CastApplicationMediaInfoPtr application_media_info); 96 void OnGetMultiroomInfo( 97 ::media::MediaResource* media_resource, 98 ::media::RendererClient* client, 99 ::media::mojom::CastApplicationMediaInfoPtr application_media_info, 100 chromecast::mojom::MultiroomInfoPtr multiroom_info); 101 void OnError(::media::PipelineStatus status); 102 void OnEnded(Stream stream); 103 void OnStatisticsUpdate(const ::media::PipelineStatistics& stats); 104 void OnBufferingStateChange(::media::BufferingState state, 105 ::media::BufferingStateChangeReason reason); 106 void OnWaiting(::media::WaitingReason reason); 107 void OnVideoNaturalSizeChange(const gfx::Size& size); 108 void OnVideoOpacityChange(bool opaque); 109 void CheckVideoResolutionPolicy(); 110 void RunInitCallback(::media::PipelineStatus status); 111 void OnVideoInitializationFinished(::media::PipelineStatus status); 112 113 CmaBackendFactory* const backend_factory_; 114 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 115 VideoModeSwitcher* video_mode_switcher_; 116 VideoResolutionPolicy* video_resolution_policy_; 117 base::UnguessableToken overlay_plane_id_; 118 mojo::Remote<chromecast::mojom::ServiceConnector> service_connector_; 119 ::media::mojom::FrameInterfaceFactory* frame_interfaces_; 120 121 ::media::RendererClient* client_; 122 CastCdmContext* cast_cdm_context_; 123 scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_; 124 std::unique_ptr<TaskRunnerImpl> backend_task_runner_; 125 std::unique_ptr<MediaPipelineImpl> pipeline_; 126 bool eos_[2]; 127 gfx::Size video_res_; 128 129 mojo::Remote<::media::mojom::CastApplicationMediaInfoManager> 130 application_media_info_manager_remote_; 131 VideoGeometrySetterService* video_geometry_setter_service_; 132 mojo::Remote<mojom::VideoGeometryChangeSubscriber> 133 video_geometry_change_subcriber_remote_; 134 mojo::Remote<chromecast::mojom::MultiroomManager> multiroom_manager_; 135 ::media::PipelineStatusCallback init_cb_; 136 mojo::Receiver<mojom::VideoGeometryChangeClient> 137 video_geometry_change_client_receiver_{this}; 138 GetOverlayCompositedCallback()139 static OverlayCompositedCallback& GetOverlayCompositedCallback() { 140 static base::NoDestructor<OverlayCompositedCallback> 141 g_overlay_composited_callback; 142 return *g_overlay_composited_callback; 143 } 144 145 base::Optional<float> pending_volume_; 146 147 base::WeakPtrFactory<CastRenderer> weak_factory_; 148 DISALLOW_COPY_AND_ASSIGN(CastRenderer); 149 }; 150 151 } // namespace media 152 } // namespace chromecast 153 154 #endif // CHROMECAST_MEDIA_SERVICE_CAST_RENDERER_H_ 155