rtph263pdepay: Fix picture header for non-writable payload
authorStian Selnes <stian@pexip.com>
Thu, 4 Feb 2016 13:16:40 +0000 (14:16 +0100)
committerOlivier CrĂȘte <olivier.crete@collabora.com>
Fri, 26 Aug 2016 15:53:22 +0000 (11:53 -0400)
Under certain conditions gst_rtp_buffer_get_payload() returns a copy of
the payload. In this case the payload modifications will not affect the
rtp buffer. So instead of modifying the payload buffer directly we
should modify the buffer that actually gets pushed on the adapter.

gst/rtp/gstrtph263pdepay.c
tests/check/elements/rtph263.c

index dbfcb66b742ae23a8621109188b47d54f51efac0..c2508b694b70e7c2dc05cb791f24c561557384af 100644 (file)
@@ -287,12 +287,8 @@ gst_rtp_h263p_depay_process (GstRTPBaseDepayload * depayload,
     goto too_small;
 
   if (P) {
     goto too_small;
 
   if (P) {
-    /* FIXME, have to make the packet writable hear. Better to reset these
-     * bytes when we copy the packet below */
     rtph263pdepay->wait_start = FALSE;
     header_len -= 2;
     rtph263pdepay->wait_start = FALSE;
     header_len -= 2;
-    payload[header_len] = 0;
-    payload[header_len + 1] = 0;
   }
 
   if (rtph263pdepay->wait_start)
   }
 
   if (rtph263pdepay->wait_start)
@@ -304,7 +300,6 @@ gst_rtp_h263p_depay_process (GstRTPBaseDepayload * depayload,
   /* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */
   /* FIXME actually use the RTP picture header when it is lost in the network */
   /* for now strip off header */
   /* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */
   /* FIXME actually use the RTP picture header when it is lost in the network */
   /* for now strip off header */
-  payload += header_len;
   payload_len -= header_len;
 
   if (M) {
   payload_len -= header_len;
 
   if (M) {
@@ -317,6 +312,8 @@ gst_rtp_h263p_depay_process (GstRTPBaseDepayload * depayload,
 
     outbuf =
         gst_rtp_buffer_get_payload_subbuffer (rtp, header_len, payload_len);
 
     outbuf =
         gst_rtp_buffer_get_payload_subbuffer (rtp, header_len, payload_len);
+    if (P)
+      gst_buffer_memset (outbuf, 0, 0, 2);
     gst_adapter_push (rtph263pdepay->adapter, outbuf);
     outbuf = NULL;
 
     gst_adapter_push (rtph263pdepay->adapter, outbuf);
     outbuf = NULL;
 
@@ -341,6 +338,8 @@ gst_rtp_h263p_depay_process (GstRTPBaseDepayload * depayload,
 
     outbuf =
         gst_rtp_buffer_get_payload_subbuffer (rtp, header_len, payload_len);
 
     outbuf =
         gst_rtp_buffer_get_payload_subbuffer (rtp, header_len, payload_len);
+    if (P)
+      gst_buffer_memset (outbuf, 0, 0, 2);
     gst_adapter_push (rtph263pdepay->adapter, outbuf);
   }
   return NULL;
     gst_adapter_push (rtph263pdepay->adapter, outbuf);
   }
   return NULL;
index ba099f165d22ae5f6a68783bb485da7fcbdd4329..b6ca38bf94fdddcf722b27a36c1bd207ab41116a 100644 (file)
@@ -142,6 +142,106 @@ GST_START_TEST (test_h263pay_mode_b_snow)
 }
 GST_END_TEST;
 
 }
 GST_END_TEST;
 
+/* gst_rtp_buffer_get_payload() may return a copy of the payload. This test
+ * makes sure that the rtph263pdepay also produces the correct output in this
+ * case. */
+GST_START_TEST (test_h263pdepay_fragmented_memory_non_writable_buffer)
+{
+  GstHarness *h;
+  GstBuffer *header_buf, *payload_buf, *buf;
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+  guint8 header[] = {
+    0x04, 0x00 };
+  guint8 payload[] = {
+    0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
+  guint8 frame[] = {
+    0x00, 0x00, 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
+
+  h = gst_harness_new ("rtph263pdepay");
+  gst_harness_set_src_caps_str (h, "application/x-rtp, media=video, "
+      "clock-rate=90000, encoding-name=H263-1998");
+
+  /* Packet with M=1, P=1 */
+  header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
+  gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
+  gst_rtp_buffer_set_marker (&rtp, TRUE);
+  memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
+  gst_rtp_buffer_unmap (&rtp);
+
+  payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
+  gst_buffer_fill (payload_buf, 0, payload, sizeof (payload));
+  buf = gst_buffer_append (header_buf, payload_buf);
+
+  gst_harness_push (h, gst_buffer_ref (buf));
+  gst_buffer_unref (buf);
+
+  buf = gst_harness_pull (h);
+  fail_unless (gst_buffer_memcmp (buf, 0, frame, sizeof (frame)) == 0);
+  gst_buffer_unref (buf);
+
+  gst_harness_teardown (h);
+}
+GST_END_TEST;
+
+/* gst_rtp_buffer_get_payload() may return a copy of the payload. This test
+ * makes sure that the rtph263pdepay also produces the correct output in this
+ * case. */
+GST_START_TEST (test_h263pdepay_fragmented_memory_non_writable_buffer_split_frame)
+{
+  GstHarness *h;
+  GstBuffer *header_buf, *payload_buf, *buf;
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+  guint8 header[] = {
+    0x04, 0x00 };
+  guint8 payload[] = {
+    0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
+  guint8 frame[] = {
+    0x00, 0x00, 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
+
+  h = gst_harness_new ("rtph263pdepay");
+  gst_harness_set_src_caps_str (h, "application/x-rtp, media=video, "
+      "clock-rate=90000, encoding-name=H263-1998");
+
+  /* First packet, M=0, P=1 */
+  header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
+  gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
+  gst_rtp_buffer_set_marker (&rtp, FALSE);
+  gst_rtp_buffer_set_seq (&rtp, 0);
+  memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
+  gst_rtp_buffer_unmap (&rtp);
+
+  payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
+  gst_buffer_fill (payload_buf, 0, payload, sizeof (payload));
+  buf = gst_buffer_append (header_buf, payload_buf);
+
+  gst_harness_push (h, gst_buffer_ref (buf));
+  gst_buffer_unref (buf);
+  fail_unless_equals_int (gst_harness_buffers_received (h), 0);
+
+  /* Second packet, M=1, P=1 */
+  header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
+  gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
+  gst_rtp_buffer_set_marker (&rtp, TRUE);
+  gst_rtp_buffer_set_seq (&rtp, 1);
+  memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
+  gst_rtp_buffer_unmap (&rtp);
+
+  payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
+  gst_buffer_memset (payload_buf, 0, 0, 10);
+  buf = gst_buffer_append (header_buf, payload_buf);
+
+  gst_harness_push (h, gst_buffer_ref (buf));
+  gst_buffer_unref (buf);
+  fail_unless_equals_int (gst_harness_buffers_received (h), 1);
+
+  buf = gst_harness_pull (h);
+  fail_unless (gst_buffer_memcmp (buf, 0, frame, sizeof (frame)) == 0);
+  gst_buffer_unref (buf);
+
+  gst_harness_teardown (h);
+}
+GST_END_TEST;
+
 static Suite *
 rtph263_suite (void)
 {
 static Suite *
 rtph263_suite (void)
 {
@@ -156,6 +256,10 @@ rtph263_suite (void)
   suite_add_tcase (s, (tc_chain = tcase_create ("h263pay")));
   tcase_add_test (tc_chain, test_h263pay_mode_b_snow);
 
   suite_add_tcase (s, (tc_chain = tcase_create ("h263pay")));
   tcase_add_test (tc_chain, test_h263pay_mode_b_snow);
 
+  suite_add_tcase (s, (tc_chain = tcase_create ("h263pdepay")));
+  tcase_add_test (tc_chain, test_h263pdepay_fragmented_memory_non_writable_buffer);
+  tcase_add_test (tc_chain, test_h263pdepay_fragmented_memory_non_writable_buffer_split_frame);
+
   return s;
 }
 
   return s;
 }