OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |