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

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

Issue 2567143002: media::SilentSinkSuspender should simulate |delay| and |delay_timestamp| (Closed)
Patch Set: Created 4 years 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 "media/base/silent_sink_suspender.h" 5 #include "media/base/silent_sink_suspender.h"
6 6
7 #include "base/single_thread_task_runner.h" 7 #include "base/single_thread_task_runner.h"
8 #include "base/threading/thread_task_runner_handle.h" 8 #include "base/threading/thread_task_runner_handle.h"
9 9
10 namespace media { 10 namespace media {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 // Audio should be silent at this point, if not, it will be handled once the 46 // Audio should be silent at this point, if not, it will be handled once the
47 // transition to the fake sink is complete. 47 // transition to the fake sink is complete.
48 dest->Zero(); 48 dest->Zero();
49 return dest->frames(); 49 return dest->frames();
50 } 50 }
51 51
52 // When we're using the |fake_sink_| a null destination will be sent; we store 52 // When we're using the |fake_sink_| a null destination will be sent; we store
53 // the audio data for a future transition out of silence. 53 // the audio data for a future transition out of silence.
54 if (!dest) { 54 if (!dest) {
55 DCHECK(is_using_fake_sink_); 55 DCHECK(is_using_fake_sink_);
56 DCHECK_EQ(delay, base::TimeDelta());
57 DCHECK_EQ(prior_frames_skipped, 0); 56 DCHECK_EQ(prior_frames_skipped, 0);
57 // |delay_timestamp| contains the value cached at
58 // |fake_sink_transition_time_|
59 // so we simulate the real sink output, promoting |delay_timestamp| with
60 // |elapsedTime|.
61 base::TimeDelta elapsedTime =
62 base::TimeTicks::Now() - fake_sink_transition_time_;
63 delay_timestamp += elapsedTime;
chcunningham 2016/12/20 18:36:43 Could be a little simpler. // Same comment... DCH
Mikhail 2016/12/20 21:45:50 sorry, I made a mistake in the comment :( it cache
chcunningham 2016/12/21 07:02:54 No worries. But the core of my comment is about re
58 64
59 // If we have no buffers or a transition is pending, one or more extra 65 // If we have no buffers or a transition is pending, one or more extra
60 // Render() calls have occurred in before TransitionSinks() can run, so we 66 // Render() calls have occurred in before TransitionSinks() can run, so we
61 // store this data for the eventual transition. 67 // store this data for the eventual transition.
62 if (buffers_after_silence_.empty() || is_transition_pending_) 68 if (buffers_after_silence_.empty() || is_transition_pending_)
63 buffers_after_silence_.push_back(AudioBus::Create(params_)); 69 buffers_after_silence_.push_back(AudioBus::Create(params_));
64 dest = buffers_after_silence_.back().get(); 70 dest = buffers_after_silence_.back().get();
65 } else if (!buffers_after_silence_.empty()) { 71 } else if (!buffers_after_silence_.empty()) {
66 // Drain any non-silent transitional buffers before queuing more audio data. 72 // Drain any non-silent transitional buffers before queuing more audio data.
67 // Note: These do not skew clocks derived from frame count since we don't 73 // Note: These do not skew clocks derived from frame count since we don't
(...skipping 15 matching lines...) Expand all
83 task_runner_->PostTask( 89 task_runner_->PostTask(
84 FROM_HERE, base::Bind(sink_transition_callback_.callback(), false)); 90 FROM_HERE, base::Bind(sink_transition_callback_.callback(), false));
85 return dest->frames(); 91 return dest->frames();
86 } 92 }
87 } else if (!is_using_fake_sink_) { 93 } else if (!is_using_fake_sink_) {
88 const base::TimeTicks now = base::TimeTicks::Now(); 94 const base::TimeTicks now = base::TimeTicks::Now();
89 if (first_silence_time_.is_null()) 95 if (first_silence_time_.is_null())
90 first_silence_time_ = now; 96 first_silence_time_ = now;
91 if (now - first_silence_time_ > silence_timeout_) { 97 if (now - first_silence_time_ > silence_timeout_) {
92 is_transition_pending_ = true; 98 is_transition_pending_ = true;
99 latest_output_delay_ = delay;
100 latest_output_delay_timestamp_ = delay_timestamp;
101 fake_sink_transition_time_ = now;
93 task_runner_->PostTask( 102 task_runner_->PostTask(
94 FROM_HERE, base::Bind(sink_transition_callback_.callback(), true)); 103 FROM_HERE, base::Bind(sink_transition_callback_.callback(), true));
95 } 104 }
96 } 105 }
97 106
98 return dest->frames(); 107 return dest->frames();
99 } 108 }
100 109
101 void SilentSinkSuspender::OnRenderError() { 110 void SilentSinkSuspender::OnRenderError() {
102 callback_->OnRenderError(); 111 callback_->OnRenderError();
(...skipping 14 matching lines...) Expand all
117 // after this point, so we must acquire the lock to make sure we don't have 126 // after this point, so we must acquire the lock to make sure we don't have
118 // concurrent Render() execution. Once |is_using_fake_sink_| is set to true, 127 // concurrent Render() execution. Once |is_using_fake_sink_| is set to true,
119 // calls from |sink_| will be dropped. 128 // calls from |sink_| will be dropped.
120 { 129 {
121 base::AutoLock al(transition_lock_); 130 base::AutoLock al(transition_lock_);
122 is_transition_pending_ = false; 131 is_transition_pending_ = false;
123 is_using_fake_sink_ = true; 132 is_using_fake_sink_ = true;
124 } 133 }
125 fake_sink_.Start( 134 fake_sink_.Start(
126 base::Bind(base::IgnoreResult(&SilentSinkSuspender::Render), 135 base::Bind(base::IgnoreResult(&SilentSinkSuspender::Render),
127 base::Unretained(this), base::TimeDelta(), 136 base::Unretained(this), latest_output_delay_,
128 base::TimeTicks::Now(), 0, nullptr)); 137 latest_output_delay_timestamp_, 0, nullptr));
129 } else { 138 } else {
130 fake_sink_.Stop(); 139 fake_sink_.Stop();
131 140
132 // Despite the fake sink having a synchronous Stop(), if this transition 141 // Despite the fake sink having a synchronous Stop(), if this transition
133 // occurs too soon after pausing the real sink, we may have pending Render() 142 // occurs too soon after pausing the real sink, we may have pending Render()
134 // calls from before the transition to the fake sink. As such, we need to 143 // calls from before the transition to the fake sink. As such, we need to
135 // hold the lock here to avoid any races. 144 // hold the lock here to avoid any races.
136 { 145 {
137 base::AutoLock al(transition_lock_); 146 base::AutoLock al(transition_lock_);
138 is_transition_pending_ = false; 147 is_transition_pending_ = false;
139 is_using_fake_sink_ = false; 148 is_using_fake_sink_ = false;
140 } 149 }
141 sink_->Play(); 150 sink_->Play();
142 } 151 }
143 } 152 }
144 153
145 } // namespace content 154 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698