uvgrtp-base/include/formats/h265.hh

107 lines
4.0 KiB
C++

#pragma once
#include <map>
#include <unordered_set>
#include <vector>
#include "frame.hh"
#include "queue.hh"
#include "formats/h26x.hh"
namespace uvg_rtp {
namespace formats {
enum H265_NAL_TYPES {
H265_PKT_AGGR = 48,
H265_PKT_FRAG = 49
};
struct h265_aggregation_packet {
uint8_t nal_header[uvg_rtp::frame::HEADER_SIZE_H265_NAL];
uvg_rtp::buf_vec buffers; /* discrete NAL units */
uvg_rtp::buf_vec aggr_pkt; /* crafted aggregation packet */
};
struct h265_headers {
uint8_t nal_header[uvg_rtp::frame::HEADER_SIZE_H265_NAL];
/* there are three types of Fragmentation Unit headers:
* - header for the first fragment
* - header for all middle fragments
* - header for the last fragment */
uint8_t fu_headers[3 * uvg_rtp::frame::HEADER_SIZE_H265_FU];
};
typedef struct h265_info {
/* clock reading when the first fragment is received */
uvg_rtp::clock::hrc::hrc_t sframe_time;
/* sequence number of the frame with s-bit */
uint32_t s_seq;
/* sequence number of the frame with e-bit */
uint32_t e_seq;
/* how many fragments have been received */
size_t pkts_received;
/* total size of all fragments */
size_t total_size;
/* map of frame's fragments,
* allows out-of-order insertion and loop-through in order */
std::map<uint16_t, uvg_rtp::frame::rtp_frame *> fragments;
/* storage for fragments that require relocation */
std::vector<uvg_rtp::frame::rtp_frame *> temporary;
} h265_info_t;
typedef struct {
std::unordered_map<uint32_t, h265_info_t> frames;
std::unordered_set<uint32_t> dropped;
} h265_frame_info_t;
class h265 : public h26x {
public:
h265(uvg_rtp::socket *socket, uvg_rtp::rtp *rtp, int flags);
~h265();
/* Packet handler for RTP frames that transport HEVC bitstream
*
* If "frame" is not a fragmentation unit, packet handler checks
* if "frame" is SPS/VPS/PPS packet and if so, returns the packet
* to user immediately.
*
* If "frame" is a fragmentation unit, packet handler checks if
* it has received all fragments of a complete HEVC NAL unit and if
* so, it merges all fragments into a complete NAL unit and returns
* the NAL unit to user. If the NAL unit is not complete, packet
* handler holds onto the frame and waits for other fragments to arrive.
*
* Return RTP_OK if the packet was successfully handled
* Return RTP_PKT_READY if "frame" contains an RTP that can be returned to user
* Return RTP_PKT_NOT_HANDLED if the packet is not handled by this handler
* Return RTP_PKT_MODIFIED if the packet was modified but should be forwarded to other handlers
* Return RTP_GENERIC_ERROR if the packet was corrupted in some way */
static rtp_error_t packet_handler(void *arg, int flags, frame::rtp_frame **frame);
/* Return pointer to the internal frame info structure which is relayed to packet handler */
h265_frame_info_t *get_h265_frame_info();
protected:
rtp_error_t push_nal_unit(uint8_t *data, size_t data_len, bool more);
private:
/* Construct an aggregation packet from data in "aggr_pkt_info_" */
rtp_error_t make_aggregation_pkt();
/* Clear aggregation buffers */
void clear_aggregation_info();
h265_frame_info_t finfo_;
h265_aggregation_packet aggr_pkt_info_;
};
};
};