PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/chromecast/media/audio/net/audio_socket.h

https://github.com/chromium/chromium
C Header | 170 lines | 89 code | 32 blank | 49 comment | 0 complexity | 968f1ba7bd275d084923f8d4bbd77945 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  1. // Copyright 2021 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 CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_
  5. #define CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_
  6. #include <cstdint>
  7. #include <memory>
  8. #include "base/containers/flat_map.h"
  9. #include "base/memory/scoped_refptr.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "chromecast/net/small_message_socket.h"
  12. namespace base {
  13. class SequencedTaskRunner;
  14. } // namespace base
  15. namespace google {
  16. namespace protobuf {
  17. class MessageLite;
  18. } // namespace protobuf
  19. } // namespace google
  20. namespace net {
  21. class IOBuffer;
  22. class StreamSocket;
  23. } // namespace net
  24. namespace chromecast {
  25. class IOBufferPool;
  26. namespace media {
  27. // Base class for sending and receiving messages to/from audio services (e.g.
  28. // mixer service, audio output service).
  29. // Not thread-safe; all usage of a given instance must be on the same IO
  30. // sequence.
  31. class AudioSocket : public SmallMessageSocket::Delegate {
  32. public:
  33. class Delegate {
  34. public:
  35. // Called when audio data is received from the other side of the connection.
  36. // Return |true| if the socket should continue to receive messages.
  37. virtual bool HandleAudioData(char* data, size_t size, int64_t timestamp);
  38. // Called when audio data is received from the other side of the connection
  39. // using an IOBufferPool. The |buffer| reference may be held as long as
  40. // needed by the delegate implementation. The buffer contains the full
  41. // message header including size; the |data| points to the audio data, and
  42. // the |size| is the size of the audio data. |data| will always be
  43. // kAudioMessageHeaderSize bytes past the start of the buffer.
  44. // Return |true| if the socket should continue to receive messages.
  45. virtual bool HandleAudioBuffer(scoped_refptr<net::IOBuffer> buffer,
  46. char* data,
  47. size_t size,
  48. int64_t timestamp);
  49. // Called when the connection is lost; no further data will be sent or
  50. // received after OnConnectionError() is called. It is safe to delete the
  51. // AudioSocket inside the OnConnectionError() implementation.
  52. virtual void OnConnectionError() {}
  53. protected:
  54. virtual ~Delegate() = default;
  55. };
  56. explicit AudioSocket(std::unique_ptr<net::StreamSocket> socket);
  57. AudioSocket(const AudioSocket&) = delete;
  58. AudioSocket& operator=(const AudioSocket&) = delete;
  59. ~AudioSocket() override;
  60. // Used to create local (in-process) connections.
  61. AudioSocket();
  62. void SetLocalCounterpart(
  63. base::WeakPtr<AudioSocket> local_counterpart,
  64. scoped_refptr<base::SequencedTaskRunner> counterpart_task_runner);
  65. base::WeakPtr<AudioSocket> GetWeakPtr();
  66. // Sets/changes the delegate. Must be called immediately after creation
  67. // (ie, synchronously on the same sequence).
  68. void SetDelegate(Delegate* delegate);
  69. // Adds a |buffer_pool| used to allocate buffers to receive messages into,
  70. // and for sending protos. If the pool-allocated buffers are too small for a
  71. // given message, a normal IOBuffer will be dynamically allocated instead.
  72. void UseBufferPool(scoped_refptr<IOBufferPool> buffer_pool);
  73. // 16-bit type and 64-bit timestamp, plus 32-bit padding to align to 16 bytes.
  74. static constexpr size_t kAudioHeaderSize =
  75. sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t);
  76. // Includes additional 16-bit size field for SmallMessageSocket.
  77. static constexpr size_t kAudioMessageHeaderSize =
  78. sizeof(uint16_t) + kAudioHeaderSize;
  79. // Fills in the audio message header for |buffer|, so it can later be sent via
  80. // SendPreparedAudioBuffer(). |buffer| should have |kAudioMessageHeaderSize|
  81. // bytes reserved at the start of the buffer, followed by |filled_bytes| of
  82. // audio data.
  83. static void PrepareAudioBuffer(net::IOBuffer* buffer,
  84. int filled_bytes,
  85. int64_t timestamp);
  86. // Prepares |audio_buffer| and then sends it across the connection. Returns
  87. // |false| if the audio could not be sent.
  88. bool SendAudioBuffer(scoped_refptr<net::IOBuffer> audio_buffer,
  89. int filled_bytes,
  90. int64_t timestamp);
  91. // Sends |audio_buffer| across the connection. |audio_buffer| should have
  92. // previously been prepared using PrepareAudioBuffer(). Returns |false| if the
  93. // audio could not be sent.
  94. bool SendPreparedAudioBuffer(scoped_refptr<net::IOBuffer> audio_buffer);
  95. // Sends an arbitrary protobuf across the connection. |type| indicates the
  96. // type of message; if the write cannot complete immediately, one message of
  97. // each type will be stored for later sending; if a newer message is sent with
  98. // the same type, then the previous message is overwritten. When writes become
  99. // available again, the stored messages are written in order of |type| (lowest
  100. // type first). Note that |type| is completely determined by the caller, and
  101. // you can reuse the same type value for different messages as long as they
  102. // are on different socket instances. A type of 0 means to never store the
  103. // message. Returns |false| if the message was not sent or stored.
  104. bool SendProto(int type, const google::protobuf::MessageLite& message);
  105. // Resumes receiving messages. Delegate calls may be called synchronously
  106. // from within this method.
  107. void ReceiveMoreMessages();
  108. private:
  109. // Parses the meta data received from the connection.
  110. virtual bool ParseMetadata(char* data, size_t size) = 0;
  111. bool SendBuffer(int type,
  112. scoped_refptr<net::IOBuffer> buffer,
  113. size_t buffer_size);
  114. bool SendBufferToSocket(int type,
  115. scoped_refptr<net::IOBuffer> buffer,
  116. size_t buffer_size);
  117. // SmallMessageSocket::Delegate implementation:
  118. void OnSendUnblocked() override;
  119. void OnError(int error) override;
  120. void OnEndOfStream() override;
  121. bool OnMessage(char* data, size_t size) override;
  122. bool OnMessageBuffer(scoped_refptr<net::IOBuffer> buffer,
  123. size_t size) override;
  124. bool ParseAudio(char* data, size_t size);
  125. bool ParseAudioBuffer(scoped_refptr<net::IOBuffer> buffer,
  126. char* data,
  127. size_t size);
  128. Delegate* delegate_ = nullptr;
  129. const std::unique_ptr<SmallMessageSocket> socket_;
  130. scoped_refptr<IOBufferPool> buffer_pool_;
  131. base::flat_map<int, scoped_refptr<net::IOBuffer>> pending_writes_;
  132. base::WeakPtr<AudioSocket> local_counterpart_;
  133. scoped_refptr<base::SequencedTaskRunner> counterpart_task_runner_;
  134. base::WeakPtrFactory<AudioSocket> weak_factory_{this};
  135. };
  136. } // namespace media
  137. } // namespace chromecast
  138. #endif // CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_