コード例 #1
0
/* prepare a buffer for transmission by passing data through libvorbis */
static GstBuffer *
gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
    ogg_packet * packet)
{
  GstBuffer *outbuf;

  outbuf = gst_buffer_new_and_alloc (packet->bytes);
  memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
  /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
   * time representation */
  GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos +
      vorbisenc->granulepos_offset;
  GST_BUFFER_OFFSET (outbuf) = granulepos_to_timestamp (vorbisenc,
      GST_BUFFER_OFFSET_END (outbuf));
  GST_BUFFER_TIMESTAMP (outbuf) = vorbisenc->next_ts;

  /* update the next timestamp, taking granulepos_offset and subgranule offset
   * into account */
  vorbisenc->next_ts =
      granulepos_to_timestamp_offset (vorbisenc, packet->granulepos);
  GST_BUFFER_DURATION (outbuf) =
      vorbisenc->next_ts - GST_BUFFER_TIMESTAMP (outbuf);

  if (vorbisenc->next_discont) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
    vorbisenc->next_discont = FALSE;
  }

  GST_LOG_OBJECT (vorbisenc, "encoded buffer of %d bytes",
      GST_BUFFER_SIZE (outbuf));
  return outbuf;
}
コード例 #2
0
/* prepare a buffer for transmission by passing data through libtheora */
static GstFlowReturn
theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
    GstClockTime timestamp, GstClockTime running_time,
    GstClockTime duration, GstBuffer ** buffer)
{
  GstBuffer *buf;
  GstFlowReturn ret = GST_FLOW_OK;

  buf = gst_buffer_new_and_alloc (packet->bytes);
  if (!buf) {
    GST_WARNING_OBJECT (enc, "Could not allocate buffer");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
  gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
  /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
   * time representation */
  GST_BUFFER_OFFSET_END (buf) =
      granulepos_add (packet->granulepos, enc->granulepos_offset,
      enc->granule_shift);
  GST_BUFFER_OFFSET (buf) = granulepos_to_timestamp (enc,
      GST_BUFFER_OFFSET_END (buf));

  GST_BUFFER_TIMESTAMP (buf) = timestamp;
  GST_BUFFER_DURATION (buf) = duration;

  if (enc->next_discont) {
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    enc->next_discont = FALSE;
  }

  /* the second most significant bit of the first data byte is cleared
   * for keyframes */
  if ((packet->packet[0] & 0x40) == 0) {
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
  } else {
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
  }
  enc->packetno++;

done:
  *buffer = buf;
  return ret;
}
コード例 #3
0
static GstFlowReturn
theora_enc_pre_push (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
{
    GstTheoraEnc *enc = GST_THEORA_ENC (benc);
    guint64 pfn;

    /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
     * time representation */
    /* granulepos from sync frame */
    pfn = frame->presentation_frame_number - frame->distance_from_sync;
    /* correct to correspond to linear running time */
    pfn -= enc->pfn_offset;
    pfn += enc->granulepos_offset + 1;
    /* granulepos */
    GST_BUFFER_OFFSET_END (frame->output_buffer) =
        (pfn << enc->info.keyframe_granule_shift) + frame->distance_from_sync;
    GST_BUFFER_OFFSET (frame->output_buffer) = granulepos_to_timestamp (enc,
            GST_BUFFER_OFFSET_END (frame->output_buffer));

    return GST_FLOW_OK;
}