• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
6 #define MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
7 
8 #include "base/basictypes.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/shared_memory.h"
12 #include "base/sync_socket.h"
13 #include "base/synchronization/lock.h"
14 #include "media/audio/audio_parameters.h"
15 #include "media/base/media_export.h"
16 
17 namespace base {
18 class MessageLoop;
19 }
20 
21 namespace media {
22 class AudioBus;
23 
24 // Data transfer between browser and render process uses a combination
25 // of sync sockets and shared memory. To read from the socket and render
26 // data, we use a worker thread, a.k.a. the AudioDeviceThread, which reads
27 // data from the browser via the socket and fills the shared memory from the
28 // audio thread via the AudioDeviceThread::Callback interface/class.
29 // For more details see the documentation in audio_device.h.
30 //
31 // TODO(tommi): Multiple audio input/output device instances should be able to
32 // share the same thread instead of spinning one per instance.
33 class MEDIA_EXPORT AudioDeviceThread {
34  public:
35   // This is the callback interface/base class that Audio[Output|Input]Device
36   // implements to render input/output data. The callbacks run on the
37   // thread owned by AudioDeviceThread.
38   class Callback {
39    public:
40     Callback(const AudioParameters& audio_parameters,
41              base::SharedMemoryHandle memory,
42              int memory_length,
43              int total_segments);
44     virtual ~Callback();
45 
46     // One time initialization for the callback object on the audio thread.
47     void InitializeOnAudioThread();
48 
49     // Derived implementations must call shared_memory_.Map appropriately
50     // before Process can be called.
51     virtual void MapSharedMemory() = 0;
52 
53     // Called whenever we receive notifications about pending data.
54     virtual void Process(int pending_data) = 0;
55 
56    protected:
57     // Protected so that derived classes can access directly.
58     // The variables are 'const' since values are calculated/set in the
59     // constructor and must never change.
60     const AudioParameters audio_parameters_;
61     const int samples_per_ms_;
62     const int bytes_per_ms_;
63 
64     base::SharedMemory shared_memory_;
65     const int memory_length_;
66     const int total_segments_;
67     int segment_length_;
68 
69    private:
70     DISALLOW_COPY_AND_ASSIGN(Callback);
71   };
72 
73   AudioDeviceThread();
74   ~AudioDeviceThread();
75 
76   // Starts the audio thread. The thread must not already be running.  If
77   // |sychronized_buffers| is set, the browser expects to be notified via the
78   // |socket| every time AudioDeviceThread::Process() completes.
79   void Start(AudioDeviceThread::Callback* callback,
80              base::SyncSocket::Handle socket,
81              const char* thread_name,
82              bool synchronized_buffers);
83 
84   // This tells the audio thread to stop and clean up the data.
85   // The method can stop the thread synchronously or asynchronously.
86   // In the latter case, the thread will still be running after Stop()
87   // returns, but the callback pointer is cleared so no further callbacks will
88   // be made (IOW after Stop() returns, it is safe to delete the callback).
89   // The |loop_for_join| parameter is required for asynchronous operation
90   // in order to join the worker thread and close the thread handle later via a
91   // posted task.
92   // If set to NULL, function will wait for the thread to exit before returning.
93   void Stop(base::MessageLoop* loop_for_join);
94 
95   // Returns true if the thread is stopped or stopping.
96   bool IsStopped();
97 
98  private:
99   // Our own private SimpleThread override.  We implement this in a
100   // private class so that we get the following benefits:
101   // 1) AudioDeviceThread doesn't expose SimpleThread methods.
102   //    I.e. the caller can't call Start()/Stop() - which would be bad.
103   // 2) We override ThreadMain to add additional on-thread initialization
104   //    while still synchronized with SimpleThread::Start() to provide
105   //    reliable initialization.
106   class Thread;
107 
108   base::Lock thread_lock_;
109   scoped_refptr<AudioDeviceThread::Thread> thread_;
110 
111   DISALLOW_COPY_AND_ASSIGN(AudioDeviceThread);
112 };
113 
114 }  // namespace media.
115 
116 #endif  // MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
117