| // Copyright 2016 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 CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_ |
| #define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_ |
| |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/unguessable_token.h" |
| #include "content/common/content_export.h" |
| #include "content/public/browser/document_service.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "media/base/android/media_player_bridge.h" |
| #include "media/base/media_log.h" |
| #include "media/base/media_resource.h" |
| #include "media/base/renderer.h" |
| #include "media/base/renderer_client.h" |
| #include "media/mojo/mojom/renderer_extensions.mojom.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| #include "url/gurl.h" |
| |
| namespace content { |
| class RenderFrameHostImpl; |
| class MediaPlayerRendererWebContentsObserver; |
| |
| // MediaPlayerRenderer bridges the media::Renderer and Android MediaPlayer |
| // interfaces. It owns a MediaPlayerBridge, which exposes c++ methods to call |
| // into a native Android MediaPlayer. |
| // |
| // Each MediaPlayerRenderer is associated with one MediaPlayerRendererClient, |
| // living in WMPI in the Renderer process. |
| class CONTENT_EXPORT MediaPlayerRenderer |
| : public media::Renderer, |
| public DocumentService<media::mojom::MediaPlayerRendererExtension>, |
| public media::MediaPlayerBridge::Client { |
| public: |
| using RendererExtension = media::mojom::MediaPlayerRendererExtension; |
| using ClientExtension = media::mojom::MediaPlayerRendererClientExtension; |
| |
| // Permits embedders to handle custom urls. |
| static void RegisterMediaUrlInterceptor( |
| media::MediaUrlInterceptor* media_url_interceptor); |
| |
| MediaPlayerRenderer( |
| RenderFrameHostImpl* rfh, |
| mojo::PendingReceiver<RendererExtension> renderer_extension_receiver, |
| mojo::PendingRemote<ClientExtension> client_extension_remote); |
| |
| MediaPlayerRenderer(const MediaPlayerRenderer&) = delete; |
| MediaPlayerRenderer& operator=(const MediaPlayerRenderer&) = delete; |
| |
| ~MediaPlayerRenderer() override; |
| |
| // media::Renderer implementation |
| void Initialize(media::MediaResource* media_resource, |
| media::RendererClient* client, |
| media::PipelineStatusCallback init_cb) override; |
| void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override; |
| void Flush(base::OnceClosure flush_cb) override; |
| void StartPlayingFrom(base::TimeDelta time) override; |
| |
| // N.B: MediaPlayerBridge doesn't support variable playback rates (but it |
| // could be exposed from MediaPlayer in the future). For the moment: |
| // - If |playback_rate| is 0, we pause the video. |
| // - For other |playback_rate| values, we start playing at 1x speed. |
| void SetPlaybackRate(double playback_rate) override; |
| void SetVolume(float volume) override; |
| base::TimeDelta GetMediaTime() override; |
| |
| // media::MediaPlayerBridge::Client implementation |
| media::MediaResourceGetter* GetMediaResourceGetter() override; |
| media::MediaUrlInterceptor* GetMediaUrlInterceptor() override; |
| void OnMediaDurationChanged(base::TimeDelta duration) override; |
| void OnPlaybackComplete() override; |
| void OnError(int error) override; |
| void OnVideoSizeChanged(int width, int height) override; |
| |
| void OnUpdateAudioMutingState(bool muted); |
| void OnWebContentsDestroyed(); |
| |
| // media::mojom::MediaPlayerRendererExtension implementation. |
| // |
| // Registers a request in the content::ScopedSurfaceRequestManager, and |
| // returns the token associated to the request. The token can then be used to |
| // complete the request via the gpu::ScopedSurfaceRequestConduit. |
| // A completed request will call back to OnScopedSurfaceRequestCompleted(). |
| // |
| // NOTE: If a request is already pending, calling this method again will |
| // safely cancel the pending request before registering a new one. |
| void InitiateScopedSurfaceRequest( |
| InitiateScopedSurfaceRequestCallback callback) override; |
| |
| void OnScopedSurfaceRequestCompleted(gl::ScopedJavaSurface surface); |
| |
| private: |
| void CreateMediaPlayer(const media::MediaUrlParams& params, |
| media::PipelineStatusCallback init_cb); |
| |
| // Cancels the pending request started by InitiateScopedSurfaceRequest(), if |
| // it exists. No-ops otherwise. |
| void CancelScopedSurfaceRequest(); |
| |
| void UpdateVolume(); |
| |
| mojo::Remote<ClientExtension> client_extension_; |
| |
| media::RendererClient* renderer_client_; |
| |
| std::unique_ptr<media::MediaPlayerBridge> media_player_; |
| |
| // Current duration of the media. |
| base::TimeDelta duration_; |
| |
| // Indicates if a serious error has been encountered by the |media_player_|. |
| bool has_error_; |
| |
| gfx::Size video_size_; |
| |
| base::UnguessableToken surface_request_token_; |
| |
| std::unique_ptr<media::MediaResourceGetter> media_resource_getter_; |
| |
| bool web_contents_muted_; |
| MediaPlayerRendererWebContentsObserver* web_contents_observer_; |
| float volume_; |
| |
| // NOTE: Weak pointers must be invalidated before all other member variables. |
| base::WeakPtrFactory<MediaPlayerRenderer> weak_factory_{this}; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_ |