Home | History | Annotate | Download | only in filters
      1 // Copyright (c) 2012 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 // Implements the Demuxer interface using FFmpeg's libavformat.  At this time
      6 // will support demuxing any audio/video format thrown at it.  The streams
      7 // output mime types audio/x-ffmpeg and video/x-ffmpeg and include an integer
      8 // key FFmpegCodecID which contains the CodecID enumeration value.  The CodecIDs
      9 // can be used to create and initialize the corresponding FFmpeg decoder.
     10 //
     11 // FFmpegDemuxer sets the duration of pipeline during initialization by using
     12 // the duration of the longest audio/video stream.
     13 //
     14 // NOTE: since FFmpegDemuxer reads packets sequentially without seeking, media
     15 // files with very large drift between audio/video streams may result in
     16 // excessive memory consumption.
     17 //
     18 // When stopped, FFmpegDemuxer and FFmpegDemuxerStream release all callbacks
     19 // and buffered packets.  Reads from a stopped FFmpegDemuxerStream will not be
     20 // replied to.
     21 
     22 #ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_H_
     23 #define MEDIA_FILTERS_FFMPEG_DEMUXER_H_
     24 
     25 #include <string>
     26 #include <vector>
     27 
     28 #include "base/callback.h"
     29 #include "base/gtest_prod_util.h"
     30 #include "base/memory/scoped_vector.h"
     31 #include "base/threading/thread.h"
     32 #include "media/base/audio_decoder_config.h"
     33 #include "media/base/decoder_buffer.h"
     34 #include "media/base/decoder_buffer_queue.h"
     35 #include "media/base/demuxer.h"
     36 #include "media/base/pipeline.h"
     37 #include "media/base/video_decoder_config.h"
     38 #include "media/filters/blocking_url_protocol.h"
     39 
     40 // FFmpeg forward declarations.
     41 struct AVPacket;
     42 struct AVRational;
     43 struct AVStream;
     44 
     45 namespace media {
     46 
     47 // A new potentially encrypted stream has been parsed.
     48 // First parameter - The type of initialization data.
     49 // Second parameter - The initialization data associated with the stream.
     50 // Third parameter - Number of bytes of the initialization data.
     51 typedef base::Callback<void(const std::string& type,
     52                             scoped_ptr<uint8[]> init_data,
     53                             int init_data_size)> FFmpegNeedKeyCB;
     54 
     55 class MediaLog;
     56 class FFmpegDemuxer;
     57 class FFmpegGlue;
     58 class FFmpegH264ToAnnexBBitstreamConverter;
     59 class ScopedPtrAVFreePacket;
     60 
     61 typedef scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> ScopedAVPacket;
     62 
     63 class FFmpegDemuxerStream : public DemuxerStream {
     64  public:
     65   // Keeps a copy of |demuxer| and initializes itself using information
     66   // inside |stream|.  Both parameters must outlive |this|.
     67   FFmpegDemuxerStream(FFmpegDemuxer* demuxer, AVStream* stream);
     68   virtual ~FFmpegDemuxerStream();
     69 
     70   // Enqueues the given AVPacket. It is invalid to queue a |packet| after
     71   // SetEndOfStream() has been called.
     72   void EnqueuePacket(ScopedAVPacket packet);
     73 
     74   // Enters the end of stream state. After delivering remaining queued buffers
     75   // only end of stream buffers will be delivered.
     76   void SetEndOfStream();
     77 
     78   // Drops queued buffers and clears end of stream state.
     79   void FlushBuffers();
     80 
     81   // Empties the queues and ignores any additional calls to Read().
     82   void Stop();
     83 
     84   // Returns the duration of this stream.
     85   base::TimeDelta duration();
     86 
     87   // DemuxerStream implementation.
     88   virtual Type type() OVERRIDE;
     89   virtual void Read(const ReadCB& read_cb) OVERRIDE;
     90   virtual void EnableBitstreamConverter() OVERRIDE;
     91   virtual AudioDecoderConfig audio_decoder_config() OVERRIDE;
     92   virtual VideoDecoderConfig video_decoder_config() OVERRIDE;
     93 
     94   // Returns the range of buffered data in this stream.
     95   Ranges<base::TimeDelta> GetBufferedRanges() const;
     96 
     97   // Returns elapsed time based on the already queued packets.
     98   // Used to determine stream duration when it's not known ahead of time.
     99   base::TimeDelta GetElapsedTime() const;
    100 
    101   // Returns true if this stream has capacity for additional data.
    102   bool HasAvailableCapacity();
    103 
    104  private:
    105   friend class FFmpegDemuxerTest;
    106 
    107   // Runs |read_cb_| if present with the front of |buffer_queue_|, calling
    108   // NotifyCapacityAvailable() if capacity is still available.
    109   void SatisfyPendingRead();
    110 
    111   // Converts an FFmpeg stream timestamp into a base::TimeDelta.
    112   static base::TimeDelta ConvertStreamTimestamp(const AVRational& time_base,
    113                                                 int64 timestamp);
    114 
    115   FFmpegDemuxer* demuxer_;
    116   scoped_refptr<base::MessageLoopProxy> message_loop_;
    117   AVStream* stream_;
    118   AudioDecoderConfig audio_config_;
    119   VideoDecoderConfig video_config_;
    120   Type type_;
    121   base::TimeDelta duration_;
    122   bool end_of_stream_;
    123   base::TimeDelta last_packet_timestamp_;
    124   Ranges<base::TimeDelta> buffered_ranges_;
    125 
    126   DecoderBufferQueue buffer_queue_;
    127   ReadCB read_cb_;
    128 
    129   scoped_ptr<FFmpegH264ToAnnexBBitstreamConverter> bitstream_converter_;
    130   bool bitstream_converter_enabled_;
    131 
    132   std::string encryption_key_id_;
    133 
    134   DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream);
    135 };
    136 
    137 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
    138  public:
    139   FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
    140                 DataSource* data_source,
    141                 const FFmpegNeedKeyCB& need_key_cb,
    142                 const scoped_refptr<MediaLog>& media_log);
    143   virtual ~FFmpegDemuxer();
    144 
    145   // Demuxer implementation.
    146   virtual void Initialize(DemuxerHost* host,
    147                           const PipelineStatusCB& status_cb) OVERRIDE;
    148   virtual void Stop(const base::Closure& callback) OVERRIDE;
    149   virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
    150   virtual void OnAudioRendererDisabled() OVERRIDE;
    151   virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
    152   virtual DemuxerStream* GetStream(DemuxerStream::Type type) OVERRIDE;
    153   virtual base::TimeDelta GetStartTime() const OVERRIDE;
    154 
    155   // Calls |need_key_cb_| with the initialization data encountered in the file.
    156   void FireNeedKey(const std::string& init_data_type,
    157                    const std::string& encryption_key_id);
    158 
    159   // Allow FFmpegDemuxerStream to notify us when there is updated information
    160   // about capacity and what buffered data is available.
    161   void NotifyCapacityAvailable();
    162   void NotifyBufferingChanged();
    163 
    164  private:
    165   // To allow tests access to privates.
    166   friend class FFmpegDemuxerTest;
    167 
    168   // FFmpeg callbacks during initialization.
    169   void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result);
    170   void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result);
    171 
    172   // FFmpeg callbacks during seeking.
    173   void OnSeekFrameDone(const PipelineStatusCB& cb, int result);
    174 
    175   // FFmpeg callbacks during reading + helper method to initiate reads.
    176   void ReadFrameIfNeeded();
    177   void OnReadFrameDone(ScopedAVPacket packet, int result);
    178 
    179   // DataSource callbacks during stopping.
    180   void OnDataSourceStopped(const base::Closure& callback);
    181 
    182   // Returns true iff any stream has additional capacity. Note that streams can
    183   // go over capacity depending on how the file is muxed.
    184   bool StreamsHaveAvailableCapacity();
    185 
    186   // Signal all FFmpegDemuxerStreams that the stream has ended.
    187   void StreamHasEnded();
    188 
    189   // Called by |url_protocol_| whenever |data_source_| returns a read error.
    190   void OnDataSourceError();
    191 
    192   // Returns the stream from |streams_| that matches |type| as an
    193   // FFmpegDemuxerStream.
    194   FFmpegDemuxerStream* GetFFmpegStream(DemuxerStream::Type type) const;
    195 
    196   DemuxerHost* host_;
    197 
    198   scoped_refptr<base::MessageLoopProxy> message_loop_;
    199   base::WeakPtrFactory<FFmpegDemuxer> weak_factory_;
    200   base::WeakPtr<FFmpegDemuxer> weak_this_;
    201 
    202   // Thread on which all blocking FFmpeg operations are executed.
    203   base::Thread blocking_thread_;
    204 
    205   // Tracks if there's an outstanding av_read_frame() operation.
    206   //
    207   // TODO(scherkus): Allow more than one read in flight for higher read
    208   // throughput using demuxer_bench to verify improvements.
    209   bool pending_read_;
    210 
    211   // Tracks if there's an outstanding av_seek_frame() operation. Used to discard
    212   // results of pre-seek av_read_frame() operations.
    213   bool pending_seek_;
    214 
    215   // |streams_| mirrors the AVStream array in |format_context_|. It contains
    216   // FFmpegDemuxerStreams encapsluating AVStream objects at the same index.
    217   //
    218   // Since we only support a single audio and video stream, |streams_| will
    219   // contain NULL entries for additional audio/video streams as well as for
    220   // stream types that we do not currently support.
    221   //
    222   // Once initialized, operations on FFmpegDemuxerStreams should be carried out
    223   // on the demuxer thread.
    224   typedef ScopedVector<FFmpegDemuxerStream> StreamVector;
    225   StreamVector streams_;
    226 
    227   // Provides asynchronous IO to this demuxer. Consumed by |url_protocol_| to
    228   // integrate with libavformat.
    229   DataSource* data_source_;
    230 
    231   scoped_refptr<MediaLog> media_log_;
    232 
    233   // Derived bitrate after initialization has completed.
    234   int bitrate_;
    235 
    236   // The first timestamp of the opened media file. This is used to set the
    237   // starting clock value to match the timestamps in the media file. Default
    238   // is 0.
    239   base::TimeDelta start_time_;
    240 
    241   // Whether audio has been disabled for this demuxer (in which case this class
    242   // drops packets destined for AUDIO demuxer streams on the floor).
    243   bool audio_disabled_;
    244 
    245   // Set if we know duration of the audio stream. Used when processing end of
    246   // stream -- at this moment we definitely know duration.
    247   bool duration_known_;
    248 
    249   // FFmpegURLProtocol implementation and corresponding glue bits.
    250   BlockingUrlProtocol url_protocol_;
    251   scoped_ptr<FFmpegGlue> glue_;
    252 
    253   const FFmpegNeedKeyCB need_key_cb_;
    254 
    255   DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer);
    256 };
    257 
    258 }  // namespace media
    259 
    260 #endif  // MEDIA_FILTERS_FFMPEG_DEMUXER_H_
    261