1 // Copyright 2020 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 CAST_STANDALONE_SENDER_STREAMING_OPUS_ENCODER_H_ 6 #define CAST_STANDALONE_SENDER_STREAMING_OPUS_ENCODER_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "cast/streaming/encoded_frame.h" 13 #include "cast/streaming/sender.h" 14 #include "platform/api/time.h" 15 16 extern "C" { 17 struct OpusEncoder; 18 } 19 20 namespace openscreen { 21 namespace cast { 22 23 // Wraps the libopus encoder so that the application can stream 24 // interleaved-floats audio samples to a Sender. Either mono or stereo sound is 25 // supported. 26 class StreamingOpusEncoder { 27 public: 28 // Constructs the encoder for mono or stereo sound, dividing the stream of 29 // audio samples up into chunks as determined by the given 30 // |cast_frames_per_second|, and for EncodedFrame output to the given 31 // |sender|. The sample rate of the audio is assumed to be the Sender's fixed 32 // |rtp_timebase()|. 33 StreamingOpusEncoder(int num_channels, 34 int cast_frames_per_second, 35 Sender* sender); 36 37 ~StreamingOpusEncoder(); 38 num_channels()39 int num_channels() const { return num_channels_; } sample_rate()40 int sample_rate() const { return sender_->rtp_timebase(); } 41 42 int GetBitrate() const; 43 44 // Sets the encoder back to its "AUTO" bitrate setting, for standard quality. 45 // This and UseHighQuality() may be called as often as needed as conditions 46 // change. 47 // 48 // Note: As of 2020-01-21, the encoder in "auto bitrate" mode would use a 49 // bitrate of 102kbps for 2-channel, 48 kHz audio and a 10 ms frame size. 50 void UseStandardQuality(); 51 52 // Sets the encoder to use a high bitrate (virtually no artifacts), when 53 // plenty of network bandwidth is available. This and UseStandardQuality() may 54 // be called as often as needed as conditions change. 55 void UseHighQuality(); 56 57 // Encode and send the given |interleaved_samples|, which contains 58 // |num_samples| tuples (i.e., multiply by the number of channels to determine 59 // the number of array elements). The audio is assumed to have been captured 60 // at the required |sample_rate()|. |reference_time| refers to the first 61 // sample. 62 void EncodeAndSend(const float* interleaved_samples, 63 int num_samples, 64 Clock::time_point reference_time); 65 66 static constexpr int kDefaultCastAudioFramesPerSecond = 67 100; // 10 ms frame duration. 68 69 private: encoder()70 OpusEncoder* encoder() const { 71 return reinterpret_cast<OpusEncoder*>(encoder_storage_.get()); 72 } 73 74 // Updates the |codec_delay_| based on the current encoder settings. 75 void UpdateCodecDelay(); 76 77 // Sets the next frame's reference time, accounting for codec buffering delay. 78 // Also, checks whether the reference time has drifted too far forwards, and 79 // skips if necessary. 80 void ResolveTimestampsAndMaybeSkip(Clock::time_point reference_time); 81 82 // Fills the input buffer as much as possible from the given source data, and 83 // returns the number of samples copied into the buffer. 84 int FillInputBuffer(const float* interleaved_samples, int num_samples); 85 86 const int num_channels_; 87 Sender* const sender_; 88 const int samples_per_cast_frame_; 89 const Clock::duration approximate_cast_frame_duration_; 90 const std::unique_ptr<uint8_t[]> encoder_storage_; 91 const std::unique_ptr<float[]> input_; // Interleaved audio samples. 92 const std::unique_ptr<uint8_t[]> output_; // Opus-encoded packet. 93 94 // The audio delay introduced by the codec. 95 Clock::duration codec_delay_{}; 96 97 // The number of mono/stereo tuples currently queued in the |input_| buffer. 98 // Multiply by |num_channels_| to get the number of array elements. 99 int num_samples_queued_ = 0; 100 101 // The reference time of the first frame passed to EncodeAndSend(), offset by 102 // the codec delay. 103 Clock::time_point start_time_ = Clock::time_point::min(); 104 105 // Initialized and used by EncodeAndSend() to hold the metadata and data 106 // pointer for each frame being sent. 107 EncodedFrame frame_; 108 109 // The |reference_time| for the last sent frame. This is used to check that 110 // the reference times are monotonically increasing. If they have [illegally] 111 // gone backwards too much, warnings will be logged. 112 Clock::time_point last_sent_frame_reference_time_; 113 114 // This is the recommended value, according to documentation in 115 // src/include/opus.h in libopus, so that the Opus encoder does not degrade 116 // the audio due to memory constraints. 117 static constexpr int kOpusMaxPayloadSize = 4000; 118 }; 119 120 } // namespace cast 121 } // namespace openscreen 122 123 #endif // CAST_STANDALONE_SENDER_STREAMING_OPUS_ENCODER_H_ 124