summaryrefslogtreecommitdiffstats
path: root/media/filters/null_audio_renderer.cc
blob: b60b47849e0919d4a88762cbbd20650b544e7963 (plain)
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