rtpsbcpay: fix if buffer size exceeds MTU
authorJochen Henneberg <jh@henneberg-systemdesign.com>
Mon, 14 Aug 2017 10:36:56 +0000 (10:36 +0000)
committerArun Raghavan <arun@arunraghavan.net>
Mon, 14 Aug 2017 11:26:17 +0000 (16:56 +0530)
The plugin queued buffer data if not all buffer data fit
into a single RTP packet. Now RTP packets are pushed as long
as enough data is available.

gst/rtp/gstrtpsbcpay.c

index d04aaf2..8aa4ef8 100644 (file)
@@ -178,51 +178,58 @@ gst_rtp_sbc_pay_flush_buffers (GstRtpSBCPay * sbcpay)
   guint frame_count;
   guint payload_length;
   struct rtp_payload *payload;
+  GstFlowReturn res;
 
   if (sbcpay->frame_length == 0) {
     GST_ERROR_OBJECT (sbcpay, "Frame length is 0");
     return GST_FLOW_ERROR;
   }
 
-  available = gst_adapter_available (sbcpay->adapter);
+  do {
+    available = gst_adapter_available (sbcpay->adapter);
+
+    max_payload =
+        gst_rtp_buffer_calc_payload_len (GST_RTP_BASE_PAYLOAD_MTU (sbcpay) -
+        RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);
+
+    max_payload = MIN (max_payload, available);
+    frame_count = max_payload / sbcpay->frame_length;
+    payload_length = frame_count * sbcpay->frame_length;
+    if (payload_length == 0)    /* Nothing to send */
+      return GST_FLOW_OK;
 
-  max_payload =
-      gst_rtp_buffer_calc_payload_len (GST_RTP_BASE_PAYLOAD_MTU (sbcpay) -
-      RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);
+    outbuf = gst_rtp_buffer_new_allocate (RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);
 
-  max_payload = MIN (max_payload, available);
-  frame_count = max_payload / sbcpay->frame_length;
-  payload_length = frame_count * sbcpay->frame_length;
-  if (payload_length == 0)      /* Nothing to send */
-    return GST_FLOW_OK;
+    /* get payload */
+    gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
 
-  outbuf = gst_rtp_buffer_new_allocate (RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);
+    gst_rtp_buffer_set_payload_type (&rtp, GST_RTP_BASE_PAYLOAD_PT (sbcpay));
 
-  /* get payload */
-  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
+    /* write header and copy data into payload */
+    payload_data = gst_rtp_buffer_get_payload (&rtp);
+    payload = (struct rtp_payload *) payload_data;
+    memset (payload, 0, sizeof (struct rtp_payload));
+    payload->frame_count = frame_count;
 
-  gst_rtp_buffer_set_payload_type (&rtp, GST_RTP_BASE_PAYLOAD_PT (sbcpay));
+    gst_rtp_buffer_unmap (&rtp);
 
-  /* write header and copy data into payload */
-  payload_data = gst_rtp_buffer_get_payload (&rtp);
-  payload = (struct rtp_payload *) payload_data;
-  memset (payload, 0, sizeof (struct rtp_payload));
-  payload->frame_count = frame_count;
+    paybuf = gst_adapter_take_buffer_fast (sbcpay->adapter, payload_length);
+    gst_rtp_copy_audio_meta (sbcpay, outbuf, paybuf);
+    outbuf = gst_buffer_append (outbuf, paybuf);
 
-  gst_rtp_buffer_unmap (&rtp);
+    GST_BUFFER_PTS (outbuf) = sbcpay->last_timestamp;
+    GST_BUFFER_DURATION (outbuf) = frame_count * sbcpay->frame_duration;
+    GST_DEBUG_OBJECT (sbcpay, "Pushing %d bytes: %" GST_TIME_FORMAT,
+        payload_length, GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)));
 
-  paybuf = gst_adapter_take_buffer_fast (sbcpay->adapter, payload_length);
-  gst_rtp_copy_audio_meta (sbcpay, outbuf, paybuf);
-  outbuf = gst_buffer_append (outbuf, paybuf);
+    sbcpay->last_timestamp += frame_count * sbcpay->frame_duration;
 
-  GST_BUFFER_PTS (outbuf) = sbcpay->last_timestamp;
-  GST_BUFFER_DURATION (outbuf) = frame_count * sbcpay->frame_duration;
-  GST_DEBUG_OBJECT (sbcpay, "Pushing %d bytes: %" GST_TIME_FORMAT,
-      payload_length, GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)));
+    res = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (sbcpay), outbuf);
 
-  sbcpay->last_timestamp += frame_count * sbcpay->frame_duration;
+    /* try to send another RTP buffer if available data exceeds MTU size */
+  } while (res == GST_FLOW_OK)
 
-  return gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (sbcpay), outbuf);
+  return res;
 }
 
 static GstFlowReturn