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

Side by Side Diff: chromecast/media/cma/backend/media_pipeline_backend_manager.cc

Issue 2712883006: [Chromecast] Add new volume control API to CastMediaShlib (Closed)
Patch Set: rebase Created 3 years, 9 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chromecast/media/cma/backend/media_pipeline_backend_manager.h" 5 #include "chromecast/media/cma/backend/media_pipeline_backend_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/location.h"
10 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
11 #include "chromecast/chromecast_features.h" 12 #include "chromecast/chromecast_features.h"
12 #include "chromecast/media/cma/backend/media_pipeline_backend_wrapper.h" 13 #include "chromecast/media/cma/backend/media_pipeline_backend_wrapper.h"
13 #include "chromecast/public/cast_media_shlib.h"
14 14
15 namespace chromecast { 15 namespace chromecast {
16 namespace media { 16 namespace media {
17 namespace { 17 namespace {
18 #if BUILDFLAG(IS_CAST_AUDIO_ONLY) 18 #if BUILDFLAG(IS_CAST_AUDIO_ONLY)
19 constexpr int kAudioDecoderLimit = std::numeric_limits<int>::max(); 19 constexpr int kAudioDecoderLimit = std::numeric_limits<int>::max();
20 #else 20 #else
21 constexpr int kAudioDecoderLimit = 2; 21 constexpr int kAudioDecoderLimit = 1;
22 #endif 22 #endif
23 } // namespace 23 } // namespace
24 24
25 MediaPipelineBackendManager::MediaPipelineBackendManager( 25 MediaPipelineBackendManager::MediaPipelineBackendManager(
26 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) 26 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
27 : media_task_runner_(std::move(media_task_runner)) { 27 : media_task_runner_(std::move(media_task_runner)),
28 DCHECK_EQ(2, NUM_DECODER_TYPES); 28 playing_noneffects_audio_streams_count_(0),
29 decoder_count_[AUDIO_DECODER] = 0; 29 allow_volume_feedback_observers_(
30 decoder_count_[VIDEO_DECODER] = 0; 30 new base::ObserverListThreadSafe<AllowVolumeFeedbackObserver>()) {
31 for (int i = 0; i < NUM_DECODER_TYPES; ++i) {
32 decoder_count_[i] = 0;
33 }
31 } 34 }
32 35
33 MediaPipelineBackendManager::~MediaPipelineBackendManager() { 36 MediaPipelineBackendManager::~MediaPipelineBackendManager() {
34 } 37 }
35 38
36 std::unique_ptr<MediaPipelineBackend> 39 std::unique_ptr<MediaPipelineBackend>
37 MediaPipelineBackendManager::CreateMediaPipelineBackend( 40 MediaPipelineBackendManager::CreateMediaPipelineBackend(
38 const media::MediaPipelineDeviceParams& params) { 41 const media::MediaPipelineDeviceParams& params) {
39 DCHECK(media_task_runner_->BelongsToCurrentThread()); 42 DCHECK(media_task_runner_->BelongsToCurrentThread());
40 return CreateMediaPipelineBackend(params, 0); 43 return base::MakeUnique<MediaPipelineBackendWrapper>(params, this);
41 }
42
43 std::unique_ptr<MediaPipelineBackend>
44 MediaPipelineBackendManager::CreateMediaPipelineBackend(
45 const media::MediaPipelineDeviceParams& params,
46 int stream_type) {
47 DCHECK(media_task_runner_->BelongsToCurrentThread());
48 LOG(INFO) << "Creating a " << params.device_id << " stream.";
49 std::unique_ptr<MediaPipelineBackend> backend_ptr(
50 new MediaPipelineBackendWrapper(
51 base::WrapUnique(
52 media::CastMediaShlib::CreateMediaPipelineBackend(params)),
53 stream_type, GetVolumeMultiplier(stream_type), this));
54 media_pipeline_backends_.push_back(backend_ptr.get());
55 return backend_ptr;
56 } 44 }
57 45
58 bool MediaPipelineBackendManager::IncrementDecoderCount(DecoderType type) { 46 bool MediaPipelineBackendManager::IncrementDecoderCount(DecoderType type) {
59 DCHECK(media_task_runner_->BelongsToCurrentThread()); 47 DCHECK(media_task_runner_->BelongsToCurrentThread());
60 DCHECK(type < NUM_DECODER_TYPES); 48 DCHECK(type < NUM_DECODER_TYPES);
61 const int limit = (type == AUDIO_DECODER) ? kAudioDecoderLimit : 1; 49 const int limit = (type == AUDIO_DECODER) ? kAudioDecoderLimit : 1;
62 if (decoder_count_[type] >= limit) { 50 if (decoder_count_[type] >= limit) {
63 LOG(WARNING) << "Decoder limit reached for type " << type; 51 LOG(WARNING) << "Decoder limit reached for type " << type;
64 return false; 52 return false;
65 } 53 }
66 54
67 ++decoder_count_[type]; 55 ++decoder_count_[type];
68 return true; 56 return true;
69 } 57 }
70 58
71 void MediaPipelineBackendManager::DecrementDecoderCount(DecoderType type) { 59 void MediaPipelineBackendManager::DecrementDecoderCount(DecoderType type) {
72 DCHECK(media_task_runner_->BelongsToCurrentThread()); 60 DCHECK(media_task_runner_->BelongsToCurrentThread());
73 DCHECK(type < NUM_DECODER_TYPES); 61 DCHECK(type < NUM_DECODER_TYPES);
74 DCHECK(decoder_count_[type] > 0); 62 DCHECK(decoder_count_[type] > 0);
63
75 decoder_count_[type]--; 64 decoder_count_[type]--;
76 } 65 }
77 66
78 void MediaPipelineBackendManager::OnMediaPipelineBackendDestroyed( 67 void MediaPipelineBackendManager::UpdatePlayingAudioCount(int change) {
79 const MediaPipelineBackend* backend) { 68 DCHECK(change == -1 || change == 1) << "bad count change: " << change;
80 DCHECK(media_task_runner_->BelongsToCurrentThread());
81 media_pipeline_backends_.erase(
82 std::remove(media_pipeline_backends_.begin(),
83 media_pipeline_backends_.end(), backend),
84 media_pipeline_backends_.end());
85 }
86 69
87 void MediaPipelineBackendManager::SetVolumeMultiplier(int stream_type, 70 // Volume feedback sounds are only allowed when there are no non-effects
88 float volume) { 71 // audio streams playing.
89 DCHECK(media_task_runner_->BelongsToCurrentThread()); 72 bool prev_allow_feedback = (playing_noneffects_audio_streams_count_ == 0);
90 volume = std::max(0.0f, std::min(volume, 1.0f)); 73 playing_noneffects_audio_streams_count_ += change;
91 volume_by_stream_type_[stream_type] = volume; 74 DCHECK_GE(playing_noneffects_audio_streams_count_, 0);
75 bool new_allow_feedback = (playing_noneffects_audio_streams_count_ == 0);
92 76
93 // Set volume for each open media pipeline backends. 77 if (new_allow_feedback != prev_allow_feedback) {
94 for (auto it = media_pipeline_backends_.begin(); 78 allow_volume_feedback_observers_->Notify(
95 it != media_pipeline_backends_.end(); it++) { 79 FROM_HERE, &AllowVolumeFeedbackObserver::AllowVolumeFeedbackSounds,
96 MediaPipelineBackendWrapper* wrapper = 80 new_allow_feedback);
97 static_cast<MediaPipelineBackendWrapper*>(*it);
98 if (wrapper->GetStreamType() == stream_type)
99 wrapper->SetStreamTypeVolume(volume);
100 } 81 }
101 } 82 }
102 83
103 float MediaPipelineBackendManager::GetVolumeMultiplier(int stream_type) { 84 void MediaPipelineBackendManager::AddAllowVolumeFeedbackObserver(
104 DCHECK(media_task_runner_->BelongsToCurrentThread()); 85 AllowVolumeFeedbackObserver* observer) {
105 auto it = volume_by_stream_type_.find(stream_type); 86 allow_volume_feedback_observers_->AddObserver(observer);
106 if (it == volume_by_stream_type_.end()) { 87 }
107 return 1.0; 88
108 } else { 89 void MediaPipelineBackendManager::RemoveAllowVolumeFeedbackObserver(
109 return it->second; 90 AllowVolumeFeedbackObserver* observer) {
110 } 91 allow_volume_feedback_observers_->RemoveObserver(observer);
111 } 92 }
112 93
113 } // namespace media 94 } // namespace media
114 } // namespace chromecast 95 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698