static gpointer
make_samr_magic_cookie (GstBuffer * codec_data, gsize * len)
{
  guint8 *res;

  *len = 48;
  res = g_malloc0 (0x30);

  /* 12 first bytes are 'frma' (format) atom with 'samr' value */
  GST_WRITE_UINT32_BE (res, 0xc);
  GST_WRITE_UINT32_LE (res + 4, QT_MAKE_FOURCC_BE ('f', 'r', 'm', 'a'));
  GST_WRITE_UINT32_LE (res + 8, QT_MAKE_FOURCC_BE ('s', 'a', 'm', 'r'));

  /* 10 bytes for 'enda' atom with 0 */
  GST_WRITE_UINT32_BE (res + 12, 10);
  GST_WRITE_UINT32_LE (res + 16, QT_MAKE_FOURCC_BE ('e', 'n', 'd', 'a'));

  /* 17(+1) bytes for the codec_data contents */
  GST_WRITE_UINT32_BE (res + 22, 18);
  memcpy (res + 26, GST_BUFFER_DATA (codec_data) + 4, 17);

  /* yes... we need to replace 'damr' by 'samr'. Blame Apple ! */
  GST_WRITE_UINT8 (res + 26, 's');

  /* Terminator atom */
  GST_WRITE_UINT32_BE (res + 40, 8);

#if DEBUG_DUMP
  gst_util_dump_mem (res, 48);
#endif

  return res;
}
static gpointer
make_alac_magic_cookie (GstBuffer * codec_data, gsize * len)
{
  guint8 *res;

  if (GST_BUFFER_SIZE (codec_data) < 4)
    return NULL;

  *len = 20 + GST_BUFFER_SIZE (codec_data);
  res = g_malloc0 (*len);

  /* 12 first bytes are 'frma' (format) atom with 'alac' value */
  GST_WRITE_UINT32_BE (res, 0xc);       /* Atom length: 12 bytes */
  GST_WRITE_UINT32_LE (res + 4, QT_MAKE_FOURCC_BE ('f', 'r', 'm', 'a'));
  GST_WRITE_UINT32_LE (res + 8, QT_MAKE_FOURCC_BE ('a', 'l', 'a', 'c'));

  /* Write the codec_data, but with the first four bytes reversed (different
     endianness). This is the 'alac' atom. */
  GST_WRITE_UINT32_BE (res + 12,
      GST_READ_UINT32_LE (GST_BUFFER_DATA (codec_data)));
  memcpy (res + 16, GST_BUFFER_DATA (codec_data) + 4,
      GST_BUFFER_SIZE (codec_data) - 4);

  /* Terminator atom */
  GST_WRITE_UINT32_BE (res + 12 + GST_BUFFER_SIZE (codec_data), 8);
  GST_WRITE_UINT32_BE (res + 12 + GST_BUFFER_SIZE (codec_data) + 4, 0);

  return res;
}
Example #3
0
static GstBuffer *
gst_wavenc_create_header_buf (GstWavEnc * wavenc, guint audio_data_size)
{
  struct wave_header wave;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *header;

  buf = gst_buffer_new_and_alloc (WAV_HEADER_LEN);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  header = map.data;
  memset (header, 0, WAV_HEADER_LEN);

  wave.common.wChannels = wavenc->channels;
  wave.common.wBitsPerSample = wavenc->width;
  wave.common.dwSamplesPerSec = wavenc->rate;

  /* Fill out our wav-header with some information */
  memcpy (wave.riff.id, "RIFF", 4);
  wave.riff.len = audio_data_size + WAV_HEADER_LEN - 8;
  memcpy (wave.riff.wav_id, "WAVE", 4);

  memcpy (wave.format.id, "fmt ", 4);
  wave.format.len = 16;

  wave.common.wFormatTag = wavenc->format;
  wave.common.wBlockAlign = (wavenc->width / 8) * wave.common.wChannels;
  wave.common.dwAvgBytesPerSec =
      wave.common.wBlockAlign * wave.common.dwSamplesPerSec;

  memcpy (wave.data.id, "data", 4);
  wave.data.len = audio_data_size;

  memcpy (header, (char *) wave.riff.id, 4);
  GST_WRITE_UINT32_LE (header + 4, wave.riff.len);
  memcpy (header + 8, (char *) wave.riff.wav_id, 4);
  memcpy (header + 12, (char *) wave.format.id, 4);
  GST_WRITE_UINT32_LE (header + 16, wave.format.len);
  GST_WRITE_UINT16_LE (header + 20, wave.common.wFormatTag);
  GST_WRITE_UINT16_LE (header + 22, wave.common.wChannels);
  GST_WRITE_UINT32_LE (header + 24, wave.common.dwSamplesPerSec);
  GST_WRITE_UINT32_LE (header + 28, wave.common.dwAvgBytesPerSec);
  GST_WRITE_UINT16_LE (header + 32, wave.common.wBlockAlign);
  GST_WRITE_UINT16_LE (header + 34, wave.common.wBitsPerSample);
  memcpy (header + 36, (char *) wave.data.id, 4);
  GST_WRITE_UINT32_LE (header + 40, wave.data.len);

  gst_buffer_unmap (buf, &map);

  return buf;
}
Example #4
0
static void
gst_mim_enc_create_tcp_header (GstMimEnc * mimenc, guint8 * p,
    guint32 payload_size, GstClockTime ts, gboolean keyframe, gboolean paused)
{
  p[0] = 24;
  p[1] = paused ? 1 : 0;
  GST_WRITE_UINT16_LE (p + 2, mimenc->width);
  GST_WRITE_UINT16_LE (p + 4, mimenc->height);
  GST_WRITE_UINT16_LE (p + 6, keyframe ? 1 : 0);
  GST_WRITE_UINT32_LE (p + 8, payload_size);
  GST_WRITE_UINT32_LE (p + 12, paused ? 0 :
      GST_MAKE_FOURCC ('M', 'L', '2', '0'));
  GST_WRITE_UINT32_LE (p + 16, 0);
  GST_WRITE_UINT32_LE (p + 20, ts / GST_MSECOND);
}
Example #5
0
static GstAdapter *
create_and_fill_adapter (void)
{
  GstAdapter *adapter;
  gint i, j;

  adapter = gst_adapter_new ();
  fail_unless (adapter != NULL);

  for (i = 0; i < 10000; i += 4) {
    GstBuffer *buf = gst_buffer_new_and_alloc (sizeof (guint32) * 4);
    guint8 *data;

    fail_unless (buf != NULL);
    data = GST_BUFFER_DATA (buf);

    for (j = 0; j < 4; j++) {
      GST_WRITE_UINT32_LE (data, i + j);
      data += sizeof (guint32);
    }
    gst_adapter_push (adapter, buf);
  }

  return adapter;
}
Example #6
0
static GstAdapter *
create_and_fill_adapter (void)
{
  GstAdapter *adapter;
  gint i, j;

  adapter = gst_adapter_new ();
  fail_unless (adapter != NULL);

  for (i = 0; i < 10000; i += 4) {
    GstBuffer *buf;
    GstMapInfo info;
    guint8 *ptr;

    buf = gst_buffer_new_and_alloc (sizeof (guint32) * 4);
    fail_unless (buf != NULL);

    fail_unless (gst_buffer_map (buf, &info, GST_MAP_WRITE));
    ptr = info.data;

    for (j = 0; j < 4; j++) {
      GST_WRITE_UINT32_LE (ptr, i + j);
      ptr += sizeof (guint32);
    }
    gst_buffer_unmap (buf, &info);

    gst_adapter_push (adapter, buf);
  }

  return adapter;
}
Example #7
0
static gboolean
gst_wavenc_write_labls (guint8 ** data, GList * list)
{
  GstWavEncLabl *labl;

  while (list) {
    labl = list->data;
    memcpy (*data, (gchar *) labl->chunk_id, 4);
    GST_WRITE_UINT32_LE (*data + 4, labl->chunk_data_size);
    GST_WRITE_UINT32_LE (*data + 8, labl->cue_point_id);
    memcpy (*data + 12, (gchar *) labl->text, strlen (labl->text));
    *data += 8 + GST_ROUND_UP_2 (labl->chunk_data_size);
    list = g_list_next (list);
  }

  return TRUE;
}
Example #8
0
static gboolean
gst_wavenc_write_notes (guint8 ** data, GList * list)
{
  GstWavEncNote *note;

  while (list) {
    note = list->data;
    memcpy (*data, (gchar *) note->chunk_id, 4);
    GST_WRITE_UINT32_LE (*data + 4, note->chunk_data_size);
    GST_WRITE_UINT32_LE (*data + 8, note->cue_point_id);
    memcpy (*data + 12, (gchar *) note->text, strlen (note->text));
    *data += 8 + GST_ROUND_UP_2 (note->chunk_data_size);
    list = g_list_next (list);
  }

  return TRUE;
}
Example #9
0
static gboolean
gst_wavenc_write_cues (guint8 ** data, GList * list)
{
  GstWavEncCue *cue;

  while (list) {
    cue = list->data;
    GST_WRITE_UINT32_LE (*data, cue->id);
    GST_WRITE_UINT32_LE (*data + 4, cue->position);
    memcpy (*data + 8, (gchar *) cue->data_chunk_id, 4);
    GST_WRITE_UINT32_LE (*data + 12, cue->chunk_start);
    GST_WRITE_UINT32_LE (*data + 16, cue->block_start);
    GST_WRITE_UINT32_LE (*data + 20, cue->sample_offset);
    *data += 24;
    list = g_list_next (list);
  }

  return TRUE;
}
Example #10
0
static GstBuffer *
gst_mimenc_create_tcp_header (GstMimEnc * mimenc, guint32 payload_size,
    GstClockTime timestamp, gboolean keyframe, gboolean paused)
{
  // 24 bytes
  GstBuffer *buf_header = gst_buffer_new_and_alloc (24);
  guchar *p = (guchar *) GST_BUFFER_DATA (buf_header);

  GST_BUFFER_TIMESTAMP (buf_header) = timestamp;

  p[0] = 24;
  p[1] = paused ? 1 : 0;
  GST_WRITE_UINT16_LE (p + 2, mimenc->width);
  GST_WRITE_UINT16_LE (p + 4, mimenc->height);
  GST_WRITE_UINT16_LE (p + 6, keyframe ? 1 : 0);
  GST_WRITE_UINT32_LE (p + 8, payload_size);
  GST_WRITE_UINT32_LE (p + 12, paused ? 0 :
      GST_MAKE_FOURCC ('M', 'L', '2', '0'));
  GST_WRITE_UINT32_LE (p + 16, 0);
  GST_WRITE_UINT32_LE (p + 20, timestamp / GST_MSECOND);

  return buf_header;
}
Example #11
0
static ImageDescription *
image_description_for_avc1 (GstBuffer * buf)
{
  ImageDescription *desc = NULL;
  guint8 *pos;

  desc = g_malloc0 (sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8);
  pos = (guint8 *) desc + sizeof (ImageDescription);

  desc->idSize = sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8;
  /* write size in Big-Endian */
  GST_WRITE_UINT32_BE (pos, GST_BUFFER_SIZE (buf) + 8);
  GST_WRITE_UINT32_LE (pos + 4, QT_MAKE_FOURCC_BE ('a', 'v', 'c', 'C'));
  g_memmove (pos + 8, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));

  return desc;
}
static guint8 *
gss_adaptive_assemble_chunk (GssTransaction * t, GssAdaptive * adaptive,
    GssAdaptiveLevel * level, GssIsomFragment * fragment)
{
  GError *error = NULL;
  guint8 *mdat_data;
  int fd;
  gboolean ret;

  g_return_val_if_fail (t != NULL, NULL);
  g_return_val_if_fail (adaptive != NULL, NULL);
  g_return_val_if_fail (level != NULL, NULL);
  g_return_val_if_fail (fragment != NULL, NULL);

  fd = open (level->filename, O_RDONLY);
  if (fd < 0) {
    GST_WARNING ("failed to open \"%s\", error=\"%s\", broken manifest?",
        level->filename, g_strerror (errno));
    gss_transaction_error_not_found (t,
        "failed to open file (broken manifest?)");
    return NULL;
  }

  mdat_data = g_malloc (fragment->mdat_size);

  GST_WRITE_UINT32_BE (mdat_data, fragment->mdat_size);
  GST_WRITE_UINT32_LE (mdat_data + 4, GST_MAKE_FOURCC ('m', 'd', 'a', 't'));

  ret = gss_sglist_load (fragment->sglist, fd, mdat_data + 8, &error);
  if (!ret) {
    gss_transaction_error_not_found (t, error->message);
    g_error_free (error);
    g_free (mdat_data);
    close (fd);
    return NULL;
  }

  close (fd);

  return mdat_data;
}
Example #13
0
/* Correctly format samples with width!=depth for the wav format, i.e.
 * have the data in the highest depth bits and all others zero */
static void
gst_wavenc_format_samples (GstBuffer * buf, guint width, guint depth)
{
  guint8 *data = GST_BUFFER_DATA (buf);
  guint nsamples = (GST_BUFFER_SIZE (buf) * 8) / width;
  guint32 tmp;

  for (; nsamples; nsamples--) {
    switch (width) {

      case 8:
        tmp = *data;
        *data = *data << (width - depth);
        data += 1;
        break;
      case 16:
        tmp = GST_READ_UINT16_LE (data);
        tmp = tmp << (width - depth);
        GST_WRITE_UINT16_LE (data, tmp);
        data += 2;
        break;
      case 24:
        tmp = READ24_FROM_LE (data);
        tmp = tmp << (width - depth);
        WRITE24_TO_LE (data, tmp);
        data += 3;
        break;
      case 32:
        tmp = GST_READ_UINT32_LE (data);
        tmp = tmp << (width - depth);
        GST_WRITE_UINT32_LE (data, tmp);
        data += 4;
        break;
    }
  }
}
Example #14
0
static GstFlowReturn
gst_wavenc_write_toc (GstWavEnc * wavenc)
{
  GList *list;
  GstToc *toc;
  GstTocEntry *entry, *subentry;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data;
  guint32 ncues, size, cues_size, labls_size, notes_size;

  if (!wavenc->toc) {
    GST_DEBUG_OBJECT (wavenc, "have no toc, checking toc_setter");
    wavenc->toc = gst_toc_setter_get_toc (GST_TOC_SETTER (wavenc));
  }
  if (!wavenc->toc) {
    GST_WARNING_OBJECT (wavenc, "have no toc");
    return GST_FLOW_OK;
  }

  toc = gst_toc_ref (wavenc->toc);
  size = 0;
  cues_size = 0;
  labls_size = 0;
  notes_size = 0;

  /* check if the TOC entries is valid */
  list = gst_toc_get_entries (toc);
  entry = list->data;
  if (gst_toc_entry_is_alternative (entry)) {
    list = gst_toc_entry_get_sub_entries (entry);
    while (list) {
      subentry = list->data;
      if (!gst_toc_entry_is_sequence (subentry))
        return FALSE;
      list = g_list_next (list);
    }
    list = gst_toc_entry_get_sub_entries (entry);
  }
  if (gst_toc_entry_is_sequence (entry)) {
    while (list) {
      entry = list->data;
      if (!gst_toc_entry_is_sequence (entry))
        return FALSE;
      list = g_list_next (list);
    }
    list = gst_toc_get_entries (toc);
  }

  ncues = g_list_length (list);
  GST_DEBUG_OBJECT (wavenc, "number of cue entries: %d", ncues);

  while (list) {
    guint32 id = 0;
    gint64 id64;
    const gchar *uid;

    entry = list->data;
    uid = gst_toc_entry_get_uid (entry);
    id64 = g_ascii_strtoll (uid, NULL, 0);
    /* check if id unique compatible with guint32 else generate random */
    if (id64 >= 0 && gst_wavenc_is_cue_id_unique (id64, wavenc->cues)) {
      id = (guint32) id64;
    } else {
      do {
        id = g_random_int ();
      } while (!gst_wavenc_is_cue_id_unique (id, wavenc->cues));
    }
    gst_wavenc_parse_cue (wavenc, id, entry);
    gst_wavenc_parse_labl (wavenc, id, entry);
    gst_wavenc_parse_note (wavenc, id, entry);
    list = g_list_next (list);
  }

  /* count cues size */
  if (wavenc->cues) {
    cues_size = 24 * g_list_length (wavenc->cues);
    size += 12 + cues_size;
  } else {
    GST_WARNING_OBJECT (wavenc, "cue's not found");
    return FALSE;
  }
  /* count labls size */
  if (wavenc->labls) {
    list = wavenc->labls;
    while (list) {
      GstWavEncLabl *labl;
      labl = list->data;
      labls_size += 8 + GST_ROUND_UP_2 (labl->chunk_data_size);
      list = g_list_next (list);
    }
    size += labls_size;
  }
  /* count notes size */
  if (wavenc->notes) {
    list = wavenc->notes;
    while (list) {
      GstWavEncNote *note;
      note = list->data;
      notes_size += 8 + GST_ROUND_UP_2 (note->chunk_data_size);
      list = g_list_next (list);
    }
    size += notes_size;
  }
  if (wavenc->labls || wavenc->notes) {
    size += 12;
  }

  buf = gst_buffer_new_and_alloc (size);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;
  memset (data, 0, size);

  /* write Cue Chunk */
  if (wavenc->cues) {
    memcpy (data, (gchar *) "cue ", 4);
    GST_WRITE_UINT32_LE (data + 4, 4 + cues_size);
    GST_WRITE_UINT32_LE (data + 8, ncues);
    data += 12;
    gst_wavenc_write_cues (&data, wavenc->cues);

    /* write Associated Data List Chunk */
    if (wavenc->labls || wavenc->notes) {
      memcpy (data, (gchar *) "LIST", 4);
      GST_WRITE_UINT32_LE (data + 4, 4 + labls_size + notes_size);
      memcpy (data + 8, (gchar *) "adtl", 4);
      data += 12;
      if (wavenc->labls)
        gst_wavenc_write_labls (&data, wavenc->labls);
      if (wavenc->notes)
        gst_wavenc_write_notes (&data, wavenc->notes);
    }
  }

  /* free resources */
  if (toc)
    gst_toc_unref (toc);
  if (wavenc->cues)
    g_list_free_full (wavenc->cues, g_free);
  if (wavenc->labls)
    g_list_free_full (wavenc->labls, g_free);
  if (wavenc->notes)
    g_list_free_full (wavenc->notes, g_free);

  gst_buffer_unmap (buf, &map);
  wavenc->meta_length += gst_buffer_get_size (buf);

  return gst_pad_push (wavenc->srcpad, buf);
}
Example #15
0
static ImageDescription *
image_description_for_mp4v (GstBuffer * buf)
{
  ImageDescription *desc = NULL;
  guint32 offset = sizeof (ImageDescription);
  guint8 *location;

  GST_LOG ("buf %p , size:%d", buf, GST_BUFFER_SIZE (buf));

  /* this image description contains:
   *  ImageDescription  sizeof(ImageDescription)
   *  esds atom         34 bytes
   *  buffer            GST_BUFFER_SIZE (buf)
   *  ending            3 bytes
   */

  desc = g_malloc0 (offset + 37 + GST_BUFFER_SIZE (buf));
  desc->idSize = offset + 37 + GST_BUFFER_SIZE (buf);

  location = (guint8 *) desc + offset;

  /* Fill in ESDS */
  /*  size */
  GST_WRITE_UINT32_BE (location, 37 + GST_BUFFER_SIZE (buf));
  /*  atom */
  GST_WRITE_UINT32_LE (location + 4, GST_MAKE_FOURCC ('e', 's', 'd', 's'));
  /*  version + flags */
  QT_WRITE_UINT32 (location + 8, 0);
  /*  tag */
  QT_WRITE_UINT8 (location + 12, 0x3);
  /*  size (buffsize + 23) */
  QT_WRITE_UINT8 (location + 13, GST_BUFFER_SIZE (buf) + 23);
  /*  ESID */
  QT_WRITE_UINT16 (location + 14, 0);
  /*  priority */
  QT_WRITE_UINT8 (location + 16, 0);
  /*  tag */
  QT_WRITE_UINT8 (location + 17, 0x4);
  /*  size (buffsize + 8) */
  QT_WRITE_UINT8 (location + 18, GST_BUFFER_SIZE (buf) + 15);
  /*  object type */
  QT_WRITE_UINT8 (location + 19, 0x20);
  /*  stream type */
  QT_WRITE_UINT8 (location + 20, 0x11);
  /*  buffersize db */
  QT_WRITE_UINT24 (location + 21, 13640);
  /*  max bitrate */
  QT_WRITE_UINT32 (location + 24, 1849648);
  /*  avg bitrate */
  QT_WRITE_UINT32 (location + 28, 918191);
  /*  tag */
  QT_WRITE_UINT8 (location + 32, 0x05);
  /*  size */
  QT_WRITE_UINT8 (location + 33, GST_BUFFER_SIZE (buf));
  /*  codec data */
  g_memmove (location + 34, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
  /*  end */
  QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf), 0x06);
  QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 1, 0x01);
  QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 2, 0x02);

  return desc;
}
gboolean
moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf,
    FILE * outf, GError ** err)
{
  guint8 auxdata[16];
  guint8 *data = NULL;
  guint8 *prefix_data = NULL;
  guint8 *mvhd_data = NULL;
  guint8 *trak_data = NULL;
  guint32 moov_size = 0;
  gint i;
  guint64 stbl_children_size = 0;
  guint8 *stbl_children = NULL;
  guint32 longest_duration = 0;
  guint16 version;

  /* check the version */
  if (fseek (moovrf->file, 0, SEEK_SET) != 0) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to seek to the start of the moov recovery file");
    goto fail;
  }
  if (fread (auxdata, 1, 2, moovrf->file) != 2) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to read version from file");
  }

  version = GST_READ_UINT16_BE (auxdata);
  if (version != ATOMS_RECOV_FILE_VERSION) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_VERSION,
        "Input file version (%u) is not supported in this version (%u)",
        version, ATOMS_RECOV_FILE_VERSION);
    return FALSE;
  }

  /* write the ftyp */
  prefix_data = g_malloc (moovrf->prefix_size);
  if (fread (prefix_data, 1, moovrf->prefix_size,
          moovrf->file) != moovrf->prefix_size) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to read the ftyp atom from file");
    goto fail;
  }
  if (fwrite (prefix_data, 1, moovrf->prefix_size, outf) != moovrf->prefix_size) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }
  g_free (prefix_data);
  prefix_data = NULL;

  /* need to calculate the moov size beforehand to add the offset to
   * chunk offset entries */
  moov_size += moovrf->mvhd_size + 8;   /* mvhd + moov size + fourcc */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    guint32 duration;           /* in moov's timescale */
    guint32 trak_size;

    /* convert trak duration to moov's duration */
    duration = gst_util_uint64_scale_round (trak->duration, moovrf->timescale,
        trak->timescale);

    if (duration > longest_duration)
      longest_duration = duration;
    trak_size = trak_recov_data_get_trak_atom_size (trak);
    if (trak_size == 0) {
      g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_GENERIC,
          "Failed to estimate trak atom size");
      goto fail;
    }
    moov_size += trak_size;
  }

  /* add chunks offsets */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    /* 16 for the mdat header */
    gint64 offset = moov_size + ftell (outf) + 16;
    atom_stco64_chunks_add_offset (&trak->stbl.stco64, offset);
  }

  /* write the moov */
  GST_WRITE_UINT32_BE (auxdata, moov_size);
  GST_WRITE_UINT32_LE (auxdata + 4, FOURCC_moov);
  if (fwrite (auxdata, 1, 8, outf) != 8) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }

  /* write the mvhd */
  mvhd_data = g_malloc (moovrf->mvhd_size);
  if (fseek (moovrf->file, moovrf->mvhd_pos, SEEK_SET) != 0)
    goto fail;
  if (fread (mvhd_data, 1, moovrf->mvhd_size,
          moovrf->file) != moovrf->mvhd_size)
    goto fail;
  GST_WRITE_UINT32_BE (mvhd_data + 20, moovrf->timescale);
  GST_WRITE_UINT32_BE (mvhd_data + 24, longest_duration);
  if (fwrite (mvhd_data, 1, moovrf->mvhd_size, outf) != moovrf->mvhd_size) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }
  g_free (mvhd_data);
  mvhd_data = NULL;

  /* write the traks, this is the tough part because we need to update:
   * - stbl atom
   * - sizes of atoms from stbl to trak
   * - trak duration
   */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    guint trak_data_size;
    guint32 stbl_new_size;
    guint32 minf_new_size;
    guint32 mdia_new_size;
    guint32 trak_new_size;
    guint32 size_diff;
    guint32 duration;           /* in moov's timescale */

    /* convert trak duration to moov's duration */
    duration = gst_util_uint64_scale_round (trak->duration, moovrf->timescale,
        trak->timescale);

    stbl_children = moov_recov_get_stbl_children_data (moovrf, trak,
        &stbl_children_size);
    if (stbl_children == NULL)
      goto fail;

    /* calc the new size of the atoms from stbl to trak in the atoms tree */
    stbl_new_size = trak->stsd_size + stbl_children_size + 8;
    size_diff = stbl_new_size - trak->stbl_size;
    minf_new_size = trak->minf_size + size_diff;
    mdia_new_size = trak->mdia_size + size_diff;
    trak_new_size = trak->trak_size + size_diff;

    if (fseek (moovrf->file, trak->file_offset, SEEK_SET) != 0)
      goto fail;
    trak_data_size = trak->post_stsd_offset - trak->file_offset;
    trak_data = g_malloc (trak_data_size);
    if (fread (trak_data, 1, trak_data_size, moovrf->file) != trak_data_size) {
      goto fail;
    }
    /* update the size values in those read atoms before writing */
    GST_WRITE_UINT32_BE (trak_data, trak_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->mdia_file_offset -
            trak->file_offset), mdia_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->minf_file_offset -
            trak->file_offset), minf_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->stbl_file_offset -
            trak->file_offset), stbl_new_size);

    /* update duration values in tkhd and mdhd */
    GST_WRITE_UINT32_BE (trak_data + (trak->tkhd_file_offset -
            trak->file_offset) + 28, duration);
    GST_WRITE_UINT32_BE (trak_data + (trak->mdhd_file_offset -
            trak->file_offset) + 24, trak->duration);

    if (fwrite (trak_data, 1, trak_data_size, outf) != trak_data_size) {
      ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
      goto fail;
    }
    if (fwrite (stbl_children, 1, stbl_children_size, outf) !=
        stbl_children_size) {
      ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
      goto fail;
    }
    g_free (trak_data);
    trak_data = NULL;
    g_free (stbl_children);
    stbl_children = NULL;
  }

  /* write the mdat */
  /* write the header first */
  GST_WRITE_UINT32_BE (auxdata, 1);
  GST_WRITE_UINT32_LE (auxdata + 4, FOURCC_mdat);
  GST_WRITE_UINT64_BE (auxdata + 8, mdatrf->mdat_size);
  if (fwrite (auxdata, 1, 16, outf) != 16) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }

  /* now read the mdat data and output to the file */
  if (fseek (mdatrf->file, mdatrf->mdat_start +
          (mdatrf->rawfile ? 0 : mdatrf->mdat_header_size), SEEK_SET) != 0)
    goto fail;

  data = g_malloc (4096);
  while (!feof (mdatrf->file)) {
    gint read, write;

    read = fread (data, 1, 4096, mdatrf->file);
    write = fwrite (data, 1, read, outf);

    if (write != read) {
      g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
          "Failed to copy data to output file: %s", g_strerror (errno));
      goto fail;
    }
  }
  g_free (data);

  return TRUE;

fail:
  g_free (stbl_children);
  g_free (mvhd_data);
  g_free (prefix_data);
  g_free (trak_data);
  g_free (data);
  return FALSE;
}
Example #17
0
static GstFlowReturn
gst_rtp_asf_pay_handle_packet (GstRtpAsfPay * rtpasfpay, GstBuffer * buffer)
{
  GstBaseRTPPayload *rtppay;
  GstAsfPacketInfo *packetinfo;
  guint8 flags;
  guint8 *data;
  guint32 packet_util_size;
  guint32 packet_offset;
  guint32 size_left;
  GstFlowReturn ret = GST_FLOW_OK;

  rtppay = GST_BASE_RTP_PAYLOAD (rtpasfpay);
  packetinfo = &rtpasfpay->packetinfo;

  if (!gst_asf_parse_packet (buffer, packetinfo, TRUE,
          rtpasfpay->asfinfo.packet_size)) {
    GST_ERROR_OBJECT (rtpasfpay, "Error while parsing asf packet");
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }

  if (packetinfo->packet_size == 0)
    packetinfo->packet_size = rtpasfpay->asfinfo.packet_size;

  GST_LOG_OBJECT (rtpasfpay, "Packet size: %" G_GUINT32_FORMAT
      ", padding: %" G_GUINT32_FORMAT, packetinfo->packet_size,
      packetinfo->padding);

  /* update padding field to 0 */
  if (packetinfo->padding > 0) {
    GstAsfPacketInfo info;
    /* find padding field offset */
    guint offset = packetinfo->err_cor_len + 2 +
        gst_asf_get_var_size_field_len (packetinfo->packet_field_type) +
        gst_asf_get_var_size_field_len (packetinfo->seq_field_type);
    buffer = gst_buffer_make_writable (buffer);
    switch (packetinfo->padd_field_type) {
      case ASF_FIELD_TYPE_DWORD:
        GST_WRITE_UINT32_LE (&(GST_BUFFER_DATA (buffer)[offset]), 0);
        break;
      case ASF_FIELD_TYPE_WORD:
        GST_WRITE_UINT16_LE (&(GST_BUFFER_DATA (buffer)[offset]), 0);
        break;
      case ASF_FIELD_TYPE_BYTE:
        GST_BUFFER_DATA (buffer)[offset] = 0;
        break;
      case ASF_FIELD_TYPE_NONE:
      default:
        break;
    }
    gst_asf_parse_packet (buffer, &info, FALSE, 0);
  }

  if (packetinfo->padding != 0)
    packet_util_size = rtpasfpay->asfinfo.packet_size - packetinfo->padding;
  else
    packet_util_size = packetinfo->packet_size;
  packet_offset = 0;
  while (packet_util_size > 0) {
    /* Even if we don't fill completely an output buffer we
     * push it when we add an fragment. Because it seems that
     * it is not possible to determine where a asf packet
     * fragment ends inside a rtp packet payload.
     * This flag tells us to push the packet.
     */
    gboolean force_push = FALSE;

    /* we have no output buffer pending, create one */
    if (rtpasfpay->current == NULL) {
      GST_LOG_OBJECT (rtpasfpay, "Creating new output buffer");
      rtpasfpay->current =
          gst_rtp_buffer_new_allocate_len (GST_BASE_RTP_PAYLOAD_MTU (rtpasfpay),
          0, 0);
      rtpasfpay->cur_off = gst_rtp_buffer_get_header_len (rtpasfpay->current);
      rtpasfpay->has_ts = FALSE;
      rtpasfpay->marker = FALSE;
    }
    data = GST_BUFFER_DATA (rtpasfpay->current) + rtpasfpay->cur_off;
    size_left = GST_BUFFER_SIZE (rtpasfpay->current) - rtpasfpay->cur_off;

    GST_DEBUG_OBJECT (rtpasfpay, "Input buffer bytes consumed: %"
        G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT, packet_offset,
        GST_BUFFER_SIZE (buffer));

    GST_DEBUG_OBJECT (rtpasfpay, "Output rtpbuffer status");
    GST_DEBUG_OBJECT (rtpasfpay, "Current offset: %" G_GUINT32_FORMAT,
        rtpasfpay->cur_off);
    GST_DEBUG_OBJECT (rtpasfpay, "Size left: %" G_GUINT32_FORMAT, size_left);
    GST_DEBUG_OBJECT (rtpasfpay, "Has ts: %s",
        rtpasfpay->has_ts ? "yes" : "no");
    if (rtpasfpay->has_ts) {
      GST_DEBUG_OBJECT (rtpasfpay, "Ts: %" G_GUINT32_FORMAT, rtpasfpay->ts);
    }

    flags = 0;
    if (packetinfo->has_keyframe) {
      flags = flags | 0x80;
    }
    flags = flags | 0x20;       /* Relative timestamp is present */

    if (!rtpasfpay->has_ts) {
      /* this is the first asf packet, its send time is the 
       * rtp packet timestamp */
      rtpasfpay->has_ts = TRUE;
      rtpasfpay->ts = packetinfo->send_time;
    }

    if (GST_BUFFER_SIZE (rtpasfpay->current) - rtpasfpay->cur_off >=
        packet_util_size + 8) {
      /* enough space for the rest of the packet */
      if (packet_offset == 0) {
        flags = flags | 0x40;
        GST_WRITE_UINT24_BE (data + 1, packet_util_size);
      } else {
        GST_WRITE_UINT24_BE (data + 1, packet_offset);
        force_push = TRUE;
      }
      data[0] = flags;
      GST_WRITE_UINT32_BE (data + 4,
          (gint32) (packetinfo->send_time) - (gint32) rtpasfpay->ts);
      memcpy (data + 8, GST_BUFFER_DATA (buffer) + packet_offset,
          packet_util_size);

      /* updating status variables */
      rtpasfpay->cur_off += 8 + packet_util_size;
      size_left -= packet_util_size + 8;
      packet_offset += packet_util_size;
      packet_util_size = 0;
      rtpasfpay->marker = TRUE;
    } else {
      /* fragment packet */
      data[0] = flags;
      GST_WRITE_UINT24_BE (data + 1, packet_offset);
      GST_WRITE_UINT32_BE (data + 4,
          (gint32) (packetinfo->send_time) - (gint32) rtpasfpay->ts);
      memcpy (data + 8, GST_BUFFER_DATA (buffer) + packet_offset,
          size_left - 8);

      /* updating status variables */
      rtpasfpay->cur_off += size_left;
      packet_offset += size_left - 8;
      packet_util_size -= size_left - 8;
      size_left = 0;
      force_push = TRUE;
    }

    /* there is not enough room for any more buffers */
    if (force_push || size_left <= 8) {

      if (size_left != 0) {
        /* trim remaining bytes not used */
        GstBuffer *aux = gst_buffer_create_sub (rtpasfpay->current, 0,
            GST_BUFFER_SIZE (rtpasfpay->current) - size_left);
        gst_buffer_unref (rtpasfpay->current);
        rtpasfpay->current = aux;
      }
      gst_rtp_buffer_set_ssrc (rtpasfpay->current, rtppay->current_ssrc);
      gst_rtp_buffer_set_marker (rtpasfpay->current, rtpasfpay->marker);
      gst_rtp_buffer_set_payload_type (rtpasfpay->current,
          GST_BASE_RTP_PAYLOAD_PT (rtppay));
      gst_rtp_buffer_set_seq (rtpasfpay->current, rtppay->seqnum + 1);
      gst_rtp_buffer_set_timestamp (rtpasfpay->current, packetinfo->send_time);

      GST_BUFFER_TIMESTAMP (rtpasfpay->current) = GST_BUFFER_TIMESTAMP (buffer);

      gst_buffer_set_caps (rtpasfpay->current,
          GST_PAD_CAPS (GST_BASE_RTP_PAYLOAD_SRCPAD (rtppay)));

      rtppay->seqnum++;
      rtppay->timestamp = packetinfo->send_time;

      GST_DEBUG_OBJECT (rtpasfpay, "Pushing rtp buffer");
      ret =
          gst_pad_push (GST_BASE_RTP_PAYLOAD_SRCPAD (rtppay),
          rtpasfpay->current);
      rtpasfpay->current = NULL;
      if (ret != GST_FLOW_OK) {
        gst_buffer_unref (buffer);
        return ret;
      }
    }
  }
  gst_buffer_unref (buffer);
  return ret;
}
Example #18
0
static void fill_bmp_header(guint8 *image_data, guint image_width, guint image_height)
{
    guint dib_image_row_size = ((DIB_BITS_PER_PIXEL * image_width + 31) / 32) * 4;
    guint dib_image_size = dib_image_row_size * image_height;
    guint8 *data = image_data;

    *data = 'B';
    data++;
    *data = 'M';
    data++;
    GST_WRITE_UINT32_LE(data, (BMP_HEADER_SIZE + dib_image_size));
    data += 4;
    GST_WRITE_UINT16_LE(data, BMP_RESERVED);
    data += 2;
    GST_WRITE_UINT16_LE(data, BMP_RESERVED);
    data += 2;
    GST_WRITE_UINT32_LE(data, BMP_HEADER_SIZE);
    data += 4;
    GST_WRITE_UINT32_LE(data, DIB_HEADER_SIZE);
    data += 4;
    GST_WRITE_UINT32_LE(data, image_width);
    data += 4;
    GST_WRITE_UINT32_LE(data, image_height);
    data += 4;
    GST_WRITE_UINT16_LE(data, DIB_COLOR_PLANES);
    data += 2;
    GST_WRITE_UINT16_LE(data, DIB_BITS_PER_PIXEL);
    data += 2;
    GST_WRITE_UINT32_LE(data, DIB_COMPRESSION);
    data += 4;
    GST_WRITE_UINT32_LE(data, dib_image_size);
    data += 4;
    GST_WRITE_UINT32_LE(data, DIB_HORIZONTAL_RESOLUTION);
    data += 4;
    GST_WRITE_UINT32_LE(data, DIB_VERTICAL_RESOLUTION);
    data += 4;
    GST_WRITE_UINT32_LE(data, DIB_COLORS_IN_PALETTE);
    data += 4;
    GST_WRITE_UINT32_LE(data, DIB_IMPORTANT_COLORS);
    data += 4;
}
static gboolean
gst_rtp_celt_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  GstStructure *structure;
  GstRtpCELTDepay *rtpceltdepay;
  gint clock_rate, nb_channels = 0, frame_size = 0;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *ptr;
  const gchar *params;
  GstCaps *srccaps;
  gboolean res;

  rtpceltdepay = GST_RTP_CELT_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    goto no_clockrate;
  depayload->clock_rate = clock_rate;

  if ((params = gst_structure_get_string (structure, "encoding-params")))
    nb_channels = atoi (params);
  if (!nb_channels)
    nb_channels = DEFAULT_CHANNELS;

  if ((params = gst_structure_get_string (structure, "frame-size")))
    frame_size = atoi (params);
  if (!frame_size)
    frame_size = DEFAULT_FRAMESIZE;
  rtpceltdepay->frame_size = frame_size;

  GST_DEBUG_OBJECT (depayload, "clock-rate=%d channels=%d frame-size=%d",
      clock_rate, nb_channels, frame_size);

  /* construct minimal header and comment packet for the decoder */
  buf = gst_buffer_new_and_alloc (60);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  ptr = map.data;
  memcpy (ptr, "CELT    ", 8);
  ptr += 8;
  memcpy (ptr, "1.1.12", 7);
  ptr += 20;
  GST_WRITE_UINT32_LE (ptr, 0x80000006);        /* version */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, 56);        /* header_size */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, clock_rate);        /* rate */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, nb_channels);       /* channels */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, frame_size);        /* frame-size */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, -1);        /* overlap */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, -1);        /* bytes_per_packet */
  ptr += 4;
  GST_WRITE_UINT32_LE (ptr, 0); /* extra headers */
  gst_buffer_unmap (buf, &map);

  srccaps = gst_caps_new_empty_simple ("audio/x-celt");
  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpceltdepay), buf);

  buf = gst_buffer_new_and_alloc (sizeof (gst_rtp_celt_comment));
  gst_buffer_fill (buf, 0, gst_rtp_celt_comment, sizeof (gst_rtp_celt_comment));

  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpceltdepay), buf);

  return res;

  /* ERRORS */
no_clockrate:
  {
    GST_ERROR_OBJECT (depayload, "no clock-rate specified");
    return FALSE;
  }
}
Example #20
0
static gboolean
gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
{
  GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
  GstStructure *s = gst_caps_get_structure (caps, 0);
  gint version, res, width, height, format, subformat;
  gint framerate_num, framerate_denom;
  gchar data[36];
  gboolean bres;
  const GValue *v;

  if (!gst_structure_get_int (s, "rmversion", &version) ||
      !gst_structure_get_int (s, "width", (gint *) & width) ||
      !gst_structure_get_int (s, "height", (gint *) & height) ||
      !gst_structure_get_int (s, "format", &format) ||
      !gst_structure_get_int (s, "subformat", &subformat) ||
      !gst_structure_get_fraction (s, "framerate", &framerate_num,
          &framerate_denom))
    goto missing_keys;

  GST_LOG_OBJECT (dec, "Setting version to %d", version);

  close_library (dec, &dec->lib);

  if (!open_library (dec, version, &dec->lib))
    goto open_failed;

  /* Initialize REAL driver. */
  GST_WRITE_UINT16_LE (data + 0, 11);
  GST_WRITE_UINT16_LE (data + 2, width);
  GST_WRITE_UINT16_LE (data + 4, height);
  GST_WRITE_UINT16_LE (data + 6, 0);
  GST_WRITE_UINT32_LE (data + 8, 0);
  GST_WRITE_UINT32_LE (data + 12, subformat);
  GST_WRITE_UINT32_LE (data + 16, 1);
  GST_WRITE_UINT32_LE (data + 20, format);

  if ((res = dec->lib.Init (&data, &dec->lib.context)))
    goto could_not_initialize;

  if ((v = gst_structure_get_value (s, "codec_data"))) {
    GstBuffer *buf;
    guint32 *msgdata;
    guint i;
    guint8 *bufdata;
    guint bufsize;
    struct
    {
      guint32 type;
      guint32 msg;
      gpointer data;
      guint32 extra[6];
    } msg;

    buf = g_value_peek_pointer (v);

    bufdata = GST_BUFFER_DATA (buf);
    bufsize = GST_BUFFER_SIZE (buf);

    /* skip format and subformat */
    bufdata += 8;
    bufsize -= 8;

    GST_LOG_OBJECT (dec, "Creating custom message of length %d", bufsize);

    msgdata = g_new0 (guint32, bufsize + 2);
    if (!msgdata)
      goto could_not_allocate;

    msg.type = 0x24;
    msg.msg = 1 + ((subformat >> 16) & 7);
    msg.data = msgdata;
    for (i = 0; i < 6; i++)
      msg.extra[i] = 0;
    msgdata[0] = width;
    msgdata[1] = height;
    for (i = 0; i < bufsize; i++)
      msgdata[i + 2] = 4 * (guint32) bufdata[i];

    res = dec->lib.Message (&msg, dec->lib.context);

    g_free (msgdata);
    if (res)
      goto could_not_send_message;
  }
Example #21
0
static gboolean
gst_rtp_speex_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  GstStructure *structure;
  GstRtpSPEEXDepay *rtpspeexdepay;
  gint clock_rate, nb_channels;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data;
  const gchar *params;
  GstCaps *srccaps;
  gboolean res;

  rtpspeexdepay = GST_RTP_SPEEX_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    goto no_clockrate;
  depayload->clock_rate = clock_rate;

  if (!(params = gst_structure_get_string (structure, "encoding-params")))
    nb_channels = 1;
  else {
    nb_channels = atoi (params);
  }

  /* construct minimal header and comment packet for the decoder */
  buf = gst_buffer_new_and_alloc (80);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;
  memcpy (data, "Speex   ", 8);
  data += 8;
  memcpy (data, "1.1.12", 7);
  data += 20;
  GST_WRITE_UINT32_LE (data, 1);        /* version */
  data += 4;
  GST_WRITE_UINT32_LE (data, 80);       /* header_size */
  data += 4;
  GST_WRITE_UINT32_LE (data, clock_rate);       /* rate */
  data += 4;
  GST_WRITE_UINT32_LE (data, gst_rtp_speex_depay_get_mode (clock_rate));        /* mode */
  data += 4;
  GST_WRITE_UINT32_LE (data, 4);        /* mode_bitstream_version */
  data += 4;
  GST_WRITE_UINT32_LE (data, nb_channels);      /* nb_channels */
  data += 4;
  GST_WRITE_UINT32_LE (data, -1);       /* bitrate */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0xa0);     /* frame_size */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* VBR */
  data += 4;
  GST_WRITE_UINT32_LE (data, 1);        /* frames_per_packet */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* extra_headers */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* reserved1 */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* reserved2 */
  gst_buffer_unmap (buf, &map);

  srccaps = gst_caps_new_empty_simple ("audio/x-speex");
  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpspeexdepay), buf);

  buf = gst_buffer_new_and_alloc (sizeof (gst_rtp_speex_comment));
  gst_buffer_fill (buf, 0, gst_rtp_speex_comment,
      sizeof (gst_rtp_speex_comment));

  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpspeexdepay), buf);

  return res;

  /* ERRORS */
no_clockrate:
  {
    GST_DEBUG_OBJECT (depayload, "no clock-rate specified");
    return FALSE;
  }
}
Example #22
0
static GstFlowReturn
gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf)
{
    GstFlowReturn ret = GST_FLOW_OK;
    jas_stream_t *stream = NULL;
    gint i;
    guint size, boxsize;

    g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);

    *outbuf = NULL;

    boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0;

    if (!(stream = jas_stream_memopen (NULL, 0)))
        goto fail_stream;

    for (i = 0; i < enc->channels; ++i) {
        gint x, y, cwidth, cheight, inc, stride, cmpt;
        guint8 *row_pix, *in_pix;
        glong *tb;

        cmpt = i;
        inc = enc->inc[i];
        stride = enc->stride[i];
        cheight = enc->cheight[cmpt];
        cwidth = enc->cwidth[cmpt];

        GST_LOG_OBJECT (enc,
                        "write component %d<=%d, size %dx%d, offset %d, inc %d, stride %d",
                        i, cmpt, cwidth, cheight, enc->offset[i], inc, stride);

        row_pix = data + enc->offset[i];

        for (y = 0; y < cheight; y++) {
            in_pix = row_pix;
            tb = enc->buf;
            for (x = 0; x < cwidth; x++) {
                *tb = *in_pix;
                in_pix += inc;
                tb++;
            }
            if (jas_image_writecmpt2 (enc->image, cmpt, 0, y, cwidth, 1, enc->buf))
                goto fail_image;
            row_pix += stride;
        }
    }

    GST_LOG_OBJECT (enc, "all components written");

    if (jas_image_encode (enc->image, stream, enc->fmt, (char *) "sop"))
        goto fail_encode;

    GST_LOG_OBJECT (enc, "image encoded");

    size = jas_stream_length (stream);
    ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
            GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad),
            outbuf);

    if (ret != GST_FLOW_OK)
        goto no_buffer;

    data = GST_BUFFER_DATA (*outbuf);
    if (jas_stream_flush (stream) ||
            jas_stream_rewind (stream) < 0 ||
            jas_stream_read (stream, data + boxsize, size) < size)
        goto fail_image_out;

    if (boxsize) {
        /* write atom prefix */
        GST_WRITE_UINT32_BE (data, size + 8);
        GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c'));
    }

done:
    if (stream)
        jas_stream_close (stream);

    return ret;

    /* ERRORS */
fail_stream:
    {
        GST_DEBUG_OBJECT (enc, "Failed to create inputstream.");
        goto fail;
    }
fail_encode:
    {
        GST_DEBUG_OBJECT (enc, "Failed to encode image.");
        goto fail;
    }
fail_image:
    {
        GST_DEBUG_OBJECT (enc, "Failed to process input image.");
        goto fail;
    }
fail_image_out:
    {
        GST_DEBUG_OBJECT (enc, "Failed to process encoded image.");
        goto fail;
    }
fail:
    {
        if (*outbuf)
            gst_buffer_unref (*outbuf);
        *outbuf = NULL;
        GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), (NULL));
        ret = GST_FLOW_ERROR;
        goto done;
    }
no_buffer:
    {
        GST_DEBUG_OBJECT (enc, "Failed to create outbuffer - %s",
                          gst_flow_get_name (ret));
        goto done;
    }
}
Example #23
0
static gboolean
gst_rtp_celt_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
{
  GstStructure *structure;
  GstRtpCELTDepay *rtpceltdepay;
  gint clock_rate, nb_channels, frame_size;
  GstBuffer *buf;
  guint8 *data;
  const gchar *params;
  GstCaps *srccaps;
  gboolean res;

  rtpceltdepay = GST_RTP_CELT_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    goto no_clockrate;
  depayload->clock_rate = clock_rate;

  if (!(params = gst_structure_get_string (structure, "encoding-params")))
    nb_channels = 1;
  else {
    nb_channels = atoi (params);
  }

  if (!(params = gst_structure_get_string (structure, "frame-size")))
    frame_size = 480;
  else {
    frame_size = atoi (params);
  }

  /* construct minimal header and comment packet for the decoder */
  buf = gst_buffer_new_and_alloc (60);
  data = GST_BUFFER_DATA (buf);
  memcpy (data, "CELT    ", 8);
  data += 8;
  memcpy (data, "1.1.12", 7);
  data += 20;
  GST_WRITE_UINT32_LE (data, 0x80000006);       /* version */
  data += 4;
  GST_WRITE_UINT32_LE (data, 56);       /* header_size */
  data += 4;
  GST_WRITE_UINT32_LE (data, clock_rate);       /* rate */
  data += 4;
  GST_WRITE_UINT32_LE (data, nb_channels);      /* channels */
  data += 4;
  GST_WRITE_UINT32_LE (data, frame_size);       /* frame-size */
  data += 4;
  GST_WRITE_UINT32_LE (data, -1);       /* overlap */
  data += 4;
  GST_WRITE_UINT32_LE (data, -1);       /* bytes_per_packet */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* extra headers */

  srccaps = gst_caps_new_simple ("audio/x-celt", NULL);
  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

  gst_buffer_set_caps (buf, GST_PAD_CAPS (depayload->srcpad));
  gst_base_rtp_depayload_push (GST_BASE_RTP_DEPAYLOAD (rtpceltdepay), buf);

  buf = gst_buffer_new_and_alloc (sizeof (gst_rtp_celt_comment));
  memcpy (GST_BUFFER_DATA (buf), gst_rtp_celt_comment,
      sizeof (gst_rtp_celt_comment));

  gst_buffer_set_caps (buf, GST_PAD_CAPS (depayload->srcpad));
  gst_base_rtp_depayload_push (GST_BASE_RTP_DEPAYLOAD (rtpceltdepay), buf);

  return res;

  /* ERRORS */
no_clockrate:
  {
    GST_DEBUG_OBJECT (depayload, "no clock-rate specified");
    return FALSE;
  }
}