audio_playback_sink_ios.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2018 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. #ifndef REMOTING_IOS_AUDIO_AUDIO_PLAYBACK_SINK_IOS_H_
  5. #define REMOTING_IOS_AUDIO_AUDIO_PLAYBACK_SINK_IOS_H_
  6. #include <AudioToolbox/AudioToolbox.h>
  7. #include "base/memory/weak_ptr.h"
  8. #include "base/threading/thread_checker.h"
  9. #include "remoting/client/audio/audio_playback_sink.h"
  10. namespace remoting {
  11. // This is the iOS AudioPlaybackSink implementation that uses AudioQueue for
  12. // playback.
  13. class AudioPlaybackSinkIos : public AudioPlaybackSink {
  14. public:
  15. AudioPlaybackSinkIos();
  16. AudioPlaybackSinkIos(const AudioPlaybackSinkIos&) = delete;
  17. AudioPlaybackSinkIos& operator=(const AudioPlaybackSinkIos&) = delete;
  18. ~AudioPlaybackSinkIos() override;
  19. // AudioPlaybackSink implementations.
  20. void SetDataSupplier(AsyncAudioDataSupplier* supplier) override;
  21. void ResetStreamFormat(const AudioStreamFormat& format) override;
  22. private:
  23. // STOPPED <-----------------------------+------------+
  24. // | Received packet | |
  25. // (Start playback)--------+ | |
  26. // | Failed | Succeeded | Buffer |
  27. // v v | Underrun |
  28. // SCHEDULED_TO_RESET RUNNING---------+ |
  29. // | | |
  30. // | | Sink destructing or | Audio queue
  31. // | | format resetting | destroyed
  32. // +--------------------+--------------------------+
  33. enum class State {
  34. STOPPED,
  35. SCHEDULED_TO_RESET,
  36. RUNNING,
  37. };
  38. // Asks |supplier_| to fill audio data into the given buffer.
  39. void AsyncGetAudioData(AudioQueueBufferRef buffer);
  40. // Callback called when |supplier_| has finished filling data for |buffer|.
  41. void OnAudioDataReceived(AudioQueueBufferRef buffer);
  42. // Callback called when the AudioQueue API finished consuming the audio data.
  43. static void OnBufferDequeued(void* context,
  44. AudioQueueRef outAQ,
  45. AudioQueueBufferRef buffer);
  46. // Starts playback immediately. Posts task to reset the output queue if it
  47. // fails to start.
  48. void StartPlayback();
  49. // Stops playback immediately.
  50. void StopPlayback();
  51. // Disposes the current output queue and its buffers, creates a new queue
  52. // and buffers, and immediately request for audio data from |supplier_|.
  53. void ResetOutputQueue();
  54. // Disposes the current output queue and its buffers.
  55. void DisposeOutputQueue();
  56. // If |err| is not no-error, prints an error log at DFATAL level and disposes
  57. // the current output queue. The sink will then not be running until
  58. // ResetStreamFormat() is called again.
  59. // Returns true if error occurs and the output queue has been disposed.
  60. bool HandleError(OSStatus err, const char* function_name);
  61. THREAD_CHECKER(thread_checker_);
  62. AsyncAudioDataSupplier* supplier_ = nullptr;
  63. // Number of buffers that are currently transferred to |supplier_| for
  64. // priming.
  65. size_t priming_buffers_count_ = 0;
  66. // The current stream format.
  67. AudioStreamBasicDescription stream_format_;
  68. // The output queue. nullptr if ResetStreamFormat() has not been called.
  69. AudioQueueRef output_queue_ = nullptr;
  70. // The current state.
  71. State state_ = State::STOPPED;
  72. base::WeakPtrFactory<AudioPlaybackSinkIos> weak_factory_;
  73. };
  74. } // namespace remoting
  75. #endif // REMOTING_IOS_AUDIO_AUDIO_PLAYBACK_SINK_IOS_H_