Skip to content

Commit e96314c

Browse files
committed
HEVC RTP: support for 2 byte HEVC NAL header
1 parent 7464d86 commit e96314c

File tree

6 files changed

+32
-18
lines changed

6 files changed

+32
-18
lines changed

src/rtp/rtpdec_h264.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ static const uint8_t start_sequence[] = { 0, 0, 0, 1 };
7878
* @retval H.264 or RTP NAL type
7979
*/
8080
static uint8_t process_h264_nal(uint8_t nal, struct video_frame *frame, uint8_t *data, int data_len) {
81-
uint8_t type = H264_NALU_HDR_GET_TYPE(nal);
82-
uint8_t nri = H264_NALU_HDR_GET_NRI(nal);
81+
uint8_t type = H264_NALU_HDR_GET_TYPE(&nal);
82+
uint8_t nri = H264_NALU_HDR_GET_NRI(&nal);
8383
log_msg(LOG_LEVEL_DEBUG2, "NAL type %s (%d; nri: %d)\n",
8484
get_h264_nalu_name(type), (int) type, (int) nri);
8585

@@ -99,10 +99,14 @@ static uint8_t process_h264_nal(uint8_t nal, struct video_frame *frame, uint8_t
9999
return type;
100100
}
101101

102-
static uint8_t process_hevc_nal(uint8_t nal, struct video_frame *frame, uint8_t *data, int data_len) {
102+
static uint8_t process_hevc_nal(const uint8_t nal[2], struct video_frame *frame, uint8_t *data, int data_len) {
103+
unsigned char forbidden = nal[0] >> 7;
104+
assert(forbidden == 0);
103105
enum hevc_nal_type type = HEVC_NALU_HDR_GET_TYPE(nal);
104-
log_msg(LOG_LEVEL_DEBUG2, "HEVC NAL type %s (%d)\n",
105-
get_hevc_nalu_name(type), (int) type);
106+
unsigned layer_id = HEVC_NALU_HDR_GET_LAYER_ID(nal);
107+
unsigned tid = HEVC_NALU_HDR_GET_TID(nal);
108+
log_msg(LOG_LEVEL_DEBUG2, "HEVC NAL type %s (%d; layerID: %u, TID: %u)\n",
109+
get_hevc_nalu_name(type), (int) type, layer_id, tid);
106110

107111
if (type == NAL_HEVC_SPS) {
108112
width_height_from_hevc_sps((int *) &frame->tiles[0].width,
@@ -129,7 +133,7 @@ decode_h264_nal_unit(struct video_frame *frame, int *total_length, int pass,
129133
int fu_length = 0;
130134
uint8_t nal = data[0];
131135
uint8_t type = pass == 0 ? process_h264_nal(nal, frame, data, data_len)
132-
: H264_NALU_HDR_GET_TYPE(nal);
136+
: H264_NALU_HDR_GET_TYPE(&nal);
133137
if (type >= NAL_H264_MIN && type <= NAL_H264_MAX) {
134138
type = H264_NAL;
135139
}
@@ -161,8 +165,8 @@ decode_h264_nal_unit(struct video_frame *frame, int *total_length, int pass,
161165

162166
log_msg(LOG_LEVEL_DEBUG2,
163167
"STAP-A subpacket NAL type %d (nri: %d)\n",
164-
(int) H264_NALU_HDR_GET_TYPE(data[0]),
165-
(int) H264_NALU_HDR_GET_NRI(nal));
168+
(int) H264_NALU_HDR_GET_TYPE(data),
169+
(int) H264_NALU_HDR_GET_NRI(&nal));
166170

167171
if (nal_size <= data_len) {
168172
if (pass == 0) {
@@ -211,7 +215,7 @@ decode_h264_nal_unit(struct video_frame *frame, int *total_length, int pass,
211215
uint8_t fu_header = *data;
212216
uint8_t start_bit = fu_header >> 7;
213217
uint8_t end_bit = (fu_header & 0x40) >> 6;
214-
uint8_t nal_type = H264_NALU_HDR_GET_TYPE(fu_header);
218+
uint8_t nal_type = H264_NALU_HDR_GET_TYPE(&fu_header);
215219
uint8_t reconstructed_nal;
216220

217221
// Reconstruct this packet's true nal; only the data follows.
@@ -263,8 +267,10 @@ static bool
263267
decode_hevc_nal_unit(struct video_frame *frame, int *total_length, int pass,
264268
unsigned char **dst, uint8_t *data, int data_len)
265269
{
266-
uint8_t nal = data[0];
267-
uint8_t type = pass == 0 ? process_hevc_nal(nal, frame, data, data_len) : HEVC_NALU_HDR_GET_TYPE(nal);
270+
uint8_t nal[2] = { data[0], data[1] };
271+
enum hevc_nal_type type = pass == 0
272+
? process_hevc_nal(nal, frame, data, data_len)
273+
: HEVC_NALU_HDR_GET_TYPE(&nal);
268274

269275
if (type <= NAL_HEVC_MAX) {
270276
if (pass == 0) {

src/rtp/rtpdec_h264.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,17 @@ struct coded_data;
9090
struct decode_data_rtsp;
9191
struct video_desc;
9292

93-
#define H264_NALU_HDR_GET_TYPE(nal) ((nal) & 0x1F)
94-
#define H264_NALU_HDR_GET_NRI(nal) (((nal) & 0x60) >> 5)
95-
#define HEVC_NALU_HDR_GET_TYPE(nal) ((nal) >> 1)
93+
#define H264_NALU_HDR_GET_TYPE(nal) (*(const uint8_t *) (nal) & 0x1F)
94+
#define H264_NALU_HDR_GET_NRI(nal) ((*(const uint8_t *) (nal) & 0x60) >> 5)
95+
96+
/// @param nal pointer to **big-endian** NAL header
97+
#define HEVC_NALU_HDR_GET_TYPE(nal) (*(const uint8_t *) (nal) >> 1)
98+
#define HEVC_NALU_HDR_GET_LAYER_ID(nal) \
99+
((((const uint8_t *) (nal))[0] & 0x1) << 5 | \
100+
((const uint8_t *) (nal))[1] >> 3)
101+
#define HEVC_NALU_HDR_GET_TID(nal) \
102+
(((const uint8_t *) (nal))[1] & 0x7)
103+
96104
#define NALU_HDR_GET_TYPE(nal, is_hevc) \
97105
((is_hevc) ? HEVC_NALU_HDR_GET_TYPE((nal)) \
98106
: H264_NALU_HDR_GET_TYPE((nal)))

src/rtp/rtpenc_h264.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ rtpenc_get_first_nal(const unsigned char *src, long src_len, bool hevc)
122122
if (!nal) {
123123
return NULL;
124124
}
125-
nalu_type = NALU_HDR_GET_TYPE(nal[0], hevc);
125+
nalu_type = NALU_HDR_GET_TYPE(nal, hevc);
126126
debug_msg("Received %s NALU.\n", get_nalu_name(nalu_type, hevc));
127127
} while (nalu_type == NAL_H264_AUD || nalu_type == NAL_HEVC_AUD);
128128
return nal;

src/video_capture/rtsp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ get_nals(FILE *sdp_file, codec_t codec, char *nals, int *width, int *height) {
12981298
len_nals += length;
12991299
free(nal_decoded);
13001300

1301-
uint8_t nalInfo = (uint8_t) nals[len_nals - length];
1301+
char *nalInfo = nals + len_nals - length;
13021302
uint8_t type = NALU_HDR_GET_TYPE(nalInfo, codec == H265);
13031303
MSG(DEBUG, "%s %s (%d) (base64): %s\n", sprop_name,
13041304
get_nalu_name(type, codec == H265), (int) type, nal);

src/video_compress/libavcodec.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ store_sps_pps_vps(state_video_compress_libav *s, AVPacket *pkt)
14531453
int i = 0;
14541454
const unsigned char *endptr = nullptr;
14551455
while (nal != nullptr) {
1456-
if (NALU_HDR_GET_TYPE(nal[0], is_hevc) != nalu_req[i++]) {
1456+
if (NALU_HDR_GET_TYPE(nal, is_hevc) != nalu_req[i++]) {
14571457
return;
14581458
}
14591459
if (nalu_req[i] == 0) { // correct seq of NALU

src/video_decompress/libavcodec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ static _Bool check_first_sps_vps(struct state_libavcodec_decompress *s, unsigned
886886
return 0;
887887
}
888888
const bool hevc = s->desc.color_spec == H265;
889-
const int nalu_type = NALU_HDR_GET_TYPE(nal[0], hevc);
889+
const int nalu_type = NALU_HDR_GET_TYPE(nal, hevc);
890890

891891
if (hevc) {
892892
if (nalu_type > NAL_HEVC_CODED_SLC_FIRST) {

0 commit comments

Comments
 (0)