Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: media/filters/ffmpeg_demuxer.h

Issue 10829470: Support for parsing encrypted WebM streams by src. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implements the Demuxer interface using FFmpeg's libavformat. At this time 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 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 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 8 // key FFmpegCodecID which contains the CodecID enumeration value. The CodecIDs
9 // can be used to create and initialize the corresponding FFmpeg decoder. 9 // can be used to create and initialize the corresponding FFmpeg decoder.
10 // 10 //
11 // FFmpegDemuxer sets the duration of pipeline during initialization by using 11 // FFmpegDemuxer sets the duration of pipeline during initialization by using
12 // the duration of the longest audio/video stream. 12 // the duration of the longest audio/video stream.
13 // 13 //
14 // NOTE: since FFmpegDemuxer reads packets sequentially without seeking, media 14 // NOTE: since FFmpegDemuxer reads packets sequentially without seeking, media
15 // files with very large drift between audio/video streams may result in 15 // files with very large drift between audio/video streams may result in
16 // excessive memory consumption. 16 // excessive memory consumption.
17 // 17 //
18 // When stopped, FFmpegDemuxer and FFmpegDemuxerStream release all callbacks 18 // When stopped, FFmpegDemuxer and FFmpegDemuxerStream release all callbacks
19 // and buffered packets. Reads from a stopped FFmpegDemuxerStream will not be 19 // and buffered packets. Reads from a stopped FFmpegDemuxerStream will not be
20 // replied to. 20 // replied to.
21 21
22 #ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 22 #ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_H_
23 #define MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 23 #define MEDIA_FILTERS_FFMPEG_DEMUXER_H_
24 24
25 #include <deque> 25 #include <deque>
26 #include <string>
26 #include <vector> 27 #include <vector>
27 28
28 #include "base/callback.h" 29 #include "base/callback.h"
29 #include "base/gtest_prod_util.h" 30 #include "base/gtest_prod_util.h"
30 #include "base/synchronization/waitable_event.h" 31 #include "base/synchronization/waitable_event.h"
31 #include "media/base/audio_decoder_config.h" 32 #include "media/base/audio_decoder_config.h"
32 #include "media/base/decoder_buffer.h" 33 #include "media/base/decoder_buffer.h"
33 #include "media/base/demuxer.h" 34 #include "media/base/demuxer.h"
34 #include "media/base/pipeline.h" 35 #include "media/base/pipeline.h"
35 #include "media/base/video_decoder_config.h" 36 #include "media/base/video_decoder_config.h"
36 #include "media/filters/ffmpeg_glue.h" 37 #include "media/filters/ffmpeg_glue.h"
37 38
38 // FFmpeg forward declarations. 39 // FFmpeg forward declarations.
39 struct AVFormatContext; 40 struct AVFormatContext;
40 struct AVPacket; 41 struct AVPacket;
41 struct AVRational; 42 struct AVRational;
42 struct AVStream; 43 struct AVStream;
43 44
44 namespace media { 45 namespace media {
45 46
47 // A new potentially encrypted stream has been parsed.
48 // First parameter - The initialization data associated with the stream.
49 // Second parameter - Number of bytes of the initialization data.
50 typedef base::Callback<bool(scoped_array<uint8>, int)> FFmpegNeedKeyCB;
51
46 class FFmpegDemuxer; 52 class FFmpegDemuxer;
47 class FFmpegH264ToAnnexBBitstreamConverter; 53 class FFmpegH264ToAnnexBBitstreamConverter;
48 class ScopedPtrAVFreePacket; 54 class ScopedPtrAVFreePacket;
49 55
50 class FFmpegDemuxerStream : public DemuxerStream { 56 class FFmpegDemuxerStream : public DemuxerStream {
51 public: 57 public:
52 // Keeps a copy of |demuxer| and initializes itself using information 58 // Keeps a copy of |demuxer| and initializes itself using information
53 // inside |stream|. Both parameters must outlive |this|. 59 // inside |stream|. Both parameters must outlive |this|.
54 FFmpegDemuxerStream(FFmpegDemuxer* demuxer, AVStream* stream); 60 FFmpegDemuxerStream(FFmpegDemuxer* demuxer, AVStream* stream);
55 61
(...skipping 29 matching lines...) Expand all
85 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE; 91 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE;
86 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE; 92 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE;
87 93
88 // Returns the range of buffered data in this stream. 94 // Returns the range of buffered data in this stream.
89 Ranges<base::TimeDelta> GetBufferedRanges() const; 95 Ranges<base::TimeDelta> GetBufferedRanges() const;
90 96
91 // Returns elapsed time based on the already queued packets. 97 // Returns elapsed time based on the already queued packets.
92 // Used to determine stream duration when it's not known ahead of time. 98 // Used to determine stream duration when it's not known ahead of time.
93 base::TimeDelta GetElapsedTime() const; 99 base::TimeDelta GetElapsedTime() const;
94 100
101 void KeyAdded();
102
95 protected: 103 protected:
96 virtual ~FFmpegDemuxerStream(); 104 virtual ~FFmpegDemuxerStream();
97 105
98 private: 106 private:
99 friend class FFmpegDemuxerTest; 107 friend class FFmpegDemuxerTest;
100 108
101 // Carries out enqueuing a pending read on the demuxer thread. 109 // Carries out enqueuing a pending read on the demuxer thread.
102 void ReadTask(const ReadCB& read_cb); 110 void ReadTask(const ReadCB& read_cb);
103 111
104 // Attempts to fulfill a single pending read by dequeueing a buffer and read 112 // Attempts to fulfill a single pending read by dequeueing a buffer and read
(...skipping 16 matching lines...) Expand all
121 Ranges<base::TimeDelta> buffered_ranges_; 129 Ranges<base::TimeDelta> buffered_ranges_;
122 130
123 typedef std::deque<scoped_refptr<DecoderBuffer> > BufferQueue; 131 typedef std::deque<scoped_refptr<DecoderBuffer> > BufferQueue;
124 BufferQueue buffer_queue_; 132 BufferQueue buffer_queue_;
125 133
126 typedef std::deque<ReadCB> ReadQueue; 134 typedef std::deque<ReadCB> ReadQueue;
127 ReadQueue read_queue_; 135 ReadQueue read_queue_;
128 136
129 scoped_ptr<FFmpegH264ToAnnexBBitstreamConverter> bitstream_converter_; 137 scoped_ptr<FFmpegH264ToAnnexBBitstreamConverter> bitstream_converter_;
130 138
139 bool need_decryption_key_;
ddorwin 2012/08/22 23:20:29 Curious why the demuxer cares. It shouldn't be blo
fgalligan1 2012/08/23 02:39:11 See the other comment. Also if we don't have the d
xhwang 2012/08/23 19:04:53 I am not quite sure what's the problem. But the De
fgalligan1 2012/08/24 20:01:26 Removed. With xhwang's change this will work now.
140 std::string enc_key_id_;
ddorwin 2012/08/22 23:20:29 Why do we store the key ID as state? There can be
fgalligan1 2012/08/23 02:39:11 I'm using this to decide if to create a DecryptCon
141
131 // Used to synchronize access to |buffer_queue_|, |read_queue_|, and 142 // Used to synchronize access to |buffer_queue_|, |read_queue_|, and
132 // |stopped_|. This is so other threads can get access to buffers that have 143 // |stopped_|. This is so other threads can get access to buffers that have
133 // already been demuxed without having the demuxer thread sending the 144 // already been demuxed without having the demuxer thread sending the
134 // buffers. |lock_| must be acquired before any access to |buffer_queue_|, 145 // buffers. |lock_| must be acquired before any access to |buffer_queue_|,
135 // |read_queue_|, or |stopped_|. 146 // |read_queue_|, or |stopped_|.
136 mutable base::Lock lock_; 147 mutable base::Lock lock_;
137 148
138 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream); 149 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream);
139 }; 150 };
140 151
141 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol { 152 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
142 public: 153 public:
143 FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop, 154 FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
144 const scoped_refptr<DataSource>& data_source); 155 const scoped_refptr<DataSource>& data_source,
156 const FFmpegNeedKeyCB& need_key_cb);
145 157
146 // Posts a task to perform additional demuxing. 158 // Posts a task to perform additional demuxing.
147 virtual void PostDemuxTask(); 159 virtual void PostDemuxTask();
148 160
149 // Demuxer implementation. 161 // Demuxer implementation.
150 virtual void Initialize(DemuxerHost* host, 162 virtual void Initialize(DemuxerHost* host,
151 const PipelineStatusCB& status_cb) OVERRIDE; 163 const PipelineStatusCB& status_cb) OVERRIDE;
152 virtual void Stop(const base::Closure& callback) OVERRIDE; 164 virtual void Stop(const base::Closure& callback) OVERRIDE;
153 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE; 165 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
154 virtual void OnAudioRendererDisabled() OVERRIDE; 166 virtual void OnAudioRendererDisabled() OVERRIDE;
155 virtual void SetPlaybackRate(float playback_rate) OVERRIDE; 167 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
156 virtual scoped_refptr<DemuxerStream> GetStream( 168 virtual scoped_refptr<DemuxerStream> GetStream(
157 DemuxerStream::Type type) OVERRIDE; 169 DemuxerStream::Type type) OVERRIDE;
158 virtual base::TimeDelta GetStartTime() const OVERRIDE; 170 virtual base::TimeDelta GetStartTime() const OVERRIDE;
159 171
160 // FFmpegURLProtocol implementation. 172 // FFmpegURLProtocol implementation.
161 virtual size_t Read(size_t size, uint8* data) OVERRIDE; 173 virtual size_t Read(size_t size, uint8* data) OVERRIDE;
162 virtual bool GetPosition(int64* position_out) OVERRIDE; 174 virtual bool GetPosition(int64* position_out) OVERRIDE;
163 virtual bool SetPosition(int64 position) OVERRIDE; 175 virtual bool SetPosition(int64 position) OVERRIDE;
164 virtual bool GetSize(int64* size_out) OVERRIDE; 176 virtual bool GetSize(int64* size_out) OVERRIDE;
165 virtual bool IsStreaming() OVERRIDE; 177 virtual bool IsStreaming() OVERRIDE;
166 178
167 // Provide access to FFmpegDemuxerStream. 179 // Provide access to FFmpegDemuxerStream.
168 scoped_refptr<base::MessageLoopProxy> message_loop(); 180 scoped_refptr<base::MessageLoopProxy> message_loop();
169 181
182 virtual void KeyAdded() OVERRIDE;
183 void NeedKey(const std::string& key_id);
ddorwin 2012/08/22 23:20:29 Should this be public?
fgalligan1 2012/08/23 02:39:11 This is called from FFmpegDemuxerStream.
184
170 // Allow FFmpegDemuxerStream to notify us when there is updated information 185 // Allow FFmpegDemuxerStream to notify us when there is updated information
171 // about what buffered data is available. 186 // about what buffered data is available.
172 void NotifyBufferingChanged(); 187 void NotifyBufferingChanged();
173 188
174 private: 189 private:
175 // To allow tests access to privates. 190 // To allow tests access to privates.
176 friend class FFmpegDemuxerTest; 191 friend class FFmpegDemuxerTest;
177 192
178 virtual ~FFmpegDemuxer(); 193 virtual ~FFmpegDemuxer();
179 194
180 // Carries out initialization on the demuxer thread. 195 // Carries out initialization on the demuxer thread.
181 void InitializeTask(DemuxerHost* host, const PipelineStatusCB& status_cb); 196 void InitializeTask(DemuxerHost* host, const PipelineStatusCB& status_cb);
182 197
183 // Carries out a seek on the demuxer thread. 198 // Carries out a seek on the demuxer thread.
184 void SeekTask(base::TimeDelta time, const PipelineStatusCB& cb); 199 void SeekTask(base::TimeDelta time, const PipelineStatusCB& cb);
185 200
186 // Carries out demuxing and satisfying stream reads on the demuxer thread. 201 // Carries out demuxing and satisfying stream reads on the demuxer thread.
187 void DemuxTask(); 202 void DemuxTask();
188 203
189 // Carries out stopping the demuxer streams on the demuxer thread. 204 // Carries out stopping the demuxer streams on the demuxer thread.
190 void StopTask(const base::Closure& callback); 205 void StopTask(const base::Closure& callback);
191 206
192 // Carries out disabling the audio stream on the demuxer thread. 207 // Carries out disabling the audio stream on the demuxer thread.
193 void DisableAudioStreamTask(); 208 void DisableAudioStreamTask();
194 209
210 void KeyAddedTask();
211
195 // Returns true if any of the streams have pending reads. Since we lazily 212 // Returns true if any of the streams have pending reads. Since we lazily
196 // post a DemuxTask() for every read, we use this method to quickly terminate 213 // post a DemuxTask() for every read, we use this method to quickly terminate
197 // the tasks if there is no work to do. 214 // the tasks if there is no work to do.
198 // 215 //
199 // Must be called on the demuxer thread. 216 // Must be called on the demuxer thread.
200 bool StreamsHavePendingReads(); 217 bool StreamsHavePendingReads();
201 218
202 // Signal all FFmpegDemuxerStream that the stream has ended. 219 // Signal all FFmpegDemuxerStream that the stream has ended.
203 // 220 //
204 // Must be called on the demuxer thread. 221 // Must be called on the demuxer thread.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 base::TimeDelta start_time_; 277 base::TimeDelta start_time_;
261 278
262 // Whether audio has been disabled for this demuxer (in which case this class 279 // Whether audio has been disabled for this demuxer (in which case this class
263 // drops packets destined for AUDIO demuxer streams on the floor). 280 // drops packets destined for AUDIO demuxer streams on the floor).
264 bool audio_disabled_; 281 bool audio_disabled_;
265 282
266 // Set if we know duration of the audio stream. Used when processing end of 283 // Set if we know duration of the audio stream. Used when processing end of
267 // stream -- at this moment we definitely know duration. 284 // stream -- at this moment we definitely know duration.
268 bool duration_known_; 285 bool duration_known_;
269 286
287 FFmpegNeedKeyCB need_key_cb_;
ddorwin 2012/08/22 23:20:29 const
fgalligan1 2012/08/23 02:39:11 Done.
288
270 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer); 289 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer);
271 }; 290 };
272 291
273 } // namespace media 292 } // namespace media
274 293
275 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 294 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698