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