static void on_sending_rtcp (GObject * sess, GstBuffer * buffer, gboolean is_early, gboolean * do_not_supress) { KmsRembLocal *rl; KmsRTCPPSFBAFBREMBPacket remb_packet; GstRTCPBuffer rtcp = { NULL, }; GstRTCPPacket packet; guint packet_ssrc; rl = g_object_get_data (sess, KMS_REMB_LOCAL); if (!rl) { GST_WARNING ("Invalid RembLocal"); return; } if (is_early) { return; } if (!gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp)) { GST_WARNING_OBJECT (sess, "Cannot map buffer to RTCP"); return; } if (!gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB, &packet)) { GST_WARNING_OBJECT (sess, "Cannot add RTCP packet"); goto end; } if (!kms_remb_local_update (rl)) { goto end; } remb_packet.bitrate = rl->remb; if (rl->event_manager != NULL) { guint remb_local_max; remb_local_max = kms_utils_remb_event_manager_get_min (rl->event_manager); if (remb_local_max > 0) { GST_TRACE_OBJECT (sess, "REMB local max: %" G_GUINT32_FORMAT, remb_local_max); remb_packet.bitrate = MIN (remb_local_max, rl->remb); } } if (rl->min_bw > 0) { remb_packet.bitrate = MAX (remb_packet.bitrate, rl->min_bw * 1000); } else { remb_packet.bitrate = MAX (remb_packet.bitrate, REMB_MIN); } remb_packet.n_ssrcs = 1; remb_packet.ssrcs[0] = rl->remote_ssrc; g_object_get (sess, "internal-ssrc", &packet_ssrc, NULL); if (!kms_rtcp_psfb_afb_remb_marshall_packet (&packet, &remb_packet, packet_ssrc)) { gst_rtcp_packet_remove (&packet); } GST_TRACE_OBJECT (sess, "Sending REMB (bitrate: %" G_GUINT32_FORMAT ", ssrc: %" G_GUINT32_FORMAT ")", remb_packet.bitrate, rl->remote_ssrc); kms_remb_base_update_stats (KMS_REMB_BASE (rl), rl->remote_ssrc, remb_packet.bitrate); end: gst_rtcp_buffer_unmap (&rtcp); }
static GstFlowReturn fs_rtcp_filter_transform_ip (GstBaseTransform *transform, GstBuffer *buf) { FsRtcpFilter *filter = FS_RTCP_FILTER (transform); if (!gst_rtcp_buffer_validate (buf)) { GST_ERROR_OBJECT (transform, "Invalid RTCP buffer"); return GST_FLOW_ERROR; } GST_OBJECT_LOCK (filter); if (!filter->sending) { GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT; GstRTCPPacket packet; gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcpbuffer); if (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet)) { for (;;) { if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_SR) { GstRTCPPacket nextpacket = packet; if (gst_rtcp_packet_move_to_next (&nextpacket) && gst_rtcp_packet_get_type (&nextpacket) == GST_RTCP_TYPE_RR) { if (!gst_rtcp_packet_remove (&packet)) break; } else { guchar *data = rtcpbuffer.map.data + packet.offset; /* If there is no RR, lets add an empty one */ data[0] = (GST_RTCP_VERSION << 6); data[1] = GST_RTCP_TYPE_RR; data[2] = 0; data[3] = 1; memmove (rtcpbuffer.map.data + packet.offset + 8, rtcpbuffer.map.data + nextpacket.offset, rtcpbuffer.map.size - nextpacket.offset); rtcpbuffer.map.size -= nextpacket.offset - packet.offset - 8 ; if (!gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet)) break; } } else { if (!gst_rtcp_packet_move_to_next (&packet)) break; } } } gst_rtcp_buffer_unmap (&rtcpbuffer); } GST_OBJECT_UNLOCK (filter); return GST_FLOW_OK; }