mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-08 18:39:54 +00:00
rtpvrawpay: use buffer lists
Collect buffers to send out in buffer lists instead of pushing out single buffers one at a time. For HD video each frame might easily add up to a couple of thousand packets, multiply that by the frame rate and that's a lot of push() and sendmsg() calls per second. A good reason to push out buffers as early as possible is latency, so we don't accumulate the whole frame in a single buffer list, but instead push it out in a few chunks, which is hopefully a reasonable compromise.
This commit is contained in:
parent
884d1af074
commit
fdf95fecbd
1 changed files with 29 additions and 6 deletions
|
@ -239,15 +239,18 @@ gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstRtpVRawPay *rtpvrawpay;
|
GstRtpVRawPay *rtpvrawpay;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
guint lines_delay; /* after how many packed lines we push out a buffer list */
|
||||||
|
guint last_line; /* last pack line number we pushed out a buffer list */
|
||||||
guint line, offset;
|
guint line, offset;
|
||||||
guint8 *p0, *yp, *up, *vp;
|
guint8 *p0, *yp, *up, *vp;
|
||||||
guint ystride, uvstride;
|
guint ystride, uvstride;
|
||||||
guint pgroup;
|
guint pgroup;
|
||||||
guint mtu;
|
guint mtu;
|
||||||
guint width, height;
|
guint width, height;
|
||||||
gint field;
|
gint field, fields;
|
||||||
GstVideoFrame frame;
|
GstVideoFrame frame;
|
||||||
gint interlaced;
|
gint interlaced;
|
||||||
|
GstBufferList *list;
|
||||||
GstRTPBuffer rtp = { NULL, };
|
GstRTPBuffer rtp = { NULL, };
|
||||||
|
|
||||||
rtpvrawpay = GST_RTP_VRAW_PAY (payload);
|
rtpvrawpay = GST_RTP_VRAW_PAY (payload);
|
||||||
|
@ -275,17 +278,25 @@ gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
|
||||||
|
|
||||||
interlaced = GST_VIDEO_INFO_IS_INTERLACED (&rtpvrawpay->vinfo);
|
interlaced = GST_VIDEO_INFO_IS_INTERLACED (&rtpvrawpay->vinfo);
|
||||||
|
|
||||||
|
/* after how many packed lines we push out a buffer list */
|
||||||
|
lines_delay = GST_ROUND_UP_4 (height / 10);
|
||||||
|
|
||||||
|
fields = 1 + interlaced;
|
||||||
|
|
||||||
/* start with line 0, offset 0 */
|
/* start with line 0, offset 0 */
|
||||||
for (field = 0; field < 1 + interlaced; field++) {
|
for (field = 0; field < fields; field++) {
|
||||||
line = field;
|
line = field;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
last_line = 0;
|
||||||
|
|
||||||
|
list = gst_buffer_list_new ();
|
||||||
|
|
||||||
/* write all lines */
|
/* write all lines */
|
||||||
while (line < height) {
|
while (line < height) {
|
||||||
guint left;
|
guint left, pack_line;
|
||||||
GstBuffer *out;
|
GstBuffer *out;
|
||||||
guint8 *outdata, *headers;
|
guint8 *outdata, *headers;
|
||||||
gboolean next_line;
|
gboolean next_line, complete = FALSE;
|
||||||
guint length, cont, pixels;
|
guint length, cont, pixels;
|
||||||
|
|
||||||
/* get the max allowed payload length size, we try to fill the complete MTU */
|
/* get the max allowed payload length size, we try to fill the complete MTU */
|
||||||
|
@ -496,6 +507,7 @@ gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
|
||||||
if (line >= height) {
|
if (line >= height) {
|
||||||
GST_LOG_OBJECT (rtpvrawpay, "field/frame complete, set marker");
|
GST_LOG_OBJECT (rtpvrawpay, "field/frame complete, set marker");
|
||||||
gst_rtp_buffer_set_marker (&rtp, TRUE);
|
gst_rtp_buffer_set_marker (&rtp, TRUE);
|
||||||
|
complete = TRUE;
|
||||||
}
|
}
|
||||||
gst_rtp_buffer_unmap (&rtp);
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
if (left > 0) {
|
if (left > 0) {
|
||||||
|
@ -503,8 +515,19 @@ gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
|
||||||
gst_buffer_resize (out, 0, gst_buffer_get_size (out) - left);
|
gst_buffer_resize (out, 0, gst_buffer_get_size (out) - left);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push buffer */
|
gst_buffer_list_add (list, out);
|
||||||
ret = gst_rtp_base_payload_push (payload, out);
|
|
||||||
|
pack_line = (line - field) / fields;
|
||||||
|
if (complete || (pack_line > last_line && pack_line % lines_delay == 0)) {
|
||||||
|
/* push buffers */
|
||||||
|
GST_LOG_OBJECT (rtpvrawpay, "pushing list of %u buffers up to pack "
|
||||||
|
"line %u", gst_buffer_list_length (list), pack_line);
|
||||||
|
ret = gst_rtp_base_payload_push_list (payload, list);
|
||||||
|
list = NULL;
|
||||||
|
if (!complete)
|
||||||
|
list = gst_buffer_list_new ();
|
||||||
|
last_line = pack_line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue