From af43648bdf3c9e40dcd48c3bce571d7d933e061d Mon Sep 17 00:00:00 2001 From: Peter Stensson Date: Tue, 27 Jun 2023 10:40:47 +0200 Subject: [PATCH] rtpvp8pay: Only mark first outgoing packet as non delta-unit Part-of: --- .../gst-plugins-good/gst/rtp/gstrtpvp8pay.c | 14 ++++++- .../tests/check/elements/rtpvp8.c | 38 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtpvp8pay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtpvp8pay.c index 0b47c17f88..c216a125cf 100644 --- a/subprojects/gst-plugins-good/gst/rtp/gstrtpvp8pay.c +++ b/subprojects/gst-plugins-good/gst/rtp/gstrtpvp8pay.c @@ -611,7 +611,7 @@ gst_rtp_vp8_drop_vp8_meta (gpointer element, GstBuffer * buf) static guint gst_rtp_vp8_payload_next (GstRtpVP8Pay * self, GstBufferList * list, guint offset, GstBuffer * buffer, gsize buffer_size, gsize max_payload_len, - GstCustomMeta * meta) + GstCustomMeta * meta, gboolean delta_unit) { guint partition; GstBuffer *header; @@ -651,6 +651,9 @@ gst_rtp_vp8_payload_next (GstRtpVP8Pay * self, GstBufferList * list, out = gst_buffer_append (header, sub); + if (delta_unit) + GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DELTA_UNIT); + gst_buffer_list_insert (list, -1, out); return available; @@ -666,9 +669,12 @@ gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) GstCustomMeta *meta; gsize size, max_paylen; guint offset, mtu, vp8_hdr_len; + gboolean delta_unit; size = gst_buffer_get_size (buffer); meta = gst_buffer_get_custom_meta (buffer, "GstVP8Meta"); + delta_unit = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); + if (G_UNLIKELY (!gst_rtp_vp8_pay_parse_frame (self, buffer, size))) { GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), ("Failed to parse VP8 frame")); @@ -699,7 +705,11 @@ gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) while (offset < size) { offset += gst_rtp_vp8_payload_next (self, list, offset, buffer, size, - max_paylen, meta); + max_paylen, meta, delta_unit); + + /* only the first outgoing packet should not have the DELTA_UNIT flag */ + if (!delta_unit) + delta_unit = TRUE; } ret = gst_rtp_base_payload_push_list (payload, list); diff --git a/subprojects/gst-plugins-good/tests/check/elements/rtpvp8.c b/subprojects/gst-plugins-good/tests/check/elements/rtpvp8.c index d07def1f34..f0802481a1 100644 --- a/subprojects/gst-plugins-good/tests/check/elements/rtpvp8.c +++ b/subprojects/gst-plugins-good/tests/check/elements/rtpvp8.c @@ -831,6 +831,43 @@ GST_START_TEST (test_depay_resend_gap_event) GST_END_TEST; +GST_START_TEST (test_pay_delta_unit_flag) +{ + guint8 vp8_bitstream_payload[] = { + 0x30, 0x00, 0x00, 0x9d, 0x01, 0x2a, 0xb0, 0x00, + 0x90, 0x00, 0x06, 0x47, 0x08, 0x85, 0x85, 0x88, + 0x99, 0x84, 0x88, 0x21, 0x00 + }; + + /* set mtu so that the buffer is split into multiple packets */ + GstHarness *h = gst_harness_new_parse ("rtpvp8pay mtu=28"); + GstFlowReturn ret; + GstBuffer *buffer; + + gst_harness_set_src_caps_str (h, "video/x-vp8"); + + buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + vp8_bitstream_payload, sizeof (vp8_bitstream_payload), 0, + sizeof (vp8_bitstream_payload), NULL, NULL); + + ret = gst_harness_push (h, buffer); + fail_unless_equals_int (ret, GST_FLOW_OK); + + /* the input buffer 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); + + gst_harness_teardown (h); +} + +GST_END_TEST; + static Suite * rtpvp8_suite (void) { @@ -849,6 +886,7 @@ rtpvp8_suite (void) tcase_add_test (tc_chain, test_pay_continuous_picture_id_and_tl0picidx); tcase_add_test (tc_chain, test_pay_tl0picidx_split_buffer); tcase_add_test (tc_chain, test_pay_continuous_picture_id_on_flush); + tcase_add_test (tc_chain, test_pay_delta_unit_flag); suite_add_tcase (s, (tc_chain = tcase_create ("vp8depay"))); tcase_add_loop_test (tc_chain, test_depay_stop_gap_events, 0,