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