Home | History | Annotate | Download | only in android
      1 // Copyright 2013 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 CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
      6 #define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/callback.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/time/time.h"
     17 #include "media/base/decryptor.h"
     18 #include "media/base/demuxer.h"
     19 #include "media/base/media_keys.h"
     20 #include "media/base/pipeline_status.h"
     21 #include "media/base/ranges.h"
     22 #include "media/base/text_track.h"
     23 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
     24 
     25 namespace media {
     26 class ChunkDemuxer;
     27 class DecoderBuffer;
     28 class DecryptingDemuxerStream;
     29 class DemuxerStream;
     30 class MediaLog;
     31 struct DemuxerConfigs;
     32 struct DemuxerData;
     33 }
     34 
     35 namespace content {
     36 
     37 class RendererDemuxerAndroid;
     38 
     39 class MediaSourceDelegate : public media::DemuxerHost {
     40  public:
     41   typedef base::Callback<void(blink::WebMediaSource*)>
     42       MediaSourceOpenedCB;
     43   typedef base::Callback<void(blink::WebMediaPlayer::NetworkState)>
     44       UpdateNetworkStateCB;
     45   typedef base::Callback<void(const base::TimeDelta&)> DurationChangeCB;
     46 
     47   // Helper class used by scoped_ptr to destroy an instance of
     48   // MediaSourceDelegate.
     49   class Destroyer {
     50    public:
     51     inline void operator()(void* media_source_delegate) const {
     52       static_cast<MediaSourceDelegate*>(media_source_delegate)->Destroy();
     53     }
     54   };
     55 
     56   MediaSourceDelegate(RendererDemuxerAndroid* demuxer_client,
     57                       int demuxer_client_id,
     58                       const scoped_refptr<base::MessageLoopProxy>& media_loop,
     59                       media::MediaLog* media_log);
     60 
     61   // Initialize the MediaSourceDelegate. |media_source| will be owned by
     62   // this object after this call.
     63   void InitializeMediaSource(
     64       const MediaSourceOpenedCB& media_source_opened_cb,
     65       const media::Demuxer::NeedKeyCB& need_key_cb,
     66       const media::SetDecryptorReadyCB& set_decryptor_ready_cb,
     67       const UpdateNetworkStateCB& update_network_state_cb,
     68       const DurationChangeCB& duration_change_cb);
     69 
     70 #if defined(GOOGLE_TV)
     71   void InitializeMediaStream(
     72       media::Demuxer* demuxer,
     73       const UpdateNetworkStateCB& update_network_state_cb);
     74 #endif
     75 
     76   const blink::WebTimeRanges& Buffered();
     77   size_t DecodedFrameCount() const;
     78   size_t DroppedFrameCount() const;
     79   size_t AudioDecodedByteCount() const;
     80   size_t VideoDecodedByteCount() const;
     81 
     82   // In MSE case, calls ChunkDemuxer::CancelPendingSeek(). Also sets the
     83   // expectation that a regular seek will be arriving and to trivially finish
     84   // any browser seeks that may be requested prior to the regular seek.
     85   void CancelPendingSeek(const base::TimeDelta& seek_time);
     86 
     87   // In MSE case, calls ChunkDemuxer::StartWaitingForSeek(), first calling
     88   // ChunkDemuxer::CancelPendingSeek() if a browser seek is in progress.
     89   // Also sets the expectation that a regular seek will be arriving and to
     90   // trivially finish any browser seeks that may be requested prior to the
     91   // regular seek.
     92   void StartWaitingForSeek(const base::TimeDelta& seek_time);
     93 
     94   // Seeks the demuxer and later calls OnDemuxerSeekDone() after the seek has
     95   // been completed. There must be no other seek of the demuxer currently in
     96   // process when this method is called.
     97   // If |is_browser_seek| is true, then this is a short-term hack browser
     98   // seek.
     99   // TODO(wolenetz): Instead of doing browser seek, browser player should replay
    100   // cached data since last keyframe. See http://crbug.com/304234.
    101   void Seek(const base::TimeDelta& seek_time, bool is_browser_seek);
    102 
    103   void NotifyKeyAdded(const std::string& key_system);
    104 
    105   // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer.
    106   void OnReadFromDemuxer(media::DemuxerStream::Type type);
    107 
    108   // Called when the player needs the new config data from ChunkDemuxer.
    109   void OnMediaConfigRequest();
    110 
    111   // Called by the Destroyer to destroy an instance of this object.
    112   void Destroy();
    113 
    114  private:
    115   typedef base::Callback<void(scoped_ptr<media::DemuxerData> data)>
    116       ReadFromDemuxerAckCB;
    117   typedef base::Callback<void(scoped_ptr<media::DemuxerConfigs> configs)>
    118       DemuxerReadyCB;
    119 
    120   // This is private to enforce use of the Destroyer.
    121   virtual ~MediaSourceDelegate();
    122 
    123   // Methods inherited from DemuxerHost.
    124   virtual void SetTotalBytes(int64 total_bytes) OVERRIDE;
    125   virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE;
    126   virtual void AddBufferedTimeRange(base::TimeDelta start,
    127                                     base::TimeDelta end) OVERRIDE;
    128   virtual void SetDuration(base::TimeDelta duration) OVERRIDE;
    129   virtual void OnDemuxerError(media::PipelineStatus status) OVERRIDE;
    130   virtual void AddTextStream(media::DemuxerStream* text_stream,
    131                              const media::TextTrackConfig& config) OVERRIDE;
    132   virtual void RemoveTextStream(media::DemuxerStream* text_stream) OVERRIDE;
    133 
    134   // Notifies |demuxer_client_| and fires |duration_changed_cb_|.
    135   void OnDurationChanged(const base::TimeDelta& duration);
    136 
    137   // Callback for ChunkDemuxer initialization.
    138   void OnDemuxerInitDone(media::PipelineStatus status);
    139 
    140   // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted.
    141   void InitAudioDecryptingDemuxerStream();
    142   void InitVideoDecryptingDemuxerStream();
    143 
    144   // Callbacks for DecryptingDemuxerStream::Initialize().
    145   void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
    146   void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
    147 
    148   // Callback for ChunkDemuxer::Seek() and callback chain for resetting
    149   // decrypted audio/video streams if present.
    150   //
    151   // Runs on the media thread.
    152   void OnDemuxerSeekDone(media::PipelineStatus status);
    153   void ResetAudioDecryptingDemuxerStream();
    154   void ResetVideoDecryptingDemuxerStream();
    155   void FinishResettingDecryptingDemuxerStreams();
    156 
    157   void OnDemuxerStopDone();
    158   void OnDemuxerOpened();
    159   void OnNeedKey(const std::string& type,
    160                  const std::vector<uint8>& init_data);
    161   void NotifyDemuxerReady();
    162   bool CanNotifyDemuxerReady();
    163 
    164   void StopDemuxer();
    165   void InitializeDemuxer();
    166   void SeekInternal(const base::TimeDelta& seek_time);
    167   // Reads an access unit from the demuxer stream |stream| and stores it in
    168   // the |index|th access unit in |params|.
    169   void ReadFromDemuxerStream(media::DemuxerStream::Type type,
    170                              scoped_ptr<media::DemuxerData> data,
    171                              size_t index);
    172   void OnBufferReady(media::DemuxerStream::Type type,
    173                      scoped_ptr<media::DemuxerData> data,
    174                      size_t index,
    175                      media::DemuxerStream::Status status,
    176                      const scoped_refptr<media::DecoderBuffer>& buffer);
    177 
    178   // Helper function for calculating duration.
    179   int GetDurationMs();
    180 
    181   bool HasEncryptedStream();
    182 
    183   bool IsSeeking() const;
    184 
    185   // Returns |seek_time| if it is still buffered or if there is no currently
    186   // buffered range including or soon after |seek_time|. If |seek_time| is not
    187   // buffered, but there is a later range buffered near to |seek_time|, returns
    188   // next buffered range's start time instead. Only call this for browser seeks.
    189   // |seeking_lock_| must be held by caller.
    190   base::TimeDelta FindBufferedBrowserSeekTime_Locked(
    191       const base::TimeDelta& seek_time) const;
    192 
    193   // Message loop for main renderer thread and corresponding weak pointer.
    194   const scoped_refptr<base::MessageLoopProxy> main_loop_;
    195   base::WeakPtrFactory<MediaSourceDelegate> main_weak_factory_;
    196   base::WeakPtr<MediaSourceDelegate> main_weak_this_;
    197 
    198   // Message loop for media thread and corresponding weak pointer.
    199   const scoped_refptr<base::MessageLoopProxy> media_loop_;
    200   base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_;
    201 
    202   RendererDemuxerAndroid* demuxer_client_;
    203   int demuxer_client_id_;
    204 
    205   scoped_refptr<media::MediaLog> media_log_;
    206   UpdateNetworkStateCB update_network_state_cb_;
    207   DurationChangeCB duration_change_cb_;
    208 
    209   scoped_ptr<media::ChunkDemuxer> chunk_demuxer_;
    210   media::Demuxer* demuxer_;
    211   bool is_demuxer_ready_;
    212 
    213   media::SetDecryptorReadyCB set_decryptor_ready_cb_;
    214 
    215   scoped_ptr<media::DecryptingDemuxerStream> audio_decrypting_demuxer_stream_;
    216   scoped_ptr<media::DecryptingDemuxerStream> video_decrypting_demuxer_stream_;
    217 
    218   media::DemuxerStream* audio_stream_;
    219   media::DemuxerStream* video_stream_;
    220 
    221   media::PipelineStatistics statistics_;
    222   media::Ranges<base::TimeDelta> buffered_time_ranges_;
    223   // Keep a list of buffered time ranges.
    224   blink::WebTimeRanges buffered_web_time_ranges_;
    225 
    226   MediaSourceOpenedCB media_source_opened_cb_;
    227   media::Demuxer::NeedKeyCB need_key_cb_;
    228 
    229   // The currently selected key system. Empty string means that no key system
    230   // has been selected.
    231   blink::WebString current_key_system_;
    232 
    233   // Temporary for EME v0.1. In the future the init data type should be passed
    234   // through GenerateKeyRequest() directly from WebKit.
    235   std::string init_data_type_;
    236 
    237   // Lock used to serialize access for |seeking_|.
    238   mutable base::Lock seeking_lock_;
    239   bool seeking_;
    240 
    241   // Track if we are currently performing a browser seek, and track whether or
    242   // not a regular seek is expected soon. If a regular seek is expected soon,
    243   // then any in-progress browser seek will be canceled pending the
    244   // regular seek, if using |chunk_demuxer_|, and any requested browser seek
    245   // will be trivially finished. Access is serialized by |seeking_lock_|.
    246   bool doing_browser_seek_;
    247   base::TimeDelta browser_seek_time_;
    248   bool expecting_regular_seek_;
    249 
    250 #if defined(GOOGLE_TV)
    251   bool key_added_;
    252   std::string key_system_;
    253 #endif  // defined(GOOGLE_TV)
    254 
    255   size_t access_unit_size_;
    256 
    257   DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate);
    258 };
    259 
    260 }  // namespace content
    261 
    262 #endif  // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
    263