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

Side by Side Diff: media/base/pipeline_impl.h

Issue 149123: Asynchronous initialization of media::PipelineThread... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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
« no previous file with comments | « no previous file | media/base/pipeline_impl.cc » ('j') | media/base/pipeline_impl.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 // Implementation of Pipeline. 5 // Implementation of Pipeline.
6 6
7 #ifndef MEDIA_BASE_PIPELINE_IMPL_H_ 7 #ifndef MEDIA_BASE_PIPELINE_IMPL_H_
8 #define MEDIA_BASE_PIPELINE_IMPL_H_ 8 #define MEDIA_BASE_PIPELINE_IMPL_H_
9 9
10 #include <string> 10 #include <string>
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 154
155 // Vector of major mime types that have been rendered by this pipeline. 155 // Vector of major mime types that have been rendered by this pipeline.
156 typedef std::set<std::string> RenderedMimeTypesSet; 156 typedef std::set<std::string> RenderedMimeTypesSet;
157 RenderedMimeTypesSet rendered_mime_types_; 157 RenderedMimeTypesSet rendered_mime_types_;
158 158
159 DISALLOW_COPY_AND_ASSIGN(PipelineImpl); 159 DISALLOW_COPY_AND_ASSIGN(PipelineImpl);
160 }; 160 };
161 161
162 162
163 // The PipelineThread contains most of the logic involved with running the 163 // The PipelineThread contains most of the logic involved with running the
164 // media pipeline. Filters are created and called on a dedicated thread owned 164 // media pipeline. Filters are created and called on a dedicated thread owned
165 // by this object. 165 // by this object. This object works like a state machine to perform
166 // asynchronous initialization. Initialization is done in multiple passes in
167 // StartTask(). In each pass a different filter is created and chained with a
168 // previously created filter.
169 //
170 // Here's a state diagram that describes the lifetime of this object.
171 //
172 // [ *Created ] -> [ InitDataSource ] -> [ InitDemuxer ] ->
173 // [ InitAudioDecoder ] -> [ InitAudioRenderer ] ->
174 // [ InitVideoDecoder ] -> [ InitVideoRenderer ] -> [ Started ]
175 // | | |
176 // .-> [ Error ] .-> [ Stopped ] <-.
177 //
178 // Initialization is a series of state transitions from "Created" to
179 // "Started". If any error happens during initialization, this object will
180 // transition to the "Error" state from any state. If Stop() is called during
181 // initialization, this object will transition to "Stopped" state.
182
166 class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, 183 class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
167 public MessageLoop::DestructionObserver { 184 public MessageLoop::DestructionObserver {
168 public: 185 public:
169 // Methods called by PipelineImpl object on the client's thread. These 186 // Methods called by PipelineImpl object on the client's thread. These
170 // methods post a task to call a corresponding xxxTask() method on the 187 // methods post a task to call a corresponding xxxTask() method on the
171 // pipeline thread. For example, Seek posts a task to call SeekTask. 188 // pipeline thread. For example, Seek posts a task to call SeekTask.
172 explicit PipelineThread(PipelineImpl* pipeline); 189 explicit PipelineThread(PipelineImpl* pipeline);
173 190
191 // After Start() is called, a task of StartTask() is posted on the pipeline
192 // thread to perform initialization. See StartTask() to learn more about
193 // initialization.
174 bool Start(FilterFactory* filter_factory, 194 bool Start(FilterFactory* filter_factory,
175 const std::string& url_media_source, 195 const std::string& url_media_source,
176 PipelineCallback* init_complete_callback); 196 PipelineCallback* init_complete_callback);
177 void Stop(); 197 void Stop();
178 void SetPlaybackRate(float rate); 198 void SetPlaybackRate(float rate);
179 void Seek(base::TimeDelta time, PipelineCallback* seek_callback); 199 void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
180 void SetVolume(float volume); 200 void SetVolume(float volume);
181 201
182 // Methods called by a FilterHostImpl object. These methods may be called 202 // Methods called by a FilterHostImpl object. These methods may be called
183 // on any thread, either the pipeline's thread or any other. 203 // on any thread, either the pipeline's thread or any other.
(...skipping 20 matching lines...) Expand all
204 PipelineImpl* pipeline() const { return pipeline_; } 224 PipelineImpl* pipeline() const { return pipeline_; }
205 225
206 // Accessor used to post messages to thread's message loop. 226 // Accessor used to post messages to thread's message loop.
207 MessageLoop* message_loop() const { return thread_.message_loop(); } 227 MessageLoop* message_loop() const { return thread_.message_loop(); }
208 228
209 // Accessor used by PipelineImpl to check if we're executing on the pipeline 229 // Accessor used by PipelineImpl to check if we're executing on the pipeline
210 // thread. 230 // thread.
211 PlatformThreadId thread_id() const { return thread_.thread_id(); } 231 PlatformThreadId thread_id() const { return thread_.thread_id(); }
212 232
213 private: 233 private:
234 enum State {
235 kCreated,
236 kInitDataSource,
237 kInitDemuxer,
238 kInitAudioDecoder,
239 kInitAudioRenderer,
240 kInitVideoDecoder,
241 kInitVideoRenderer,
242 kStarted,
243 kStopped,
244 kError,
245 };
246
214 // Implementation of MessageLoop::DestructionObserver. StartTask registers 247 // Implementation of MessageLoop::DestructionObserver. StartTask registers
215 // this class as a destruction observer on the thread's message loop. 248 // this class as a destruction observer on the thread's message loop.
216 // It is used to destroy the list of FilterHosts 249 // It is used to destroy the list of FilterHosts
217 // (and thus destroy the associated filters) when all tasks have been 250 // (and thus destroy the associated filters) when all tasks have been
218 // processed and the message loop has been quit. 251 // processed and the message loop has been quit.
219 virtual void WillDestroyCurrentMessageLoop(); 252 virtual void WillDestroyCurrentMessageLoop();
220 253
221 friend class base::RefCountedThreadSafe<PipelineThread>; 254 friend class base::RefCountedThreadSafe<PipelineThread>;
222 virtual ~PipelineThread(); 255 virtual ~PipelineThread();
223 256
224 // Simple method used to make sure the pipeline is running normally. 257 // Simple method used to make sure the pipeline is running normally.
225 bool PipelineOk() { return PIPELINE_OK == pipeline_->error_; } 258 bool IsPipelineOk() { return PIPELINE_OK == pipeline_->error_; }
259
260 // Helper method to tell whether we are in the state of initializing.
261 bool IsPipelineInitializing() {
262 return state_ == kInitDataSource ||
263 state_ == kInitDemuxer ||
264 state_ == kInitAudioDecoder ||
265 state_ == kInitAudioRenderer ||
266 state_ == kInitVideoDecoder ||
267 state_ == kInitVideoRenderer;
268 }
226 269
227 // The following "task" methods correspond to the public methods, but these 270 // The following "task" methods correspond to the public methods, but these
228 // methods are run as the result of posting a task to the PipelineThread's 271 // methods are run as the result of posting a task to the PipelineThread's
229 // message loop. For example, the Start method posts a task to call the 272 // message loop.
230 // StartTask message on the pipeline thread. 273
231 void StartTask(FilterFactory* filter_factory, 274 // StartTask() is a special task that performs initialization in multiple
232 const std::string& url, 275 // passes. It is executed as a result of calling Start() or
233 PipelineCallback* init_complete_callback); 276 // InitializationComplete() that advances initialization to the next state. It
277 // works as a hub of state transition for initialization.
278 void StartTask();
234 void StopTask(); 279 void StopTask();
235 void SetPlaybackRateTask(float rate); 280 void SetPlaybackRateTask(float rate);
236 void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback); 281 void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback);
237 void SetVolumeTask(float volume); 282 void SetVolumeTask(float volume);
238 void SetTimeTask(); 283 void SetTimeTask();
239 void InitializationCompleteTask(FilterHostImpl* FilterHost);
240 284
241 // Internal methods used in the implementation of the pipeline thread. All 285 // Internal methods used in the implementation of the pipeline thread. All
242 // of these methods are only called on the pipeline thread. 286 // of these methods are only called on the pipeline thread.
243 287
244 // Calls the Stop method on every filter in the pipeline 288 // Calls the Stop method on every filter in the pipeline
245 void StopFilters(); 289 void StopFilters();
246 290
247 // The following template funcions make use of the fact that media filter 291 // The following template functions make use of the fact that media filter
248 // derived interfaces are self-describing in the sense that they all contain 292 // derived interfaces are self-describing in the sense that they all contain
249 // the static method filter_type() which returns a FilterType enum that 293 // the static method filter_type() which returns a FilterType enum that
250 // uniquely identifies the filter's interface. In addition, filters that are 294 // uniquely identifies the filter's interface. In addition, filters that are
251 // specific to audio or video also support a static method major_mime_type() 295 // specific to audio or video also support a static method major_mime_type()
252 // which returns a string of "audio/" or "video/". 296 // which returns a string of "audio/" or "video/".
253 297 //
254 // Uses the FilterFactory to create a new filter of the Filter class, and 298 // Uses the FilterFactory to create a new filter of the Filter class, and
255 // initiaializes it using the Source object. The source may be another filter 299 // initializes it using the Source object. The source may be another filter
256 // or it could be a string in the case of a DataSource. 300 // or it could be a string in the case of a DataSource.
257 // 301 //
258 // The CreateFilter method actually does much more than simply creating the 302 // The CreateFilter() method actually does much more than simply creating the
259 // filter. It creates the FilterHostImpl object, creates the filter using 303 // filter. It creates the FilterHostImpl object, creates the filter using
260 // the filter factory, calls the MediaFilter::SetHost method on the filter, 304 // the filter factory, calls the MediaFilter::SetHost() method on the filter,
261 // and then calls the filter's type-specific Initialize(source) method to 305 // and then calls the filter's type-specific Initialize(source) method to
262 // initialize the filter. It then runs the thread's message loop and waits 306 // initialize the filter. If the required filter cannot be created,
263 // until one of the following occurs: 307 // PIPELINE_ERROR_REQUIRED_FILTER_MISSING is raised, initialization is halted
264 // 1. The filter calls FilterHost::InitializationComplete() 308 // and this object will remain in the "Error" state.
265 // 2. A filter calls FilterHost::Error()
266 // 3. The client calls Pipeline::Stop()
267 // 309 //
268 // Callers can optionally use the returned Filter for further processing, 310 // Callers can optionally use the returned Filter for further processing,
269 // but since the call already placed the filter in the list of filter hosts, 311 // but since the call already placed the filter in the list of filter hosts,
270 // callers can ignore the return value. In any case, if this function can 312 // callers can ignore the return value. In any case, if this function can
271 // not create and initailze the speified Filter, then this method will return 313 // not create and initializes the specified Filter, then this method will
272 // with |pipeline_->error_| != PIPELINE_OK. 314 // return with |pipeline_->error_| != PIPELINE_OK.
273 template <class Filter, class Source> 315 template <class Filter, class Source>
274 scoped_refptr<Filter> CreateFilter(FilterFactory* filter_factory, 316 void CreateFilter(FilterFactory* filter_factory,
275 Source source, 317 Source source,
276 const MediaFormat& source_media_format); 318 const MediaFormat& source_media_format);
277 319
278 // Creates a Filter and initilizes it with the given |source|. If a Filter 320 // Creates a Filter and initilizes it with the given |source|. If a Filter
279 // could not be created or an error occurred, this metod returns NULL and the 321 // could not be created or an error occurred, this metod returns NULL and the
280 // pipeline's |error_| member will contain a specific error code. Note that 322 // pipeline's |error_| member will contain a specific error code. Note that
281 // the Source could be a filter or a DemuxerStream, but it must support the 323 // the Source could be a filter or a DemuxerStream, but it must support the
282 // GetMediaFormat() method. 324 // GetMediaFormat() method.
283 template <class Filter, class Source> 325 template <class Filter, class Source>
284 scoped_refptr<Filter> CreateFilter(FilterFactory* filter_factory, 326 void CreateFilter(FilterFactory* filter_factory, Source* source) {
285 Source* source) { 327 CreateFilter<Filter, Source*>(filter_factory,
286 return CreateFilter<Filter, Source*>(filter_factory, 328 source,
287 source, 329 source->media_format());
288 source->media_format());
289 } 330 }
290 331
291 // Creates a DataSource (the first filter in a pipeline), and initializes it 332 // Creates a DataSource (the first filter in a pipeline). Returns true if
292 // with the specified URL. 333 // the asynchronous action of creating data source has started.
293 scoped_refptr<DataSource> CreateDataSource(FilterFactory* filter_factory, 334 void CreateDataSource();
294 const std::string& url);
295 335
296 // If the |demuxer| contains a stream that matches Decoder::major_media_type() 336 // Creates a Demuxer. Returns true if the asynchronous action of creating
awong 2009/07/01 23:39:46 void function's done return...same elsewhere in fi
297 // this method creates and initializes the specified Decoder and Renderer. 337 // demuxer has started.
298 // Callers should examine the |pipeline_->error_| member to see if there was 338 void CreateDemuxer();
299 // an error duing the call. The lack of the specified stream does not 339
300 // constitute an error, and no Decoder or Renderer will be created if the 340 // Creates a decoder of type Decoder. Returns true if the asynchronous action
301 // data stream does not exist in the |demuxer|. If a stream is rendered, then 341 // of creating decoder has started. Returns false if this method did nothing
302 // this method will call |pipeline_|->InsertRenderedMimeType() to add the 342 // because the corresponding audio/video stream does not exist.
303 // mime type to the set of rendered major mime types for the pipeline. 343 template <class Decoder>
344 bool CreateDecoder();
345
346 // Creates a renderer of type Renderer and connects it with Decoder. Returns
347 // true if the asynchronous action of creating renderer has started. Returns
348 // false if this method did nothing because the corresponding audio/video
349 // stream does not exist.
304 template <class Decoder, class Renderer> 350 template <class Decoder, class Renderer>
305 void Render(FilterFactory* filter_factory, Demuxer* demuxer); 351 bool CreateRenderer();
306 352
307 // Examine the list of existing filters to find one that supports the 353 // Examine the list of existing filters to find one that supports the
308 // specified Filter interface. If one exists, the |filter_out| will contain 354 // specified Filter interface. If one exists, the |filter_out| will contain
309 // the filter, |*filter_out| will be NULL. 355 // the filter, |*filter_out| will be NULL.
310 template <class Filter> 356 template <class Filter>
311 void GetFilter(scoped_refptr<Filter>* filter_out) const; 357 void GetFilter(scoped_refptr<Filter>* filter_out) const;
312 358
313 // Pointer to the pipeline that owns this PipelineThread. 359 // Pointer to the pipeline that owns this PipelineThread.
314 PipelineImpl* const pipeline_; 360 PipelineImpl* const pipeline_;
315 361
316 // The actual thread. 362 // The actual thread.
317 base::Thread thread_; 363 base::Thread thread_;
318 364
319 // Used to avoid scheduling multiple time update tasks. If this member is 365 // Used to avoid scheduling multiple time update tasks. If this member is
320 // true then a task that will call the SetTimeTask() method is in the message 366 // true then a task that will call the SetTimeTask() method is in the message
321 // loop's queue. 367 // loop's queue.
322 bool time_update_callback_scheduled_; 368 bool time_update_callback_scheduled_;
323 369
324 // During initialization of a filter, this member points to the FilterHostImpl 370 // Member that tracks the current state.
325 // that is being initialized. 371 State state_;
326 FilterHostImpl* host_initializing_;
327 372
328 // This lock is held through the entire StartTask method to prevent the 373 // Filter factory as passed in by Start().
329 // Stop method from quitting the nested message loop of the StartTask method. 374 scoped_refptr<FilterFactory> filter_factory_;
330 Lock initialization_lock_; 375
376 // URL for the data source as passed in by Start().
377 std::string url_;
378
379 // Initialization callback as passed in by Start().
380 scoped_ptr<PipelineCallback> init_callback_;
331 381
332 // Vector of FilterHostImpl objects that contian the filters for the pipeline. 382 // Vector of FilterHostImpl objects that contian the filters for the pipeline.
333 typedef std::vector<FilterHostImpl*> FilterHostVector; 383 typedef std::vector<FilterHostImpl*> FilterHostVector;
334 FilterHostVector filter_hosts_; 384 FilterHostVector filter_hosts_;
335 385
336 typedef std::vector<base::Thread*> FilterThreadVector; 386 typedef std::vector<base::Thread*> FilterThreadVector;
337 FilterThreadVector filter_threads_; 387 FilterThreadVector filter_threads_;
338 388
339 DISALLOW_COPY_AND_ASSIGN(PipelineThread); 389 DISALLOW_COPY_AND_ASSIGN(PipelineThread);
340 }; 390 };
341 391
342 } // namespace media 392 } // namespace media
343 393
344 #endif // MEDIA_BASE_PIPELINE_IMPL_H_ 394 #endif // MEDIA_BASE_PIPELINE_IMPL_H_
OLDNEW
« no previous file with comments | « no previous file | media/base/pipeline_impl.cc » ('j') | media/base/pipeline_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698