1*3f982cf4SFabien Sanglard // Copyright 2021 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef CAST_STREAMING_RECEIVER_BASE_H_ 6*3f982cf4SFabien Sanglard #define CAST_STREAMING_RECEIVER_BASE_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <chrono> 9*3f982cf4SFabien Sanglard 10*3f982cf4SFabien Sanglard #include "absl/types/span.h" 11*3f982cf4SFabien Sanglard #include "cast/streaming/encoded_frame.h" 12*3f982cf4SFabien Sanglard #include "cast/streaming/session_config.h" 13*3f982cf4SFabien Sanglard #include "cast/streaming/ssrc.h" 14*3f982cf4SFabien Sanglard #include "platform/api/time.h" 15*3f982cf4SFabien Sanglard 16*3f982cf4SFabien Sanglard namespace openscreen { 17*3f982cf4SFabien Sanglard namespace cast { 18*3f982cf4SFabien Sanglard 19*3f982cf4SFabien Sanglard // The Cast Streaming Receiver, a peer corresponding to some Cast Streaming 20*3f982cf4SFabien Sanglard // Sender at the other end of a network link. 21*3f982cf4SFabien Sanglard // 22*3f982cf4SFabien Sanglard // Cast Streaming is a transport protocol which divides up the frames for one 23*3f982cf4SFabien Sanglard // media stream (e.g., audio or video) into multiple RTP packets containing an 24*3f982cf4SFabien Sanglard // encrypted payload. The Receiver is the peer responsible for collecting the 25*3f982cf4SFabien Sanglard // RTP packets, decrypting the payload, and re-assembling a frame that can be 26*3f982cf4SFabien Sanglard // passed to a decoder and played out. 27*3f982cf4SFabien Sanglard // 28*3f982cf4SFabien Sanglard // A Sender ↔ Receiver pair is used to transport each media stream. Typically, 29*3f982cf4SFabien Sanglard // there are two pairs in a normal system, one for the audio stream and one for 30*3f982cf4SFabien Sanglard // video stream. A local player is responsible for synchronizing the playout of 31*3f982cf4SFabien Sanglard // the frames of each stream to achieve lip-sync. See the discussion in 32*3f982cf4SFabien Sanglard // encoded_frame.h for how the |reference_time| and |rtp_timestamp| of the 33*3f982cf4SFabien Sanglard // EncodedFrames are used to achieve this. 34*3f982cf4SFabien Sanglard class ReceiverBase { 35*3f982cf4SFabien Sanglard public: 36*3f982cf4SFabien Sanglard class Consumer { 37*3f982cf4SFabien Sanglard public: 38*3f982cf4SFabien Sanglard virtual ~Consumer(); 39*3f982cf4SFabien Sanglard 40*3f982cf4SFabien Sanglard // Called whenever one or more frames have become ready for consumption. The 41*3f982cf4SFabien Sanglard // |next_frame_buffer_size| argument is identical to the result of calling 42*3f982cf4SFabien Sanglard // AdvanceToNextFrame(), and so the Consumer only needs to prepare a buffer 43*3f982cf4SFabien Sanglard // and call ConsumeNextFrame(). It may then call AdvanceToNextFrame() to 44*3f982cf4SFabien Sanglard // check whether there are any more frames ready, but this is not mandatory. 45*3f982cf4SFabien Sanglard // See usage example in class-level comments. 46*3f982cf4SFabien Sanglard virtual void OnFramesReady(int next_frame_buffer_size) = 0; 47*3f982cf4SFabien Sanglard }; 48*3f982cf4SFabien Sanglard 49*3f982cf4SFabien Sanglard ReceiverBase(); 50*3f982cf4SFabien Sanglard virtual ~ReceiverBase(); 51*3f982cf4SFabien Sanglard 52*3f982cf4SFabien Sanglard virtual const SessionConfig& config() const = 0; 53*3f982cf4SFabien Sanglard virtual int rtp_timebase() const = 0; 54*3f982cf4SFabien Sanglard virtual Ssrc ssrc() const = 0; 55*3f982cf4SFabien Sanglard 56*3f982cf4SFabien Sanglard // Set the Consumer receiving notifications when new frames are ready for 57*3f982cf4SFabien Sanglard // consumption. Frames received before this method is called will remain in 58*3f982cf4SFabien Sanglard // the queue indefinitely. 59*3f982cf4SFabien Sanglard virtual void SetConsumer(Consumer* consumer) = 0; 60*3f982cf4SFabien Sanglard 61*3f982cf4SFabien Sanglard // Sets how much time the consumer will need to decode/buffer/render/etc., and 62*3f982cf4SFabien Sanglard // otherwise fully process a frame for on-time playback. This information is 63*3f982cf4SFabien Sanglard // used by the Receiver to decide whether to skip past frames that have 64*3f982cf4SFabien Sanglard // arrived too late. This method can be called repeatedly to make adjustments 65*3f982cf4SFabien Sanglard // based on changing environmental conditions. 66*3f982cf4SFabien Sanglard // 67*3f982cf4SFabien Sanglard // Default setting: kDefaultPlayerProcessingTime 68*3f982cf4SFabien Sanglard virtual void SetPlayerProcessingTime(Clock::duration needed_time) = 0; 69*3f982cf4SFabien Sanglard 70*3f982cf4SFabien Sanglard // Propagates a "picture loss indicator" notification to the Sender, 71*3f982cf4SFabien Sanglard // requesting a key frame so that decode/playout can recover. It is safe to 72*3f982cf4SFabien Sanglard // call this redundantly. The Receiver will clear the picture loss condition 73*3f982cf4SFabien Sanglard // automatically, once a key frame is received (i.e., before 74*3f982cf4SFabien Sanglard // ConsumeNextFrame() is called to access it). 75*3f982cf4SFabien Sanglard virtual void RequestKeyFrame() = 0; 76*3f982cf4SFabien Sanglard 77*3f982cf4SFabien Sanglard // Advances to the next frame ready for consumption. This may skip-over 78*3f982cf4SFabien Sanglard // incomplete frames that will not play out on-time; but only if there are 79*3f982cf4SFabien Sanglard // completed frames further down the queue that have no dependency 80*3f982cf4SFabien Sanglard // relationship with them (e.g., key frames). 81*3f982cf4SFabien Sanglard // 82*3f982cf4SFabien Sanglard // This method returns kNoFramesReady if there is not currently a frame ready 83*3f982cf4SFabien Sanglard // for consumption. The caller should wait for a Consumer::OnFramesReady() 84*3f982cf4SFabien Sanglard // notification before trying again. Otherwise, the number of bytes of encoded 85*3f982cf4SFabien Sanglard // data is returned, and the caller should use this to ensure the buffer it 86*3f982cf4SFabien Sanglard // passes to ConsumeNextFrame() is large enough. 87*3f982cf4SFabien Sanglard virtual int AdvanceToNextFrame() = 0; 88*3f982cf4SFabien Sanglard 89*3f982cf4SFabien Sanglard // Returns the next frame, both metadata and payload data. The Consumer calls 90*3f982cf4SFabien Sanglard // this method after being notified via OnFramesReady(), and it can also call 91*3f982cf4SFabien Sanglard // this whenever AdvanceToNextFrame() indicates another frame is ready. 92*3f982cf4SFabien Sanglard // |buffer| must point to a sufficiently-sized buffer that will be populated 93*3f982cf4SFabien Sanglard // with the frame's payload data. Upon return |frame->data| will be set to the 94*3f982cf4SFabien Sanglard // portion of the buffer that was populated. 95*3f982cf4SFabien Sanglard virtual EncodedFrame ConsumeNextFrame(absl::Span<uint8_t> buffer) = 0; 96*3f982cf4SFabien Sanglard 97*3f982cf4SFabien Sanglard // The default "player processing time" amount. See SetPlayerProcessingTime(). 98*3f982cf4SFabien Sanglard static constexpr std::chrono::milliseconds kDefaultPlayerProcessingTime{5}; 99*3f982cf4SFabien Sanglard 100*3f982cf4SFabien Sanglard // Returned by AdvanceToNextFrame() when there are no frames currently ready 101*3f982cf4SFabien Sanglard // for consumption. 102*3f982cf4SFabien Sanglard static constexpr int kNoFramesReady = -1; 103*3f982cf4SFabien Sanglard }; 104*3f982cf4SFabien Sanglard 105*3f982cf4SFabien Sanglard } // namespace cast 106*3f982cf4SFabien Sanglard } // namespace openscreen 107*3f982cf4SFabien Sanglard 108*3f982cf4SFabien Sanglard #endif // CAST_STREAMING_RECEIVER_BASE_H_ 109