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   blink::WebTimeRanges Buffered() const;
     71   size_t DecodedFrameCount() const;
     72   size_t DroppedFrameCount() const;
     73   size_t AudioDecodedByteCount() const;
     74   size_t VideoDecodedByteCount() const;
     75 
     76   // In MSE case, calls ChunkDemuxer::CancelPendingSeek(). Also sets the
     77   // expectation that a regular seek will be arriving and to trivially finish
     78   // any browser seeks that may be requested prior to the regular seek.
     79   void CancelPendingSeek(const base::TimeDelta& seek_time);
     80 
     81   // In MSE case, calls ChunkDemuxer::StartWaitingForSeek(), first calling
     82   // ChunkDemuxer::CancelPendingSeek() if a browser seek is in progress.
     83   // Also sets the expectation that a regular seek will be arriving and to
     84   // trivially finish any browser seeks that may be requested prior to the
     85   // regular seek.
     86   void StartWaitingForSeek(const base::TimeDelta& seek_time);
     87 
     88   // Seeks the demuxer and later calls OnDemuxerSeekDone() after the seek has
     89   // been completed. There must be no other seek of the demuxer currently in
     90   // process when this method is called.
     91   // If |is_browser_seek| is true, then this is a short-term hack browser
     92   // seek.
     93   // TODO(wolenetz): Instead of doing browser seek, browser player should replay
     94   // cached data since last keyframe. See http://crbug.com/304234.
     95   void Seek(const base::TimeDelta& seek_time, bool is_browser_seek);
     96 
     97   // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer.
     98   void OnReadFromDemuxer(media::DemuxerStream::Type type);
     99 
    100   // Called by the Destroyer to destroy an instance of this object.
    101   void Destroy();
    102 
    103   // Called on the main thread to check whether the video stream is encrypted.
    104   bool IsVideoEncrypted();
    105 
    106   // Gets the ChunkDemuxer timeline offset.
    107   base::Time GetTimelineOffset() const;
    108 
    109  private:
    110   // This is private to enforce use of the Destroyer.
    111   virtual ~MediaSourceDelegate();
    112 
    113   // Methods inherited from DemuxerHost.
    114   virtual void AddBufferedTimeRange(base::TimeDelta start,
    115                                     base::TimeDelta end) OVERRIDE;
    116   virtual void SetDuration(base::TimeDelta duration) OVERRIDE;
    117   virtual void OnDemuxerError(media::PipelineStatus status) OVERRIDE;
    118   virtual void AddTextStream(media::DemuxerStream* text_stream,
    119                              const media::TextTrackConfig& config) OVERRIDE;
    120   virtual void RemoveTextStream(media::DemuxerStream* text_stream) OVERRIDE;
    121 
    122   // Notifies |demuxer_client_| and fires |duration_changed_cb_|.
    123   void OnDurationChanged(const base::TimeDelta& duration);
    124 
    125   // Callback for ChunkDemuxer initialization.
    126   void OnDemuxerInitDone(media::PipelineStatus status);
    127 
    128   // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted.
    129   void InitAudioDecryptingDemuxerStream();
    130   void InitVideoDecryptingDemuxerStream();
    131 
    132   // Callbacks for DecryptingDemuxerStream::Initialize().
    133   void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
    134   void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
    135 
    136   // Callback for ChunkDemuxer::Seek() and callback chain for resetting
    137   // decrypted audio/video streams if present.
    138   //
    139   // Runs on the media thread.
    140   void OnDemuxerSeekDone(media::PipelineStatus status);
    141   void ResetAudioDecryptingDemuxerStream();
    142   void ResetVideoDecryptingDemuxerStream();
    143   void FinishResettingDecryptingDemuxerStreams();
    144 
    145   // Callback for ChunkDemuxer::Stop() and helper for deleting |this| on the
    146   // main thread.
    147   void OnDemuxerStopDone();
    148   void DeleteSelf();
    149 
    150   void OnDemuxerOpened();
    151   void OnNeedKey(const std::string& type,
    152                  const std::vector<uint8>& init_data);
    153   void NotifyDemuxerReady();
    154 
    155   void StopDemuxer();
    156   void InitializeDemuxer();
    157   void SeekInternal(const base::TimeDelta& seek_time);
    158   // Reads an access unit from the demuxer stream |stream| and stores it in
    159   // the |index|th access unit in |params|.
    160   void ReadFromDemuxerStream(media::DemuxerStream::Type type,
    161                              scoped_ptr<media::DemuxerData> data,
    162                              size_t index);
    163   void OnBufferReady(media::DemuxerStream::Type type,
    164                      scoped_ptr<media::DemuxerData> data,
    165                      size_t index,
    166                      media::DemuxerStream::Status status,
    167                      const scoped_refptr<media::DecoderBuffer>& buffer);
    168 
    169   // Helper function for calculating duration.
    170   base::TimeDelta GetDuration() const;
    171 
    172   bool IsSeeking() const;
    173 
    174   // Returns |seek_time| if it is still buffered or if there is no currently
    175   // buffered range including or soon after |seek_time|. If |seek_time| is not
    176   // buffered, but there is a later range buffered near to |seek_time|, returns
    177   // next buffered range's start time instead. Only call this for browser seeks.
    178   // |seeking_lock_| must be held by caller.
    179   base::TimeDelta FindBufferedBrowserSeekTime_Locked(
    180       const base::TimeDelta& seek_time) const;
    181 
    182   // Get the demuxer configs for a particular stream identified by |is_audio|.
    183   // Returns true on success, of false otherwise.
    184   bool GetDemuxerConfigFromStream(media::DemuxerConfigs* configs,
    185                                   bool is_audio);
    186 
    187   RendererDemuxerAndroid* demuxer_client_;
    188   int demuxer_client_id_;
    189 
    190   scoped_refptr<media::MediaLog> media_log_;
    191   UpdateNetworkStateCB update_network_state_cb_;
    192   DurationChangeCB duration_change_cb_;
    193 
    194   scoped_ptr<media::ChunkDemuxer> chunk_demuxer_;
    195   bool is_demuxer_ready_;
    196 
    197   media::SetDecryptorReadyCB set_decryptor_ready_cb_;
    198 
    199   scoped_ptr<media::DecryptingDemuxerStream> audio_decrypting_demuxer_stream_;
    200   scoped_ptr<media::DecryptingDemuxerStream> video_decrypting_demuxer_stream_;
    201 
    202   media::DemuxerStream* audio_stream_;
    203   media::DemuxerStream* video_stream_;
    204 
    205   media::PipelineStatistics statistics_;
    206   media::Ranges<base::TimeDelta> buffered_time_ranges_;
    207 
    208   MediaSourceOpenedCB media_source_opened_cb_;
    209   media::Demuxer::NeedKeyCB need_key_cb_;
    210 
    211   // Temporary for EME v0.1. In the future the init data type should be passed
    212   // through GenerateKeyRequest() directly from WebKit.
    213   std::string init_data_type_;
    214 
    215   // Lock used to serialize access for |seeking_|.
    216   mutable base::Lock seeking_lock_;
    217   bool seeking_;
    218 
    219   // Lock used to serialize access for |is_video_encrypted_|.
    220   mutable base::Lock is_video_encrypted_lock_;
    221   bool is_video_encrypted_;
    222 
    223   // Track if we are currently performing a browser seek, and track whether or
    224   // not a regular seek is expected soon. If a regular seek is expected soon,
    225   // then any in-progress browser seek will be canceled pending the
    226   // regular seek, if using |chunk_demuxer_|, and any requested browser seek
    227   // will be trivially finished. Access is serialized by |seeking_lock_|.
    228   bool doing_browser_seek_;
    229   base::TimeDelta browser_seek_time_;
    230   bool expecting_regular_seek_;
    231 
    232   size_t access_unit_size_;
    233 
    234   // Message loop for main renderer and media threads.
    235   const scoped_refptr<base::MessageLoopProxy> main_loop_;
    236   const scoped_refptr<base::MessageLoopProxy> media_loop_;
    237 
    238   // NOTE: Weak pointers must be invalidated before all other member variables.
    239   base::WeakPtrFactory<MediaSourceDelegate> main_weak_factory_;
    240   base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_;
    241   base::WeakPtr<MediaSourceDelegate> main_weak_this_;
    242 
    243   DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate);
    244 };
    245 
    246 }  // namespace content
    247 
    248 #endif  // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
    249