| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <algorithm> | |
| 6 #include <cmath> | |
| 7 | |
| 8 #include "base/bind.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/threading/platform_thread.h" | |
| 11 #include "media/base/filter_host.h" | |
| 12 #include "media/filters/null_audio_renderer.h" | |
| 13 | |
| 14 namespace media { | |
| 15 | |
| 16 // How "long" our buffer should be in terms of milliseconds. In OnInitialize | |
| 17 // we calculate the size of one second of audio data and use this number to | |
| 18 // allocate a buffer to pass to FillBuffer. | |
| 19 static const size_t kBufferSizeInMilliseconds = 100; | |
| 20 | |
| 21 NullAudioRenderer::NullAudioRenderer() | |
| 22 : AudioRendererBase(), | |
| 23 bytes_per_millisecond_(0), | |
| 24 buffer_size_(0), | |
| 25 bytes_per_frame_(0), | |
| 26 thread_("AudioThread") { | |
| 27 } | |
| 28 | |
| 29 NullAudioRenderer::~NullAudioRenderer() { | |
| 30 DCHECK(!thread_.IsRunning()); | |
| 31 } | |
| 32 | |
| 33 void NullAudioRenderer::SetVolume(float volume) { | |
| 34 // Do nothing. | |
| 35 } | |
| 36 | |
| 37 bool NullAudioRenderer::OnInitialize(int bits_per_channel, | |
| 38 ChannelLayout channel_layout, | |
| 39 int sample_rate) { | |
| 40 // Calculate our bytes per millisecond value and allocate our buffer. | |
| 41 int channels = ChannelLayoutToChannelCount(channel_layout); | |
| 42 int bytes_per_channel = bits_per_channel / 8; | |
| 43 bytes_per_frame_ = channels * bytes_per_channel; | |
| 44 | |
| 45 bytes_per_millisecond_ = (bytes_per_frame_ * sample_rate) / | |
| 46 base::Time::kMillisecondsPerSecond; | |
| 47 | |
| 48 buffer_size_ = | |
| 49 bytes_per_millisecond_ * kBufferSizeInMilliseconds; | |
| 50 | |
| 51 buffer_.reset(new uint8[buffer_size_]); | |
| 52 DCHECK(buffer_.get()); | |
| 53 | |
| 54 if (!thread_.Start()) | |
| 55 return false; | |
| 56 | |
| 57 thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | |
| 58 &NullAudioRenderer::FillBufferTask, this)); | |
| 59 return true; | |
| 60 } | |
| 61 | |
| 62 void NullAudioRenderer::OnStop() { | |
| 63 thread_.Stop(); | |
| 64 } | |
| 65 | |
| 66 void NullAudioRenderer::FillBufferTask() { | |
| 67 base::TimeDelta delay; | |
| 68 | |
| 69 // Only consume buffers when actually playing. | |
| 70 if (GetPlaybackRate() > 0.0f) { | |
| 71 size_t requested_frames = buffer_size_ / bytes_per_frame_; | |
| 72 size_t frames = FillBuffer( | |
| 73 buffer_.get(), requested_frames, base::TimeDelta()); | |
| 74 size_t bytes = frames * bytes_per_frame_; | |
| 75 | |
| 76 // Calculate our sleep duration, taking playback rate into consideration. | |
| 77 delay = base::TimeDelta::FromMilliseconds( | |
| 78 bytes / (bytes_per_millisecond_ * GetPlaybackRate())); | |
| 79 } else { | |
| 80 // If paused, sleep for 10 milliseconds before polling again. | |
| 81 delay = base::TimeDelta::FromMilliseconds(10); | |
| 82 } | |
| 83 | |
| 84 // Sleep for at least one millisecond so we don't spin the CPU. | |
| 85 MessageLoop::current()->PostDelayedTask( | |
| 86 FROM_HERE, | |
| 87 base::Bind(&NullAudioRenderer::FillBufferTask, this), | |
| 88 std::max(delay, base::TimeDelta::FromMilliseconds(1))); | |
| 89 } | |
| 90 | |
| 91 void NullAudioRenderer::OnRenderEndOfStream() { | |
| 92 SignalEndOfStream(); | |
| 93 } | |
| 94 | |
| 95 } // namespace media | |
| OLD | NEW |