summaryrefslogtreecommitdiffstats
path: root/content/renderer/media/audio_renderer_impl.h
blob: 5ba9bc5adb11eeb6a1c16121a7ac3168dcc1951c (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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright (c) 2011 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.
//
// Audio rendering unit utilizing audio output stream provided by browser
// process through IPC.
//
// Relationship of classes.
//
//    AudioRendererHost                AudioRendererImpl
//           ^                                ^
//           |                                |
//           v                 IPC            v
//   RenderMessageFilter   <---------> AudioMessageFilter
//
// Implementation of interface with audio device is in AudioRendererHost and
// it provides services and entry points in RenderMessageFilter, allowing
// usage of IPC calls to interact with audio device. AudioMessageFilter acts
// as a portal for IPC calls and does no more than delegation.
//
// Transportation of audio buffer is done by using shared memory, after
// OnCreateStream is executed, OnCreated would be called along with a
// SharedMemoryHandle upon successful creation of audio output stream in the
// browser process. The same piece of shared memory would be used during the
// lifetime of this unit.
//
// This class lives inside three threads during it's lifetime, namely:
// 1. IO thread.
//    The thread within which this class receives all the IPC messages and
//    IPC communications can only happen in this thread.
// 2. Pipeline thread
//    Initialization of filter and proper stopping of filters happens here.
//    Properties of this filter is also set in this thread.
// 3. Audio decoder thread (If there's one.)
//    Responsible for decoding audio data and gives raw PCM data to this object.

#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
#pragma once

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/shared_memory.h"
#include "base/synchronization/lock.h"
#include "base/threading/simple_thread.h"
#include "content/renderer/media/audio_message_filter.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/base/filters.h"
#include "media/filters/audio_renderer_base.h"

class AudioMessageFilter;

class AudioRendererImpl : public media::AudioRendererBase,
                          public AudioMessageFilter::Delegate,
                          public base::DelegateSimpleThread::Delegate,
                          public MessageLoop::DestructionObserver {
 public:
  // Methods called on Render thread ------------------------------------------
  explicit AudioRendererImpl();
  virtual ~AudioRendererImpl();

  // Methods called on IO thread ----------------------------------------------
  // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
  virtual void OnRequestPacket(AudioBuffersState buffers_state);
  virtual void OnStateChanged(AudioStreamState state);
  virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length);
  virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
                                   base::SyncSocket::Handle socket_handle,
                                   uint32 length);
  virtual void OnVolume(double volume);

  // Methods called on pipeline thread ----------------------------------------
  // media::Filter implementation.
  virtual void SetPlaybackRate(float rate);
  virtual void Pause(media::FilterCallback* callback);
  virtual void Seek(base::TimeDelta time, const media::FilterStatusCB& cb);
  virtual void Play(media::FilterCallback* callback);

  // media::AudioRenderer implementation.
  virtual void SetVolume(float volume);

 protected:
  // Methods called on audio renderer thread ----------------------------------
  // These methods are called from AudioRendererBase.
  virtual bool OnInitialize(const media::AudioDecoderConfig& config);
  virtual void OnStop();

  // Called when the decoder completes a Read().
  virtual void ConsumeAudioSamples(scoped_refptr<media::Buffer> buffer_in);

 private:
  // We are using either low- or high-latency code path.
  enum LatencyType {
    kUninitializedLatency = 0,
    kLowLatency,
    kHighLatency
  };
  static LatencyType latency_type_;

  // For access to constructor and IO thread methods.
  friend class AudioRendererImplTest;
  friend class DelegateCaller;
  FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop);
  FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
                           DestroyedMessageLoop_ConsumeAudioSamples);
  // Helper methods.
  // Convert number of bytes to duration of time using information about the
  // number of channels, sample rate and sample bits.
  base::TimeDelta ConvertToDuration(int bytes);

  // Methods call on IO thread ------------------------------------------------
  // The following methods are tasks posted on the IO thread that needs to
  // be executed on that thread. They interact with AudioMessageFilter and
  // sends IPC messages on that thread.
  void CreateStreamTask(const AudioParameters& params);
  void PlayTask();
  void PauseTask();
  void SeekTask();
  void SetVolumeTask(double volume);
  void NotifyPacketReadyTask();
  void DestroyTask();

  // Called on IO thread when message loop is dying.
  virtual void WillDestroyCurrentMessageLoop();

  // DelegateSimpleThread::Delegate implementation.
  virtual void Run();

  // (Re-)starts playback.
  void NotifyDataAvailableIfNecessary();

  // Creates socket. Virtual so tests can override.
  virtual void CreateSocket(base::SyncSocket::Handle socket_handle);

  // Launching audio thread. Virtual so tests can override.
  virtual void CreateAudioThread();

  // Accessors used by tests.
  LatencyType latency_type() {
    return latency_type_;
  }

  // Should be called before any class instance is created.
  static void set_latency_type(LatencyType latency_type);

  // Helper method for IPC send calls.
  void Send(IPC::Message* message);

  // Used to calculate audio delay given bytes.
  uint32 bytes_per_second_;

  // ID of the stream created in the browser process.
  int32 stream_id_;

  // Memory shared by the browser process for audio buffer.
  scoped_ptr<base::SharedMemory> shared_memory_;
  uint32 shared_memory_size_;

  // Cached audio message filter (lives on the main render thread).
  scoped_refptr<AudioMessageFilter> filter_;

  // Low latency IPC stuff.
  scoped_ptr<base::SyncSocket> socket_;

  // That thread waits for audio input.
  scoped_ptr<base::DelegateSimpleThread> audio_thread_;

  // Protects:
  // - |stopped_|
  // - |pending_request_|
  // - |request_buffers_state_|
  base::Lock lock_;

  // A flag that indicates this filter is called to stop.
  bool stopped_;

  // A flag that indicates an outstanding packet request.
  bool pending_request_;

  // State of the audio buffers at time of the last request.
  AudioBuffersState request_buffers_state_;

  // State variables for prerolling.
  bool prerolling_;

  // Remaining bytes for prerolling to complete.
  uint32 preroll_bytes_;

  DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
};

#endif  // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_