/chromecast/media/audio/net/audio_socket.h
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
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_
- #define CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_
- #include <cstdint>
- #include <memory>
- #include "base/containers/flat_map.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/memory/weak_ptr.h"
- #include "chromecast/net/small_message_socket.h"
- namespace base {
- class SequencedTaskRunner;
- } // namespace base
- namespace google {
- namespace protobuf {
- class MessageLite;
- } // namespace protobuf
- } // namespace google
- namespace net {
- class IOBuffer;
- class StreamSocket;
- } // namespace net
- namespace chromecast {
- class IOBufferPool;
- namespace media {
- // Base class for sending and receiving messages to/from audio services (e.g.
- // mixer service, audio output service).
- // Not thread-safe; all usage of a given instance must be on the same IO
- // sequence.
- class AudioSocket : public SmallMessageSocket::Delegate {
- public:
- class Delegate {
- public:
- // Called when audio data is received from the other side of the connection.
- // Return |true| if the socket should continue to receive messages.
- virtual bool HandleAudioData(char* data, size_t size, int64_t timestamp);
- // Called when audio data is received from the other side of the connection
- // using an IOBufferPool. The |buffer| reference may be held as long as
- // needed by the delegate implementation. The buffer contains the full
- // message header including size; the |data| points to the audio data, and
- // the |size| is the size of the audio data. |data| will always be
- // kAudioMessageHeaderSize bytes past the start of the buffer.
- // Return |true| if the socket should continue to receive messages.
- virtual bool HandleAudioBuffer(scoped_refptr<net::IOBuffer> buffer,
- char* data,
- size_t size,
- int64_t timestamp);
- // Called when the connection is lost; no further data will be sent or
- // received after OnConnectionError() is called. It is safe to delete the
- // AudioSocket inside the OnConnectionError() implementation.
- virtual void OnConnectionError() {}
- protected:
- virtual ~Delegate() = default;
- };
- explicit AudioSocket(std::unique_ptr<net::StreamSocket> socket);
- AudioSocket(const AudioSocket&) = delete;
- AudioSocket& operator=(const AudioSocket&) = delete;
- ~AudioSocket() override;
- // Used to create local (in-process) connections.
- AudioSocket();
- void SetLocalCounterpart(
- base::WeakPtr<AudioSocket> local_counterpart,
- scoped_refptr<base::SequencedTaskRunner> counterpart_task_runner);
- base::WeakPtr<AudioSocket> GetWeakPtr();
- // Sets/changes the delegate. Must be called immediately after creation
- // (ie, synchronously on the same sequence).
- void SetDelegate(Delegate* delegate);
- // Adds a |buffer_pool| used to allocate buffers to receive messages into,
- // and for sending protos. If the pool-allocated buffers are too small for a
- // given message, a normal IOBuffer will be dynamically allocated instead.
- void UseBufferPool(scoped_refptr<IOBufferPool> buffer_pool);
- // 16-bit type and 64-bit timestamp, plus 32-bit padding to align to 16 bytes.
- static constexpr size_t kAudioHeaderSize =
- sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t);
- // Includes additional 16-bit size field for SmallMessageSocket.
- static constexpr size_t kAudioMessageHeaderSize =
- sizeof(uint16_t) + kAudioHeaderSize;
- // Fills in the audio message header for |buffer|, so it can later be sent via
- // SendPreparedAudioBuffer(). |buffer| should have |kAudioMessageHeaderSize|
- // bytes reserved at the start of the buffer, followed by |filled_bytes| of
- // audio data.
- static void PrepareAudioBuffer(net::IOBuffer* buffer,
- int filled_bytes,
- int64_t timestamp);
- // Prepares |audio_buffer| and then sends it across the connection. Returns
- // |false| if the audio could not be sent.
- bool SendAudioBuffer(scoped_refptr<net::IOBuffer> audio_buffer,
- int filled_bytes,
- int64_t timestamp);
- // Sends |audio_buffer| across the connection. |audio_buffer| should have
- // previously been prepared using PrepareAudioBuffer(). Returns |false| if the
- // audio could not be sent.
- bool SendPreparedAudioBuffer(scoped_refptr<net::IOBuffer> audio_buffer);
- // Sends an arbitrary protobuf across the connection. |type| indicates the
- // type of message; if the write cannot complete immediately, one message of
- // each type will be stored for later sending; if a newer message is sent with
- // the same type, then the previous message is overwritten. When writes become
- // available again, the stored messages are written in order of |type| (lowest
- // type first). Note that |type| is completely determined by the caller, and
- // you can reuse the same type value for different messages as long as they
- // are on different socket instances. A type of 0 means to never store the
- // message. Returns |false| if the message was not sent or stored.
- bool SendProto(int type, const google::protobuf::MessageLite& message);
- // Resumes receiving messages. Delegate calls may be called synchronously
- // from within this method.
- void ReceiveMoreMessages();
- private:
- // Parses the meta data received from the connection.
- virtual bool ParseMetadata(char* data, size_t size) = 0;
- bool SendBuffer(int type,
- scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size);
- bool SendBufferToSocket(int type,
- scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size);
- // SmallMessageSocket::Delegate implementation:
- void OnSendUnblocked() override;
- void OnError(int error) override;
- void OnEndOfStream() override;
- bool OnMessage(char* data, size_t size) override;
- bool OnMessageBuffer(scoped_refptr<net::IOBuffer> buffer,
- size_t size) override;
- bool ParseAudio(char* data, size_t size);
- bool ParseAudioBuffer(scoped_refptr<net::IOBuffer> buffer,
- char* data,
- size_t size);
- Delegate* delegate_ = nullptr;
- const std::unique_ptr<SmallMessageSocket> socket_;
- scoped_refptr<IOBufferPool> buffer_pool_;
- base::flat_map<int, scoped_refptr<net::IOBuffer>> pending_writes_;
- base::WeakPtr<AudioSocket> local_counterpart_;
- scoped_refptr<base::SequencedTaskRunner> counterpart_task_runner_;
- base::WeakPtrFactory<AudioSocket> weak_factory_{this};
- };
- } // namespace media
- } // namespace chromecast
- #endif // CHROMECAST_MEDIA_AUDIO_NET_AUDIO_SOCKET_H_