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(demuxer_, this, 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 |