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

Side by Side Diff: media/base/pipeline.cc

Issue 511323003: media: Remove FilterCollection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase & fix player_x11 Created 6 years, 3 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
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 #include "media/base/pipeline.h" 5 #include "media/base/pipeline.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
13 #include "base/location.h" 14 #include "base/location.h"
14 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
15 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/synchronization/condition_variable.h" 20 #include "base/synchronization/condition_variable.h"
20 #include "media/base/filter_collection.h"
21 #include "media/base/media_log.h" 21 #include "media/base/media_log.h"
22 #include "media/base/media_switches.h"
22 #include "media/base/renderer.h" 23 #include "media/base/renderer.h"
23 #include "media/base/text_renderer.h" 24 #include "media/base/text_renderer.h"
24 #include "media/base/text_track_config.h" 25 #include "media/base/text_track_config.h"
25 #include "media/base/video_decoder_config.h" 26 #include "media/base/video_decoder_config.h"
26 27
27 using base::TimeDelta; 28 using base::TimeDelta;
28 29
29 namespace media { 30 namespace media {
30 31
31 Pipeline::Pipeline( 32 Pipeline::Pipeline(
(...skipping 21 matching lines...) Expand all
53 DCHECK(thread_checker_.CalledOnValidThread()) 54 DCHECK(thread_checker_.CalledOnValidThread())
54 << "Pipeline must be destroyed on same thread that created it"; 55 << "Pipeline must be destroyed on same thread that created it";
55 DCHECK(!running_) << "Stop() must complete before destroying object"; 56 DCHECK(!running_) << "Stop() must complete before destroying object";
56 DCHECK(stop_cb_.is_null()); 57 DCHECK(stop_cb_.is_null());
57 DCHECK(seek_cb_.is_null()); 58 DCHECK(seek_cb_.is_null());
58 59
59 media_log_->AddEvent( 60 media_log_->AddEvent(
60 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); 61 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED));
61 } 62 }
62 63
63 void Pipeline::Start(scoped_ptr<FilterCollection> collection, 64 void Pipeline::Start(Demuxer* demuxer,
65 scoped_ptr<Renderer> renderer,
64 const base::Closure& ended_cb, 66 const base::Closure& ended_cb,
65 const PipelineStatusCB& error_cb, 67 const PipelineStatusCB& error_cb,
66 const PipelineStatusCB& seek_cb, 68 const PipelineStatusCB& seek_cb,
67 const PipelineMetadataCB& metadata_cb, 69 const PipelineMetadataCB& metadata_cb,
68 const BufferingStateCB& buffering_state_cb, 70 const BufferingStateCB& buffering_state_cb,
69 const base::Closure& duration_change_cb) { 71 const base::Closure& duration_change_cb,
72 const AddTextTrackCB& add_text_track_cb) {
70 DCHECK(!ended_cb.is_null()); 73 DCHECK(!ended_cb.is_null());
71 DCHECK(!error_cb.is_null()); 74 DCHECK(!error_cb.is_null());
72 DCHECK(!seek_cb.is_null()); 75 DCHECK(!seek_cb.is_null());
73 DCHECK(!metadata_cb.is_null()); 76 DCHECK(!metadata_cb.is_null());
74 DCHECK(!buffering_state_cb.is_null()); 77 DCHECK(!buffering_state_cb.is_null());
75 78
76 base::AutoLock auto_lock(lock_); 79 base::AutoLock auto_lock(lock_);
77 CHECK(!running_) << "Media pipeline is already running"; 80 CHECK(!running_) << "Media pipeline is already running";
78 running_ = true; 81 running_ = true;
79 82
80 filter_collection_ = collection.Pass(); 83 demuxer_ = demuxer;
84 renderer_ = renderer.Pass();
81 ended_cb_ = ended_cb; 85 ended_cb_ = ended_cb;
82 error_cb_ = error_cb; 86 error_cb_ = error_cb;
83 seek_cb_ = seek_cb; 87 seek_cb_ = seek_cb;
84 metadata_cb_ = metadata_cb; 88 metadata_cb_ = metadata_cb;
85 buffering_state_cb_ = buffering_state_cb; 89 buffering_state_cb_ = buffering_state_cb;
86 duration_change_cb_ = duration_change_cb; 90 duration_change_cb_ = duration_change_cb;
91 add_text_track_cb_ = add_text_track_cb;
87 92
88 task_runner_->PostTask( 93 task_runner_->PostTask(
89 FROM_HERE, base::Bind(&Pipeline::StartTask, weak_factory_.GetWeakPtr())); 94 FROM_HERE, base::Bind(&Pipeline::StartTask, weak_factory_.GetWeakPtr()));
90 } 95 }
91 96
92 void Pipeline::Stop(const base::Closure& stop_cb) { 97 void Pipeline::Stop(const base::Closure& stop_cb) {
93 DVLOG(2) << __FUNCTION__; 98 DVLOG(2) << __FUNCTION__;
94 task_runner_->PostTask( 99 task_runner_->PostTask(
95 FROM_HERE, 100 FROM_HERE,
96 base::Bind(&Pipeline::StopTask, weak_factory_.GetWeakPtr(), stop_cb)); 101 base::Bind(&Pipeline::StopTask, weak_factory_.GetWeakPtr(), stop_cb));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 DCHECK(stop_cb_.is_null()) 228 DCHECK(stop_cb_.is_null())
224 << "State transitions don't happen when stopping"; 229 << "State transitions don't happen when stopping";
225 DCHECK_EQ(status_, PIPELINE_OK) 230 DCHECK_EQ(status_, PIPELINE_OK)
226 << "State transitions don't happen when there's an error: " << status_; 231 << "State transitions don't happen when there's an error: " << status_;
227 232
228 switch (state_) { 233 switch (state_) {
229 case kCreated: 234 case kCreated:
230 return kInitDemuxer; 235 return kInitDemuxer;
231 236
232 case kInitDemuxer: 237 case kInitDemuxer:
233 if (demuxer_->GetStream(DemuxerStream::AUDIO) || 238 return kInitRenderer;
234 demuxer_->GetStream(DemuxerStream::VIDEO)) {
235 return kInitRenderer;
236 }
237 return kPlaying;
238 239
239 case kInitRenderer: 240 case kInitRenderer:
240 case kSeeking: 241 case kSeeking:
241 return kPlaying; 242 return kPlaying;
242 243
243 case kPlaying: 244 case kPlaying:
244 case kStopping: 245 case kStopping:
245 case kStopped: 246 case kStopped:
246 break; 247 break;
247 } 248 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // Switch states, performing any entrance actions for the new state as well. 333 // Switch states, performing any entrance actions for the new state as well.
333 SetState(GetNextState()); 334 SetState(GetNextState());
334 switch (state_) { 335 switch (state_) {
335 case kInitDemuxer: 336 case kInitDemuxer:
336 return InitializeDemuxer(done_cb); 337 return InitializeDemuxer(done_cb);
337 338
338 case kInitRenderer: 339 case kInitRenderer:
339 return InitializeRenderer(done_cb); 340 return InitializeRenderer(done_cb);
340 341
341 case kPlaying: 342 case kPlaying:
342 // Finish initial start sequence the first time we enter the playing 343 // Report meta data the first time we enter the playing state.
scherkus (not reviewing) 2014/08/28 18:48:22 nit: metadata
xhwang 2014/08/28 19:52:04 Done.
343 // state.
344 if (!is_initialized_) { 344 if (!is_initialized_) {
345 if (!renderer_) {
346 ErrorChangedTask(PIPELINE_ERROR_COULD_NOT_RENDER);
347 return;
348 }
349
350 is_initialized_ = true; 345 is_initialized_ = true;
351 346 ReportMetaData();
352 {
353 PipelineMetadata metadata;
354 metadata.has_audio = renderer_->HasAudio();
355 metadata.has_video = renderer_->HasVideo();
356 metadata.timeline_offset = demuxer_->GetTimelineOffset();
357 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
358 if (stream) {
359 metadata.natural_size =
360 stream->video_decoder_config().natural_size();
361 metadata.video_rotation = stream->video_rotation();
362 }
363 metadata_cb_.Run(metadata);
364 }
365 } 347 }
366 348
367 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 349 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
368 350
369 renderer_->StartPlayingFrom(start_timestamp_); 351 renderer_->StartPlayingFrom(start_timestamp_);
370 352
371 if (text_renderer_) 353 if (text_renderer_)
372 text_renderer_->StartPlaying(); 354 text_renderer_->StartPlaying();
373 355
374 PlaybackRateChangedTask(GetPlaybackRate()); 356 PlaybackRateChangedTask(GetPlaybackRate());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 DCHECK_EQ(state_, kStopping); 423 DCHECK_EQ(state_, kStopping);
442 DCHECK(!renderer_); 424 DCHECK(!renderer_);
443 DCHECK(!text_renderer_); 425 DCHECK(!text_renderer_);
444 426
445 { 427 {
446 base::AutoLock auto_lock(lock_); 428 base::AutoLock auto_lock(lock_);
447 running_ = false; 429 running_ = false;
448 } 430 }
449 431
450 SetState(kStopped); 432 SetState(kStopped);
451 filter_collection_.reset();
452 demuxer_ = NULL; 433 demuxer_ = NULL;
453 434
454 // If we stop during initialization/seeking we want to run |seek_cb_| 435 // If we stop during initialization/seeking we want to run |seek_cb_|
455 // followed by |stop_cb_| so we don't leave outstanding callbacks around. 436 // followed by |stop_cb_| so we don't leave outstanding callbacks around.
456 if (!seek_cb_.is_null()) { 437 if (!seek_cb_.is_null()) {
457 base::ResetAndReturn(&seek_cb_).Run(status_); 438 base::ResetAndReturn(&seek_cb_).Run(status_);
458 error_cb_.Reset(); 439 error_cb_.Reset();
459 } 440 }
460 if (!stop_cb_.is_null()) { 441 if (!stop_cb_.is_null()) {
461 error_cb_.Reset(); 442 error_cb_.Reset();
(...skipping 29 matching lines...) Expand all
491 statistics_.video_frames_decoded += stats.video_frames_decoded; 472 statistics_.video_frames_decoded += stats.video_frames_decoded;
492 statistics_.video_frames_dropped += stats.video_frames_dropped; 473 statistics_.video_frames_dropped += stats.video_frames_dropped;
493 } 474 }
494 475
495 void Pipeline::StartTask() { 476 void Pipeline::StartTask() {
496 DCHECK(task_runner_->BelongsToCurrentThread()); 477 DCHECK(task_runner_->BelongsToCurrentThread());
497 478
498 CHECK_EQ(kCreated, state_) 479 CHECK_EQ(kCreated, state_)
499 << "Media pipeline cannot be started more than once"; 480 << "Media pipeline cannot be started more than once";
500 481
501 text_renderer_ = filter_collection_->GetTextRenderer(); 482 text_renderer_ = CreateTextRenderer();
502
503 if (text_renderer_) { 483 if (text_renderer_) {
504 text_renderer_->Initialize( 484 text_renderer_->Initialize(
505 base::Bind(&Pipeline::OnTextRendererEnded, weak_factory_.GetWeakPtr())); 485 base::Bind(&Pipeline::OnTextRendererEnded, weak_factory_.GetWeakPtr()));
506 } 486 }
507 487
508 StateTransitionTask(PIPELINE_OK); 488 StateTransitionTask(PIPELINE_OK);
509 } 489 }
510 490
511 void Pipeline::StopTask(const base::Closure& stop_cb) { 491 void Pipeline::StopTask(const base::Closure& stop_cb) {
512 DCHECK(task_runner_->BelongsToCurrentThread()); 492 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 if (renderer_ && !renderer_ended_) 611 if (renderer_ && !renderer_ended_)
632 return; 612 return;
633 613
634 if (text_renderer_ && text_renderer_->HasTracks() && !text_renderer_ended_) 614 if (text_renderer_ && text_renderer_->HasTracks() && !text_renderer_ended_)
635 return; 615 return;
636 616
637 DCHECK_EQ(status_, PIPELINE_OK); 617 DCHECK_EQ(status_, PIPELINE_OK);
638 ended_cb_.Run(); 618 ended_cb_.Run();
639 } 619 }
640 620
621 scoped_ptr<TextRenderer> Pipeline::CreateTextRenderer() {
622 DCHECK(task_runner_->BelongsToCurrentThread());
623
624 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
625 if (!cmd_line->HasSwitch(switches::kEnableInbandTextTracks))
626 return scoped_ptr<media::TextRenderer>();
627
628 return scoped_ptr<media::TextRenderer>(new media::TextRenderer(
629 task_runner_,
630 base::Bind(&Pipeline::OnAddTextTrack, weak_factory_.GetWeakPtr())));
631 }
632
641 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream, 633 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream,
642 const TextTrackConfig& config) { 634 const TextTrackConfig& config) {
643 DCHECK(task_runner_->BelongsToCurrentThread()); 635 DCHECK(task_runner_->BelongsToCurrentThread());
644 // TODO(matthewjheaney): fix up text_ended_ when text stream 636 // TODO(matthewjheaney): fix up text_ended_ when text stream
645 // is added (http://crbug.com/321446). 637 // is added (http://crbug.com/321446).
646 text_renderer_->AddTextStream(text_stream, config); 638 if (text_renderer_)
639 text_renderer_->AddTextStream(text_stream, config);
647 } 640 }
648 641
649 void Pipeline::RemoveTextStreamTask(DemuxerStream* text_stream) { 642 void Pipeline::RemoveTextStreamTask(DemuxerStream* text_stream) {
650 DCHECK(task_runner_->BelongsToCurrentThread()); 643 DCHECK(task_runner_->BelongsToCurrentThread());
651 text_renderer_->RemoveTextStream(text_stream); 644 if (text_renderer_)
645 text_renderer_->RemoveTextStream(text_stream);
646 }
647
648 void Pipeline::OnAddTextTrack(const TextTrackConfig& config,
649 const AddTextTrackDoneCB& done_cb) {
650 DCHECK(task_runner_->BelongsToCurrentThread());
651 add_text_track_cb_.Run(config, done_cb);
652 } 652 }
653 653
654 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { 654 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) {
655 DCHECK(task_runner_->BelongsToCurrentThread()); 655 DCHECK(task_runner_->BelongsToCurrentThread());
656
657 demuxer_ = filter_collection_->GetDemuxer();
658 demuxer_->Initialize(this, done_cb, text_renderer_); 656 demuxer_->Initialize(this, done_cb, text_renderer_);
659 } 657 }
660 658
661 void Pipeline::InitializeRenderer(const PipelineStatusCB& done_cb) { 659 void Pipeline::InitializeRenderer(const PipelineStatusCB& done_cb) {
662 DCHECK(task_runner_->BelongsToCurrentThread()); 660 DCHECK(task_runner_->BelongsToCurrentThread());
663 661
664 renderer_ = filter_collection_->GetRenderer(); 662 if (!demuxer_->GetStream(DemuxerStream::AUDIO) &&
663 !demuxer_->GetStream(DemuxerStream::VIDEO)) {
664 renderer_.reset();
665 task_runner_->PostTask(
666 FROM_HERE, base::Bind(done_cb, PIPELINE_ERROR_COULD_NOT_RENDER));
667 return;
668 }
665 669
666 base::WeakPtr<Pipeline> weak_this = weak_factory_.GetWeakPtr(); 670 base::WeakPtr<Pipeline> weak_this = weak_factory_.GetWeakPtr();
667 renderer_->Initialize( 671 renderer_->Initialize(
668 done_cb, 672 done_cb,
669 base::Bind(&Pipeline::OnUpdateStatistics, weak_this), 673 base::Bind(&Pipeline::OnUpdateStatistics, weak_this),
670 base::Bind(&Pipeline::OnRendererEnded, weak_this), 674 base::Bind(&Pipeline::OnRendererEnded, weak_this),
671 base::Bind(&Pipeline::OnError, weak_this), 675 base::Bind(&Pipeline::OnError, weak_this),
672 base::Bind(&Pipeline::BufferingStateChanged, weak_this), 676 base::Bind(&Pipeline::BufferingStateChanged, weak_this),
673 base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this))); 677 base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this)));
674 } 678 }
675 679
680 void Pipeline::ReportMetaData() {
681 DCHECK(task_runner_->BelongsToCurrentThread());
682 PipelineMetadata metadata;
683 metadata.has_audio = renderer_->HasAudio();
684 metadata.has_video = renderer_->HasVideo();
685 metadata.timeline_offset = demuxer_->GetTimelineOffset();
686 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
687 if (stream) {
688 metadata.natural_size = stream->video_decoder_config().natural_size();
689 metadata.video_rotation = stream->video_rotation();
690 }
691 metadata_cb_.Run(metadata);
692 }
693
676 void Pipeline::BufferingStateChanged(BufferingState new_buffering_state) { 694 void Pipeline::BufferingStateChanged(BufferingState new_buffering_state) {
677 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") "; 695 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") ";
678 DCHECK(task_runner_->BelongsToCurrentThread()); 696 DCHECK(task_runner_->BelongsToCurrentThread());
679 buffering_state_cb_.Run(new_buffering_state); 697 buffering_state_cb_.Run(new_buffering_state);
680 } 698 }
681 699
682 } // namespace media 700 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698