Home | History | Annotate | Download | only in audio
      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