mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +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 *
|
||||
basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts,
|
||||
gboolean delta_unit);
|
||||
basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts);
|
||||
static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload *
|
||||
basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
/* not critical but warn */
|
||||
GST_WARNING_OBJECT (basepayload, "failed pushing VPS/SPS/PPS");
|
||||
|
@ -996,8 +995,7 @@ gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay)
|
|||
|
||||
static GstFlowReturn
|
||||
gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
||||
GPtrArray * paybufs, GstClockTime dts, GstClockTime pts,
|
||||
gboolean delta_unit)
|
||||
GPtrArray * paybufs, GstClockTime dts, GstClockTime pts)
|
||||
{
|
||||
GstRtpH265Pay *rtph265pay;
|
||||
guint mtu;
|
||||
|
@ -1023,6 +1021,7 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|
|||
gboolean send_ps;
|
||||
guint size;
|
||||
gboolean marker;
|
||||
gboolean delta_unit;
|
||||
|
||||
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);
|
||||
delta_unit = GST_BUFFER_FLAG_IS_SET (paybuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
|
||||
size = gst_buffer_get_size (paybuf);
|
||||
gst_buffer_extract (paybuf, 0, nal_header, 2);
|
||||
|
@ -1583,6 +1583,14 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
|||
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
|
||||
* advance_bytes () will switch to the correct GstMemory. The payloader
|
||||
* 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;
|
||||
remaining_buffer_size -= nal_len;
|
||||
}
|
||||
ret =
|
||||
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;
|
||||
ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
|
||||
|
||||
gst_buffer_memory_unmap (&memory);
|
||||
gst_buffer_unref (buffer);
|
||||
|
@ -1713,6 +1715,10 @@ gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
|
|||
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) {
|
||||
rtph265pay->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);
|
||||
}
|
||||
/* put the data in one or more RTP packets */
|
||||
ret =
|
||||
gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts,
|
||||
rtph265pay->delta_unit);
|
||||
ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
|
||||
g_array_set_size (nal_queue, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1181,6 +1181,87 @@ GST_START_TEST (test_rtph265pay_delta_unit_flag)
|
|||
|
||||
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)
|
||||
{
|
||||
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_verify_nalu_hdr);
|
||||
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);
|
||||
|
||||
return s;
|
||||
|
|
Loading…
Reference in a new issue