blob: 9debfc331b09f8522433c4c827425afdb27b81c1 [file] [log] [blame]
// 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/render_frame_host.h"
#include "media/base/android/media_player_bridge.h"
#include "media/base/android/media_player_manager.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 "url/gurl.h"
namespace content {
// 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.
//
// N.B: MediaPlayerRenderer implements MediaPlayerManager, since
// MediaPlayerBridge is tightly coupled with the manager abstraction.
// |player_id| is ignored in all MediaPlayerManager calls, as there is only one
// MediaPlayer per MediaPlayerRenderer.
//
// TODO(tguilbert): Remove the MediaPlayerManager implementation and update
// MediaPlayerBridge, once WMPA has been deleted. See http://crbug.com/580626
class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
public media::MediaPlayerManager {
public:
// Permits embedders to handle custom urls.
static void RegisterMediaUrlInterceptor(
media::MediaUrlInterceptor* media_url_interceptor);
explicit MediaPlayerRenderer(content::RenderFrameHost* render_frame_host);
~MediaPlayerRenderer() override;
// media::Renderer implementation
void Initialize(media::MediaResource* media_resource,
media::RendererClient* client,
const media::PipelineStatusCB& init_cb) override;
void SetCdm(media::CdmContext* cdm_context,
const media::CdmAttachedCB& cdm_attached_cb) override;
void Flush(const base::Closure& 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::MediaPlayerManager implementation
media::MediaResourceGetter* GetMediaResourceGetter() override;
media::MediaUrlInterceptor* GetMediaUrlInterceptor() override;
void OnTimeUpdate(int player_id,
base::TimeDelta current_timestamp,
base::TimeTicks current_time_ticks) override;
void OnMediaMetadataChanged(int player_id,
base::TimeDelta duration,
int width,
int height,
bool success) override;
void OnPlaybackComplete(int player_id) override;
void OnMediaInterrupted(int player_id) override;
void OnBufferingUpdate(int player_id, int percentage) override;
void OnSeekComplete(int player_id,
const base::TimeDelta& current_time) override;
void OnError(int player_id, int error) override;
void OnVideoSizeChanged(int player_id, int width, int height) override;
media::MediaPlayerAndroid* GetFullscreenPlayer() override;
media::MediaPlayerAndroid* GetPlayer(int player_id) override;
bool RequestPlay(int player_id,
base::TimeDelta duration,
bool has_audio) override;
// 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.
base::UnguessableToken InitiateScopedSurfaceRequest();
void OnScopedSurfaceRequestCompleted(gl::ScopedJavaSurface surface);
private:
void CreateMediaPlayer(const media::MediaUrlParams& params,
const media::PipelineStatusCB& init_cb);
// Used when creating |media_player_|.
void OnDecoderResourcesReleased(int player_id);
// Cancels the pending request started by InitiateScopedSurfaceRequest(), if
// it exists. No-ops otherwise.
void CancelScopedSurfaceRequest();
RenderFrameHost* render_frame_host_;
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_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<MediaPlayerRenderer> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MediaPlayerRenderer);
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_