1*3f982cf4SFabien Sanglard // Copyright 2019 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_FRAME_COLLECTOR_H_ 6*3f982cf4SFabien Sanglard #define CAST_STREAMING_FRAME_COLLECTOR_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <vector> 9*3f982cf4SFabien Sanglard 10*3f982cf4SFabien Sanglard #include "absl/types/span.h" 11*3f982cf4SFabien Sanglard #include "cast/streaming/frame_crypto.h" 12*3f982cf4SFabien Sanglard #include "cast/streaming/frame_id.h" 13*3f982cf4SFabien Sanglard #include "cast/streaming/rtcp_common.h" 14*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_packet_parser.h" 15*3f982cf4SFabien Sanglard 16*3f982cf4SFabien Sanglard namespace openscreen { 17*3f982cf4SFabien Sanglard namespace cast { 18*3f982cf4SFabien Sanglard 19*3f982cf4SFabien Sanglard // Used by a Receiver to collect the parts of a frame, track what is 20*3f982cf4SFabien Sanglard // missing/complete, and assemble a complete frame. 21*3f982cf4SFabien Sanglard class FrameCollector { 22*3f982cf4SFabien Sanglard public: 23*3f982cf4SFabien Sanglard FrameCollector(); 24*3f982cf4SFabien Sanglard ~FrameCollector(); 25*3f982cf4SFabien Sanglard 26*3f982cf4SFabien Sanglard // Sets the ID of the current frame being collected. This must be called after 27*3f982cf4SFabien Sanglard // each Reset(), and before any of the other methods. set_frame_id(FrameId frame_id)28*3f982cf4SFabien Sanglard void set_frame_id(FrameId frame_id) { frame_.frame_id = frame_id; } 29*3f982cf4SFabien Sanglard 30*3f982cf4SFabien Sanglard // Examine the parsed packet, representing part of the whole frame, and 31*3f982cf4SFabien Sanglard // collect any data/metadata from it that helps complete the frame. Returns 32*3f982cf4SFabien Sanglard // false if the |part| contained invalid data. On success, this method takes 33*3f982cf4SFabien Sanglard // the data contained within the |buffer|, into which |part.payload| is 34*3f982cf4SFabien Sanglard // pointing, in lieu of copying the data. 35*3f982cf4SFabien Sanglard [[nodiscard]] bool CollectRtpPacket(const RtpPacketParser::ParseResult& part, 36*3f982cf4SFabien Sanglard std::vector<uint8_t>* buffer); 37*3f982cf4SFabien Sanglard 38*3f982cf4SFabien Sanglard // Returns true if the frame data collection is complete and the frame can be 39*3f982cf4SFabien Sanglard // assembled. is_complete()40*3f982cf4SFabien Sanglard bool is_complete() const { return num_missing_packets_ == 0; } 41*3f982cf4SFabien Sanglard 42*3f982cf4SFabien Sanglard // Appends zero or more elements to |nacks| representing which packets are not 43*3f982cf4SFabien Sanglard // yet collected. If all packets for the frame are missing, this appends a 44*3f982cf4SFabien Sanglard // single element containing the special kAllPacketsLost packet ID. Otherwise, 45*3f982cf4SFabien Sanglard // one element is appended for each missing packet, in increasing order of 46*3f982cf4SFabien Sanglard // packet ID. 47*3f982cf4SFabien Sanglard void GetMissingPackets(std::vector<PacketNack>* nacks) const; 48*3f982cf4SFabien Sanglard 49*3f982cf4SFabien Sanglard // Returns a read-only reference to the completely-collected frame, assembling 50*3f982cf4SFabien Sanglard // it if necessary. The caller should reset the FrameCollector (see Reset() 51*3f982cf4SFabien Sanglard // below) to free-up memory once it has finished reading from the returned 52*3f982cf4SFabien Sanglard // frame. 53*3f982cf4SFabien Sanglard // 54*3f982cf4SFabien Sanglard // Precondition: is_complete() must return true before this method can be 55*3f982cf4SFabien Sanglard // called. 56*3f982cf4SFabien Sanglard const EncryptedFrame& PeekAtAssembledFrame(); 57*3f982cf4SFabien Sanglard 58*3f982cf4SFabien Sanglard // Resets the FrameCollector back to its initial state, freeing-up memory. 59*3f982cf4SFabien Sanglard void Reset(); 60*3f982cf4SFabien Sanglard 61*3f982cf4SFabien Sanglard private: 62*3f982cf4SFabien Sanglard struct PayloadChunk { 63*3f982cf4SFabien Sanglard std::vector<uint8_t> buffer; 64*3f982cf4SFabien Sanglard absl::Span<const uint8_t> payload; // Once set, is within |buffer.data()|. 65*3f982cf4SFabien Sanglard 66*3f982cf4SFabien Sanglard PayloadChunk(); 67*3f982cf4SFabien Sanglard ~PayloadChunk(); 68*3f982cf4SFabien Sanglard has_dataPayloadChunk69*3f982cf4SFabien Sanglard bool has_data() const { return !!payload.data(); } 70*3f982cf4SFabien Sanglard }; 71*3f982cf4SFabien Sanglard 72*3f982cf4SFabien Sanglard // Storage for frame metadata and data. Once the frame has been completely 73*3f982cf4SFabien Sanglard // collected and assembled, |frame_.data| is set to non-null, and this is 74*3f982cf4SFabien Sanglard // exposed externally (read-only). 75*3f982cf4SFabien Sanglard EncryptedFrame frame_; 76*3f982cf4SFabien Sanglard 77*3f982cf4SFabien Sanglard // The number of packets needed to complete the frame, or the maximum int if 78*3f982cf4SFabien Sanglard // this is not yet known. 79*3f982cf4SFabien Sanglard int num_missing_packets_; 80*3f982cf4SFabien Sanglard 81*3f982cf4SFabien Sanglard // The chunks of payload data being collected, where element indices 82*3f982cf4SFabien Sanglard // correspond 1:1 with packet IDs. When the first part is collected, this is 83*3f982cf4SFabien Sanglard // resized to match the total number of packets being expected. 84*3f982cf4SFabien Sanglard std::vector<PayloadChunk> chunks_; 85*3f982cf4SFabien Sanglard }; 86*3f982cf4SFabien Sanglard 87*3f982cf4SFabien Sanglard } // namespace cast 88*3f982cf4SFabien Sanglard } // namespace openscreen 89*3f982cf4SFabien Sanglard 90*3f982cf4SFabien Sanglard #endif // CAST_STREAMING_FRAME_COLLECTOR_H_ 91