1// Copyright 2014 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#ifndef CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_
6#define CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_
7
8#include <deque>
9
10#include "base/compiler_specific.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "base/synchronization/lock.h"
14#include "base/threading/thread_checker.h"
15#include "content/public/renderer/media_stream_audio_sink.h"
16#include "content/renderer/pepper/pepper_media_stream_track_host_base.h"
17#include "media/audio/audio_parameters.h"
18#include "ppapi/host/host_message_context.h"
19#include "ppapi/shared_impl/media_stream_audio_track_shared.h"
20#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
21
22namespace base {
23class MessageLoopProxy;
24}  // namespace base
25
26namespace content {
27
28class PepperMediaStreamAudioTrackHost : public PepperMediaStreamTrackHostBase {
29 public:
30  PepperMediaStreamAudioTrackHost(RendererPpapiHost* host,
31                                  PP_Instance instance,
32                                  PP_Resource resource,
33                                  const blink::WebMediaStreamTrack& track);
34
35 private:
36  // A helper class for receiving audio samples in the audio thread.
37  // This class is created and destroyed on the renderer main thread.
38  class AudioSink : public MediaStreamAudioSink {
39   public:
40    explicit AudioSink(PepperMediaStreamAudioTrackHost* host);
41    virtual ~AudioSink();
42
43    // Enqueues a free buffer index into |buffers_| which will be used for
44    // sending audio samples to plugin.
45    // This function is called on the main thread.
46    void EnqueueBuffer(int32_t index);
47
48    // This function is called on the main thread.
49    int32_t Configure(int32_t number_of_buffers, int32_t duration,
50                      const ppapi::host::ReplyMessageContext& context);
51
52    // Send a reply to the currently pending |Configure()| request.
53    void SendConfigureReply(int32_t result);
54
55   private:
56    // Initializes buffers on the main thread.
57    void SetFormatOnMainThread(int bytes_per_second, int bytes_per_frame);
58
59    void InitBuffers();
60
61    // Send enqueue buffer message on the main thread.
62    void SendEnqueueBufferMessageOnMainThread(int32_t index,
63                                              int32_t buffers_generation);
64
65    // MediaStreamAudioSink overrides:
66    // These two functions should be called on the audio thread.
67    virtual void OnData(const int16* audio_data,
68                        int sample_rate,
69                        int number_of_channels,
70                        int number_of_frames) OVERRIDE;
71    virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE;
72
73    // Unowned host which is available during the AudioSink's lifespan.
74    // It is mainly used in the main thread. But the audio thread will use
75    // host_->buffer_manager() to read some buffer properties. It is safe
76    // because the buffer_manager()'s properties will not be changed after
77    // initialization.
78    PepperMediaStreamAudioTrackHost* host_;
79
80    // Timestamp of the next received audio buffer.
81    // Access only on the audio thread.
82    base::TimeDelta timestamp_;
83
84    // Duration of one audio buffer.
85    // Access only on the audio thread.
86    base::TimeDelta buffer_duration_;
87
88    // The current audio parameters.
89    // Access only on the audio thread.
90    media::AudioParameters audio_params_;
91
92    // The original audio parameters which is set in the first time of
93    // OnSetFormat being called.
94    // Access only on the audio thread.
95    media::AudioParameters original_audio_params_;
96
97    // The audio data size of one audio buffer in bytes.
98    // Access only on the audio thread.
99    uint32_t buffer_data_size_;
100
101    // Index of the currently active buffer.
102    // Access only on the audio thread.
103    int active_buffer_index_;
104
105    // Generation of buffers corresponding to the currently active
106    // buffer. Used to make sure the active buffer is still valid.
107    // Access only on the audio thread.
108    int32_t active_buffers_generation_;
109
110    // Current offset, in bytes, within the currently active buffer.
111    // Access only on the audio thread.
112    uint32_t active_buffer_offset_;
113
114    // A lock to protect the index queue |buffers_|, |buffers_generation_|,
115    // buffers in |host_->buffer_manager()|, and |output_buffer_size_|.
116    base::Lock lock_;
117
118    // A queue for free buffer indices.
119    std::deque<int32_t> buffers_;
120
121    // Generation of buffers. It is increased by every |InitBuffers()| call.
122    int32_t buffers_generation_;
123
124    // Intended size of each output buffer.
125    int32_t output_buffer_size_;
126
127    scoped_refptr<base::MessageLoopProxy> main_message_loop_proxy_;
128
129    base::ThreadChecker audio_thread_checker_;
130
131    // Number of buffers.
132    int32_t number_of_buffers_;
133
134    // Number of bytes per second.
135    int bytes_per_second_;
136
137    // Number of bytes per frame = channels * bytes per sample.
138    int bytes_per_frame_;
139
140    // User-configured buffer duration, in milliseconds.
141    int32_t user_buffer_duration_;
142
143    // Pending |Configure()| reply context.
144    ppapi::host::ReplyMessageContext pending_configure_reply_;
145
146    base::WeakPtrFactory<AudioSink> weak_factory_;
147
148    DISALLOW_COPY_AND_ASSIGN(AudioSink);
149  };
150
151  virtual ~PepperMediaStreamAudioTrackHost();
152
153  // ResourceMessageHandler overrides:
154  virtual int32_t OnResourceMessageReceived(
155      const IPC::Message& msg,
156      ppapi::host::HostMessageContext* context) OVERRIDE;
157
158  // Message handlers:
159  int32_t OnHostMsgConfigure(
160      ppapi::host::HostMessageContext* context,
161      const ppapi::MediaStreamAudioTrackShared::Attributes& attributes);
162
163  // PepperMediaStreamTrackHostBase overrides:
164  virtual void OnClose() OVERRIDE;
165
166  // MediaStreamBufferManager::Delegate overrides:
167  virtual void OnNewBufferEnqueued() OVERRIDE;
168
169  // ResourceHost overrides:
170  virtual void DidConnectPendingHostToResource() OVERRIDE;
171
172  blink::WebMediaStreamTrack track_;
173
174  // True if |audio_sink_| has been added to |blink::WebMediaStreamTrack|
175  // as a sink.
176  bool connected_;
177
178  AudioSink audio_sink_;
179
180  DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamAudioTrackHost);
181};
182
183}  // namespace content
184
185#endif  // CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_
186