| OLD | NEW |
| 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_impl.h" | 5 #include "media/base/pipeline_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 350 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 351 DCHECK(IsRunning()); | 351 DCHECK(IsRunning()); |
| 352 DCHECK_NE(PIPELINE_OK, error); | 352 DCHECK_NE(PIPELINE_OK, error); |
| 353 VLOG(1) << "Media pipeline error: " << error; | 353 VLOG(1) << "Media pipeline error: " << error; |
| 354 | 354 |
| 355 media_task_runner_->PostTask( | 355 media_task_runner_->PostTask( |
| 356 FROM_HERE, | 356 FROM_HERE, |
| 357 base::Bind(&PipelineImpl::ErrorChangedTask, weak_this_, error)); | 357 base::Bind(&PipelineImpl::ErrorChangedTask, weak_this_, error)); |
| 358 } | 358 } |
| 359 | 359 |
| 360 void PipelineImpl::OnEnded() { |
| 361 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 362 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); |
| 363 |
| 364 if (state_ != kPlaying) |
| 365 return; |
| 366 |
| 367 DCHECK(!renderer_ended_); |
| 368 renderer_ended_ = true; |
| 369 |
| 370 RunEndedCallbackIfNeeded(); |
| 371 } |
| 372 |
| 373 void PipelineImpl::OnStatisticsUpdate(const PipelineStatistics& stats) { |
| 374 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 375 |
| 376 base::AutoLock auto_lock(lock_); |
| 377 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 378 statistics_.video_bytes_decoded += stats.video_bytes_decoded; |
| 379 statistics_.video_frames_decoded += stats.video_frames_decoded; |
| 380 statistics_.video_frames_dropped += stats.video_frames_dropped; |
| 381 statistics_.audio_memory_usage += stats.audio_memory_usage; |
| 382 statistics_.video_memory_usage += stats.video_memory_usage; |
| 383 } |
| 384 |
| 385 void PipelineImpl::OnBufferingStateChange(BufferingState state) { |
| 386 DVLOG(1) << __FUNCTION__ << "(" << state << ") "; |
| 387 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 388 |
| 389 main_task_runner_->PostTask( |
| 390 FROM_HERE, base::Bind(&Pipeline::Client::OnBufferingStateChange, |
| 391 weak_client_, state)); |
| 392 } |
| 393 |
| 394 void PipelineImpl::OnWaitingForDecryptionKey() { |
| 395 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 396 |
| 397 main_task_runner_->PostTask( |
| 398 FROM_HERE, |
| 399 base::Bind(&Pipeline::Client::OnWaitingForDecryptionKey, weak_client_)); |
| 400 } |
| 401 |
| 360 void PipelineImpl::SetDuration(TimeDelta duration) { | 402 void PipelineImpl::SetDuration(TimeDelta duration) { |
| 361 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer | 403 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer |
| 362 // implementations call DemuxerHost on the media thread. | 404 // implementations call DemuxerHost on the media thread. |
| 363 DCHECK(IsRunning()); | 405 DCHECK(IsRunning()); |
| 364 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET, | 406 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET, |
| 365 "duration", duration)); | 407 "duration", duration)); |
| 366 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); | 408 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); |
| 367 | 409 |
| 368 base::AutoLock auto_lock(lock_); | 410 base::AutoLock auto_lock(lock_); |
| 369 duration_ = duration; | 411 duration_ = duration; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 572 |
| 531 void PipelineImpl::OnBufferedTimeRangesChanged( | 573 void PipelineImpl::OnBufferedTimeRangesChanged( |
| 532 const Ranges<base::TimeDelta>& ranges) { | 574 const Ranges<base::TimeDelta>& ranges) { |
| 533 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer | 575 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer |
| 534 // implementations call DemuxerHost on the media thread. | 576 // implementations call DemuxerHost on the media thread. |
| 535 base::AutoLock auto_lock(lock_); | 577 base::AutoLock auto_lock(lock_); |
| 536 buffered_time_ranges_ = ranges; | 578 buffered_time_ranges_ = ranges; |
| 537 did_loading_progress_ = true; | 579 did_loading_progress_ = true; |
| 538 } | 580 } |
| 539 | 581 |
| 540 // Called from any thread. | |
| 541 void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats_delta) { | |
| 542 base::AutoLock auto_lock(lock_); | |
| 543 statistics_.audio_bytes_decoded += stats_delta.audio_bytes_decoded; | |
| 544 statistics_.video_bytes_decoded += stats_delta.video_bytes_decoded; | |
| 545 statistics_.video_frames_decoded += stats_delta.video_frames_decoded; | |
| 546 statistics_.video_frames_dropped += stats_delta.video_frames_dropped; | |
| 547 statistics_.audio_memory_usage += stats_delta.audio_memory_usage; | |
| 548 statistics_.video_memory_usage += stats_delta.video_memory_usage; | |
| 549 } | |
| 550 | |
| 551 void PipelineImpl::OnWaitingForDecryptionKey() { | |
| 552 DCHECK(media_task_runner_->BelongsToCurrentThread()); | |
| 553 | |
| 554 main_task_runner_->PostTask( | |
| 555 FROM_HERE, | |
| 556 base::Bind(&Pipeline::Client::OnWaitingForDecryptionKey, weak_client_)); | |
| 557 } | |
| 558 | |
| 559 void PipelineImpl::StartTask() { | 582 void PipelineImpl::StartTask() { |
| 560 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 583 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 561 | 584 |
| 562 CHECK_EQ(kCreated, state_) | 585 CHECK_EQ(kCreated, state_) |
| 563 << "Media pipeline cannot be started more than once"; | 586 << "Media pipeline cannot be started more than once"; |
| 564 | 587 |
| 565 text_renderer_ = CreateTextRenderer(); | 588 text_renderer_ = CreateTextRenderer(); |
| 566 if (text_renderer_) { | 589 if (text_renderer_) { |
| 567 text_renderer_->Initialize( | 590 text_renderer_->Initialize( |
| 568 base::Bind(&PipelineImpl::OnTextRendererEnded, weak_this_)); | 591 base::Bind(&PipelineImpl::OnTextRendererEnded, weak_this_)); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 | 824 |
| 802 void PipelineImpl::OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, | 825 void PipelineImpl::OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, |
| 803 CdmContext* cdm_context, | 826 CdmContext* cdm_context, |
| 804 bool success) { | 827 bool success) { |
| 805 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 828 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 806 if (success) | 829 if (success) |
| 807 cdm_context_ = cdm_context; | 830 cdm_context_ = cdm_context; |
| 808 cdm_attached_cb.Run(success); | 831 cdm_attached_cb.Run(success); |
| 809 } | 832 } |
| 810 | 833 |
| 811 void PipelineImpl::OnRendererEnded() { | |
| 812 DCHECK(media_task_runner_->BelongsToCurrentThread()); | |
| 813 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | |
| 814 | |
| 815 if (state_ != kPlaying) | |
| 816 return; | |
| 817 | |
| 818 DCHECK(!renderer_ended_); | |
| 819 renderer_ended_ = true; | |
| 820 | |
| 821 RunEndedCallbackIfNeeded(); | |
| 822 } | |
| 823 | |
| 824 void PipelineImpl::OnTextRendererEnded() { | 834 void PipelineImpl::OnTextRendererEnded() { |
| 825 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 835 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 826 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED)); | 836 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED)); |
| 827 | 837 |
| 828 if (state_ != kPlaying) | 838 if (state_ != kPlaying) |
| 829 return; | 839 return; |
| 830 | 840 |
| 831 DCHECK(!text_renderer_ended_); | 841 DCHECK(!text_renderer_ended_); |
| 832 text_renderer_ended_ = true; | 842 text_renderer_ended_ = true; |
| 833 | 843 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 base::AutoLock auto_lock(lock_); | 910 base::AutoLock auto_lock(lock_); |
| 901 renderer_.reset(); | 911 renderer_.reset(); |
| 902 } | 912 } |
| 903 OnError(PIPELINE_ERROR_COULD_NOT_RENDER); | 913 OnError(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 904 return; | 914 return; |
| 905 } | 915 } |
| 906 | 916 |
| 907 if (cdm_context_) | 917 if (cdm_context_) |
| 908 renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached)); | 918 renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached)); |
| 909 | 919 |
| 910 renderer_->Initialize( | 920 renderer_->Initialize(this, demuxer_, done_cb); |
| 911 demuxer_, done_cb, | |
| 912 base::Bind(&PipelineImpl::OnUpdateStatistics, weak_this_), | |
| 913 base::Bind(&PipelineImpl::BufferingStateChanged, weak_this_), | |
| 914 base::Bind(&PipelineImpl::OnRendererEnded, weak_this_), | |
| 915 base::Bind(&PipelineImpl::OnError, weak_this_), | |
| 916 base::Bind(&PipelineImpl::OnWaitingForDecryptionKey, weak_this_)); | |
| 917 } | 921 } |
| 918 | 922 |
| 919 void PipelineImpl::ReportMetadata() { | 923 void PipelineImpl::ReportMetadata() { |
| 920 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 924 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 921 | 925 |
| 922 PipelineMetadata metadata; | 926 PipelineMetadata metadata; |
| 923 metadata.timeline_offset = demuxer_->GetTimelineOffset(); | 927 metadata.timeline_offset = demuxer_->GetTimelineOffset(); |
| 924 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 928 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 925 if (stream) { | 929 if (stream) { |
| 926 metadata.has_video = true; | 930 metadata.has_video = true; |
| 927 metadata.natural_size = stream->video_decoder_config().natural_size(); | 931 metadata.natural_size = stream->video_decoder_config().natural_size(); |
| 928 metadata.video_rotation = stream->video_rotation(); | 932 metadata.video_rotation = stream->video_rotation(); |
| 929 } | 933 } |
| 930 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { | 934 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { |
| 931 metadata.has_audio = true; | 935 metadata.has_audio = true; |
| 932 } | 936 } |
| 933 | 937 |
| 934 main_task_runner_->PostTask( | 938 main_task_runner_->PostTask( |
| 935 FROM_HERE, | 939 FROM_HERE, |
| 936 base::Bind(&Pipeline::Client::OnMetadata, weak_client_, metadata)); | 940 base::Bind(&Pipeline::Client::OnMetadata, weak_client_, metadata)); |
| 937 } | 941 } |
| 938 | 942 |
| 939 void PipelineImpl::BufferingStateChanged(BufferingState new_buffering_state) { | |
| 940 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") "; | |
| 941 DCHECK(media_task_runner_->BelongsToCurrentThread()); | |
| 942 | |
| 943 main_task_runner_->PostTask( | |
| 944 FROM_HERE, base::Bind(&Pipeline::Client::OnBufferingStateChange, | |
| 945 weak_client_, new_buffering_state)); | |
| 946 } | |
| 947 | |
| 948 } // namespace media | 943 } // namespace media |
| OLD | NEW |