static GstFlowReturn
gst_rdt_manager_chain_rtcp (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstRDTManager *src;

#ifdef HAVE_RTCP
  gboolean valid;
  GstRTCPPacket packet;
  gboolean more;
#endif

  src = GST_RDT_MANAGER (parent);

  GST_DEBUG_OBJECT (src, "got rtcp packet");

#ifdef HAVE_RTCP
  valid = gst_rtcp_buffer_validate (buffer);
  if (!valid)
    goto bad_packet;

  /* position on first packet */
  more = gst_rtcp_buffer_get_first_packet (buffer, &packet);
  while (more) {
    switch (gst_rtcp_packet_get_type (&packet)) {
      case GST_RTCP_TYPE_SR:
      {
        guint32 ssrc, rtptime, packet_count, octet_count;
        guint64 ntptime;
        guint count, i;

        gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, &rtptime,
            &packet_count, &octet_count);

        GST_DEBUG_OBJECT (src,
            "got SR packet: SSRC %08x, NTP %" G_GUINT64_FORMAT
            ", RTP %u, PC %u, OC %u", ssrc, ntptime, rtptime, packet_count,
            octet_count);

        count = gst_rtcp_packet_get_rb_count (&packet);
        for (i = 0; i < count; i++) {
          guint32 ssrc, exthighestseq, jitter, lsr, dlsr;
          guint8 fractionlost;
          gint32 packetslost;

          gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost,
              &packetslost, &exthighestseq, &jitter, &lsr, &dlsr);

          GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u"
              ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost,
              packetslost, exthighestseq, jitter, lsr, dlsr);
        }
        break;
      }
      case GST_RTCP_TYPE_RR:
      {
        guint32 ssrc;
        guint count, i;

        ssrc = gst_rtcp_packet_rr_get_ssrc (&packet);

        GST_DEBUG_OBJECT (src, "got RR packet: SSRC %08x", ssrc);

        count = gst_rtcp_packet_get_rb_count (&packet);
        for (i = 0; i < count; i++) {
          guint32 ssrc, exthighestseq, jitter, lsr, dlsr;
          guint8 fractionlost;
          gint32 packetslost;

          gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost,
              &packetslost, &exthighestseq, &jitter, &lsr, &dlsr);

          GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u"
              ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost,
              packetslost, exthighestseq, jitter, lsr, dlsr);
        }
        break;
      }
      case GST_RTCP_TYPE_SDES:
      {
        guint chunks, i, j;
        gboolean more_chunks, more_items;

        chunks = gst_rtcp_packet_sdes_get_chunk_count (&packet);
        GST_DEBUG_OBJECT (src, "got SDES packet with %d chunks", chunks);

        more_chunks = gst_rtcp_packet_sdes_first_chunk (&packet);
        i = 0;
        while (more_chunks) {
          guint32 ssrc;

          ssrc = gst_rtcp_packet_sdes_get_ssrc (&packet);

          GST_DEBUG_OBJECT (src, "chunk %d, SSRC %08x", i, ssrc);

          more_items = gst_rtcp_packet_sdes_first_item (&packet);
          j = 0;
          while (more_items) {
            GstRTCPSDESType type;
            guint8 len;
            gchar *data;

            gst_rtcp_packet_sdes_get_item (&packet, &type, &len, &data);

            GST_DEBUG_OBJECT (src, "item %d, type %d, len %d, data %s", j,
                type, len, data);

            more_items = gst_rtcp_packet_sdes_next_item (&packet);
            j++;
          }
          more_chunks = gst_rtcp_packet_sdes_next_chunk (&packet);
          i++;
        }
        break;
      }
      case GST_RTCP_TYPE_BYE:
      {
        guint count, i;
        gchar *reason;

        reason = gst_rtcp_packet_bye_get_reason (&packet);
        GST_DEBUG_OBJECT (src, "got BYE packet (reason: %s)",
            GST_STR_NULL (reason));
        g_free (reason);

        count = gst_rtcp_packet_bye_get_ssrc_count (&packet);
        for (i = 0; i < count; i++) {
          guint32 ssrc;


          ssrc = gst_rtcp_packet_bye_get_nth_ssrc (&packet, i);

          GST_DEBUG_OBJECT (src, "SSRC: %08x", ssrc);
        }
        break;
      }
      case GST_RTCP_TYPE_APP:
        GST_DEBUG_OBJECT (src, "got APP packet");
        break;
      default:
        GST_WARNING_OBJECT (src, "got unknown RTCP packet");
        break;
    }
    more = gst_rtcp_packet_move_to_next (&packet);
  }
  gst_buffer_unref (buffer);
  return GST_FLOW_OK;

bad_packet:
  {
    GST_WARNING_OBJECT (src, "got invalid RTCP packet");
    return GST_FLOW_OK;
  }
#else
  return GST_FLOW_OK;
#endif
}
示例#2
0
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;
}