diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtpvp9pay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtpvp9pay.c index 153c56de41..f5db16b2cf 100644 --- a/subprojects/gst-plugins-good/gst/rtp/gstrtpvp9pay.c +++ b/subprojects/gst-plugins-good/gst/rtp/gstrtpvp9pay.c @@ -510,7 +510,8 @@ gst_rtp_vp9_create_header_buffer (GstRtpVP9Pay * self, static guint gst_rtp_vp9_payload_next (GstRtpVP9Pay * self, GstBufferList * list, - guint offset, GstBuffer * buffer, gsize buffer_size, gsize max_payload_len) + guint offset, GstBuffer * buffer, gsize buffer_size, gsize max_payload_len, + gboolean delta_unit) { GstBuffer *header; GstBuffer *sub; @@ -532,6 +533,9 @@ gst_rtp_vp9_payload_next (GstRtpVP9Pay * 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; @@ -561,8 +565,10 @@ gst_rtp_vp9_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) GstBufferList *list; gsize size, max_paylen; guint offset, mtu, vp9_hdr_len; + gboolean delta_unit; size = gst_buffer_get_size (buffer); + delta_unit = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); if (G_UNLIKELY (!gst_rtp_vp9_pay_parse_frame (self, buffer, size))) { GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), @@ -579,7 +585,12 @@ gst_rtp_vp9_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) offset = 0; while (offset < size) { offset += - gst_rtp_vp9_payload_next (self, list, offset, buffer, size, max_paylen); + gst_rtp_vp9_payload_next (self, list, offset, buffer, size, max_paylen, + 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/rtpvp9.c b/subprojects/gst-plugins-good/tests/check/elements/rtpvp9.c index 2cbb261db0..f49c5bc4ec 100644 --- a/subprojects/gst-plugins-good/tests/check/elements/rtpvp9.c +++ b/subprojects/gst-plugins-good/tests/check/elements/rtpvp9.c @@ -439,11 +439,54 @@ GST_START_TEST (test_depay_svc_forgive_invalid_sid) GST_END_TEST; +GST_START_TEST (test_pay_delta_unit_flag) +{ + guint8 vp9_bitstream_payload[] = { + 0xa2, 0x49, 0x83, 0x42, 0x20, 0x00, 0x1e, 0x00, + 0x1e, 0xc0, 0x07, 0x04, 0x83, 0x83, 0x08, 0x40, + 0x00, 0x06, 0x60, 0x00, 0x00, 0x10, 0xbf, 0xff, + 0x5a, 0x0f, 0xff, 0xff, 0xff, 0xfb, 0xc9, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x34, 0xca, 0x00 + }; + + /* set mtu so that the buffer is split into multiple packets */ + GstHarness *h = gst_harness_new_parse ("rtpvp9pay mtu=48"); + GstFlowReturn ret; + GstBuffer *buffer; + + gst_harness_set_src_caps_str (h, "video/x-vp9"); + + buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + vp9_bitstream_payload, sizeof (vp9_bitstream_payload), 0, + sizeof (vp9_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 * rtpvp9_suite (void) { Suite *s = suite_create ("rtpvp9"); TCase *tc_chain; + + suite_add_tcase (s, (tc_chain = tcase_create ("vp9pay"))); + tcase_add_test (tc_chain, test_pay_delta_unit_flag); + suite_add_tcase (s, (tc_chain = tcase_create ("vp9depay"))); tcase_add_test (tc_chain, test_depay_flexible_mode); tcase_add_test (tc_chain, test_depay_non_flexible_mode);