static GstBuffer *
gst_opus_enc_create_id_buffer (gint nchannels, gint n_stereo_streams,
    gint sample_rate, guint8 channel_mapping_family,
    const guint8 * channel_mapping)
{
  GstBuffer *buffer;
  GstByteWriter bw;
  gboolean hdl = TRUE;

  g_return_val_if_fail (nchannels > 0 && nchannels < 256, NULL);
  g_return_val_if_fail (n_stereo_streams >= 0, NULL);
  g_return_val_if_fail (n_stereo_streams <= nchannels - n_stereo_streams, NULL);

  gst_byte_writer_init (&bw);

  /* See http://wiki.xiph.org/OggOpus */
  hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
  hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
  hdl &= gst_byte_writer_put_uint8 (&bw, nchannels);
  hdl &= gst_byte_writer_put_uint16_le (&bw, 0);        /* pre-skip */
  hdl &= gst_byte_writer_put_uint32_le (&bw, sample_rate);
  hdl &= gst_byte_writer_put_uint16_le (&bw, 0);        /* output gain */
  hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
  if (channel_mapping_family > 0) {
    hdl &= gst_byte_writer_put_uint8 (&bw, nchannels - n_stereo_streams);
    hdl &= gst_byte_writer_put_uint8 (&bw, n_stereo_streams);
    hdl &= gst_byte_writer_put_data (&bw, channel_mapping, nchannels);
  }

  if (!hdl)
    GST_WARNING ("Error creating header");

  buffer = gst_byte_writer_reset_and_get_buffer (&bw);

  GST_BUFFER_OFFSET (buffer) = 0;
  GST_BUFFER_OFFSET_END (buffer) = 0;

  return buffer;
}
Example #2
0
static GstFlowReturn
gst_jif_mux_recombine_image (GstJifMux * self, GstBuffer ** new_buf,
                             GstBuffer * old_buf)
{
    GstBuffer *buf;
    GstByteWriter *writer;
    GstFlowReturn fret;
    GstJifMuxMarker *m;
    GList *node;
    guint size = self->priv->scan_size;
    gboolean writer_status = TRUE;

    /* iterate list and collect size */
    for (node = self->priv->markers; node; node = g_list_next (node)) {
        m = (GstJifMuxMarker *) node->data;

        /* some markers like e.g. SOI are empty */
        if (m->size) {
            size += 2 + m->size;
        }
        /* 0xff <marker> */
        size += 2;
    }
    GST_INFO_OBJECT (self, "old size: %u, new size: %u",
                     GST_BUFFER_SIZE (old_buf), size);

    /* allocate new buffer */
    fret = gst_pad_alloc_buffer_and_set_caps (self->priv->srcpad,
            GST_BUFFER_OFFSET (old_buf), size, GST_PAD_CAPS (self->priv->srcpad),
            &buf);
    if (fret != GST_FLOW_OK)
        goto no_buffer;

    /* copy buffer metadata */
    gst_buffer_copy_metadata (buf, old_buf,
                              GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);

    /* memcopy markers */
    writer = gst_byte_writer_new_with_buffer (buf, TRUE);
    for (node = self->priv->markers; node && writer_status;
            node = g_list_next (node)) {
        m = (GstJifMuxMarker *) node->data;

        writer_status &= gst_byte_writer_put_uint8 (writer, 0xff);
        writer_status &= gst_byte_writer_put_uint8 (writer, m->marker);

        GST_DEBUG_OBJECT (self, "marker = %2x, size = %u", m->marker, m->size + 2);

        if (m->size) {
            writer_status &= gst_byte_writer_put_uint16_be (writer, m->size + 2);
            writer_status &= gst_byte_writer_put_data (writer, m->data, m->size);
        }

        if (m->marker == SOS) {
            GST_DEBUG_OBJECT (self, "scan data, size = %u", self->priv->scan_size);
            writer_status &=
                gst_byte_writer_put_data (writer, self->priv->scan_data,
                                          self->priv->scan_size);
        }
    }
    gst_byte_writer_free (writer);

    if (!writer_status) {
        GST_WARNING_OBJECT (self, "Failed to write to buffer, calculated size "
                            "was probably too short");
        g_assert_not_reached ();
    }

    *new_buf = buf;
    return GST_FLOW_OK;

no_buffer:
    GST_WARNING_OBJECT (self, "failed to allocate output buffer, flow_ret = %s",
                        gst_flow_get_name (fret));
    return fret;
}
static gboolean
flx_decode_delta_flc (GstFlxDec * flxdec, GstByteReader * reader,
    GstByteWriter * writer)
{
  guint16 lines, start_l;

  g_return_val_if_fail (flxdec != NULL, FALSE);
  g_return_val_if_fail (flxdec->delta_data != NULL, FALSE);

  /* use last frame for delta */
  if (!gst_byte_writer_put_data (writer, flxdec->delta_data, flxdec->size))
    goto error;
  if (!gst_byte_reader_get_uint16_le (reader, &lines))
    goto error;

  if (lines > flxdec->hdr.height) {
    GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. too many lines.");
    return FALSE;
  }

  start_l = lines;

  while (lines) {
    guint16 opcode;

    if (!gst_byte_writer_set_pos (writer,
            flxdec->hdr.width * (start_l - lines)))
      goto error;

    /* process opcode(s) */
    while (TRUE) {
      if (!gst_byte_reader_get_uint16_le (reader, &opcode))
        goto error;
      if ((opcode & 0xc000) == 0)
        break;

      if ((opcode & 0xc000) == 0xc000) {
        /* line skip count */
        gulong skip = (0x10000 - opcode);
        if (skip > flxdec->hdr.height) {
          GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
              "skip line count too big.");
          return FALSE;
        }
        start_l += skip;
        if (!gst_byte_writer_set_pos (writer,
                gst_byte_writer_get_pos (writer) + flxdec->hdr.width * skip))
          goto error;
      } else {
        /* last pixel */
        if (!gst_byte_writer_set_pos (writer,
                gst_byte_writer_get_pos (writer) + flxdec->hdr.width))
          goto error;
        if (!gst_byte_writer_put_uint8 (writer, opcode & 0xff))
          goto error;
      }
    }

    /* last opcode is the packet count */
    GST_LOG_OBJECT (flxdec, "have %d packets", opcode);
    while (opcode--) {
      /* skip count */
      guint8 skip;
      gint8 count;

      if (!gst_byte_reader_get_uint8 (reader, &skip))
        goto error;
      if (!gst_byte_writer_set_pos (writer,
              gst_byte_writer_get_pos (writer) + skip))
        goto error;

      /* RLE count */
      if (!gst_byte_reader_get_int8 (reader, &count))
        goto error;

      if (count < 0) {
        guint16 x;

        /* replicate word run */
        count = ABS (count);

        GST_LOG_OBJECT (flxdec, "have replicate run of size %d at offset %d",
            count, skip);

        if (skip + count > flxdec->hdr.width) {
          GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
              "line too long.");
          return FALSE;
        }

        if (!gst_byte_reader_get_uint16_le (reader, &x))
          goto error;

        while (count--) {
          if (!gst_byte_writer_put_uint16_le (writer, x)) {
            goto error;
          }
        }
      } else {
        GST_LOG_OBJECT (flxdec, "have literal run of size %d at offset %d",
            count, skip);

        if (skip + count > flxdec->hdr.width) {
          GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
              "line too long.");
          return FALSE;
        }

        while (count--) {
          guint16 x;

          if (!gst_byte_reader_get_uint16_le (reader, &x))
            goto error;
          if (!gst_byte_writer_put_uint16_le (writer, x))
            goto error;
        }
      }
    }
    lines--;
  }

  return TRUE;

error:
  GST_ERROR_OBJECT (flxdec, "Failed to decode FLI packet");
  return FALSE;
}