audio_device_thread.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Copyright (c) 2012 The Chromium Authors. All rights reserved.
26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Use of this source code is governed by a BSD-style license that can be
3bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson// found in the LICENSE file.
4bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson
5bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson#ifndef MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
6bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson#define MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
7bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson
8bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson#include "base/basictypes.h"
9bc13ab2bc75bd997a2a40e371f50a4c456d8ee69Anders Carlsson#include "base/memory/ref_counted.h"
102531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "base/memory/scoped_ptr.h"
112531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "base/shared_memory.h"
122531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "base/sync_socket.h"
132531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "base/synchronization/lock.h"
142531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "media/base/media_export.h"
152531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "media/audio/audio_parameters.h"
162531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor#include "media/audio/shared_memory_util.h"
172531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor
182531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregornamespace base {
192531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregorclass MessageLoop;
202531c2d2f1e8ce35f2ce8e9539738ddf8dccb7ccDouglas Gregor}
21891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor
22891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregornamespace media {
23891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregorclass AudioBus;
24891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor
25891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// Data transfer between browser and render process uses a combination
26891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// of sync sockets and shared memory. To read from the socket and render
27891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// data, we use a worker thread, a.k.a. the AudioDeviceThread, which reads
28891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// data from the browser via the socket and fills the shared memory from the
29891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// audio thread via the AudioDeviceThread::Callback interface/class.
30891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// For more details see the documentation in audio_device.h.
31891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor//
32891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// TODO(tommi): Multiple audio input/output device instances should be able to
33891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor// share the same thread instead of spinning one per instance.
34891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregorclass MEDIA_EXPORT AudioDeviceThread {
35891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor public:
36891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor  // This is the callback interface/base class that Audio[Output|Input]Device
37891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor  // implements to render input/output data. The callbacks run on the
38891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor  // thread owned by AudioDeviceThread.
39891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor  class Callback {
40891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor   public:
41891fdae811e991d15b26fc165724c4cf6b6737a6Douglas Gregor    Callback(const AudioParameters& audio_parameters,
42ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson             base::SharedMemoryHandle memory,
43ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson             int memory_length,
44ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson             int total_segments);
45ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson    virtual ~Callback();
46bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth
47bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // One time initialization for the callback object on the audio thread.
48bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    void InitializeOnAudioThread();
49bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth
50bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // Derived implementations must call shared_memory_.Map appropriately
51bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // before Process can be called.
52bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    virtual void MapSharedMemory() = 0;
53bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth
54bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // Called whenever we receive notifications about pending data.
55bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    virtual void Process(int pending_data) = 0;
56bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth
57bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth   protected:
58bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // Protected so that derived classes can access directly.
59bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // The variables are 'const' since values are calculated/set in the
60bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    // constructor and must never change.
61bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    const AudioParameters audio_parameters_;
62bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    const int samples_per_ms_;
63bd64729ac6de8fed320e7a722597cc5444709c63Chandler Carruth    const int bytes_per_ms_;
64a113e7263c5337731c65fada9de7ff72af25423bJohn McCall
65a113e7263c5337731c65fada9de7ff72af25423bJohn McCall    base::SharedMemory shared_memory_;
66a113e7263c5337731c65fada9de7ff72af25423bJohn McCall    const int memory_length_;
67a113e7263c5337731c65fada9de7ff72af25423bJohn McCall    const int total_segments_;
68a113e7263c5337731c65fada9de7ff72af25423bJohn McCall    int segment_length_;
69a113e7263c5337731c65fada9de7ff72af25423bJohn McCall
70a113e7263c5337731c65fada9de7ff72af25423bJohn McCall   private:
71a113e7263c5337731c65fada9de7ff72af25423bJohn McCall    DISALLOW_COPY_AND_ASSIGN(Callback);
72a113e7263c5337731c65fada9de7ff72af25423bJohn McCall  };
73a113e7263c5337731c65fada9de7ff72af25423bJohn McCall
74a113e7263c5337731c65fada9de7ff72af25423bJohn McCall  AudioDeviceThread();
75a113e7263c5337731c65fada9de7ff72af25423bJohn McCall  ~AudioDeviceThread();
76a113e7263c5337731c65fada9de7ff72af25423bJohn McCall
77a113e7263c5337731c65fada9de7ff72af25423bJohn McCall  // Starts the audio thread. The thread must not already be running.
78a113e7263c5337731c65fada9de7ff72af25423bJohn McCall  void Start(AudioDeviceThread::Callback* callback,
79a113e7263c5337731c65fada9de7ff72af25423bJohn McCall             base::SyncSocket::Handle socket,
80a113e7263c5337731c65fada9de7ff72af25423bJohn McCall             const char* thread_name);
817edb5fdf9703e1abd780417db691b77d5fcbc610John McCall
827edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // This tells the audio thread to stop and clean up the data.
837edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // The method can stop the thread synchronously or asynchronously.
847edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // In the latter case, the thread will still be running after Stop()
857edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // returns, but the callback pointer is cleared so no further callbacks will
867edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // be made (IOW after Stop() returns, it is safe to delete the callback).
877edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // The |loop_for_join| parameter is required for asynchronous operation
887edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // in order to join the worker thread and close the thread handle later via a
897edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // posted task.
907edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // If set to NULL, function will wait for the thread to exit before returning.
917edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  void Stop(base::MessageLoop* loop_for_join);
927edb5fdf9703e1abd780417db691b77d5fcbc610John McCall
937edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // Returns true if the thread is stopped or stopping.
947edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  bool IsStopped();
957edb5fdf9703e1abd780417db691b77d5fcbc610John McCall
967edb5fdf9703e1abd780417db691b77d5fcbc610John McCall private:
977edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // Our own private SimpleThread override.  We implement this in a
987edb5fdf9703e1abd780417db691b77d5fcbc610John McCall  // private class so that we get the following benefits:
9978b810559d89e996e00684335407443936ce34a1John McCall  // 1) AudioDeviceThread doesn't expose SimpleThread methods.
10078b810559d89e996e00684335407443936ce34a1John McCall  //    I.e. the caller can't call Start()/Stop() - which would be bad.
10178b810559d89e996e00684335407443936ce34a1John McCall  // 2) We override ThreadMain to add additional on-thread initialization
10278b810559d89e996e00684335407443936ce34a1John McCall  //    while still synchronized with SimpleThread::Start() to provide
10378b810559d89e996e00684335407443936ce34a1John McCall  //    reliable initialization.
10478b810559d89e996e00684335407443936ce34a1John McCall  class Thread;
10578b810559d89e996e00684335407443936ce34a1John McCall
10678b810559d89e996e00684335407443936ce34a1John McCall  base::Lock thread_lock_;
10778b810559d89e996e00684335407443936ce34a1John McCall  scoped_refptr<AudioDeviceThread::Thread> thread_;
10878b810559d89e996e00684335407443936ce34a1John McCall
10978b810559d89e996e00684335407443936ce34a1John McCall  DISALLOW_COPY_AND_ASSIGN(AudioDeviceThread);
11078b810559d89e996e00684335407443936ce34a1John McCall};
11178b810559d89e996e00684335407443936ce34a1John McCall
1126fb0729241ab204e9bed9a5ff2f5bd396db111d4Douglas Gregor}  // namespace media.
1136fb0729241ab204e9bed9a5ff2f5bd396db111d4Douglas Gregor
1146fb0729241ab204e9bed9a5ff2f5bd396db111d4Douglas Gregor#endif  // MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_
1156fb0729241ab204e9bed9a5ff2f5bd396db111d4Douglas Gregor