From: Kristofer Björkström Date: Fri, 10 Jan 2020 15:30:33 +0000 (+0100) Subject: rtph265pay: TID for NALU type 48 was always set to 7 X-Git-Tag: 1.19.3~509^2~775 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9c86414279f9eb37374fc573670e1ce47021b3b1;p=platform%2Fupstream%2Fgstreamer.git rtph265pay: TID for NALU type 48 was always set to 7 A typo bug: | instead of & resulted in TID alwasy being set to 7 for the aggregated NALU of type 48 --- diff --git a/gst/rtp/gstrtph265pay.c b/gst/rtp/gstrtph265pay.c index 95d2aeb..d5285f0 100644 --- a/gst/rtp/gstrtph265pay.c +++ b/gst/rtp/gstrtph265pay.c @@ -1297,7 +1297,7 @@ gst_rtp_h265_pay_send_bundle (GstRtpH265Pay * rtph265pay, gboolean marker) } ap_header[0] = (AP_TYPE_ID << 1) | (layer_id & 0x20); - ap_header[1] = ((layer_id & 0x1F) << 3) | (temporal_id | 0x07); + ap_header[1] = ((layer_id & 0x1F) << 3) | (temporal_id & 0x07); gst_buffer_fill (outbuf, 0, &ap_header, sizeof ap_header); diff --git a/tests/check/elements/rtph265.c b/tests/check/elements/rtph265.c index ea07c59..2c2ff3c 100644 --- a/tests/check/elements/rtph265.c +++ b/tests/check/elements/rtph265.c @@ -24,6 +24,7 @@ #include #include #include +#include #define ALLOCATOR_CUSTOM_SYSMEM "CustomSysMem" @@ -1000,7 +1001,126 @@ GST_START_TEST (test_rtph265pay_aggregate_until_vcl) GST_END_TEST; +GST_START_TEST (test_rtph265pay_aggregate_verify_nalu_hdr) +{ + GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123" + " name=p"); + GstFlowReturn ret; + GstBuffer *buffer; + GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; + guint8 *payload = NULL; + gint paylen; + guint nalu_type; + guint nal_hdr_idx = 0; + guint nal_size_idx; + guint f_bit; + guint max_f_bit; + guint layer_id; + guint layer_id_min; + guint tid; + guint tid_min; + guint i; + + gst_harness_set_src_caps_str (h, + "video/x-h265,alignment=nal,stream-format=byte-stream"); + buffer = wrap_static_buffer_with_pts (h265_vps, sizeof (h265_vps), 0); + ret = gst_harness_push (h, buffer); + fail_unless_equals_int (ret, GST_FLOW_OK); + + buffer = wrap_static_buffer_with_pts (h265_sps, sizeof (h265_sps), 0); + ret = gst_harness_push (h, buffer); + fail_unless_equals_int (ret, GST_FLOW_OK); + + buffer = wrap_static_buffer_with_pts (h265_pps, sizeof (h265_pps), 0); + ret = gst_harness_push (h, buffer); + fail_unless_equals_int (ret, GST_FLOW_OK); + + buffer = wrap_static_buffer_with_pts (h265_idr_slice_1, + sizeof (h265_idr_slice_1), 0); + ret = gst_harness_push (h, buffer); + fail_unless_equals_int (ret, GST_FLOW_OK); + + fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1); + + buffer = gst_harness_pull (h); + fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp)); + fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0); + fail_unless_equals_uint64 (gst_rtp_buffer_get_timestamp (&rtp), 123); + /* RTP header = 12, STAP header = 2, 2 bytes length per NAL */ + fail_unless_equals_int (gst_buffer_get_size (buffer), 12 + 2 + + (2 + sizeof (h265_vps) - 4) + + (2 + sizeof (h265_sps) - 4) + + (2 + sizeof (h265_pps) - 4) + (2 + sizeof (h265_idr_slice_1) - 4)); + + paylen = gst_rtp_buffer_get_payload_len (&rtp); + payload = gst_rtp_buffer_get_payload (&rtp); + fail_unless (payload); + + /* Verify NAL unit type is 48. We need to shift to the rigth to get rid of the + * first bit belonging to LayerID */ + nalu_type = ((0x7e & payload[nal_hdr_idx]) >> 1); + fail_unless (nalu_type == 48); + + /* The F bit MUST be cleared if all F bits of the aggregated NAL units + * are zero; otherwise, it MUST be set. rfc7798 4.4.2 */ + f_bit = (0x80 & payload[nal_hdr_idx]); + max_f_bit = 0; + + /* The value of LayerId and TID MUST be equal to the lowest value of LayerId + * resp TID of all the aggregated NAL units */ + layer_id = ((0x01 & payload[nal_hdr_idx]) << 5) | + ((payload[nal_hdr_idx + 1] >> 3) & 0x1F); + tid = payload[nal_hdr_idx + 1] & 0x7; + + nal_hdr_idx = 4; + nal_size_idx = 2; + layer_id_min = 63; + tid_min = 7; + i = 0; + while (nal_size_idx < paylen) { + guint nal_type = ((0x7e & payload[nal_hdr_idx]) >> 1); + if (i == 0) { + fail_unless (nal_type == GST_H265_NAL_VPS); + } else if (i == 1) { + fail_unless (nal_type == GST_H265_NAL_SPS); + } else if (i == 2) { + fail_unless (nal_type == GST_H265_NAL_PPS); + } else if (i == 3) { + fail_unless (nal_type == GST_H265_NAL_SLICE_IDR_N_LP); + } + + if ((0x80 & payload[nal_hdr_idx]) > max_f_bit) + max_f_bit = (0x80 & payload[nal_hdr_idx]); + + if ((((0x01 & payload[nal_hdr_idx]) << 5) | ((payload[nal_hdr_idx + 1] >> 3) + & 0x1F)) < layer_id_min) + layer_id_min = + ((0x01 & payload[nal_hdr_idx]) << 5) | ((payload[nal_hdr_idx + 1] + >> 3) & 0x1F); + + if ((payload[nal_hdr_idx + 1] & 0x7) < tid_min) + tid_min = payload[nal_hdr_idx + 1] & 0x7; + + nal_size_idx = + (payload[nal_size_idx] << 8 | payload[nal_size_idx + 1]) + + nal_size_idx + 2; + nal_hdr_idx = nal_size_idx + 2; + i++; + } + + fail_unless (nal_size_idx == paylen); + fail_unless (max_f_bit == f_bit); + fail_unless (layer_id_min == layer_id); + fail_unless (tid_min == tid); + + gst_rtp_buffer_unmap (&rtp); + gst_buffer_unref (buffer); + + gst_harness_teardown (h); +} + +GST_END_TEST; static Suite * rtph265_suite (void) { @@ -1026,6 +1146,7 @@ rtph265_suite (void) tcase_add_test (tc_chain, test_rtph265pay_aggregate_with_ts_change); tcase_add_test (tc_chain, test_rtph265pay_aggregate_with_discont); tcase_add_test (tc_chain, test_rtph265pay_aggregate_until_vcl); + tcase_add_test (tc_chain, test_rtph265pay_aggregate_verify_nalu_hdr); return s; }