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 <utility> 27 #include <vector> 28 29 #include "base/callback.h" 30 #include "base/gtest_prod_util.h" 31 #include "base/memory/scoped_vector.h" 32 #include "base/threading/thread.h" 33 #include "media/base/audio_decoder_config.h" 34 #include "media/base/decoder_buffer.h" 35 #include "media/base/decoder_buffer_queue.h" 36 #include "media/base/demuxer.h" 37 #include "media/base/pipeline.h" 38 #include "media/base/text_track_config.h" 39 #include "media/base/video_decoder_config.h" 40 #include "media/ffmpeg/ffmpeg_deleters.h" 41 #include "media/filters/blocking_url_protocol.h" 42 43 // FFmpeg forward declarations. 44 struct AVPacket; 45 struct AVRational; 46 struct AVStream; 47 48 namespace media { 49 50 class MediaLog; 51 class FFmpegDemuxer; 52 class FFmpegGlue; 53 class FFmpegH264ToAnnexBBitstreamConverter; 54 55 typedef scoped_ptr<AVPacket, ScopedPtrAVFreePacket> ScopedAVPacket; 56 57 class FFmpegDemuxerStream : public DemuxerStream { 58 public: 59 // Keeps a copy of |demuxer| and initializes itself using information inside 60 // |stream|. Both parameters must outlive |this|. 61 FFmpegDemuxerStream(FFmpegDemuxer* demuxer, AVStream* stream); 62 virtual ~FFmpegDemuxerStream(); 63 64 // Enqueues the given AVPacket. It is invalid to queue a |packet| after 65 // SetEndOfStream() has been called. 66 void EnqueuePacket(ScopedAVPacket packet); 67 68 // Enters the end of stream state. After delivering remaining queued buffers 69 // only end of stream buffers will be delivered. 70 void SetEndOfStream(); 71 72 // Drops queued buffers and clears end of stream state. 73 void FlushBuffers(); 74 75 // Empties the queues and ignores any additional calls to Read(). 76 void Stop(); 77 78 base::TimeDelta duration() const { return duration_; } 79 80 // Enables fixes for ogg files with negative timestamps. For AUDIO streams, 81 // all packets with negative timestamps will be marked for post-decode 82 // discard. For all other stream types, if FFmpegDemuxer::start_time() is 83 // negative, it will not be used to shift timestamps during EnqueuePacket(). 84 void enable_negative_timestamp_fixups_for_ogg() { 85 fixup_negative_ogg_timestamps_ = true; 86 } 87 88 // DemuxerStream implementation. 89 virtual Type type() OVERRIDE; 90 virtual void Read(const ReadCB& read_cb) OVERRIDE; 91 virtual void EnableBitstreamConverter() OVERRIDE; 92 virtual bool SupportsConfigChanges() OVERRIDE; 93 virtual AudioDecoderConfig audio_decoder_config() OVERRIDE; 94 virtual VideoDecoderConfig video_decoder_config() OVERRIDE; 95 virtual VideoRotation video_rotation() OVERRIDE; 96 97 // Returns the range of buffered data in this stream. 98 Ranges<base::TimeDelta> GetBufferedRanges() const; 99 100 // Returns elapsed time based on the already queued packets. 101 // Used to determine stream duration when it's not known ahead of time. 102 base::TimeDelta GetElapsedTime() const; 103 104 // Returns true if this stream has capacity for additional data. 105 bool HasAvailableCapacity(); 106 107 // Returns the total buffer size FFMpegDemuxerStream is holding onto. 108 size_t MemoryUsage() const; 109 110 TextKind GetTextKind() const; 111 112 // Returns the value associated with |key| in the metadata for the avstream. 113 // Returns an empty string if the key is not present. 114 std::string GetMetadata(const char* key) const; 115 116 private: 117 friend class FFmpegDemuxerTest; 118 119 // Runs |read_cb_| if present with the front of |buffer_queue_|, calling 120 // NotifyCapacityAvailable() if capacity is still available. 121 void SatisfyPendingRead(); 122 123 // Converts an FFmpeg stream timestamp into a base::TimeDelta. 124 static base::TimeDelta ConvertStreamTimestamp(const AVRational& time_base, 125 int64 timestamp); 126 127 FFmpegDemuxer* demuxer_; 128 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 129 AVStream* stream_; 130 AudioDecoderConfig audio_config_; 131 VideoDecoderConfig video_config_; 132 Type type_; 133 base::TimeDelta duration_; 134 bool end_of_stream_; 135 base::TimeDelta last_packet_timestamp_; 136 base::TimeDelta last_packet_duration_; 137 Ranges<base::TimeDelta> buffered_ranges_; 138 VideoRotation video_rotation_; 139 140 DecoderBufferQueue buffer_queue_; 141 ReadCB read_cb_; 142 143 #if defined(USE_PROPRIETARY_CODECS) 144 scoped_ptr<FFmpegH264ToAnnexBBitstreamConverter> bitstream_converter_; 145 #endif 146 147 bool bitstream_converter_enabled_; 148 149 std::string encryption_key_id_; 150 bool fixup_negative_ogg_timestamps_; 151 152 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream); 153 }; 154 155 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer { 156 public: 157 FFmpegDemuxer(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 158 DataSource* data_source, 159 const NeedKeyCB& need_key_cb, 160 const scoped_refptr<MediaLog>& media_log); 161 virtual ~FFmpegDemuxer(); 162 163 // Demuxer implementation. 164 virtual void Initialize(DemuxerHost* host, 165 const PipelineStatusCB& status_cb, 166 bool enable_text_tracks) OVERRIDE; 167 virtual void Stop() OVERRIDE; 168 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE; 169 virtual base::Time GetTimelineOffset() const OVERRIDE; 170 virtual DemuxerStream* GetStream(DemuxerStream::Type type) OVERRIDE; 171 virtual base::TimeDelta GetStartTime() const OVERRIDE; 172 virtual Liveness GetLiveness() const OVERRIDE; 173 174 // Calls |need_key_cb_| with the initialization data encountered in the file. 175 void FireNeedKey(const std::string& init_data_type, 176 const std::string& encryption_key_id); 177 178 // Allow FFmpegDemuxerStream to notify us when there is updated information 179 // about capacity and what buffered data is available. 180 void NotifyCapacityAvailable(); 181 void NotifyBufferingChanged(); 182 183 // The lowest demuxed timestamp. If negative, DemuxerStreams must use this to 184 // adjust packet timestamps such that external clients see a zero-based 185 // timeline. 186 base::TimeDelta start_time() const { return start_time_; } 187 188 private: 189 // To allow tests access to privates. 190 friend class FFmpegDemuxerTest; 191 192 // FFmpeg callbacks during initialization. 193 void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result); 194 void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result); 195 196 // FFmpeg callbacks during seeking. 197 void OnSeekFrameDone(const PipelineStatusCB& cb, int result); 198 199 // FFmpeg callbacks during reading + helper method to initiate reads. 200 void ReadFrameIfNeeded(); 201 void OnReadFrameDone(ScopedAVPacket packet, int result); 202 203 // Returns true iff any stream has additional capacity. Note that streams can 204 // go over capacity depending on how the file is muxed. 205 bool StreamsHaveAvailableCapacity(); 206 207 // Returns true if the maximum allowed memory usage has been reached. 208 bool IsMaxMemoryUsageReached() const; 209 210 // Signal all FFmpegDemuxerStreams that the stream has ended. 211 void StreamHasEnded(); 212 213 // Called by |url_protocol_| whenever |data_source_| returns a read error. 214 void OnDataSourceError(); 215 216 // Returns the stream from |streams_| that matches |type| as an 217 // FFmpegDemuxerStream. 218 FFmpegDemuxerStream* GetFFmpegStream(DemuxerStream::Type type) const; 219 220 // Called after the streams have been collected from the media, to allow 221 // the text renderer to bind each text stream to the cue rendering engine. 222 void AddTextStreams(); 223 224 DemuxerHost* host_; 225 226 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 227 228 // Thread on which all blocking FFmpeg operations are executed. 229 base::Thread blocking_thread_; 230 231 // Tracks if there's an outstanding av_read_frame() operation. 232 // 233 // TODO(scherkus): Allow more than one read in flight for higher read 234 // throughput using demuxer_bench to verify improvements. 235 bool pending_read_; 236 237 // Tracks if there's an outstanding av_seek_frame() operation. Used to discard 238 // results of pre-seek av_read_frame() operations. 239 bool pending_seek_; 240 241 // |streams_| mirrors the AVStream array in AVFormatContext. It contains 242 // FFmpegDemuxerStreams encapsluating AVStream objects at the same index. 243 // 244 // Since we only support a single audio and video stream, |streams_| will 245 // contain NULL entries for additional audio/video streams as well as for 246 // stream types that we do not currently support. 247 // 248 // Once initialized, operations on FFmpegDemuxerStreams should be carried out 249 // on the demuxer thread. 250 typedef ScopedVector<FFmpegDemuxerStream> StreamVector; 251 StreamVector streams_; 252 253 // Provides asynchronous IO to this demuxer. Consumed by |url_protocol_| to 254 // integrate with libavformat. 255 DataSource* data_source_; 256 257 scoped_refptr<MediaLog> media_log_; 258 259 // Derived bitrate after initialization has completed. 260 int bitrate_; 261 262 // The first timestamp of the audio or video stream, whichever is lower. This 263 // is used to adjust timestamps so that external consumers always see a zero 264 // based timeline. 265 base::TimeDelta start_time_; 266 267 // The index and start time of the preferred streams for seeking. Filled upon 268 // completion of OnFindStreamInfoDone(). Each info entry represents an index 269 // into |streams_| and the start time of that stream. 270 // 271 // Seek() will attempt to use |preferred_stream_for_seeking_| if the seek 272 // point occurs after its associated start time. Otherwise it will use 273 // |fallback_stream_for_seeking_|. 274 typedef std::pair<int, base::TimeDelta> StreamSeekInfo; 275 StreamSeekInfo preferred_stream_for_seeking_; 276 StreamSeekInfo fallback_stream_for_seeking_; 277 278 // The Time associated with timestamp 0. Set to a null 279 // time if the file doesn't have an association to Time. 280 base::Time timeline_offset_; 281 282 // Liveness of the stream. 283 Liveness liveness_; 284 285 // Whether text streams have been enabled for this demuxer. 286 bool text_enabled_; 287 288 // Set if we know duration of the audio stream. Used when processing end of 289 // stream -- at this moment we definitely know duration. 290 bool duration_known_; 291 292 // FFmpegURLProtocol implementation and corresponding glue bits. 293 scoped_ptr<BlockingUrlProtocol> url_protocol_; 294 scoped_ptr<FFmpegGlue> glue_; 295 296 const NeedKeyCB need_key_cb_; 297 298 // NOTE: Weak pointers must be invalidated before all other member variables. 299 base::WeakPtrFactory<FFmpegDemuxer> weak_factory_; 300 301 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer); 302 }; 303 304 } // namespace media 305 306 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 307