1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <cmath>
#include "base/logging.h"
#include "media/base/filter_host.h"
#include "media/filters/null_audio_renderer.h"
namespace media {
// How "long" our buffer should be in terms of milliseconds. In OnInitialize
// we calculate the size of one second of audio data and use this number to
// allocate a buffer to pass to FillBuffer.
static const size_t kBufferSizeInMilliseconds = 100;
NullAudioRenderer::NullAudioRenderer()
: AudioRendererBase(),
bytes_per_millisecond_(0),
buffer_size_(0),
thread_(kNullThreadHandle),
shutdown_(false) {
}
NullAudioRenderer::~NullAudioRenderer() {
DCHECK_EQ(kNullThreadHandle, thread_);
}
void NullAudioRenderer::SetVolume(float volume) {
// Do nothing.
}
void NullAudioRenderer::ThreadMain() {
// Loop until we're signaled to stop.
while (!shutdown_) {
float sleep_in_milliseconds = 0.0f;
// Only consume buffers when actually playing.
if (GetPlaybackRate() > 0.0f) {
size_t bytes = FillBuffer(buffer_.get(),
buffer_size_,
base::TimeDelta(),
true);
// Calculate our sleep duration, taking playback rate into consideration.
sleep_in_milliseconds =
floor(bytes / static_cast<float>(bytes_per_millisecond_));
sleep_in_milliseconds /= GetPlaybackRate();
} else {
// If paused, sleep for 10 milliseconds before polling again.
sleep_in_milliseconds = 10.0f;
}
// Sleep for at least one millisecond so we don't spin the CPU.
PlatformThread::Sleep(std::max(1, static_cast<int>(sleep_in_milliseconds)));
}
}
bool NullAudioRenderer::OnInitialize(const MediaFormat& media_format) {
// Parse out audio parameters.
int channels;
int sample_rate;
int sample_bits;
if (!ParseMediaFormat(media_format, &channels, &sample_rate, &sample_bits)) {
return false;
}
// Calculate our bytes per millisecond value and allocate our buffer.
bytes_per_millisecond_ = (channels * sample_rate * sample_bits / 8)
/ base::Time::kMillisecondsPerSecond;
buffer_size_ = bytes_per_millisecond_ * kBufferSizeInMilliseconds;
buffer_.reset(new uint8[buffer_size_]);
DCHECK(buffer_.get());
// It's safe to start the thread now because it simply sleeps when playback
// rate is 0.0f.
return PlatformThread::Create(0, this, &thread_);
}
void NullAudioRenderer::OnStop() {
shutdown_ = true;
if (thread_) {
PlatformThread::Join(thread_);
thread_ = kNullThreadHandle;
}
}
} // namespace media
|