Exemplo n.º 1
0
/**
 * gst_audio_format_fill_silence:
 * @info: a #GstAudioFormatInfo
 * @dest: (array length=length) (element-type guint8): a destination
 *   to fill
 * @length: the length to fill
 *
 * Fill @length bytes in @dest with silence samples for @info.
 */
void
gst_audio_format_fill_silence (const GstAudioFormatInfo * info,
    gpointer dest, gsize length)
{
  guint8 *dptr = dest;

  g_return_if_fail (info != NULL);
  g_return_if_fail (dest != NULL);

  if (info->flags & GST_AUDIO_FORMAT_FLAG_FLOAT ||
      info->flags & GST_AUDIO_FORMAT_FLAG_SIGNED) {
    /* float or signed always 0 */
    orc_memset (dest, 0, length);
  } else {
    gint i, j, bps = info->width >> 3;

    switch (bps) {
      case 1:
        orc_memset (dest, info->silence[0], length);
        break;
      case 2:{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
        guint16 silence = GST_READ_UINT16_LE (info->silence);
#else
        guint16 silence = GST_READ_UINT16_BE (info->silence);
#endif
        audio_orc_splat_u16 (dest, silence, length / bps);
        break;
      }
      case 4:{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
        guint32 silence = GST_READ_UINT32_LE (info->silence);
#else
        guint32 silence = GST_READ_UINT32_BE (info->silence);
#endif
        audio_orc_splat_u32 (dest, silence, length / bps);
        break;
      }
      case 8:{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
        guint64 silence = GST_READ_UINT64_LE (info->silence);
#else
        guint64 silence = GST_READ_UINT64_BE (info->silence);
#endif
        audio_orc_splat_u64 (dest, silence, length / bps);
        break;
      }
      default:
        for (i = 0; i < length; i += bps) {
          for (j = 0; j < bps; j++)
            *dptr++ = info->silence[j];
        }
        break;
    }
  }
}
Exemplo n.º 2
0
/**
 * gst_net_time_packet_new:
 * @buffer: (array): a buffer from which to construct the packet, or NULL
 *
 * Creates a new #GstNetTimePacket from a buffer received over the network. The
 * caller is responsible for ensuring that @buffer is at least
 * #GST_NET_TIME_PACKET_SIZE bytes long.
 *
 * If @buffer is %NULL, the local and remote times will be set to
 * #GST_CLOCK_TIME_NONE.
 *
 * MT safe. Caller owns return value (gst_net_time_packet_free to free).
 *
 * Returns: The new #GstNetTimePacket.
 */
GstNetTimePacket *
gst_net_time_packet_new (const guint8 * buffer)
{
  GstNetTimePacket *ret;

  g_assert (sizeof (GstClockTime) == 8);

  ret = g_new0 (GstNetTimePacket, 1);

  if (buffer) {
    ret->local_time = GST_READ_UINT64_BE (buffer);
    ret->remote_time = GST_READ_UINT64_BE (buffer + sizeof (GstClockTime));
  } else {
    ret->local_time = GST_CLOCK_TIME_NONE;
    ret->remote_time = GST_CLOCK_TIME_NONE;
  }

  return ret;
}
Exemplo n.º 3
0
/**
 * gst_rtp_hdrext_get_ntp_64:
 * @data: the data to read from
 * @size: the size of @data
 * @ntptime: the result NTP time
 *
 * Reads the NTP time from the @size NTP-64 extension bytes in @data and store the
 * result in @ntptime.
 *
 * Returns: %TRUE on success.
 */
gboolean
gst_rtp_hdrext_get_ntp_64 (gpointer data, guint size, guint64 * ntptime)
{
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (size >= GST_RTP_HDREXT_NTP_64_SIZE, FALSE);

  if (ntptime)
    *ntptime = GST_READ_UINT64_BE (data);

  return TRUE;
}
static gboolean
moov_recov_parse_buffer_entry (MoovRecovFile * moovrf, TrakBufferEntryInfo * b)
{
  guint8 data[TRAK_BUFFER_ENTRY_INFO_SIZE];
  gint read;

  read = fread (data, 1, TRAK_BUFFER_ENTRY_INFO_SIZE, moovrf->file);
  if (read != TRAK_BUFFER_ENTRY_INFO_SIZE)
    return FALSE;

  b->track_id = GST_READ_UINT32_BE (data);
  b->nsamples = GST_READ_UINT32_BE (data + 4);
  b->delta = GST_READ_UINT32_BE (data + 8);
  b->size = GST_READ_UINT32_BE (data + 12);
  b->chunk_offset = GST_READ_UINT64_BE (data + 16);
  b->sync = data[24] != 0;
  b->do_pts = data[25] != 0;
  b->pts_offset = GST_READ_UINT64_BE (data + 26);
  return TRUE;
}
Exemplo n.º 5
0
static void
do_ntp_time (GstClockTime buffer_time, gint segment_start, gint segment_base)
{
  GstSegment segment;
  GstBuffer *buffer;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
  guint8 *data;
  guint64 expected_ntp_time;
  guint64 timestamp;

  /* create a segment that controls the behavior
   * by changing segment.start and segment.base we affect the stream time and
   * running time respectively */
  gst_segment_init (&segment, GST_FORMAT_TIME);
  segment.start = segment_start;
  segment.base = segment_base;
  gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));

  expected_ntp_time = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME,
      buffer_time);
    expected_ntp_time += NTP_OFFSET;
  expected_ntp_time = gst_util_uint64_scale (expected_ntp_time,
      (G_GINT64_CONSTANT (1) << 32), GST_SECOND);

  buffer = create_rtp_buffer (buffer_time, FALSE);
  fail_unless_equals_int (gst_pad_push (mysrcpad, buffer), GST_FLOW_OK);
  fail_unless_equals_int (g_list_length (buffers), 1);

  buffer = g_list_last (buffers)->data;

  /* get the extension header */
  fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtpbuffer));
  fail_unless (gst_rtp_buffer_get_extension_data (&rtpbuffer, NULL,
          (gpointer) & data, NULL));

  /* ...and read the NTP timestamp and verify that it's the expected one */
  timestamp = GST_READ_UINT64_BE (data);
  fail_unless_equals_uint64 (timestamp, expected_ntp_time);

  gst_rtp_buffer_unmap (&rtpbuffer);
  gst_check_drop_buffers ();
}
Exemplo n.º 6
0
/* SMPTE 377M 11.1 */
gboolean
mxf_random_index_pack_parse (const MXFUL * key, const guint8 * data, guint size,
    GArray ** array)
{
  guint len, i;
  MXFRandomIndexPackEntry entry;

  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (array != NULL, FALSE);

  if (size < 4)
    return FALSE;

  if ((size - 4) % 12 != 0)
    return FALSE;

  GST_DEBUG ("Parsing random index pack:");

  len = (size - 4) / 12;

  GST_DEBUG ("  number of entries = %u", len);

  *array =
      g_array_sized_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry), len);

  for (i = 0; i < len; i++) {
    entry.body_sid = GST_READ_UINT32_BE (data);
    entry.offset = GST_READ_UINT64_BE (data + 4);
    data += 12;

    GST_DEBUG ("  entry %u = body sid %u at offset %" G_GUINT64_FORMAT, i,
        entry.body_sid, entry.offset);

    g_array_append_val (*array, entry);
  }

  return TRUE;
}
Exemplo n.º 7
0
/* SMPTE 377M 10.2.3 */
gboolean
mxf_index_table_segment_parse (const MXFUL * key,
    MXFIndexTableSegment * segment, const MXFPrimerPack * primer,
    const guint8 * data, guint size)
{
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif
  guint16 tag, tag_size;
  const guint8 *tag_data;

  g_return_val_if_fail (key != NULL, FALSE);
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (primer != NULL, FALSE);

  memset (segment, 0, sizeof (MXFIndexTableSegment));

  if (size < 70)
    return FALSE;

  GST_DEBUG ("Parsing index table segment:");

  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
    if (tag_size == 0 || tag == 0x0000)
      goto next;

    switch (tag) {
      case 0x3c0a:
        if (tag_size != 16)
          goto error;
        memcpy (&segment->instance_id, tag_data, 16);
        GST_DEBUG ("  instance id = %s",
            mxf_ul_to_string (&segment->instance_id, str));
        break;
      case 0x3f0b:
        if (!mxf_fraction_parse (&segment->index_edit_rate, tag_data, tag_size))
          goto error;
        GST_DEBUG ("  index edit rate = %d/%d", segment->index_edit_rate.n,
            segment->index_edit_rate.d);
        break;
      case 0x3f0c:
        if (tag_size != 8)
          goto error;
        segment->index_start_position = GST_READ_UINT64_BE (tag_data);
        GST_DEBUG ("  index start position = %" G_GINT64_FORMAT,
            segment->index_start_position);
        break;
      case 0x3f0d:
        if (tag_size != 8)
          goto error;
        segment->index_duration = GST_READ_UINT64_BE (tag_data);
        GST_DEBUG ("  index duration = %" G_GINT64_FORMAT,
            segment->index_duration);
        break;
      case 0x3f05:
        if (tag_size != 4)
          goto error;
        segment->edit_unit_byte_count = GST_READ_UINT32_BE (tag_data);
        GST_DEBUG ("  edit unit byte count = %u",
            segment->edit_unit_byte_count);
        break;
      case 0x3f06:
        if (tag_size != 4)
          goto error;
        segment->index_sid = GST_READ_UINT32_BE (tag_data);
        GST_DEBUG ("  index sid = %u", segment->index_sid);
        break;
      case 0x3f07:
        if (tag_size != 4)
          goto error;
        segment->body_sid = GST_READ_UINT32_BE (tag_data);
        GST_DEBUG ("  body sid = %u", segment->body_sid);
        break;
      case 0x3f08:
        if (tag_size != 1)
          goto error;
        segment->slice_count = GST_READ_UINT8 (tag_data);
        GST_DEBUG ("  slice count = %u", segment->slice_count);
        break;
      case 0x3f0e:
        if (tag_size != 1)
          goto error;
        segment->pos_table_count = GST_READ_UINT8 (tag_data);
        GST_DEBUG ("  pos table count = %u", segment->pos_table_count);
        break;
      case 0x3f09:{
        guint len, i;

        if (tag_size < 8)
          goto error;

        len = GST_READ_UINT32_BE (tag_data);
        segment->n_delta_entries = len;
        GST_DEBUG ("  number of delta entries = %u", segment->n_delta_entries);
        if (len == 0)
          goto next;
        tag_data += 4;
        tag_size -= 4;

        if (GST_READ_UINT32_BE (tag_data) != 6)
          goto error;

        tag_data += 4;
        tag_size -= 4;

        if (tag_size < len * 6)
          goto error;

        segment->delta_entries = g_new (MXFDeltaEntry, len);

        for (i = 0; i < len; i++) {
          GST_DEBUG ("    delta entry %u:", i);

          segment->delta_entries[i].pos_table_index = GST_READ_UINT8 (tag_data);
          tag_data += 1;
          tag_size -= 1;
          GST_DEBUG ("    pos table index = %d",
              segment->delta_entries[i].pos_table_index);

          segment->delta_entries[i].slice = GST_READ_UINT8 (tag_data);
          tag_data += 1;
          tag_size -= 1;
          GST_DEBUG ("    slice = %u", segment->delta_entries[i].slice);

          segment->delta_entries[i].element_delta =
              GST_READ_UINT32_BE (tag_data);
          tag_data += 4;
          tag_size -= 4;
          GST_DEBUG ("    element delta = %u",
              segment->delta_entries[i].element_delta);
        }
        break;
      }
      case 0x3f0a:{
        guint len, i, j;

        if (tag_size < 8)
          goto error;

        len = GST_READ_UINT32_BE (tag_data);
        segment->n_index_entries = len;
        GST_DEBUG ("  number of index entries = %u", segment->n_index_entries);
        if (len == 0)
          goto next;
        tag_data += 4;
        tag_size -= 4;

        if (GST_READ_UINT32_BE (tag_data) !=
            (11 + 4 * segment->slice_count + 8 * segment->pos_table_count))
          goto error;

        tag_data += 4;
        tag_size -= 4;

        if (tag_size <
            len * (11 + 4 * segment->slice_count +
                8 * segment->pos_table_count))
          goto error;

        segment->index_entries = g_new (MXFIndexEntry, len);

        for (i = 0; i < len; i++) {
          MXFIndexEntry *entry = &segment->index_entries[i];

          GST_DEBUG ("    index entry %u:", i);

          entry->temporal_offset = GST_READ_UINT8 (tag_data);
          tag_data += 1;
          tag_size -= 1;
          GST_DEBUG ("    temporal offset = %d", entry->temporal_offset);

          entry->key_frame_offset = GST_READ_UINT8 (tag_data);
          tag_data += 1;
          tag_size -= 1;
          GST_DEBUG ("    keyframe offset = %d", entry->key_frame_offset);

          entry->flags = GST_READ_UINT8 (tag_data);
          tag_data += 1;
          tag_size -= 1;
          GST_DEBUG ("    flags = 0x%02x", entry->flags);

          entry->stream_offset = GST_READ_UINT64_BE (tag_data);
          tag_data += 8;
          tag_size -= 8;
          GST_DEBUG ("    stream offset = %" G_GUINT64_FORMAT,
              entry->stream_offset);

          for (j = 0; j < segment->slice_count; j++) {
            entry->slice_offset[j] = GST_READ_UINT32_BE (tag_data);
            tag_data += 4;
            tag_size -= 4;
            GST_DEBUG ("    slice %u offset = %u", j, entry->slice_offset[j]);
          }

          for (j = 0; j < segment->pos_table_count; j++) {
            mxf_fraction_parse (&entry->pos_table[j], tag_data, tag_size);
            tag_data += 8;
            tag_size -= 8;
            GST_DEBUG ("    pos table %u = %d/%d", j, entry->pos_table[j].n,
                entry->pos_table[j].d);
          }
        }
        break;
      }
      default:
        if (!mxf_local_tag_add_to_hash_table (primer, tag, tag_data, tag_size,
                &segment->other_tags))
          goto error;
        break;
    }

  next:
    data += 4 + tag_size;
    size -= 4 + tag_size;
  }
  return TRUE;

error:
  GST_ERROR ("Invalid index table segment");
  return FALSE;
}
Exemplo n.º 8
0
/* SMPTE 377M 6.1, Table 2 */
gboolean
mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
    const guint8 * data, guint size)
{
  guint i;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (size >= 84, FALSE);

  memset (pack, 0, sizeof (MXFPartitionPack));

  GST_DEBUG ("Parsing partition pack:");

  if (key->u[13] == 0x02)
    pack->type = MXF_PARTITION_PACK_HEADER;
  else if (key->u[13] == 0x03)
    pack->type = MXF_PARTITION_PACK_BODY;
  else if (key->u[13] == 0x04)
    pack->type = MXF_PARTITION_PACK_FOOTER;

  GST_DEBUG ("  type = %s",
      (pack->type == MXF_PARTITION_PACK_HEADER) ? "header" : (pack->type ==
          MXF_PARTITION_PACK_BODY) ? "body" : "footer");

  pack->closed = (key->u[14] == 0x02 || key->u[14] == 0x04);
  pack->complete = (key->u[14] == 0x03 || key->u[14] == 0x04);

  GST_DEBUG ("  closed = %s, complete = %s", (pack->closed) ? "yes" : "no",
      (pack->complete) ? "yes" : "no");

  pack->major_version = GST_READ_UINT16_BE (data);
  if (pack->major_version != 1)
    goto error;
  data += 2;
  size -= 2;

  pack->minor_version = GST_READ_UINT16_BE (data);
  data += 2;
  size -= 2;

  GST_DEBUG ("  MXF version = %u.%u", pack->major_version, pack->minor_version);

  pack->kag_size = GST_READ_UINT32_BE (data);
  data += 4;
  size -= 4;

  GST_DEBUG ("  KAG size = %u", pack->kag_size);

  pack->this_partition = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  GST_DEBUG ("  this partition offset = %" G_GUINT64_FORMAT,
      pack->this_partition);

  pack->prev_partition = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  GST_DEBUG ("  previous partition offset = %" G_GUINT64_FORMAT,
      pack->prev_partition);

  pack->footer_partition = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  GST_DEBUG ("  footer partition offset = %" G_GUINT64_FORMAT,
      pack->footer_partition);

  pack->header_byte_count = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  GST_DEBUG ("  header byte count = %" G_GUINT64_FORMAT,
      pack->header_byte_count);

  pack->index_byte_count = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  pack->index_sid = GST_READ_UINT32_BE (data);
  data += 4;
  size -= 4;

  GST_DEBUG ("  index sid = %u, size = %" G_GUINT64_FORMAT, pack->index_sid,
      pack->index_byte_count);

  pack->body_offset = GST_READ_UINT64_BE (data);
  data += 8;
  size -= 8;

  pack->body_sid = GST_READ_UINT32_BE (data);
  data += 4;
  size -= 4;

  GST_DEBUG ("  body sid = %u, offset = %" G_GUINT64_FORMAT, pack->body_sid,
      pack->body_offset);

  memcpy (&pack->operational_pattern, data, 16);
  data += 16;
  size -= 16;

  GST_DEBUG ("  operational pattern = %s",
      mxf_ul_to_string (&pack->operational_pattern, str));

  pack->n_essence_containers = GST_READ_UINT32_BE (data);
  data += 4;
  size -= 4;

  GST_DEBUG ("  number of essence containers = %u", pack->n_essence_containers);

  if (GST_READ_UINT32_BE (data) != 16)
    goto error;
  data += 4;
  size -= 4;

  if (size < 16 * pack->n_essence_containers)
    goto error;

  if (pack->n_essence_containers) {
    pack->essence_containers = g_new (MXFUL, pack->n_essence_containers);
    for (i = 0; i < pack->n_essence_containers; i++) {
      memcpy (&pack->essence_containers[i], data + i * 16, 16);
      GST_DEBUG ("  essence container %u = %s", i,
          mxf_ul_to_string (&pack->essence_containers[i], str));
    }
  }

  pack->valid = TRUE;

  return TRUE;

error:
  GST_ERROR ("Invalid partition pack");

  mxf_partition_pack_reset (pack);
  return FALSE;
}
Exemplo n.º 9
0
/* Callbacks used for websocket clients */
static gboolean
try_parse_websocket_fragment (SnraServerClient * client)
{
    guint64 frag_size;
    gchar *header, *outptr;
    gchar *mask;
    gchar *decoded;
    gsize i, avail;

    // g_print ("Got %u bytes to parse\n", (guint) client->in_bufavail);
    if (client->in_bufavail < 2)
        return FALSE;

    header = outptr = client->in_bufptr;
    avail = client->in_bufavail;

    if (header[0] & 0x80)
        g_print ("FIN flag. Payload type 0x%x\n", header[0] & 0xf);

    frag_size = header[1] & 0x7f;
    outptr += 2;

    if (frag_size < 126) {
        avail -= 2;
    } else if (frag_size == 126) {
        if (avail < 4)
            return FALSE;
        frag_size = GST_READ_UINT16_BE (outptr);
        outptr += 2;
        avail -= 8;
    } else {
        if (avail < 10)
            return FALSE;
        frag_size = GST_READ_UINT64_BE (outptr);
        outptr += 8;
        avail -= 8;
    }

    if ((header[1] & 0x80) == 0) {
        /* FIXME: drop the connection */
        g_print ("Received packet not masked. Skipping\n");
        snra_server_connection_lost (client);
        goto skip_out;
    }

    if (avail < 4 + frag_size) {
        /* Wait for more data */
        return FALSE;
    }

    /* Consume the 4 mask bytes */
    mask = outptr;
    outptr += 4;
    avail -= 4;

    decoded = g_malloc (frag_size + 1);
    for (i = 0; i < frag_size; i++) {
        decoded[i] = outptr[i] ^ mask[i % 4];
    }
    decoded[frag_size] = 0;

    /* Fire a signal to get this packet processed */
    g_signal_emit (client, snra_server_client_signals[MSG_RECEIVED], 0,
                   decoded, (guint64)(frag_size));

    g_free (decoded);

skip_out:
    {
        gsize consumed;

        outptr += frag_size;

        consumed = outptr - client->in_bufptr;

        client->in_bufavail -= consumed;
        client->in_bufptr = outptr;
    }

    return TRUE;
}