Exemplo n.º 1
0
guint8
gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
{
  guint header;
  gboolean length_included_flag;
  guint8 *bufdata;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);

  bufdata = GST_BUFFER_DATA (packet->buffer);

  header = packet->offset;

  length_included_flag = (bufdata[header] & 0x80) == 0x80;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  /* get flags */
  return bufdata[header];
}
Exemplo n.º 2
0
guint16
gst_rdt_packet_data_get_stream_id (GstRDTPacket * packet)
{
  guint16 result;
  guint header;
  gboolean length_included_flag;
  guint8 *bufdata;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);

  bufdata = GST_BUFFER_DATA (packet->buffer);

  header = packet->offset;

  length_included_flag = (bufdata[header] & 0x80) == 0x80;
  result = (bufdata[header] & 0x3e) >> 1;
  if (result == 31) {
    /* skip seq_no and header bits */
    header += 3;

    if (length_included_flag) {
      /* skip length */
      header += 2;
    }
    /* skip asm_rule_number and timestamp */
    header += 5;

    /* stream_id_expansion */
    result = GST_READ_UINT16_BE (&bufdata[header]);
  }
  return result;
}
Exemplo n.º 3
0
guint32
gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet)
{
  guint header;
  gboolean length_included_flag;
  guint8 *bufdata;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);

  bufdata = GST_BUFFER_DATA (packet->buffer);

  header = packet->offset;

  length_included_flag = (bufdata[header] & 0x80) == 0x80;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  /* skip asm_rule_number */
  header += 1;

  /* get timestamp */
  return GST_READ_UINT32_BE (&bufdata[header]);
}
Exemplo n.º 4
0
guint8
gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
{
  GstMapInfo map;
  guint8 result;
  guint header;
  gboolean length_included_flag;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);

  gst_buffer_map (packet->buffer, &map, GST_MAP_READ);

  header = packet->offset;

  length_included_flag = (map.data[header] & 0x80) == 0x80;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  /* get flags */
  result = map.data[header];
  gst_buffer_unmap (packet->buffer, &map);

  return result;
}
Exemplo n.º 5
0
guint32
gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet)
{
  GstMapInfo map;
  guint header;
  gboolean length_included_flag;
  guint32 result;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);

  gst_buffer_map (packet->buffer, &map, GST_MAP_READ);

  header = packet->offset;

  length_included_flag = (map.data[header] & 0x80) == 0x80;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  /* skip asm_rule_number */
  header += 1;

  /* get timestamp */
  result = GST_READ_UINT32_BE (&map.data[header]);
  gst_buffer_unmap (packet->buffer, &map);

  return result;
}
Exemplo n.º 6
0
static GstFlowReturn
gst_rdt_depay_chain (GstPad * pad, GstBuffer * buf)
{
  GstRDTDepay *rdtdepay;
  GstFlowReturn ret;
  GstClockTime timestamp;
  gboolean more;
  GstRDTPacket packet;

  rdtdepay = GST_RDT_DEPAY (GST_PAD_PARENT (pad));

  if (GST_BUFFER_IS_DISCONT (buf)) {
    GST_LOG_OBJECT (rdtdepay, "received discont");
    rdtdepay->discont = TRUE;
  }

  if (rdtdepay->header) {
    GstBuffer *out;

    out = rdtdepay->header;
    rdtdepay->header = NULL;

    /* push header data first */
    ret = gst_rdt_depay_push (rdtdepay, out);
  }

  /* save timestamp */
  timestamp = GST_BUFFER_TIMESTAMP (buf);

  ret = GST_FLOW_OK;

  GST_LOG_OBJECT (rdtdepay, "received buffer timestamp %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  /* data is in RDT format. */
  more = gst_rdt_buffer_get_first_packet (buf, &packet);
  while (more) {
    GstRDTType type;

    type = gst_rdt_packet_get_type (&packet);
    GST_DEBUG_OBJECT (rdtdepay, "Have packet of type %04x", type);

    if (GST_RDT_IS_DATA_TYPE (type)) {
      GST_DEBUG_OBJECT (rdtdepay, "We have a data packet");
      ret = gst_rdt_depay_handle_data (rdtdepay, timestamp, &packet);
    } else {
      switch (type) {
        default:
          GST_DEBUG_OBJECT (rdtdepay, "Ignoring packet");
          break;
      }
    }
    if (ret != GST_FLOW_OK)
      break;

    more = gst_rdt_packet_move_to_next (&packet);
  }

  return ret;
}
Exemplo n.º 7
0
gboolean
gst_rdt_packet_data_peek_data (GstRDTPacket * packet, guint8 ** data,
    guint * size)
{
  guint header;
  guint8 *bufdata;
  gboolean length_included_flag;
  gboolean need_reliable_flag;
  guint8 stream_id;
  guint8 asm_rule_number;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);

  bufdata = GST_BUFFER_DATA (packet->buffer);

  header = packet->offset;

  length_included_flag = (bufdata[header] & 0x80) == 0x80;
  need_reliable_flag = (bufdata[header] & 0x40) == 0x40;
  stream_id = (bufdata[header] & 0x3e) >> 1;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  asm_rule_number = (bufdata[header] & 0x3f);

  /* skip timestamp and asm_rule_number */
  header += 5;

  if (stream_id == 0x1f) {
    /* skip stream_id_expansion */
    header += 2;
  }
  if (need_reliable_flag) {
    /* skip total_reliable */
    header += 2;
  }
  if (asm_rule_number == 63) {
    /* skip asm_rule_number_expansion */
    header += 2;
  }

  if (data)
    *data = &bufdata[header];
  if (size)
    *size = packet->length - (header - packet->offset);

  return TRUE;
}
Exemplo n.º 8
0
guint8 *
gst_rdt_packet_data_map (GstRDTPacket * packet, guint * size)
{
  GstMapInfo map;
  guint header;
  gboolean length_included_flag;
  gboolean need_reliable_flag;
  guint8 stream_id;
  guint8 asm_rule_number;

  g_return_val_if_fail (packet != NULL, NULL);
  g_return_val_if_fail (packet->map.data == NULL, NULL);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), NULL);

  gst_buffer_map (packet->buffer, &map, GST_MAP_READ);

  header = packet->offset;

  length_included_flag = (map.data[header] & 0x80) == 0x80;
  need_reliable_flag = (map.data[header] & 0x40) == 0x40;
  stream_id = (map.data[header] & 0x3e) >> 1;

  /* skip seq_no and header bits */
  header += 3;

  if (length_included_flag) {
    /* skip length */
    header += 2;
  }
  asm_rule_number = (map.data[header] & 0x3f);

  /* skip timestamp and asm_rule_number */
  header += 5;

  if (stream_id == 0x1f) {
    /* skip stream_id_expansion */
    header += 2;
  }
  if (need_reliable_flag) {
    /* skip total_reliable */
    header += 2;
  }
  if (asm_rule_number == 63) {
    /* skip asm_rule_number_expansion */
    header += 2;
  }

  if (size)
    *size = packet->length - (header - packet->offset);

  packet->map = map;

  return &map.data[header];
}
Exemplo n.º 9
0
guint16
gst_rdt_packet_data_get_seq (GstRDTPacket * packet)
{
  guint header;
  guint8 *bufdata;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);

  bufdata = GST_BUFFER_DATA (packet->buffer);

  /* skip header bits */
  header = packet->offset + 1;

  /* read seq_no */
  return GST_READ_UINT16_BE (&bufdata[header]);
}
Exemplo n.º 10
0
guint16
gst_rdt_packet_data_get_seq (GstRDTPacket * packet)
{
  GstMapInfo map;
  guint header;
  guint16 result;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);

  gst_buffer_map (packet->buffer, &map, GST_MAP_READ);

  /* skip header bits */
  header = packet->offset + 1;

  /* read seq_no */
  result = GST_READ_UINT16_BE (&map.data[header]);

  gst_buffer_unmap (packet->buffer, &map);

  return result;
}
Exemplo n.º 11
0
static GstFlowReturn
gst_rdt_manager_chain_rdt (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstFlowReturn res;
  GstRDTManager *rdtmanager;
  GstRDTManagerSession *session;
  GstClockTime timestamp;
  GstRDTPacket packet;
  guint32 ssrc;
  guint8 pt;
  gboolean more;

  rdtmanager = GST_RDT_MANAGER (parent);

  GST_DEBUG_OBJECT (rdtmanager, "got RDT packet");

  ssrc = 0;
  pt = 0;

  GST_DEBUG_OBJECT (rdtmanager, "SSRC %08x, PT %d", ssrc, pt);

  /* find session */
  session = gst_pad_get_element_private (pad);

  /* see if we have the pad */
  if (!session->active) {
    activate_session (rdtmanager, session, ssrc, pt);
    session->active = TRUE;
  }

  if (GST_BUFFER_IS_DISCONT (buffer)) {
    GST_DEBUG_OBJECT (rdtmanager, "received discont");
    session->discont = TRUE;
  }

  res = GST_FLOW_OK;

  /* take the timestamp of the buffer. This is the time when the packet was
   * received and is used to calculate jitter and clock skew. We will adjust
   * this timestamp with the smoothed value after processing it in the
   * jitterbuffer. */
  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  /* bring to running time */
  timestamp = gst_segment_to_running_time (&session->segment, GST_FORMAT_TIME,
      timestamp);

  more = gst_rdt_buffer_get_first_packet (buffer, &packet);
  while (more) {
    GstRDTType type;

    type = gst_rdt_packet_get_type (&packet);
    GST_DEBUG_OBJECT (rdtmanager, "Have packet of type %04x", type);

    if (GST_RDT_IS_DATA_TYPE (type)) {
      GST_DEBUG_OBJECT (rdtmanager, "We have a data packet");
      res = gst_rdt_manager_handle_data_packet (session, timestamp, &packet);
    } else {
      switch (type) {
        default:
          GST_DEBUG_OBJECT (rdtmanager, "Ignoring packet");
          break;
      }
    }
    if (res != GST_FLOW_OK)
      break;

    more = gst_rdt_packet_move_to_next (&packet);
  }

  gst_buffer_unref (buffer);

  return res;
}
Exemplo n.º 12
0
static gboolean
read_packet_header (GstRDTPacket * packet)
{
  guint8 *data;
  guint size;
  guint offset;
  guint length;
  guint length_offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);

  data = GST_BUFFER_DATA (packet->buffer);
  size = GST_BUFFER_SIZE (packet->buffer);

  offset = packet->offset;

  /* check if we are at the end of the buffer, we add 3 because we also want to
   * ensure we can read the type, which is always at offset 1 and 2 bytes long. */
  if (offset + 3 > size)
    return FALSE;

  /* read type */
  packet->type = GST_READ_UINT16_BE (&data[offset + 1]);

  length = -1;
  length_offset = -1;

  /* figure out the length of the packet, this depends on the type */
  if (GST_RDT_IS_DATA_TYPE (packet->type)) {
    if (data[offset] & 0x80)
      /* length is present */
      length_offset = 3;
  } else {
    switch (packet->type) {
      case GST_RDT_TYPE_ASMACTION:
        if (data[offset] & 0x80)
          length_offset = 5;
        break;
      case GST_RDT_TYPE_BWREPORT:
        if (data[offset] & 0x80)
          length_offset = 3;
        break;
      case GST_RDT_TYPE_ACK:
        if (data[offset] & 0x80)
          length_offset = 3;
        break;
      case GST_RDT_TYPE_RTTREQ:
        length = 3;
        break;
      case GST_RDT_TYPE_RTTRESP:
        length = 11;
        break;
      case GST_RDT_TYPE_CONGESTION:
        length = 11;
        break;
      case GST_RDT_TYPE_STREAMEND:
        length = 9;
        /* total_reliable */
        if (data[offset] & 0x80)
          length += 2;
        /* stream_id_expansion */
        if ((data[offset] & 0x7c) == 0x7c)
          length += 2;
        /* ext_flag, FIXME, get string length */
        if ((data[offset] & 0x1) == 0x1)
          length += 7;
        break;
      case GST_RDT_TYPE_REPORT:
        if (data[offset] & 0x80)
          length_offset = 3;
        break;
      case GST_RDT_TYPE_LATENCY:
        if (data[offset] & 0x80)
          length_offset = 3;
        break;
      case GST_RDT_TYPE_INFOREQ:
        length = 3;
        /* request_time_ms */
        if (data[offset] & 0x2)
          length += 2;
        break;
      case GST_RDT_TYPE_INFORESP:
        length = 3;
        /* has_rtt_info */
        if (data[offset] & 0x4) {
          length += 4;
          /* is_delayed */
          if (data[offset] & 0x2) {
            length += 4;
          }
        }
        if (data[offset] & 0x1) {
          /* buffer_info_count, FIXME read and skip */
          length += 2;
        }
        break;
      case GST_RDT_TYPE_AUTOBW:
        if (data[offset] & 0x80)
          length_offset = 3;
        break;
      case GST_RDT_TYPE_INVALID:
      default:
        goto unknown_packet;
    }
  }

  if (length != -1) {
    /* we have a fixed length */
    packet->length = length;
  } else if (length_offset != -1) {
    /* we can read the length from an offset */
    packet->length = GST_READ_UINT16_BE (&data[length_offset]);
  } else {
    /* length is remainder of packet */
    packet->length = size - offset;
  }

  /* the length should be smaller than the remaining size */
  if (packet->length + offset > size)
    goto invalid_length;

  return TRUE;

  /* ERRORS */
unknown_packet:
  {
    packet->type = GST_RDT_TYPE_INVALID;
    return FALSE;
  }
invalid_length:
  {
    packet->type = GST_RDT_TYPE_INVALID;
    packet->length = 0;
    return FALSE;
  }
}