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