コード例 #1
0
ファイル: gstadapter.c プロジェクト: spunktsch/svtplayer
/**
 * gst_adapter_take_buffer:
 * @adapter: a #GstAdapter
 * @nbytes: the number of bytes to take
 *
 * Returns a #GstBuffer containing the first @nbytes bytes of the
 * @adapter. The returned bytes will be flushed from the adapter.
 * This function is potentially more performant than gst_adapter_take()
 * since it can reuse the memory in pushed buffers by subbuffering
 * or merging.
 *
 * Caller owns returned value. gst_buffer_unref() after usage.
 *
 * Since: 0.10.6
 *
 * Returns: a #GstBuffer containing the first @nbytes of the adapter,
 * or #NULL if @nbytes bytes are not available
 */
GstBuffer *
gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
{
    GstBuffer *buffer;
    GstBuffer *cur;
    guint hsize, skip;
    guint8 *data;

    g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
    g_return_val_if_fail (nbytes > 0, NULL);

    GST_LOG_OBJECT (adapter, "taking buffer of %u bytes", nbytes);

    /* we don't have enough data, return NULL. This is unlikely
     * as one usually does an _available() first instead of grabbing a
     * random size. */
    if (G_UNLIKELY (nbytes > adapter->size))
        return NULL;

    cur = adapter->buflist->data;
    skip = adapter->skip;
    hsize = GST_BUFFER_SIZE (cur);

    /* our head buffer has enough data left, return it */
    if (skip == 0 && hsize == nbytes) {
        GST_LOG_OBJECT (adapter, "providing buffer of %d bytes as head buffer",
                        nbytes);
        buffer = gst_buffer_ref (cur);
        goto done;
    } else if (hsize >= nbytes + skip) {
        GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
                        nbytes);
        buffer = gst_buffer_create_sub (cur, skip, nbytes);
        goto done;
    }

    if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
        /* Merged something, let's try again for sub-buffering */
        cur = adapter->buflist->data;
        if (GST_BUFFER_SIZE (cur) >= nbytes + skip) {
            GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
                            nbytes);
            buffer = gst_buffer_create_sub (cur, skip, nbytes);
            goto done;
        }
    }

    data = gst_adapter_take_internal (adapter, nbytes);

    buffer = gst_buffer_new ();
    GST_BUFFER_SIZE (buffer) = nbytes;
    GST_BUFFER_DATA (buffer) = data;
    GST_BUFFER_MALLOCDATA (buffer) = data;

done:
    gst_adapter_flush_unchecked (adapter, nbytes);

    return buffer;
}
コード例 #2
0
static void
gst_deinterlace2_push_history (GstDeinterlace2 * self, GstBuffer * buffer)
{
  int i = 1;
  GstClockTime timestamp;

  g_assert (self->history_count < MAX_FIELD_HISTORY - 2);

  for (i = MAX_FIELD_HISTORY - 1; i >= 2; i--) {
    self->field_history[i].buf = self->field_history[i - 2].buf;
    self->field_history[i].flags = self->field_history[i - 2].flags;
  }

  if (self->field_layout == GST_DEINTERLACE2_LAYOUT_AUTO) {
    GST_WARNING ("Could not detect field layout. Assuming top field first.");
    self->field_layout = GST_DEINTERLACE2_LAYOUT_TFF;
  }


  if (self->field_layout == GST_DEINTERLACE2_LAYOUT_TFF) {
    GST_DEBUG ("Top field first");
    self->field_history[0].buf =
        gst_buffer_create_sub (buffer, self->line_length,
        GST_BUFFER_SIZE (buffer) - self->line_length);
    self->field_history[0].flags = PICTURE_INTERLACED_BOTTOM;
    self->field_history[1].buf = buffer;
    self->field_history[1].flags = PICTURE_INTERLACED_TOP;
  } else {
    GST_DEBUG ("Bottom field first");
    self->field_history[0].buf = buffer;
    self->field_history[0].flags = PICTURE_INTERLACED_TOP;
    self->field_history[1].buf =
        gst_buffer_create_sub (buffer, self->line_length,
        GST_BUFFER_SIZE (buffer) - self->line_length);
    self->field_history[1].flags = PICTURE_INTERLACED_BOTTOM;
  }

  /* Timestamps are assigned to the field buffers under the assumption that
     the timestamp of the buffer equals the first fields timestamp */

  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  GST_BUFFER_TIMESTAMP (self->field_history[0].buf) =
      timestamp + self->field_duration;
  GST_BUFFER_TIMESTAMP (self->field_history[1].buf) = timestamp;

  self->history_count += 2;
  GST_DEBUG ("push, size(history): %d", self->history_count);
}
コード例 #3
0
EXPORT_C
#endif

GstBuffer *
gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
    guint len)
{
  guint poffset, plen;

  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
  g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);

  plen = gst_rtp_buffer_get_payload_len (buffer);
  /* we can't go past the length */
  if (G_UNLIKELY (offset >= plen)) {
    GST_WARNING ("offset=%u should be less then plen=%u", offset, plen);
    return (NULL);
  }

  /* apply offset */
  poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
  plen -= offset;

  /* see if we need to shrink the buffer based on @len */
  if (len != -1 && len < plen)
    plen = len;

  return gst_buffer_create_sub (buffer, poffset, plen);
}
コード例 #4
0
ファイル: audiotrim.c プロジェクト: fluffware/subrec
static GstBuffer *
buffer_slice(AudioTrim *filter, GstBuffer *buf, gint64 start, gint64 end)
{
  GstBuffer *sub;
  gint byte_start;
  gint byte_size;
  g_assert(start <= end);
  /* Check if buffer is outside range */
  if (start >= GST_BUFFER_OFFSET_END(buf)
      || end <= GST_BUFFER_OFFSET(buf)
      || start == end) {
    return NULL;
  }
  /* Return original buffer if possible */
  if (start <= GST_BUFFER_OFFSET(buf) && end >= GST_BUFFER_OFFSET_END(buf)) {
    return gst_buffer_ref(buf);
  }
  if (start < GST_BUFFER_OFFSET(buf)) start = GST_BUFFER_OFFSET(buf);
  if (end > GST_BUFFER_OFFSET_END(buf)) end = GST_BUFFER_OFFSET_END(buf);
  byte_start = (start -  GST_BUFFER_OFFSET(buf)) * sizeof(gfloat);
  g_assert(byte_start < GST_BUFFER_SIZE(buf));
  byte_size = (end - start) * sizeof(gfloat);
  sub = gst_buffer_create_sub(buf, byte_start, byte_size);
  copy_caps(buf, sub);
  GST_BUFFER_TIMESTAMP(sub) = sample_to_time(filter, start);
  GST_BUFFER_OFFSET(sub) = start;
  GST_BUFFER_DURATION(sub) = sample_to_time(filter, end-start);
  GST_BUFFER_OFFSET_END(sub) = end;
  return sub;
}
コード例 #5
0
ファイル: gsttimidity.c プロジェクト: jonasl/gst-svtplayer
static GstBuffer *
gst_timidity_clip_buffer (GstTimidity * timidity, GstBuffer * buffer)
{
  gint64 new_start, new_stop;
  gint64 offset, length;
  GstBuffer *out;

  return buffer;

  if (!gst_segment_clip (timidity->o_segment, GST_FORMAT_DEFAULT,
          GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET_END (buffer),
          &new_start, &new_stop)) {
    gst_buffer_unref (buffer);
    return NULL;
  }

  if (GST_BUFFER_OFFSET (buffer) == new_start &&
      GST_BUFFER_OFFSET_END (buffer) == new_stop)
    return buffer;

  offset = new_start - GST_BUFFER_OFFSET (buffer);
  length = new_stop - new_start;

  out = gst_buffer_create_sub (buffer, offset * timidity->bytes_per_frame,
      length * timidity->bytes_per_frame);

  GST_BUFFER_OFFSET (out) = new_start;
  GST_BUFFER_OFFSET_END (out) = new_stop;
  GST_BUFFER_TIMESTAMP (out) = new_start * timidity->time_per_frame;
  GST_BUFFER_DURATION (out) = (new_stop - new_start) * timidity->time_per_frame;

  gst_buffer_unref (buffer);

  return out;
}
コード例 #6
0
ファイル: gstrtpbuffer.c プロジェクト: zsx/ossbuild
/**
 * gst_rtp_buffer_get_payload_subbuffer:
 * @buffer: the buffer
 * @offset: the offset in the payload
 * @len: the length in the payload
 *
 * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
 * are skipped in the payload and the subbuffer will be of size @len.
 * If @len is -1 the total payload starting from @offset if subbuffered.
 *
 * Returns: A new buffer with the specified data of the payload.
 *
 * Since: 0.10.10
 */
GstBuffer *
gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
    guint len)
{
  guint poffset, plen;

  plen = gst_rtp_buffer_get_payload_len (buffer);
  /* we can't go past the length */
  if (G_UNLIKELY (offset >= plen))
    goto wrong_offset;

  /* apply offset */
  poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
  plen -= offset;

  /* see if we need to shrink the buffer based on @len */
  if (len != -1 && len < plen)
    plen = len;

  return gst_buffer_create_sub (buffer, poffset, plen);

  /* ERRORS */
wrong_offset:
  {
    g_warning ("offset=%u should be less then plen=%u", offset, plen);
    return NULL;
  }
}
コード例 #7
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static GstBuffer *
gst_vdp_mpeg_packetizer_get_next_packet (GstVdpMpegPacketizer * packetizer)
{
    guint offset, size;
    GstBuffer *buf;

    if (packetizer->start == -1)
        return NULL;

    if (!gst_byte_reader_set_pos (&packetizer->reader, packetizer->start + 3))
        return NULL;

    offset = gst_byte_reader_masked_scan_uint32 (&packetizer->reader, 0xffffff00,
             0x00000100, 0, gst_byte_reader_get_remaining (&packetizer->reader));

    if (offset != -1) {
        offset = gst_byte_reader_get_pos (&packetizer->reader) + offset;
        size = offset - packetizer->start;
    } else
        size = gst_byte_reader_get_remaining (&packetizer->reader) + 3;

    buf = gst_buffer_create_sub (packetizer->buffer, packetizer->start, size);

    packetizer->start = offset;

    return buf;
}
コード例 #8
0
static void
dxr3videosink_discard_data (Dxr3VideoSink * sink, guint cut)
{
  GstBuffer *sub;
  guint size;

  g_return_if_fail (sink->cur_buf != NULL);
  g_assert (cut <= sink->scan_pos);

  size = sink->scan_pos - cut;

  g_return_if_fail (size <= GST_BUFFER_SIZE (sink->cur_buf));

  if (GST_BUFFER_SIZE (sink->cur_buf) == size) {
    gst_buffer_unref (sink->cur_buf);
    sink->cur_buf = NULL;
  } else {
    sub = gst_buffer_create_sub (sink->cur_buf, size,
        GST_BUFFER_SIZE (sink->cur_buf)
        - size);
    gst_buffer_unref (sink->cur_buf);
    sink->cur_buf = sub;
  }

  sink->scan_state = SCAN_STATE_WAITING;
  sink->scan_pos = cut;

  sink->cur_ts = GST_CLOCK_TIME_NONE;
}
コード例 #9
0
ファイル: gstbuffer.c プロジェクト: wosigh/gstreamer
/**
 * gst_buffer_span:
 * @buf1: the first source #GstBuffer to merge.
 * @offset: the offset in the first buffer from where the new
 * buffer should start.
 * @buf2: the second source #GstBuffer to merge.
 * @len: the total length of the new buffer.
 *
 * Creates a new buffer that consists of part of buf1 and buf2.
 * Logically, buf1 and buf2 are concatenated into a single larger
 * buffer, and a new buffer is created at the given offset inside
 * this space, with a given length.
 *
 * If the two source buffers are children of the same larger buffer,
 * and are contiguous, the new buffer will be a child of the shared
 * parent, and thus no copying is necessary. you can use
 * gst_buffer_is_span_fast() to determine if a memcpy will be needed.
 *
 * MT safe.
 * Returns: the new #GstBuffer that spans the two source buffers.
 * Returns NULL if the arguments are invalid.
 */
GstBuffer *
gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
    guint32 len)
{
  GstBuffer *newbuf;

  g_return_val_if_fail (buf1 != NULL && buf2 != NULL, NULL);
  g_return_val_if_fail (buf1->mini_object.refcount > 0, NULL);
  g_return_val_if_fail (buf2->mini_object.refcount > 0, NULL);
  g_return_val_if_fail (len > 0, NULL);
  g_return_val_if_fail (len <= buf1->size + buf2->size - offset, NULL);

  /* if the two buffers have the same parent and are adjacent */
  if (gst_buffer_is_span_fast (buf1, buf2)) {
    GstBuffer *parent = GST_SUBBUFFER_CAST (buf1)->parent;

    /* we simply create a subbuffer of the common parent */
    newbuf = gst_buffer_create_sub (parent,
        buf1->data - parent->data + offset, len);
  } else {
    GST_CAT_DEBUG (GST_CAT_BUFFER,
        "slow path taken while spanning buffers %p and %p", buf1, buf2);
    /* otherwise we simply have to brute-force copy the buffers */
    newbuf = gst_buffer_new_and_alloc (len);

    /* copy the first buffer's data across */
    memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
    /* copy the second buffer's data across */
    memcpy (newbuf->data + (buf1->size - offset), buf2->data,
        len - (buf1->size - offset));
  }
  /* if the offset is 0, the new buffer has the same timestamp as buf1 */
  if (offset == 0) {
    GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
    GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buf1);

    /* if we completely merged the two buffers (appended), we can
     * calculate the duration too. Also make sure we's not messing with
     * invalid DURATIONS */
    if (buf1->size + buf2->size == len) {
      if (GST_BUFFER_DURATION_IS_VALID (buf1) &&
          GST_BUFFER_DURATION_IS_VALID (buf2)) {
        /* add duration */
        GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
            GST_BUFFER_DURATION (buf2);
      }
      if (GST_BUFFER_OFFSET_END_IS_VALID (buf2)) {
        /* add offset_end */
        GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_END (buf2);
      }
    }
  }

  return newbuf;
}
コード例 #10
0
ファイル: gstdtsdec.c プロジェクト: prajnashi/gst-plugins-bad
static GstFlowReturn
gst_dtsdec_chain_raw (GstPad * pad, GstBuffer * buf)
{
  GstDtsDec *dts;
  guint8 *data;
  gint size;
  gint length, flags, sample_rate, bit_rate, frame_length;
  GstFlowReturn result = GST_FLOW_OK;

  dts = GST_DTSDEC (GST_PAD_PARENT (pad));

  if (dts->cache) {
    buf = gst_buffer_join (dts->cache, buf);
    dts->cache = NULL;
  }

  data = GST_BUFFER_DATA (buf);
  size = GST_BUFFER_SIZE (buf);
  length = 0;
  while (size >= 7) {
    length = dts_syncinfo (dts->state, data, &flags,
        &sample_rate, &bit_rate, &frame_length);
    if (length == 0) {
      /* shift window to re-find sync */
      data++;
      size--;
    } else if (length <= size) {
      GST_DEBUG ("Sync: frame size %d", length);
      result = gst_dtsdec_handle_frame (dts, data, length,
          flags, sample_rate, bit_rate);
      if (result != GST_FLOW_OK) {
        size = 0;
        break;
      }
      size -= length;
      data += length;
    } else {
      GST_LOG ("Not enough data available (needed %d had %d)", length, size);
      break;
    }
  }

  /* keep cache */
  if (length == 0) {
    GST_LOG ("No sync found");
  }
  if (size > 0) {
    dts->cache = gst_buffer_create_sub (buf,
        GST_BUFFER_SIZE (buf) - size, size);
  }

  gst_buffer_unref (buf);

  return result;
}
コード例 #11
0
/* Output buffer preparation... if the buffer has no caps, and
 * our allowed output caps is fixed, then give the caps to the
 * buffer.
 * This ensures that outgoing buffers have caps if we can, so
 * that pipelines like:
 *   gst-launch filesrc location=rawsamples.raw !
 *       audio/x-raw-int,width=16,depth=16,rate=48000,channels=2,
 *       endianness=4321,signed='(boolean)'true ! alsasink
 * will work.
 */
static GstFlowReturn
gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
    gint size, GstCaps * caps, GstBuffer ** buf)
{
  if (GST_BUFFER_CAPS (input) != NULL) {
    /* Output buffer already has caps */
    GST_DEBUG_OBJECT (trans,
        "Input buffer already has caps (implicitely fixed)");
    /* FIXME : Move this behaviour to basetransform. The given caps are the ones
     * of the source pad, therefore our outgoing buffers should always have
     * those caps. */
    gst_buffer_set_caps (input, caps);
    gst_buffer_ref (input);
    *buf = input;
  } else {
    /* Buffer has no caps. See if the output pad only supports fixed caps */
    GstCaps *out_caps;

    out_caps = GST_PAD_CAPS (trans->srcpad);

    if (out_caps != NULL) {
      gst_caps_ref (out_caps);
    } else {
      out_caps = gst_pad_get_allowed_caps (trans->srcpad);
      g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
    }

    out_caps = gst_caps_make_writable (out_caps);
    gst_caps_do_simplify (out_caps);

    if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
      GST_DEBUG_OBJECT (trans, "Have fixed output caps %"
          GST_PTR_FORMAT " to apply to buffer with no caps", out_caps);
      if (gst_buffer_is_metadata_writable (input)) {
        gst_buffer_ref (input);
        *buf = input;
      } else {
        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
      }
      GST_BUFFER_CAPS (*buf) = out_caps;

      if (GST_PAD_CAPS (trans->srcpad) == NULL)
        gst_pad_set_caps (trans->srcpad, out_caps);
    } else {
      GST_DEBUG_OBJECT (trans, "Have unfixed output caps %" GST_PTR_FORMAT,
          out_caps);
      gst_caps_unref (out_caps);
    }
  }

  return GST_FLOW_OK;
}
コード例 #12
0
static GstData *
gst_v4ljpegsrc_get (GstPad * pad)
{
  GstV4lJpegSrc *v4ljpegsrc;
  GstV4lSrc *v4lsrc;
  GstData *data;
  GstBuffer *buf;
  GstBuffer *outbuf;
  int jpeg_size;

  g_return_val_if_fail (pad != NULL, NULL);
  v4ljpegsrc = GST_V4LJPEGSRC (gst_pad_get_parent (pad));
  v4lsrc = GST_V4LSRC (v4ljpegsrc);

  /* Fetch from the v4lsrc class get fn.  */
  data = v4ljpegsrc->getfn (pad);

  /* If not a buffer, return it unchanged */
  if (!data || (!GST_IS_BUFFER (data)))
    return data;

  buf = GST_BUFFER (data);

  /* Confirm that the buffer contains jpeg data */

  /* 
   * Create a new subbuffer from the jpeg data 
   * The first 2 bytes in the buffer are the size of the jpeg data
   */
  if (GST_BUFFER_SIZE (buf) > 2) {
    jpeg_size = (int) (GST_READ_UINT16_LE (GST_BUFFER_DATA (buf))) * 8;
  } else
    jpeg_size = 0;

  /* Check that the size is sensible */
  if ((jpeg_size <= 0) || (jpeg_size > GST_BUFFER_SIZE (buf) - 2)) {
    GST_ELEMENT_ERROR (v4ljpegsrc, STREAM, FORMAT, (NULL),
        ("Invalid non-jpeg frame from camera"));
    return NULL;
  }

  GST_DEBUG_OBJECT (v4ljpegsrc, "Creating JPEG subbuffer of size %d",
      jpeg_size);
  outbuf = gst_buffer_create_sub (buf, 2, jpeg_size);

  /* Copy timestamps onto the subbuffer */
  gst_buffer_stamp (outbuf, buf);

  /* Release the main buffer */
  gst_buffer_unref (buf);

  return GST_DATA (outbuf);
}
コード例 #13
0
ファイル: gstrfc2250enc.c プロジェクト: adesurya/gst-mobile
static void
gst_rfc2250_enc_add_slice (GstRFC2250Enc * enc, GstBuffer * buffer)
{
  gint slice_length = GST_BUFFER_SIZE (buffer);

  /* see if the slice fits in the current buffer */
  if (slice_length <= enc->remaining) {
    GstBuffer *newbuf;

    newbuf = gst_buffer_merge (enc->packet, buffer);
    gst_buffer_unref (buffer);
    gst_buffer_unref (enc->packet);
    enc->packet = newbuf;
    enc->remaining -= slice_length;
  }
  /* it doesn't fit */
  else {
    /* do we need to start a new packet? */
    if (slice_length <= enc->MTU) {
      GstBuffer *newbuf;

      gst_rfc2250_enc_new_buffer (enc);
      newbuf = gst_buffer_merge (enc->packet, buffer);
      gst_buffer_unref (buffer);
      gst_buffer_unref (enc->packet);
      enc->packet = newbuf;
      enc->remaining -= slice_length;
    }
    /* else we have to fragment */
    else {
      gint offset = 0;

      while (slice_length > 0) {
        GstBuffer *outbuf;
        GstBuffer *newbuf;

        outbuf =
            gst_buffer_create_sub (buffer, offset, MIN (enc->remaining,
                slice_length));
        newbuf = gst_buffer_merge (enc->packet, outbuf);
        slice_length -= GST_BUFFER_SIZE (outbuf);
        offset += GST_BUFFER_SIZE (outbuf);
        gst_buffer_unref (outbuf);
        gst_buffer_unref (newbuf);
        enc->packet = newbuf;
        gst_rfc2250_enc_new_buffer (enc);
      }
      gst_buffer_unref (buffer);
    }
  }
}
コード例 #14
0
/* FIXME: use version from gstcdxastrip.c */
static GstBuffer *
gst_cdxa_parse_strip (GstBuffer * buf)
{
  GstBuffer *sub;

  g_assert (GST_BUFFER_SIZE (buf) >= GST_CDXA_SECTOR_SIZE);

  /* Skip CDXA headers, only keep data.
   * FIXME: check sync, resync, ... */
  sub = gst_buffer_create_sub (buf, GST_CDXA_HEADER_SIZE, GST_CDXA_DATA_SIZE);
  gst_buffer_unref (buf);

  return sub;
}
コード例 #15
0
static GstFlowReturn
gst_video_rate_prepare_output_buffer (GstBaseTransform * trans,
    GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
{
  if (gst_buffer_is_metadata_writable (input)) {
    gst_buffer_set_caps (input, caps);
    *buf = gst_buffer_ref (input);
  } else {
    *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
    gst_buffer_set_caps (*buf, caps);
  }

  return GST_FLOW_OK;
}
コード例 #16
0
ファイル: gstrdtbuffer.c プロジェクト: ChinnaSuhas/ossbuild
GstBuffer *
gst_rdt_packet_to_buffer (GstRDTPacket * packet)
{
  GstBuffer *result;

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

  result =
      gst_buffer_create_sub (packet->buffer, packet->offset, packet->length);
  /* timestamp applies to all packets in this buffer */
  GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (packet->buffer);

  return result;
}
コード例 #17
0
ファイル: gstbuffer.c プロジェクト: wosigh/gstreamer
/**
 * gst_buffer_make_metadata_writable:
 * @buf: a #GstBuffer
 *
 * Similar to gst_buffer_make_writable, but does not ensure that the buffer
 * data array is writable. Instead, this just ensures that the returned buffer
 * is solely owned by the caller, by creating a subbuffer of the original
 * buffer if necessary.
 * 
 * After calling this function, @buf should not be referenced anymore. The
 * result of this function has guaranteed writable metadata.
 *
 * Returns: A new #GstBuffer with writable metadata.
 */
GstBuffer *
gst_buffer_make_metadata_writable (GstBuffer * buf)
{
  GstBuffer *ret;

  if (gst_buffer_is_metadata_writable (buf)) {
    ret = buf;
  } else {
    ret = gst_buffer_create_sub (buf, 0, GST_BUFFER_SIZE (buf));

    gst_buffer_unref (buf);
  }

  return ret;
}
コード例 #18
0
static GstBuffer *
asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
    guint * p_size, guint payload_len)
{
  guint off;

  g_assert (payload_len <= *p_size);

  off = (guint) (*p_data - GST_BUFFER_DATA (packet->buf));
  g_assert (off < GST_BUFFER_SIZE (packet->buf));

  *p_data += payload_len;
  *p_size -= payload_len;

  return gst_buffer_create_sub (packet->buf, off, payload_len);
}
コード例 #19
0
ファイル: audiotrim.c プロジェクト: fluffware/subrec
static GstBuffer *
buffer_head(AudioTrim *filter, GstBuffer *buf, gint64 pos)
{
  GstBuffer *head;
  guint end;
  if (pos <= GST_BUFFER_OFFSET(buf)) return NULL;
  if (pos >= GST_BUFFER_OFFSET_END(buf)) return gst_buffer_ref(buf);
  end = (pos -  GST_BUFFER_OFFSET(buf)) * sizeof(gfloat);
  g_assert(end < GST_BUFFER_SIZE(buf));
  head = gst_buffer_create_sub(buf, 0, end);
  copy_caps(buf, head);
  GST_BUFFER_DURATION(head) = sample_to_time(filter,
					    pos -  GST_BUFFER_OFFSET(buf));
  GST_BUFFER_OFFSET_END(head) = pos;
  return head;
}
コード例 #20
0
ファイル: gstfakesrc.c プロジェクト: kuailexs/symbiandump-mw1
static GstBuffer *
gst_fake_src_create_buffer (GstFakeSrc * src)
{
  GstBuffer *buf;
  guint size;
  gboolean dump = src->dump;

  size = gst_fake_src_get_size (src);
  if (size == 0)
    return gst_buffer_new ();

  switch (src->data) {
    case FAKE_SRC_DATA_ALLOCATE:
      buf = gst_fake_src_alloc_buffer (src, size);
      break;
    case FAKE_SRC_DATA_SUBBUFFER:
      /* see if we have a parent to subbuffer */
      if (!src->parent) {
        gst_fake_src_alloc_parent (src);
        g_assert (src->parent);
      }
      /* see if it's large enough */
      if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
        buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
        src->parentoffset += size;
      } else {
        /* the parent is useless now */
        gst_buffer_unref (src->parent);
        src->parent = NULL;
        /* try again (this will allocate a new parent) */
        return gst_fake_src_create_buffer (src);
      }
      gst_fake_src_prepare_buffer (src, buf);
      break;
    default:
      g_warning ("fakesrc: dunno how to allocate buffers !");
      buf = gst_buffer_new ();
      break;
  }
  if (dump) {
    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
  }

  return buf;
}
コード例 #21
0
ファイル: gsttimidity.c プロジェクト: jonasl/gst-svtplayer
/* generate audio data and advance internal timers */
static GstBuffer *
gst_timidity_fill_buffer (GstTimidity * timidity, GstBuffer * buffer)
{
  size_t bytes_read;
  gint64 samples;

  bytes_read = mid_song_read_wave (timidity->song, GST_BUFFER_DATA (buffer),
      GST_BUFFER_SIZE (buffer));

  if (bytes_read == 0) {
    gst_buffer_unref (buffer);
    return NULL;
  }

  GST_BUFFER_OFFSET (buffer) =
      timidity->o_segment->last_stop * timidity->bytes_per_frame;
  GST_BUFFER_TIMESTAMP (buffer) =
      timidity->o_segment->last_stop * timidity->time_per_frame;

  if (bytes_read < GST_BUFFER_SIZE (buffer)) {
    GstBuffer *old = buffer;

    buffer = gst_buffer_create_sub (buffer, 0, bytes_read);
    gst_buffer_unref (old);
  }

  samples = GST_BUFFER_SIZE (buffer) / timidity->bytes_per_frame;

  timidity->o_segment->last_stop += samples;

  GST_BUFFER_OFFSET_END (buffer) =
      timidity->o_segment->last_stop * timidity->bytes_per_frame;
  GST_BUFFER_DURATION (buffer) = samples * timidity->time_per_frame;

  GST_DEBUG_OBJECT (timidity,
      "generated buffer %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT
      " (%" G_GINT64_FORMAT " samples)",
      GST_TIME_ARGS ((guint64) GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (((guint64) (GST_BUFFER_TIMESTAMP (buffer) +
                  GST_BUFFER_DURATION (buffer)))), samples);

  return buffer;
}
コード例 #22
0
ファイル: audiotrim.c プロジェクト: fluffware/subrec
static GstBuffer *
buffer_tail(AudioTrim *filter, GstBuffer *buf, gint64 pos)
{
  GstBuffer *head;
  guint start;
  if (pos >= GST_BUFFER_OFFSET_END(buf)) return NULL;
  if (pos <= GST_BUFFER_OFFSET(buf)) return gst_buffer_ref(buf);
  start = (pos -  GST_BUFFER_OFFSET(buf)) * sizeof(gfloat);
  g_assert(start < GST_BUFFER_SIZE(buf));
  head = gst_buffer_create_sub(buf, start, GST_BUFFER_SIZE(buf) - start);
  copy_caps(buf, head);

  GST_BUFFER_TIMESTAMP(head) = sample_to_time(filter, pos);
  GST_BUFFER_OFFSET(head) = pos;
  GST_BUFFER_DURATION(head) = sample_to_time(filter,
					    GST_BUFFER_OFFSET_END(buf) - pos);
  GST_BUFFER_OFFSET_END(head) = GST_BUFFER_OFFSET_END(buf);
  return head;
}
コード例 #23
0
ファイル: gstwildmidi.c プロジェクト: zsx/ossbuild
static GstBuffer *
gst_wildmidi_clip_buffer (GstWildmidi * wildmidi, GstBuffer * buffer)
{
  gint64 start, stop;
  gint64 new_start, new_stop;
  gint64 offset, length;
  GstBuffer *out;
  guint64 bpf;

  /* clipping disabled for now */
  return buffer;

  start = GST_BUFFER_OFFSET (buffer);
  stop = GST_BUFFER_OFFSET_END (buffer);

  if (!gst_segment_clip (wildmidi->o_segment, GST_FORMAT_DEFAULT,
          start, stop, &new_start, &new_stop)) {
    gst_buffer_unref (buffer);
    return NULL;
  }

  if (start == new_start && stop == new_stop)
    return buffer;


  offset = new_start - start;
  length = new_stop - new_start;

  bpf = wildmidi->bytes_per_frame;
  out = gst_buffer_create_sub (buffer, offset * bpf, length * bpf);

  GST_BUFFER_OFFSET (out) = new_start;
  GST_BUFFER_OFFSET_END (out) = new_stop;
  GST_BUFFER_TIMESTAMP (out) =
      gst_util_uint64_scale_int (new_start, GST_SECOND, WILDMIDI_RATE);
  GST_BUFFER_DURATION (out) =
      gst_util_uint64_scale_int (new_stop, GST_SECOND, WILDMIDI_RATE) -
      GST_BUFFER_TIMESTAMP (out);

  gst_buffer_unref (buffer);

  return out;
}
コード例 #24
0
ファイル: gstfilesrc.c プロジェクト: puce77/openjfx-8u-dev-rt
static GstBuffer *
gst_file_src_map_small_region (GstFileSrc * src, off_t offset, gsize size)
{
  GstBuffer *ret;
  off_t mod;
  guint pagesize;

  GST_LOG_OBJECT (src,
      "attempting to map a small buffer at %" G_GUINT64_FORMAT "+%d",
      (guint64) offset, (gint) size);

  pagesize = src->pagesize;

  mod = offset % pagesize;

  /* if the offset starts at a non-page boundary, we have to special case */
  if (mod != 0) {
    gsize mapsize;
    off_t mapbase;
    GstBuffer *map;

    mapbase = offset - mod;
    mapsize = ((size + mod + pagesize - 1) / pagesize) * pagesize;

    GST_LOG_OBJECT (src,
        "not on page boundaries, resizing to map to %" G_GUINT64_FORMAT "+%d",
        (guint64) mapbase, (gint) mapsize);

    map = gst_file_src_map_region (src, mapbase, mapsize, FALSE);
    if (map == NULL)
      return NULL;

    ret = gst_buffer_create_sub (map, offset - mapbase, size);
    GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET (map) + offset - mapbase;

    gst_buffer_unref (map);
  } else {
    ret = gst_file_src_map_region (src, offset, size, FALSE);
  }

  return ret;
}
コード例 #25
0
/**
 * gst_collect_pads_read_buffer:
 * @pads: the collectspads to query
 * @data: the data to use
 * @size: the number of bytes to read
 *
 * Get a buffer of @size bytes from the given pad @data.
 *
 * This function should be called with @pads LOCK held, such as in the callback.
 *
 * Since: 0.10.18
 *
 * Returns: A #GstBuffer. The size of the buffer can be less that requested.
 * A return of NULL signals that the pad is end-of-stream.
 * Unref the buffer after use.
 *
 * MT safe.
 */
GstBuffer *
gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
    guint size)
{
  guint readsize, bufsize;
  GstBuffer *buffer;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (data != NULL, NULL);

  /* no buffer, must be EOS */
  if ((buffer = data->buffer) == NULL)
    return NULL;

  bufsize = GST_BUFFER_SIZE (buffer);

  readsize = MIN (size, bufsize - data->pos);

  if (data->pos == 0 && readsize == bufsize)
    return gst_buffer_ref (buffer);
  else
    return gst_buffer_create_sub (buffer, data->pos, readsize);
}
コード例 #26
0
static GstVaapiDecoderStatus
decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
{
    GstVaapiDecoderVC1Private * const priv = decoder->priv;
    GstVaapiDecoderStatus status;
    GstVC1ParserResult result;
    GstVC1BDU ebdu;
    GstBuffer *codec_data;
    guchar *buf;
    guint buf_size, ofs;

    buf      = GST_BUFFER_DATA(buffer);
    buf_size = GST_BUFFER_SIZE(buffer);
    if (!buf && buf_size == 0)
        return decode_sequence_end(decoder);

    gst_buffer_ref(buffer);
    gst_adapter_push(priv->adapter, buffer);

    /* Assume demuxer sends out plain frames if codec-data */
    codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
    if (codec_data && codec_data != buffer) {
        ebdu.type      = GST_VC1_FRAME;
        ebdu.size      = buf_size;
        ebdu.sc_offset = 0;
        ebdu.offset    = 0;
        ebdu.data      = buf;
        status = decode_ebdu(decoder, &ebdu);

        if (gst_adapter_available(priv->adapter) >= buf_size)
            gst_adapter_flush(priv->adapter, buf_size);
        return status;
    }

    if (priv->sub_buffer) {
        buffer = gst_buffer_merge(priv->sub_buffer, buffer);
        if (!buffer)
            return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
        gst_buffer_unref(priv->sub_buffer);
        priv->sub_buffer = NULL;
    }

    buf      = GST_BUFFER_DATA(buffer);
    buf_size = GST_BUFFER_SIZE(buffer);
    ofs      = 0;
    do {
        result = gst_vc1_identify_next_bdu(
            buf + ofs,
            buf_size - ofs,
            &ebdu
        );
        status = get_status(result);

        if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
            priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs);
            break;
        }
        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
            break;

        ofs += ebdu.offset + ebdu.size;
        if (gst_adapter_available(priv->adapter) >= ebdu.offset)
            gst_adapter_flush(priv->adapter, ebdu.offset);

        status = decode_ebdu(decoder, &ebdu);
        if (gst_adapter_available(priv->adapter) >= ebdu.size)
            gst_adapter_flush(priv->adapter, ebdu.size);
    } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
    return status;
}
コード例 #27
0
ファイル: gsticydemux.c プロジェクト: pli3/gst-plugins-good
static GstFlowReturn
gst_icydemux_chain (GstPad * pad, GstBuffer * buf)
{
  GstICYDemux *icydemux;
  guint size, chunk, offset;
  GstBuffer *sub;
  GstFlowReturn ret = GST_FLOW_OK;

  icydemux = GST_ICYDEMUX (GST_PAD_PARENT (pad));

  if (G_UNLIKELY (icydemux->meta_interval < 0))
    goto not_negotiated;

  if (icydemux->meta_interval == 0) {
    ret = gst_icydemux_typefind_or_forward (icydemux, buf);
    goto done;
  }

  /* Go through the buffer, chopping it into appropriate chunks. Forward as
   * tags or buffers, as appropriate
   */
  size = GST_BUFFER_SIZE (buf);
  offset = 0;
  while (size) {
    if (icydemux->remaining) {
      chunk = (size <= icydemux->remaining) ? size : icydemux->remaining;
      if (offset == 0 && chunk == size) {
        sub = buf;
        buf = NULL;
      } else {
        sub = gst_buffer_create_sub (buf, offset, chunk);
      }
      offset += chunk;
      icydemux->remaining -= chunk;
      size -= chunk;

      /* This buffer goes onto typefinding, and/or directly pushed out */
      ret = gst_icydemux_typefind_or_forward (icydemux, sub);
      if (ret != GST_FLOW_OK)
        goto done;
    } else if (icydemux->meta_remaining) {
      chunk = (size <= icydemux->meta_remaining) ?
          size : icydemux->meta_remaining;
      sub = gst_buffer_create_sub (buf, offset, chunk);
      gst_icydemux_add_meta (icydemux, sub);

      offset += chunk;
      icydemux->meta_remaining -= chunk;
      size -= chunk;

      if (icydemux->meta_remaining == 0) {
        /* Parse tags from meta_adapter, send off as tag messages */
        GST_DEBUG_OBJECT (icydemux, "No remaining metadata, parsing for tags");
        gst_icydemux_parse_and_send_tags (icydemux);

        icydemux->remaining = icydemux->meta_interval;
      }
    } else {
      /* We need to read a single byte (always safe at this point in the loop)
       * to figure out how many bytes of metadata exist. 
       * The 'spec' tells us to read 16 * (byte_value) bytes of metadata after
       * this (zero is common, and means the metadata hasn't changed).
       */
      icydemux->meta_remaining = 16 * GST_BUFFER_DATA (buf)[offset];
      if (icydemux->meta_remaining == 0)
        icydemux->remaining = icydemux->meta_interval;

      offset += 1;
      size -= 1;
    }
  }

done:
  if (buf)
    gst_buffer_unref (buf);

  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_WARNING_OBJECT (icydemux, "meta_interval not set, buffer probably had "
        "no caps set. Try enabling iradio-mode on the http source element");
    gst_buffer_unref (buf);
    return GST_FLOW_NOT_NEGOTIATED;
  }
}
コード例 #28
0
ファイル: gstfilesrc.c プロジェクト: puce77/openjfx-8u-dev-rt
static GstFlowReturn
gst_file_src_create_mmap (GstFileSrc * src, guint64 offset, guint length,
    GstBuffer ** buffer)
{
  GstBuffer *buf = NULL;
  gsize readsize, mapsize;
  off_t readend, mapstart, mapend;
  int i;

  /* calculate end pointers so we don't have to do so repeatedly later */
  readsize = length;
  readend = offset + readsize;  /* note this is the byte *after* the read */

  mapstart = GST_BUFFER_OFFSET (src->mapbuf);
  mapsize = GST_BUFFER_SIZE (src->mapbuf);
  mapend = mapstart + mapsize;  /* note this is the byte *after* the map */

  GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
      (unsigned long) readsize, (unsigned long) readend,
      (unsigned long) mapstart, (unsigned long) mapend);

  /* if the start is past the mapstart */
  if (offset >= mapstart) {
    /* if the end is before the mapend, the buffer is in current mmap region... */
    /* ('cause by definition if readend is in the buffer, so's readstart) */
    if (readend <= mapend) {
      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%u lives in "
          "current mapbuf %u+%u, creating subbuffer of mapbuf",
          offset, (guint) readsize, (guint) mapstart, (guint) mapsize);
      buf = gst_buffer_create_sub (src->mapbuf, offset - mapstart, readsize);
      GST_BUFFER_OFFSET (buf) = offset;

      /* if the start actually is within the current mmap region, map an overlap buffer */
    } else if (offset < mapend) {
      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%u starts in "
          "mapbuf %u+%u but ends outside, creating new mmap",
          offset, (guint) readsize, (guint) mapstart, (guint) mapsize);
      buf = gst_file_src_map_small_region (src, offset, readsize);
      if (buf == NULL)
        goto could_not_mmap;
    }

    /* the only other option is that buffer is totally outside, which means we search for it */

    /* now we can assume that the start is *before* the current mmap region */
    /* if the readend is past mapstart, we have two options */
  } else if (readend >= mapstart) {
    /* either the read buffer overlaps the start of the mmap region */
    /* or the read buffer fully contains the current mmap region    */
    /* either way, it's really not relevant, we just create a new region anyway */
    GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d starts before "
        "mapbuf %d+%d, but overlaps it", (guint64) offset, (gint) readsize,
        (gint) mapstart, (gint) mapsize);
    buf = gst_file_src_map_small_region (src, offset, readsize);
    if (buf == NULL)
      goto could_not_mmap;
  }

  /* then deal with the case where the read buffer is totally outside */
  if (buf == NULL) {
    /* first check to see if there's a map that covers the right region already */
    GST_LOG_OBJECT (src, "searching for mapbuf to cover %" G_GUINT64_FORMAT
        "+%d", offset, (int) readsize);

    /* if the read buffer crosses a mmap region boundary, create a one-off region */
    if ((offset / src->mapsize) != (readend / src->mapsize)) {
      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d crosses a "
          "%d-byte boundary, creating a one-off", offset, (int) readsize,
          (int) src->mapsize);
      buf = gst_file_src_map_small_region (src, offset, readsize);
      if (buf == NULL)
        goto could_not_mmap;

      /* otherwise we will create a new mmap region and set it to the default */
    } else {
      gsize mapsize;

      off_t nextmap = offset - (offset % src->mapsize);

      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d in new mapbuf "
          "at %" G_GUINT64_FORMAT "+%d, mapping and subbuffering",
          offset, (gint) readsize, (guint64) nextmap, (gint) src->mapsize);
      /* first, we're done with the old mapbuf */
      gst_buffer_unref (src->mapbuf);
      mapsize = src->mapsize;

      /* double the mapsize as long as the readsize is smaller */
      while (readsize + offset > nextmap + mapsize) {
        GST_LOG_OBJECT (src, "readsize smaller then mapsize %08x %d",
            (guint) readsize, (gint) mapsize);
        mapsize <<= 1;
      }
      /* create a new one */
      src->mapbuf = gst_file_src_map_region (src, nextmap, mapsize, FALSE);
      if (src->mapbuf == NULL)
        goto could_not_mmap;

      /* subbuffer it */
      buf = gst_buffer_create_sub (src->mapbuf, offset - nextmap, readsize);
      GST_BUFFER_OFFSET (buf) =
          GST_BUFFER_OFFSET (src->mapbuf) + offset - nextmap;
    }
  }

  /* if we need to touch the buffer (to bring it into memory), do so */
  if (src->touch) {
    volatile guchar *p = GST_BUFFER_DATA (buf);

    /* read first byte of each page */
    for (i = 0; i < GST_BUFFER_SIZE (buf); i += src->pagesize)
      (void) p[i];
  }

  /* we're done, return the buffer */
  *buffer = buf;

  return GST_FLOW_OK;

  /* ERROR */
could_not_mmap:
  {
    return GST_FLOW_ERROR;
  }
}
コード例 #29
0
static gboolean
gst_ogg_avi_parse_setcaps (GstPad * pad, GstCaps * caps)
{
  GstOggAviParse *ogg;
  GstStructure *structure;
  const GValue *codec_data;
  GstBuffer *buffer;
  guint8 *data;
  guint size;
  guint32 sizes[3];
  GstCaps *outcaps;
  gint i, offs;

  ogg = GST_OGG_AVI_PARSE (GST_OBJECT_PARENT (pad));

  structure = gst_caps_get_structure (caps, 0);

  /* take codec data */
  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data == NULL)
    goto no_data;

  /* only buffers are valid */
  if (G_VALUE_TYPE (codec_data) != GST_TYPE_BUFFER)
    goto wrong_format;

  /* Now parse the data */
  buffer = gst_value_get_buffer (codec_data);

  /* first 22 bytes are bits_per_sample, channel_mask, GUID
   * Then we get 3 LE guint32 with the 3 header sizes
   * then we get the bytes of the 3 headers. */
  data = GST_BUFFER_DATA (buffer);
  size = GST_BUFFER_SIZE (buffer);

  GST_LOG_OBJECT (ogg, "configuring codec_data of size %u", size);

  /* skip headers */
  data += 22;
  size -= 22;

  /* we need at least 12 bytes for the packet sizes of the 3 headers */
  if (size < 12)
    goto buffer_too_small;

  /* read sizes of the 3 headers */
  sizes[0] = GST_READ_UINT32_LE (data);
  sizes[1] = GST_READ_UINT32_LE (data + 4);
  sizes[2] = GST_READ_UINT32_LE (data + 8);

  GST_DEBUG_OBJECT (ogg, "header sizes: %u %u %u", sizes[0], sizes[1],
      sizes[2]);

  data += 12;
  size -= 12;

  /* and we need at least enough data for all the headers */
  if (size < sizes[0] + sizes[1] + sizes[2])
    goto buffer_too_small;

  /* set caps */
  outcaps = gst_caps_new_simple ("audio/x-vorbis", NULL);
  gst_pad_set_caps (ogg->srcpad, outcaps);

  /* copy header data */
  offs = 34;
  for (i = 0; i < 3; i++) {
    GstBuffer *out;

    /* now output the raw vorbis header packets */
    out = gst_buffer_create_sub (buffer, offs, sizes[i]);
    gst_buffer_set_caps (out, outcaps);
    gst_pad_push (ogg->srcpad, out);

    offs += sizes[i];
  }
  gst_caps_unref (outcaps);

  return TRUE;

  /* ERRORS */
no_data:
  {
    GST_DEBUG_OBJECT (ogg, "no codec_data found in caps");
    return FALSE;
  }
wrong_format:
  {
    GST_DEBUG_OBJECT (ogg, "codec_data is not a buffer");
    return FALSE;
  }
buffer_too_small:
  {
    GST_DEBUG_OBJECT (ogg, "codec_data is too small");
    return FALSE;
  }
}
コード例 #30
0
static GstBuffer *
gst_avi_subtitle_extract_file (GstAviSubtitle * sub, GstBuffer * buffer,
    guint offset, guint len)
{
  const gchar *input_enc = NULL;
  GstBuffer *ret = NULL;
  gchar *data;

  data = (gchar *) GST_BUFFER_DATA (buffer) + offset;

  if (len >= (3 + 1) && IS_BOM_UTF8 (data) &&
      g_utf8_validate (data + 3, len - 3, NULL)) {
    ret = gst_buffer_create_sub (buffer, offset + 3, len - 3);
  } else if (len >= 2 && IS_BOM_UTF16_BE (data)) {
    input_enc = "UTF-16BE";
    data += 2;
    len -= 2;
  } else if (len >= 2 && IS_BOM_UTF16_LE (data)) {
    input_enc = "UTF-16LE";
    data += 2;
    len -= 2;
  } else if (len >= 4 && IS_BOM_UTF32_BE (data)) {
    input_enc = "UTF-32BE";
    data += 4;
    len -= 4;
  } else if (len >= 4 && IS_BOM_UTF32_LE (data)) {
    input_enc = "UTF-32LE";
    data += 4;
    len -= 4;
  } else if (g_utf8_validate (data, len, NULL)) {
    /* not specified, check if it's UTF-8 */
    ret = gst_buffer_create_sub (buffer, offset, len);
  } else {
    /* we could fall back to gst_tag_freeform_to_utf8() here */
    GST_WARNING_OBJECT (sub, "unspecified encoding, and not UTF-8");
    return NULL;
  }

  g_return_val_if_fail (ret != NULL || input_enc != NULL, NULL);

  if (input_enc) {
    GError *err = NULL;
    gchar *utf8;

    GST_DEBUG_OBJECT (sub, "converting subtitles from %s to UTF-8", input_enc);
    utf8 = g_convert (data, len, "UTF-8", input_enc, NULL, NULL, &err);

    if (err != NULL) {
      GST_WARNING_OBJECT (sub, "conversion to UTF-8 failed : %s", err->message);
      g_error_free (err);
      return NULL;
    }

    ret = gst_buffer_new ();
    GST_BUFFER_DATA (ret) = (guint8 *) utf8;
    GST_BUFFER_MALLOCDATA (ret) = (guint8 *) utf8;
    GST_BUFFER_SIZE (ret) = strlen (utf8);
    GST_BUFFER_OFFSET (ret) = 0;
  }

  GST_BUFFER_CAPS (ret) = gst_caps_new_simple ("application/x-subtitle", NULL);
  return ret;
}