mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
rtph265pay: Only mark first NAL as non delta-unit
When the input buffer contained multiple NAL's the second one would keep the non delta-unit flag for a key frame. The delta-unit flag will now be set per NAL when preparing the buffer list to payload. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4937>
This commit is contained in:
parent
1c4de219e4
commit
b40b4ffb81
2 changed files with 103 additions and 15 deletions
|
@ -922,8 +922,7 @@ gst_rtp_h265_pay_decode_nal (GstRtpH265Pay * payloader,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn gst_rtp_h265_pay_payload_nal (GstRTPBasePayload *
|
static GstFlowReturn gst_rtp_h265_pay_payload_nal (GstRTPBasePayload *
|
||||||
basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts,
|
basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts);
|
||||||
gboolean delta_unit);
|
|
||||||
static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload *
|
static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload *
|
||||||
basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
|
basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
|
||||||
gboolean marker, gboolean delta_unit);
|
gboolean marker, gboolean delta_unit);
|
||||||
|
@ -970,7 +969,7 @@ gst_rtp_h265_pay_send_vps_sps_pps (GstRTPBasePayload * basepayload,
|
||||||
g_ptr_array_add (bufs, gst_buffer_ref (pps_buf));
|
g_ptr_array_add (bufs, gst_buffer_ref (pps_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gst_rtp_h265_pay_payload_nal (basepayload, bufs, dts, pts, FALSE);
|
ret = gst_rtp_h265_pay_payload_nal (basepayload, bufs, dts, pts);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
/* not critical but warn */
|
/* not critical but warn */
|
||||||
GST_WARNING_OBJECT (basepayload, "failed pushing VPS/SPS/PPS");
|
GST_WARNING_OBJECT (basepayload, "failed pushing VPS/SPS/PPS");
|
||||||
|
@ -996,8 +995,7 @@ gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay)
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
GPtrArray * paybufs, GstClockTime dts, GstClockTime pts,
|
GPtrArray * paybufs, GstClockTime dts, GstClockTime pts)
|
||||||
gboolean delta_unit)
|
|
||||||
{
|
{
|
||||||
GstRtpH265Pay *rtph265pay;
|
GstRtpH265Pay *rtph265pay;
|
||||||
guint mtu;
|
guint mtu;
|
||||||
|
@ -1023,6 +1021,7 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
gboolean send_ps;
|
gboolean send_ps;
|
||||||
guint size;
|
guint size;
|
||||||
gboolean marker;
|
gboolean marker;
|
||||||
|
gboolean delta_unit;
|
||||||
|
|
||||||
paybuf = g_ptr_array_index (paybufs, i);
|
paybuf = g_ptr_array_index (paybufs, i);
|
||||||
|
|
||||||
|
@ -1033,6 +1032,7 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
marker = GST_BUFFER_FLAG_IS_SET (paybuf, GST_BUFFER_FLAG_MARKER);
|
marker = GST_BUFFER_FLAG_IS_SET (paybuf, GST_BUFFER_FLAG_MARKER);
|
||||||
|
delta_unit = GST_BUFFER_FLAG_IS_SET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
size = gst_buffer_get_size (paybuf);
|
size = gst_buffer_get_size (paybuf);
|
||||||
gst_buffer_extract (paybuf, 0, nal_header, 2);
|
gst_buffer_extract (paybuf, 0, nal_header, 2);
|
||||||
|
@ -1583,6 +1583,14 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
discont = FALSE;
|
discont = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
if (!rtph265pay->delta_unit)
|
||||||
|
GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
|
if (!rtph265pay->delta_unit)
|
||||||
|
/* only the first outgoing packet doesn't have the DELTA_UNIT flag */
|
||||||
|
rtph265pay->delta_unit = TRUE;
|
||||||
|
|
||||||
/* Skip current nal. If it is split over multiple GstMemory
|
/* Skip current nal. If it is split over multiple GstMemory
|
||||||
* advance_bytes () will switch to the correct GstMemory. The payloader
|
* advance_bytes () will switch to the correct GstMemory. The payloader
|
||||||
* does not access those bytes directly but uses gst_buffer_copy_region ()
|
* does not access those bytes directly but uses gst_buffer_copy_region ()
|
||||||
|
@ -1592,13 +1600,7 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
offset += nal_len;
|
offset += nal_len;
|
||||||
remaining_buffer_size -= nal_len;
|
remaining_buffer_size -= nal_len;
|
||||||
}
|
}
|
||||||
ret =
|
ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
|
||||||
gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts,
|
|
||||||
rtph265pay->delta_unit);
|
|
||||||
|
|
||||||
if (!rtph265pay->delta_unit)
|
|
||||||
/* only the first outgoing packet doesn't have the DELTA_UNIT flag */
|
|
||||||
rtph265pay->delta_unit = TRUE;
|
|
||||||
|
|
||||||
gst_buffer_memory_unmap (&memory);
|
gst_buffer_memory_unmap (&memory);
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
@ -1713,6 +1715,10 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
discont = FALSE;
|
discont = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
if (!rtph265pay->delta_unit)
|
||||||
|
GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
if (delayed_not_delta_unit) {
|
if (delayed_not_delta_unit) {
|
||||||
rtph265pay->delta_unit = FALSE;
|
rtph265pay->delta_unit = FALSE;
|
||||||
delayed_not_delta_unit = FALSE;
|
delayed_not_delta_unit = FALSE;
|
||||||
|
@ -1726,9 +1732,7 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
||||||
gst_adapter_flush (rtph265pay->adapter, nal_len - size);
|
gst_adapter_flush (rtph265pay->adapter, nal_len - size);
|
||||||
}
|
}
|
||||||
/* put the data in one or more RTP packets */
|
/* put the data in one or more RTP packets */
|
||||||
ret =
|
ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
|
||||||
gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts,
|
|
||||||
rtph265pay->delta_unit);
|
|
||||||
g_array_set_size (nal_queue, 0);
|
g_array_set_size (nal_queue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1181,6 +1181,87 @@ GST_START_TEST (test_rtph265pay_delta_unit_flag)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_rtph265pay_delta_unit_multiple_nal)
|
||||||
|
{
|
||||||
|
GstHarness *h = gst_harness_new_parse ("rtph265pay mtu=28");
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
gst_harness_set_src_caps_str (h,
|
||||||
|
"video/x-h265,alignment=au,stream-format=hvc1,"
|
||||||
|
"codec_data=(buffer)0104080000009e28000000003ff000fcfff8f800000f032000"
|
||||||
|
"01001740010c01ffff0408000003009e2800000300003fba0240210001002f4201010"
|
||||||
|
"408000003009e2800000300003f90041020b2dd492657ff80008000b5060606040000"
|
||||||
|
"03000400000300782022000100074401c172b02240");
|
||||||
|
|
||||||
|
/* append two NAL's, each in separate memory blocks to the input buffer */
|
||||||
|
buffer = wrap_static_buffer (h265_hvc1_idr_data, sizeof (h265_hvc1_idr_data));
|
||||||
|
buffer = gst_buffer_append (buffer,
|
||||||
|
wrap_static_buffer (h265_hvc1_idr_data, sizeof (h265_hvc1_idr_data)));
|
||||||
|
|
||||||
|
ret = gst_harness_push (h, buffer);
|
||||||
|
fail_unless_equals_int (ret, GST_FLOW_OK);
|
||||||
|
|
||||||
|
/* each NAL should be split into two buffers and pushed as a buffer list,
|
||||||
|
* only the first buffer of the first buffer list should be marked as a
|
||||||
|
* non-delta unit */
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
gst_harness_teardown (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_rtph265pay_delta_unit_single_nal_multiple_memories)
|
||||||
|
{
|
||||||
|
GstHarness *h = gst_harness_new_parse ("rtph265pay mtu=28");
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
gst_harness_set_src_caps_str (h,
|
||||||
|
"video/x-h265,alignment=au,stream-format=hvc1,"
|
||||||
|
"codec_data=(buffer)0104080000009e28000000003ff000fcfff8f800000f032000"
|
||||||
|
"01001740010c01ffff0408000003009e2800000300003fba0240210001002f4201010"
|
||||||
|
"408000003009e2800000300003f90041020b2dd492657ff80008000b5060606040000"
|
||||||
|
"03000400000300782022000100074401c172b02240");
|
||||||
|
|
||||||
|
/* append one NAL spanning over two memory blocks to the input buffer */
|
||||||
|
gsize second_mem_size = 10;
|
||||||
|
gsize first_mem_size = sizeof (h265_hvc1_idr_data) - second_mem_size;
|
||||||
|
buffer = wrap_static_buffer (h265_hvc1_idr_data, first_mem_size);
|
||||||
|
buffer = gst_buffer_append (buffer,
|
||||||
|
wrap_static_buffer (h265_hvc1_idr_data + first_mem_size,
|
||||||
|
second_mem_size));
|
||||||
|
|
||||||
|
ret = gst_harness_push (h, buffer);
|
||||||
|
fail_unless_equals_int (ret, GST_FLOW_OK);
|
||||||
|
|
||||||
|
/* the NAL should be split into two buffers and pushed as a buffer list, only
|
||||||
|
* the first buffer in the buffer list should be marked as a non-delta unit */
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
buffer = gst_harness_pull (h);
|
||||||
|
fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
gst_harness_teardown (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_rtph265pay_delta_unit_flag_config_interval)
|
GST_START_TEST (test_rtph265pay_delta_unit_flag_config_interval)
|
||||||
{
|
{
|
||||||
GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123"
|
GstHarness *h = gst_harness_new_parse ("rtph265pay timestamp-offset=123"
|
||||||
|
@ -1305,6 +1386,9 @@ rtph265_suite (void)
|
||||||
tcase_add_test (tc_chain, test_rtph265pay_aggregate_until_vcl);
|
tcase_add_test (tc_chain, test_rtph265pay_aggregate_until_vcl);
|
||||||
tcase_add_test (tc_chain, test_rtph265pay_aggregate_verify_nalu_hdr);
|
tcase_add_test (tc_chain, test_rtph265pay_aggregate_verify_nalu_hdr);
|
||||||
tcase_add_test (tc_chain, test_rtph265pay_delta_unit_flag);
|
tcase_add_test (tc_chain, test_rtph265pay_delta_unit_flag);
|
||||||
|
tcase_add_test (tc_chain, test_rtph265pay_delta_unit_multiple_nal);
|
||||||
|
tcase_add_test (tc_chain,
|
||||||
|
test_rtph265pay_delta_unit_single_nal_multiple_memories);
|
||||||
tcase_add_test (tc_chain, test_rtph265pay_delta_unit_flag_config_interval);
|
tcase_add_test (tc_chain, test_rtph265pay_delta_unit_flag_config_interval);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
Loading…
Reference in a new issue