// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CAST_STREAMING_PUBLIC_RECEIVER_H_ #define CAST_STREAMING_PUBLIC_RECEIVER_H_ #include <stdint.h> #include <array> #include <chrono> #include <memory> #include <optional> #include <utility> #include <vector> #include "cast/streaming/impl/clock_drift_smoother.h" #include "cast/streaming/impl/compound_rtcp_builder.h" #include "cast/streaming/impl/frame_collector.h" #include "cast/streaming/impl/packet_receive_stats_tracker.h" #include "cast/streaming/impl/receiver_base.h" #include "cast/streaming/impl/rtcp_common.h" #include "cast/streaming/impl/rtcp_session.h" #include "cast/streaming/impl/rtp_packet_parser.h" #include "cast/streaming/impl/sender_report_parser.h" #include "cast/streaming/impl/session_config.h" #include "cast/streaming/public/environment.h" #include "cast/streaming/public/frame_id.h" #include "cast/streaming/ssrc.h" #include "platform/api/time.h" #include "platform/base/span.h" #include "util/alarm.h" namespace openscreen::cast { struct EncodedFrame; class ReceiverPacketRouter; // The Cast Streaming Receiver, a peer corresponding to some Cast Streaming // Sender at the other end of a network link. // // Cast Streaming is a transport protocol which divides up the frames for one // media stream (e.g., audio or video) into multiple RTP packets containing an // encrypted payload. The Receiver is the peer responsible for collecting the // RTP packets, decrypting the payload, and re-assembling a frame that can be // passed to a decoder and played out. // // A Sender ↔ Receiver pair is used to transport each media stream. Typically, // there are two pairs in a normal system, one for the audio stream and one for // video stream. A local player is responsible for synchronizing the playout of // the frames of each stream to achieve lip-sync. See the discussion in // encoded_frame.h for how the |reference_time| and |rtp_timestamp| of the // EncodedFrames are used to achieve this. // // See the Receiver Demo app for a reference implementation that both shows and // explains how Receivers are properly configured and started, integrated with a // decoder, and the resulting decoded media is played out. Also, here is a // general usage example: // // class MyPlayer : public openscreen::cast::Receiver::Consumer { // public: // explicit MyPlayer(Receiver* receiver) : receiver_(receiver) { // recevier_->SetPlayerProcessingTime(std::chrono::milliseconds(10)); // receiver_->SetConsumer(this); // } // // ~MyPlayer() override { // receiver_->SetConsumer(nullptr); // } // // private: // // Receiver::Consumer implementation. // void OnFramesReady(int next_frame_buffer_size) override { // std::vector<uint8_t> buffer; // buffer.resize(next_frame_buffer_size); // openscreen::cast::EncodedFrame encoded_frame = // receiver_->ConsumeNextFrame(buffer); // // display_.RenderFrame(decoder_.DecodeFrame(encoded_frame.data)); // // // Note: An implementation could call receiver_->AdvanceToNextFrame() // // and receiver_->ConsumeNextFrame() in a loop here, to consume all the // // remaining frames that are ready. // } // // Receiver* const receiver_; // MyDecoder decoder_; // MyDisplay display_; // }; // // Internally, a queue of complete and partially-received frames is maintained. // The queue is a circular queue of FrameCollectors that each maintain the // individual receive state of each in-flight frame. There are three conceptual // "pointers" that indicate what assumptions and operations are made on certain // ranges of frames in the queue: // // 1. Latest Frame Expected: The FrameId of the latest frame whose existence // is known to this Receiver. This is the highest FrameId seen in any // successfully-parsed RTP packet. // 2. Checkpoint Frame: Indicates that all of the RTP packets for all frames // up to and including the one having this FrameId have been successfully // received and processed. // 3. Last Frame Consumed: The FrameId of last frame consumed (see // ConsumeNextFrame()). Once a frame is consumed, all internal resources // related to the frame can be freed and/or re-used for later frames. class Receiver : public ReceiverBase { … }; } // namespace openscreen::cast #endif // CAST_STREAMING_PUBLIC_RECEIVER_H_