rtpbin: use PacketInfo for the sender

Avoid mapping the packet multiple times when sending RTP.
This commit is contained in:
Wim Taymans 2013-09-13 12:40:41 +02:00
parent a02c9473d8
commit 28e5f90988
4 changed files with 25 additions and 85 deletions

View file

@ -1557,6 +1557,7 @@ update_packet (GstBuffer ** buffer, guint idx, RTPPacketInfo * pinfo)
/* get packet size including header overhead */ /* get packet size including header overhead */
pinfo->bytes += gst_buffer_get_size (*buffer) + pinfo->header_len; pinfo->bytes += gst_buffer_get_size (*buffer) + pinfo->header_len;
pinfo->packets++;
if (pinfo->rtp) { if (pinfo->rtp) {
GstRTPBuffer rtp = { NULL }; GstRTPBuffer rtp = { NULL };
@ -1624,6 +1625,7 @@ update_packet_info (RTPSession * sess, RTPPacketInfo * pinfo,
pinfo->header_len = sess->header_len; pinfo->header_len = sess->header_len;
pinfo->bytes = 0; pinfo->bytes = 0;
pinfo->payload_len = 0; pinfo->payload_len = 0;
pinfo->packets = 0;
if (is_list) { if (is_list) {
GstBufferList *list = GST_BUFFER_LIST_CAST (data); GstBufferList *list = GST_BUFFER_LIST_CAST (data);
@ -2484,9 +2486,7 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list,
RTPSource *source; RTPSource *source;
gboolean prevsender; gboolean prevsender;
guint64 oldrate; guint64 oldrate;
GstBuffer *buffer; RTPPacketInfo pinfo = { 0, };
GstRTPBuffer rtp = { NULL };
guint32 ssrc;
gboolean created; gboolean created;
g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
@ -2494,26 +2494,12 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list,
GST_LOG ("received RTP %s for sending", is_list ? "list" : "packet"); GST_LOG ("received RTP %s for sending", is_list ? "list" : "packet");
if (is_list) { RTP_SESSION_LOCK (sess);
GstBufferList *list = GST_BUFFER_LIST_CAST (data); if (!update_packet_info (sess, &pinfo, TRUE, TRUE, is_list, data,
current_time, running_time, -1))
buffer = gst_buffer_list_get (list, 0);
if (!buffer)
goto no_buffer;
} else {
buffer = GST_BUFFER_CAST (data);
}
if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp))
goto invalid_packet; goto invalid_packet;
/* get SSRC and look up in session database */ source = obtain_internal_source (sess, pinfo.ssrc, &created);
ssrc = gst_rtp_buffer_get_ssrc (&rtp);
gst_rtp_buffer_unmap (&rtp);
RTP_SESSION_LOCK (sess);
source = obtain_internal_source (sess, ssrc, &created);
/* update last activity */ /* update last activity */
source->last_rtp_activity = current_time; source->last_rtp_activity = current_time;
@ -2522,7 +2508,7 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list,
oldrate = source->bitrate; oldrate = source->bitrate;
/* we use our own source to send */ /* we use our own source to send */
result = rtp_source_send_rtp (source, data, is_list, running_time); result = rtp_source_send_rtp (source, &pinfo);
source_update_sender (sess, source, prevsender); source_update_sender (sess, source, prevsender);
@ -2531,21 +2517,17 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list,
RTP_SESSION_UNLOCK (sess); RTP_SESSION_UNLOCK (sess);
g_object_unref (source); g_object_unref (source);
clean_packet_info (&pinfo);
return result; return result;
invalid_packet: invalid_packet:
{ {
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
RTP_SESSION_UNLOCK (sess);
GST_DEBUG ("invalid RTP packet received"); GST_DEBUG ("invalid RTP packet received");
return GST_FLOW_OK; return GST_FLOW_OK;
} }
no_buffer:
{
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
GST_DEBUG ("no buffer in list");
return GST_FLOW_OK;
}
} }
static void static void

View file

@ -1143,60 +1143,29 @@ rtp_source_mark_bye (RTPSource * src, const gchar * reason)
* Returns: a #GstFlowReturn. * Returns: a #GstFlowReturn.
*/ */
GstFlowReturn GstFlowReturn
rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, rtp_source_send_rtp (RTPSource * src, RTPPacketInfo * pinfo)
GstClockTime running_time)
{ {
GstFlowReturn result; GstFlowReturn result;
guint len; GstClockTime running_time;
guint32 rtptime; guint32 rtptime;
guint64 ext_rtptime; guint64 ext_rtptime;
guint64 rt_diff, rtp_diff; guint64 rt_diff, rtp_diff;
guint packets;
GstRTPBuffer rtp = { NULL };
g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR);
/* we are a sender now */ /* we are a sender now */
src->is_sender = TRUE; src->is_sender = TRUE;
if (is_list) {
GstBufferList *list = GST_BUFFER_LIST_CAST (data);
gint i;
/* Each group makes up a network packet. */
packets = gst_buffer_list_length (list);
if (packets == 0)
goto no_buffer;
for (i = 0, len = 0; i < packets; i++) {
if (!gst_rtp_buffer_map (gst_buffer_list_get (list, i), GST_MAP_READ,
&rtp))
goto invalid_packet;
len += gst_rtp_buffer_get_payload_len (&rtp);
gst_rtp_buffer_unmap (&rtp);
}
/* subsequent info taken from first list member */
gst_rtp_buffer_map (gst_buffer_list_get (list, 0), GST_MAP_READ, &rtp);
} else {
GstBuffer *buffer = GST_BUFFER_CAST (data);
packets = 1;
if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp))
goto invalid_packet;
len = gst_rtp_buffer_get_payload_len (&rtp);
}
/* update stats for the SR */ /* update stats for the SR */
src->stats.packets_sent += packets; src->stats.packets_sent += pinfo->packets;
src->stats.octets_sent += len; src->stats.octets_sent += pinfo->payload_len;
src->bytes_sent += len; src->bytes_sent += pinfo->payload_len;
running_time = pinfo->running_time;
do_bitrate_estimation (src, running_time, &src->bytes_sent); do_bitrate_estimation (src, running_time, &src->bytes_sent);
rtptime = gst_rtp_buffer_get_timestamp (&rtp); rtptime = pinfo->rtptime;
gst_rtp_buffer_unmap (&rtp);
ext_rtptime = src->last_rtptime; ext_rtptime = src->last_rtptime;
ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime); ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
@ -1224,30 +1193,18 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list,
if (!src->callbacks.push_rtp) if (!src->callbacks.push_rtp)
goto no_callback; goto no_callback;
GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT, is_list ? "list" : "packet", GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT,
src->stats.packets_sent); pinfo->is_list ? "list" : "packet", src->stats.packets_sent);
result = src->callbacks.push_rtp (src, data, src->user_data); result = src->callbacks.push_rtp (src, pinfo->data, src->user_data);
pinfo->data = NULL;
return result; return result;
/* ERRORS */ /* ERRORS */
invalid_packet:
{
GST_WARNING ("invalid packet received");
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_OK;
}
no_buffer:
{
GST_WARNING ("no buffers in buffer list");
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_OK;
}
no_callback: no_callback:
{ {
GST_WARNING ("no callback installed, dropping packet"); GST_WARNING ("no callback installed, dropping packet");
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_OK; return GST_FLOW_OK;
} }
} }

View file

@ -231,8 +231,8 @@ void rtp_source_set_rtcp_from (RTPSource *src, GSocketAddress *
/* handling RTP */ /* handling RTP */
GstFlowReturn rtp_source_process_rtp (RTPSource *src, RTPPacketInfo *pinfo); GstFlowReturn rtp_source_process_rtp (RTPSource *src, RTPPacketInfo *pinfo);
GstFlowReturn rtp_source_send_rtp (RTPSource *src, gpointer data, gboolean is_list, GstFlowReturn rtp_source_send_rtp (RTPSource *src, RTPPacketInfo *pinfo);
GstClockTime running_time);
/* RTCP messages */ /* RTCP messages */
void rtp_source_process_sr (RTPSource *src, GstClockTime time, guint64 ntptime, void rtp_source_process_sr (RTPSource *src, GstClockTime time, guint64 ntptime,
guint32 rtptime, guint32 packet_count, guint32 octet_count); guint32 rtptime, guint32 packet_count, guint32 octet_count);

View file

@ -85,6 +85,7 @@ typedef struct {
guint64 ntpnstime; guint64 ntpnstime;
guint header_len; guint header_len;
guint bytes; guint bytes;
guint packets;
guint payload_len; guint payload_len;
guint32 ssrc; guint32 ssrc;
guint16 seqnum; guint16 seqnum;