| /* |
| * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ |
| #define MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ |
| |
| #include <array> |
| #include <map> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/base/attributes.h" |
| #include "modules/video_coding/packet_buffer.h" |
| #include "rtc_base/numerics/sequence_number_unwrapper.h" |
| |
| namespace webrtc { |
| |
| class H26xPacketBuffer { |
| public: |
| // The H26xPacketBuffer does the same job as the PacketBuffer but for H264 and |
| // H265 only. To make it fit in with surronding code the PacketBuffer |
| // input/output classes are used. |
| using Packet = video_coding::PacketBuffer::Packet; |
| using InsertResult = video_coding::PacketBuffer::InsertResult; |
| |
| // |h264_idr_only_keyframes_allowed| is ignored if H.265 is used. |
| explicit H26xPacketBuffer(bool h264_idr_only_keyframes_allowed); |
| |
| ABSL_MUST_USE_RESULT InsertResult |
| InsertPacket(std::unique_ptr<Packet> packet); |
| |
| // Out of band supplied codec parameters for H.264. |
| void SetSpropParameterSets(const std::string& sprop_parameter_sets); |
| |
| private: |
| // Stores PPS payload and the active SPS ID. |
| struct PpsInfo { |
| PpsInfo() = default; |
| PpsInfo(PpsInfo&& rhs) = default; |
| PpsInfo& operator=(PpsInfo&& rhs) = default; |
| ~PpsInfo() = default; |
| |
| // The value of sps_seq_parameter_set_id for the active SPS. |
| uint32_t sps_id = 0; |
| // Payload size. |
| size_t size = 0; |
| std::unique_ptr<uint8_t[]> payload; |
| }; |
| |
| // Stores SPS payload and picture size. |
| struct SpsInfo { |
| SpsInfo() = default; |
| SpsInfo(SpsInfo&& rhs) = default; |
| SpsInfo& operator=(SpsInfo&& rhs) = default; |
| ~SpsInfo() = default; |
| |
| // The width and height of decoded pictures. |
| int width = -1; |
| int height = -1; |
| // Payload size. |
| size_t size = 0; |
| std::unique_ptr<uint8_t[]> payload; |
| }; |
| |
| static constexpr int kBufferSize = 2048; |
| static constexpr int kNumTrackedSequences = 5; |
| |
| std::unique_ptr<Packet>& GetPacket(int64_t unwrapped_seq_num); |
| bool BeginningOfStream(const Packet& packet) const; |
| InsertResult FindFrames(int64_t unwrapped_seq_num); |
| bool MaybeAssembleFrame(int64_t start_seq_num_unwrapped, |
| int64_t end_sequence_number_unwrapped, |
| InsertResult& result); |
| // Store SPS and PPS nalus. They will be used later when an IDR frame is |
| // received without SPS/PPS. |
| void InsertSpsPpsNalus(const std::vector<uint8_t>& sps, |
| const std::vector<uint8_t>& pps); |
| // Insert start code and paramter sets for H.264 payload, also update header |
| // if parameter sets are inserted. Return false if required SPS or PPS is not |
| // found. |
| bool FixH264Packet(Packet& packet); |
| |
| // Indicates whether IDR frames without SPS and PPS are allowed. |
| const bool h264_idr_only_keyframes_allowed_; |
| std::array<std::unique_ptr<Packet>, kBufferSize> buffer_; |
| std::array<int64_t, kNumTrackedSequences> last_continuous_in_sequence_; |
| int64_t last_continuous_in_sequence_index_ = 0; |
| |
| // Map from pps_pic_parameter_set_id to the PPS payload associated with this |
| // ID. |
| std::map<int, PpsInfo> pps_data_; |
| // Map from sps_video_parameter_set_id to the SPS payload associated with this |
| // ID. |
| std::map<int, SpsInfo> sps_data_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ |