| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 void Suspend(); | 50 void Suspend(); |
| 51 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time); | 51 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time); |
| 52 void SetPlaybackRate(double playback_rate); | 52 void SetPlaybackRate(double playback_rate); |
| 53 void SetVolume(float volume); | 53 void SetVolume(float volume); |
| 54 base::TimeDelta GetMediaTime() const; | 54 base::TimeDelta GetMediaTime() const; |
| 55 Ranges<base::TimeDelta> GetBufferedTimeRanges() const; | 55 Ranges<base::TimeDelta> GetBufferedTimeRanges() const; |
| 56 bool DidLoadingProgress(); | 56 bool DidLoadingProgress(); |
| 57 PipelineStatistics GetStatistics() const; | 57 PipelineStatistics GetStatistics() const; |
| 58 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); | 58 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); |
| 59 | 59 |
| 60 // |enabledTrackIds| contains track ids of enabled audio tracks. |
| 61 void OnEnabledAudioTracksChanged( |
| 62 const std::vector<MediaTrack::Id>& enabledTrackIds); |
| 63 |
| 64 // |trackId| either empty, which means no video track is selected, or contain |
| 65 // one element - the selected video track id. |
| 66 void OnSelectedVideoTrackChanged( |
| 67 const std::vector<MediaTrack::Id>& selectedTrackId); |
| 68 |
| 60 private: | 69 private: |
| 61 // Contains state shared between main and media thread. | 70 // Contains state shared between main and media thread. |
| 62 // Main thread can only read. Media thread can both - read and write. | 71 // Main thread can only read. Media thread can both - read and write. |
| 63 // So it is not necessary to lock when reading from the media thread. | 72 // So it is not necessary to lock when reading from the media thread. |
| 64 // This struct should only contain state that is not immediately needed by | 73 // This struct should only contain state that is not immediately needed by |
| 65 // PipelineClient and can be cached on the media thread until queried. | 74 // PipelineClient and can be cached on the media thread until queried. |
| 66 // Alternatively we could cache it on the main thread by posting the | 75 // Alternatively we could cache it on the main thread by posting the |
| 67 // notification to the main thread. But some of the state change notifications | 76 // notification to the main thread. But some of the state change notifications |
| 68 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more | 77 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more |
| 69 // frequently than needed. Posting all those notifications to the main thread | 78 // frequently than needed. Posting all those notifications to the main thread |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 492 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); |
| 484 | 493 |
| 485 if (state_ != kPlaying) | 494 if (state_ != kPlaying) |
| 486 return; | 495 return; |
| 487 | 496 |
| 488 DCHECK(!renderer_ended_); | 497 DCHECK(!renderer_ended_); |
| 489 renderer_ended_ = true; | 498 renderer_ended_ = true; |
| 490 CheckPlaybackEnded(); | 499 CheckPlaybackEnded(); |
| 491 } | 500 } |
| 492 | 501 |
| 502 void PipelineImpl::OnEnabledAudioTracksChanged( |
| 503 const std::vector<MediaTrack::Id>& enabledTrackIds) { |
| 504 DCHECK(thread_checker_.CalledOnValidThread()); |
| 505 media_task_runner_->PostTask( |
| 506 FROM_HERE, |
| 507 base::Bind(&RendererWrapper::OnEnabledAudioTracksChanged, |
| 508 base::Unretained(renderer_wrapper_.get()), enabledTrackIds)); |
| 509 } |
| 510 |
| 511 void PipelineImpl::OnSelectedVideoTrackChanged( |
| 512 const std::vector<MediaTrack::Id>& selectedTrackId) { |
| 513 DCHECK(thread_checker_.CalledOnValidThread()); |
| 514 media_task_runner_->PostTask( |
| 515 FROM_HERE, |
| 516 base::Bind(&RendererWrapper::OnSelectedVideoTrackChanged, |
| 517 base::Unretained(renderer_wrapper_.get()), selectedTrackId)); |
| 518 } |
| 519 |
| 520 void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged( |
| 521 const std::vector<MediaTrack::Id>& enabledTrackIds) { |
| 522 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 523 |
| 524 // Track status notifications might be delivered asynchronously. If we receive |
| 525 // a notification when pipeline is stopped/shut down, it's safe to ignore it. |
| 526 if (state_ == kStopping || state_ == kStopped) { |
| 527 return; |
| 528 } |
| 529 |
| 530 DCHECK(demuxer_); |
| 531 DCHECK(shared_state_.renderer); |
| 532 |
| 533 base::TimeDelta currTime = (state_ == kPlaying) |
| 534 ? shared_state_.renderer->GetMediaTime() |
| 535 : start_timestamp_; |
| 536 demuxer_->OnEnabledAudioTracksChanged(enabledTrackIds, currTime); |
| 537 } |
| 538 |
| 539 void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged( |
| 540 const std::vector<MediaTrack::Id>& selectedTrackId) { |
| 541 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 542 |
| 543 // Track status notifications might be delivered asynchronously. If we receive |
| 544 // a notification when pipeline is stopped/shut down, it's safe to ignore it. |
| 545 if (state_ == kStopping || state_ == kStopped) { |
| 546 return; |
| 547 } |
| 548 |
| 549 DCHECK(demuxer_); |
| 550 DCHECK(shared_state_.renderer); |
| 551 |
| 552 base::TimeDelta currTime = (state_ == kPlaying) |
| 553 ? shared_state_.renderer->GetMediaTime() |
| 554 : start_timestamp_; |
| 555 demuxer_->OnSelectedVideoTrackChanged(selectedTrackId, currTime); |
| 556 } |
| 557 |
| 493 void PipelineImpl::RendererWrapper::OnStatisticsUpdate( | 558 void PipelineImpl::RendererWrapper::OnStatisticsUpdate( |
| 494 const PipelineStatistics& stats) { | 559 const PipelineStatistics& stats) { |
| 495 DVLOG(3) << __FUNCTION__; | 560 DVLOG(3) << __FUNCTION__; |
| 496 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 561 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 497 | 562 |
| 498 base::AutoLock auto_lock(shared_state_lock_); | 563 base::AutoLock auto_lock(shared_state_lock_); |
| 499 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded; | 564 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 500 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded; | 565 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded; |
| 501 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded; | 566 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded; |
| 502 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped; | 567 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped; |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 seek_cb_.Reset(); | 1026 seek_cb_.Reset(); |
| 962 suspend_cb_.Reset(); | 1027 suspend_cb_.Reset(); |
| 963 client_ = nullptr; | 1028 client_ = nullptr; |
| 964 | 1029 |
| 965 // Invalidate self weak pointers effectively canceling all pending | 1030 // Invalidate self weak pointers effectively canceling all pending |
| 966 // notifications in the message queue. | 1031 // notifications in the message queue. |
| 967 weak_factory_.InvalidateWeakPtrs(); | 1032 weak_factory_.InvalidateWeakPtrs(); |
| 968 } | 1033 } |
| 969 | 1034 |
| 970 void PipelineImpl::Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb) { | 1035 void PipelineImpl::Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb) { |
| 971 DVLOG(2) << __FUNCTION__; | 1036 DVLOG(2) << __FUNCTION__ << " to " << time.InMicroseconds(); |
| 972 DCHECK(thread_checker_.CalledOnValidThread()); | 1037 DCHECK(thread_checker_.CalledOnValidThread()); |
| 973 DCHECK(!seek_cb.is_null()); | 1038 DCHECK(!seek_cb.is_null()); |
| 974 | 1039 |
| 975 if (!IsRunning()) { | 1040 if (!IsRunning()) { |
| 976 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; | 1041 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; |
| 977 return; | 1042 return; |
| 978 } | 1043 } |
| 979 | 1044 |
| 980 DCHECK(seek_cb_.is_null()); | 1045 DCHECK(seek_cb_.is_null()); |
| 981 seek_cb_ = seek_cb; | 1046 seek_cb_ = seek_cb; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 void PipelineImpl::OnSuspendDone(base::TimeDelta suspend_time) { | 1295 void PipelineImpl::OnSuspendDone(base::TimeDelta suspend_time) { |
| 1231 DVLOG(3) << __FUNCTION__ << "(" << suspend_time.InMicroseconds() << ")"; | 1296 DVLOG(3) << __FUNCTION__ << "(" << suspend_time.InMicroseconds() << ")"; |
| 1232 DCHECK(thread_checker_.CalledOnValidThread()); | 1297 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1233 DCHECK(IsRunning()); | 1298 DCHECK(IsRunning()); |
| 1234 | 1299 |
| 1235 DCHECK(!suspend_cb_.is_null()); | 1300 DCHECK(!suspend_cb_.is_null()); |
| 1236 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); | 1301 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); |
| 1237 } | 1302 } |
| 1238 | 1303 |
| 1239 } // namespace media | 1304 } // namespace media |
| OLD | NEW |