xref: /aosp_15_r20/external/openscreen/cast/streaming/frame_collector.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
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