blob: 2d9dc580d7a19875bbd719adc4c317209211dc4b [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MEDIA_BASE_STARBOARD_PLAYER_H_
#define MEDIA_BASE_STARBOARD_PLAYER_H_
#include <map>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "base/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decoder_buffer_cache.h"
#include "media/base/demuxer_stream.h"
#include "media/base/sbplayer_set_bounds_helper.h"
#include "media/base/video_decoder_config.h"
#include "starboard/media.h"
#include "starboard/player.h"
namespace media {
// TODO: Add switch to disable caching
class StarboardPlayer : public base::SupportsWeakPtr<StarboardPlayer> {
public:
class Host {
public:
virtual void OnNeedData(DemuxerStream::Type type) = 0;
virtual void OnPlayerStatus(SbPlayerState state) = 0;
protected:
~Host() {}
};
StarboardPlayer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
const AudioDecoderConfig& audio_config,
const VideoDecoderConfig& video_config,
SbWindow window,
SbDrmSystem drm_system,
Host* host,
SbPlayerSetBoundsHelper* set_bounds_helper);
~StarboardPlayer();
bool IsValid() const { return SbPlayerIsValid(player_); }
void UpdateVideoResolution(int frame_width, int frame_height);
void WriteBuffer(DemuxerStream::Type type,
const scoped_refptr<DecoderBuffer>& buffer);
void SetBounds(const gfx::Rect& rect);
void PrepareForSeek();
void Seek(base::TimeDelta time);
void SetVolume(float volume);
void SetPause(bool pause);
void GetInfo(uint32* video_frames_decoded,
uint32* video_frames_dropped,
base::TimeDelta* media_time);
void Suspend();
void Resume();
private:
enum State {
kPlaying,
kSuspended,
kResuming,
};
static const int64 kClearDecoderCacheIntervalInMilliseconds = 1000;
// A map from raw data pointer returned by DecoderBuffer::GetData() to the
// DecoderBuffer and a reference count. The reference count indicates how
// many instances of the DecoderBuffer is currently being decoded in the
// pipeline.
typedef std::map<const void*, std::pair<scoped_refptr<DecoderBuffer>, int> >
DecodingBuffers;
void CreatePlayer();
void ClearDecoderBufferCache();
void OnDecoderStatus(SbPlayer player,
SbMediaType type,
SbPlayerDecoderState state,
int ticket);
void OnPlayerStatus(SbPlayer player, SbPlayerState state, int ticket);
void OnDeallocateSample(const void* sample_buffer);
static void DecoderStatusCB(SbPlayer player,
void* context,
SbMediaType type,
SbPlayerDecoderState state,
int ticket);
static void PlayerStatusCB(SbPlayer player,
void* context,
SbPlayerState state,
int ticket);
static void DeallocateSampleCB(SbPlayer player,
void* context,
const void* sample_buffer);
// The following variables are initialized in the ctor and never changed.
const scoped_refptr<base::MessageLoopProxy> message_loop_;
AudioDecoderConfig audio_config_;
VideoDecoderConfig video_config_;
const SbWindow window_;
const SbDrmSystem drm_system_;
Host* const host_;
SbPlayerSetBoundsHelper* const set_bounds_helper_;
const base::WeakPtr<StarboardPlayer> weak_this_;
// The following variables are only changed or accessed from the
// |message_loop_|.
int frame_width_;
int frame_height_;
DecodingBuffers decoding_buffers_;
int ticket_;
float volume_;
bool paused_;
bool seek_pending_;
DecoderBufferCache decoder_buffer_cache_;
// The following variables can be accessed from GetInfo(), which can be called
// from any threads. So some of their usages have to be guarded by |lock_|.
base::Lock lock_;
State state_;
SbPlayer player_;
uint32 cached_video_frames_decoded_;
uint32 cached_video_frames_dropped_;
base::TimeDelta preroll_timestamp_;
};
} // namespace media
#endif // MEDIA_BASE_STARBOARD_PLAYER_H_