예제 #1
0
static GstSegment *
gst_timidity_get_segment (GstTimidity * timidity, GstFormat format,
    gboolean update)
{
  gint64 start, stop, time;

  GstSegment *segment = gst_segment_new ();

  gst_timidity_src_convert (timidity,
      timidity->o_segment->format, timidity->o_segment->start, &format, &start);

  if (timidity->o_segment->stop == GST_CLOCK_TIME_NONE) {
    stop = GST_CLOCK_TIME_NONE;
  } else {
    gst_timidity_src_convert (timidity,
        timidity->o_segment->format, timidity->o_segment->stop, &format, &stop);
  }

  gst_timidity_src_convert (timidity,
      timidity->o_segment->format, timidity->o_segment->time, &format, &time);

  gst_segment_set_newsegment_full (segment, update,
      timidity->o_segment->rate, timidity->o_segment->applied_rate,
      format, start, stop, time);

  segment->last_stop = time;

  return segment;
}
예제 #2
0
void
gst_kate_util_decoder_base_new_segment_event (GstKateDecoderBase * decoder,
    GstEvent * event)
{
  gboolean update;
  gdouble rate;
  GstFormat format;
  gint64 start, stop, time;
  gdouble arate;

  gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
      &start, &stop, &time);
  GST_DEBUG_OBJECT (decoder, "kate pad segment:"
      " Update %d, rate %g arate %g format %d start %" GST_TIME_FORMAT
      " %" GST_TIME_FORMAT " position %" GST_TIME_FORMAT,
      update, rate, arate, format, GST_TIME_ARGS (start),
      GST_TIME_ARGS (stop), GST_TIME_ARGS (time));
  if (!update) {
    /* Tiger uses this segment is used to remap the video running time to the
       Kate running time. The sending of segment updates to keep streams in sync
       does kinda rain on our parade though, and since we don't need these,
       we just ignore those here */
    gst_segment_set_newsegment_full (&decoder->kate_segment, update, rate,
        arate, format, start, stop, time);
  }
}
/**
 * gst_segment_set_newsegment:
 * @segment: a #GstSegment structure.
 * @update: flag indicating a new segment is started or updated
 * @rate: the rate of the segment.
 * @format: the format of the segment.
 * @start: the new start value
 * @stop: the new stop value
 * @time: the new stream time
 *
 * Update the segment structure with the field values of a new segment event and
 * with a default applied_rate of 1.0.
 *
 * Since: 0.10.6
 */
void
gst_segment_set_newsegment (GstSegment * segment, gboolean update, gdouble rate,
    GstFormat format, gint64 start, gint64 stop, gint64 time)
{
  gst_segment_set_newsegment_full (segment, update, rate, 1.0, format, start,
      stop, time);
}
예제 #4
0
static gboolean
gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
{
  GstPngDec *pngdec;
  gboolean res;

  pngdec = GST_PNGDEC (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:{
      gdouble rate, arate;
      gboolean update;
      gint64 start, stop, position;
      GstFormat fmt;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
          &start, &stop, &position);

      gst_segment_set_newsegment_full (&pngdec->segment, update, rate, arate,
          fmt, start, stop, position);

      GST_LOG_OBJECT (pngdec, "NEWSEGMENT (%s)", gst_format_get_name (fmt));

      if (fmt == GST_FORMAT_TIME) {
        pngdec->need_newsegment = FALSE;
        res = gst_pad_push_event (pngdec->srcpad, event);
      } else {
        gst_event_unref (event);
        res = TRUE;
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      gst_pngdec_libpng_clear (pngdec);
      gst_pngdec_libpng_init (pngdec);
      png_set_progressive_read_fn (pngdec->png, pngdec,
          user_info_callback, user_endrow_callback, user_end_callback);
      pngdec->ret = GST_FLOW_OK;
      gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
      res = gst_pad_push_event (pngdec->srcpad, event);
      break;
    }
    case GST_EVENT_EOS:
    {
      GST_LOG_OBJECT (pngdec, "EOS");
      gst_pngdec_libpng_clear (pngdec);
      pngdec->ret = GST_FLOW_UNEXPECTED;
      res = gst_pad_push_event (pngdec->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (pngdec->srcpad, event);
      break;
  }

  gst_object_unref (pngdec);
  return res;
}
void QGstreamerPlayerSession::processNewSegment(GstEvent *event)
{
    gboolean update;
    GstFormat format;
    gdouble rate, arate;
    gint64 start, stop, time;

    gst_event_parse_new_segment_full(event, &update, &rate, &arate, &format,
                                      &start, &stop, &time);

    gst_segment_set_newsegment_full(&m_segment, update,
              rate, arate, format, start, stop, time);
}
static gboolean
gst_audio_ringbuffer_handle_sink_event (GstPad * pad, GstEvent * event)
{
  GstAudioRingbuffer *ringbuffer;
  gboolean forward;

  ringbuffer = GST_AUDIO_RINGBUFFER (GST_OBJECT_PARENT (pad));

  forward = ringbuffer->pushing || ringbuffer->pulling;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    {
      GST_LOG_OBJECT (ringbuffer, "received flush start event");
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      ringbuffer->is_eos = FALSE;
      GST_LOG_OBJECT (ringbuffer, "received flush stop event");
      break;
    }
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      gdouble rate, arate;
      GstFormat format;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      gst_segment_set_newsegment_full (&ringbuffer->sink_segment, update, rate,
          arate, format, start, stop, time);
      break;
    }
    case GST_EVENT_EOS:
      ringbuffer->is_eos = TRUE;
      break;
    default:
      break;
  }
  if (forward) {
    gst_pad_push_event (ringbuffer->srcpad, event);
  } else {
    if (event)
      gst_event_unref (event);
  }
  return TRUE;
}
예제 #7
0
파일: fs-funnel.c 프로젝트: zsx/ossbuild
static gboolean
fs_funnel_event (GstPad * pad, GstEvent * event)
{
  FsFunnel *funnel = FS_FUNNEL (gst_pad_get_parent (pad));
  FsFunnelPadPrivate *priv = gst_pad_get_element_private (pad);
  gboolean forward = TRUE;
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
      {
        gboolean update;
        gdouble rate, arate;
        GstFormat format;
        gint64 start;
        gint64 stop;
        gint64 time;

        gst_event_parse_new_segment_full (event, &update, &rate, &arate,
            &format, &start, &stop, &time);


        GST_OBJECT_LOCK (funnel);
        gst_segment_set_newsegment_full (&priv->segment, update, rate, arate,
            format, start, stop, time);
        GST_OBJECT_UNLOCK (funnel);

        forward = FALSE;
        gst_event_unref (event);
      }
      break;
    case GST_EVENT_FLUSH_STOP:
      {
        GST_OBJECT_LOCK (funnel);
        gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED);
        GST_OBJECT_UNLOCK (funnel);
      }
      break;
    default:
      break;
  }


  if (forward)
    res = gst_pad_push_event (funnel->srcpad, event);

  gst_object_unref (funnel);

  return res;
}
예제 #8
0
static gboolean
gst_rsvg_dec_sink_event (GstPad * pad, GstEvent * event)
{
  GstRsvgDec *rsvg = GST_RSVG_DEC (gst_pad_get_parent (pad));
  gboolean res = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:{
      gdouble rate, arate;
      gboolean update;
      gint64 start, stop, position;
      GstFormat fmt;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
          &start, &stop, &position);

      gst_segment_set_newsegment_full (&rsvg->segment, update, rate, arate,
          fmt, start, stop, position);

      if (fmt == GST_FORMAT_TIME) {
        rsvg->need_newsegment = FALSE;
        res = gst_pad_push_event (rsvg->srcpad, event);
      } else {
        gst_event_unref (event);
        res = TRUE;
      }
      break;
    }
    case GST_EVENT_EOS:
    case GST_EVENT_FLUSH_STOP:
      gst_adapter_clear (rsvg->adapter);
      /* fall through */
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (rsvg->srcpad, event);
      break;
    default:
      if (GST_PAD_CAPS (rsvg->srcpad)) {
        res = gst_pad_push_event (rsvg->srcpad, event);
      } else {
        res = TRUE;
        rsvg->pending_events = g_list_append (rsvg->pending_events, event);
      }
      break;
  }

  gst_object_unref (rsvg);

  return res;
}
예제 #9
0
static gboolean
gst_visual_sink_event (GstPad * pad, GstEvent * event)
{
  GstVisual *visual;
  gboolean res;

  visual = GST_VISUAL (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (visual->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      /* reset QoS and adapter. */
      gst_visual_reset (visual);
      res = gst_pad_push_event (visual->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;
      gboolean update;

      /* the newsegment values are used to clip the input samples
       * and to convert the incomming timestamps to running time so
       * we can do QoS */
      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      /* now configure the values */
      gst_segment_set_newsegment_full (&visual->segment, update,
          rate, arate, format, start, stop, time);

      /* and forward */
      res = gst_pad_push_event (visual->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (visual->srcpad, event);
      break;
  }

  gst_object_unref (visual);
  return res;
}
예제 #10
0
static gboolean
dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event)
{
  GstDvdLpcmDec *dvdlpcmdec;
  gboolean res;

  dvdlpcmdec = GST_DVDLPCMDEC (GST_PAD_PARENT (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
    {
      gdouble rate, arate;
      GstFormat format;
      gboolean update;
      gint64 start, stop, pos;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate,
          &format, &start, &stop, &pos);

      GST_DEBUG_OBJECT (dvdlpcmdec,
          "new segment, format=%d, start = %" G_GINT64_FORMAT
          ", stop = %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
          format, start, stop, pos);

      gst_segment_set_newsegment_full (&dvdlpcmdec->segment, update,
          rate, arate, format, start, stop, pos);

      if (format == GST_FORMAT_TIME) {
        dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
      } else {
        dvdlpcmdec->timestamp = 0;
      }
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&dvdlpcmdec->segment, GST_FORMAT_UNDEFINED);
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
  }

  return res;
}
예제 #11
0
static gboolean
gst_monoscope_sink_event (GstPad * pad, GstEvent * event)
{
  GstMonoscope *monoscope;
  gboolean res;

  monoscope = GST_MONOSCOPE (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_monoscope_reset (monoscope);
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;
      gboolean update;

      /* the newsegment values are used to clip the input samples
       * and to convert the incomming timestamps to running time so
       * we can do QoS */
      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      /* now configure the values */
      gst_segment_set_newsegment_full (&monoscope->segment, update,
          rate, arate, format, start, stop, time);

      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (monoscope->srcpad, event);
      break;
  }

  gst_object_unref (monoscope);

  return res;
}
예제 #12
0
static gboolean
gst_gsmdec_sink_event (GstPad * pad, GstEvent * event)
{
    gboolean res;
    GstGSMDec *gsmdec;

    gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
        res = gst_pad_push_event (gsmdec->srcpad, event);
        break;
    case GST_EVENT_FLUSH_STOP:
        gst_segment_init (&gsmdec->segment, GST_FORMAT_UNDEFINED);
        res = gst_pad_push_event (gsmdec->srcpad, event);
        break;
    case GST_EVENT_NEWSEGMENT:
    {
        gboolean update;
        GstFormat format;
        gdouble rate, arate;
        gint64 start, stop, time;

        gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
                                          &start, &stop, &time);

        /* now configure the values */
        gst_segment_set_newsegment_full (&gsmdec->segment, update,
                                         rate, arate, format, start, stop, time);

        /* and forward */
        res = gst_pad_push_event (gsmdec->srcpad, event);
        break;
    }
    case GST_EVENT_EOS:
    default:
        res = gst_pad_push_event (gsmdec->srcpad, event);
        break;
    }

    gst_object_unref (gsmdec);

    return res;
}
예제 #13
0
파일: gstpgmdec.c 프로젝트: ladiko/walet
static gboolean gst_pgmdec_sink_event (GstPad * pad, GstEvent * event)
{
	gboolean ret = TRUE;
	Gstpgmdec *filter = GST_PGMDEC (GST_OBJECT_PARENT (pad));

	GST_DEBUG_OBJECT (filter, "event : %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:{
      GST_DEBUG_OBJECT (filter, "Aborting decompress");
      //jpeg_abort_decompress (&dec->cinfo);
      gst_segment_init (&filter->segment, GST_FORMAT_UNDEFINED);
      //gst_jpeg_dec_reset_qos (dec);
      break;
    }

    case GST_EVENT_NEWSEGMENT:{
      gboolean update;
      gdouble rate, applied_rate;
      GstFormat format;
      gint64 start, stop, position;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &position);

      GST_DEBUG_OBJECT (filter, "Got NEWSEGMENT [%" GST_TIME_FORMAT
          " - %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "]",
          GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
          GST_TIME_ARGS (position));

      gst_segment_set_newsegment_full (&filter->segment, update, rate,
          applied_rate, format, start, stop, position);

      break;
    }
    default:
      break;
  }

  ret = gst_pad_push_event (filter->srcpad, event);

  return ret;
}
static gboolean
gst_vdp_vpp_sink_event (GstPad * pad, GstEvent * event)
{
  GstVdpVideoPostProcess *vpp =
      GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
    {
      GST_DEBUG_OBJECT (vpp, "flush stop");

      gst_vdp_vpp_flush (vpp);

      res = gst_pad_event_default (pad, event);
      break;
    }
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      gdouble rate, applied_rate;
      GstFormat format;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &time);

      GST_OBJECT_LOCK (vpp);
      gst_segment_set_newsegment_full (&vpp->segment, update, rate,
          applied_rate, format, start, stop, time);
      GST_OBJECT_UNLOCK (vpp);

      res = gst_pad_event_default (pad, event);
      break;
    }
    default:
      res = gst_pad_event_default (pad, event);
  }

  gst_object_unref (vpp);

  return res;
}
예제 #15
0
static gboolean
gst_dvdec_sink_event (GstPad * pad, GstEvent * event)
{
  GstDVDec *dvdec;
  gboolean res = TRUE;

  dvdec = GST_DVDEC (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (dvdec->segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_NEWSEGMENT:{
      gboolean update;
      gdouble rate, applied_rate;
      GstFormat format;
      gint64 start, stop, position;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &position);

      GST_DEBUG_OBJECT (dvdec, "Got NEWSEGMENT [%" GST_TIME_FORMAT
          " - %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "]",
          GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
          GST_TIME_ARGS (position));

      gst_segment_set_newsegment_full (dvdec->segment, update, rate,
          applied_rate, format, start, stop, position);
      break;
    }
    default:
      break;
  }

  res = gst_pad_push_event (dvdec->srcpad, event);

  return res;
}
static gboolean
gst_play_sink_video_convert_sink_event (GstPad * pad, GstEvent * event)
{
    GstPlaySinkVideoConvert *self =
        GST_PLAY_SINK_VIDEO_CONVERT (gst_pad_get_parent (pad));
    gboolean ret;

    ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));

    if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
        gboolean update;
        gdouble rate, applied_rate;
        GstFormat format;
        gint64 start, stop, position;

        GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
        gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
                                          &format, &start, &stop, &position);

        GST_DEBUG_OBJECT (self, "Segment before %" GST_SEGMENT_FORMAT,
                          &self->segment);
        gst_segment_set_newsegment_full (&self->segment, update, rate, applied_rate,
                                         format, start, stop, position);
        GST_DEBUG_OBJECT (self, "Segment after %" GST_SEGMENT_FORMAT,
                          &self->segment);
        GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
    } else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
        GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
        GST_DEBUG_OBJECT (self, "Resetting segment");
        gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
        GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
    }

    gst_event_unref (event);
    gst_object_unref (self);

    return ret;
}
예제 #17
0
static gboolean
theora_enc_sink_event (GstPad * pad, GstEvent * event)
{
  GstTheoraEnc *enc;
  ogg_packet op;
  gboolean res;

  enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      gdouble rate, applied_rate;
      GstFormat format;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &time);

      gst_segment_set_newsegment_full (&enc->segment, update, rate,
          applied_rate, format, start, stop, time);

      res = gst_pad_push_event (enc->srcpad, event);
      break;
    }
    case GST_EVENT_EOS:
      if (enc->initialised) {
        /* push last packet with eos flag, should not be called */
        while (th_encode_packetout (enc->encoder, 1, &op)) {
          GstClockTime next_time =
              th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;

          theora_push_packet (enc, &op, GST_CLOCK_TIME_NONE, enc->next_ts,
              next_time - enc->next_ts);
          enc->next_ts = next_time;
        }
      }
      if (enc->initialised && enc->multipass_cache_fd
          && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
        theora_enc_write_multipass_cache (enc, TRUE, TRUE);

      theora_enc_clear_multipass_cache (enc);

      res = gst_pad_push_event (enc->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *s;

      s = gst_event_get_structure (event);

      if (gst_structure_has_name (s, "GstForceKeyUnit"))
        theora_enc_force_keyframe (enc);
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (enc->srcpad, event);
      break;
  }
  return res;
}
예제 #18
0
static gboolean
theora_enc_sink_event (GstPad * pad, GstEvent * event)
{
  GstTheoraEnc *enc;
  ogg_packet op;
  gboolean res;

  enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      gdouble rate, applied_rate;
      GstFormat format;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &time);

      gst_segment_set_newsegment_full (&enc->segment, update, rate,
          applied_rate, format, start, stop, time);

      res = gst_pad_push_event (enc->srcpad, event);
      break;
    }
    case GST_EVENT_EOS:
      if (enc->initialised) {
        /* push last packet with eos flag, should not be called */
        while (theora_encode_packetout (&enc->state, 1, &op)) {
          GstClockTime next_time =
              theora_enc_get_ogg_packet_end_time (enc, &op);

          theora_push_packet (enc, &op, GST_CLOCK_TIME_NONE, enc->next_ts,
              next_time - enc->next_ts);
          enc->next_ts = next_time;
        }
      }
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *s;

      s = gst_event_get_structure (event);

      if (gst_structure_has_name (s, "GstForceKeyUnit")) {
        GstClockTime next_ts;

        /* make sure timestamps increment after resetting the decoder */
        next_ts = enc->next_ts + enc->timestamp_offset;

        theora_enc_reset (enc);
        enc->granulepos_offset =
            gst_util_uint64_scale (next_ts, enc->fps_n,
            GST_SECOND * enc->fps_d);
        enc->timestamp_offset = next_ts;
        enc->next_ts = 0;
      }
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (enc->srcpad, event);
      break;
  }
  return res;
}
예제 #19
0
static gboolean
rsn_audiomunge_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean ret = FALSE;
  RsnAudioMunge *munge = RSN_AUDIOMUNGE (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      rsn_audiomunge_reset (munge);
      ret = gst_pad_push_event (munge->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstSegment *segment;
      gboolean update;
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      /* we need TIME format */
      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      /* now configure the values */
      segment = &munge->sink_segment;

      gst_segment_set_newsegment_full (segment, update,
          rate, arate, format, start, stop, time);

      if (munge->have_audio) {
        ret = gst_pad_push_event (munge->srcpad, event);
        break;
      }

      /*
       * FIXME:
       * If the accum >= threshold or we're in a still frame and there's been
       * no audio received, then we need to generate some audio data.
       * If caused by a segment start update (time advancing in a gap) adjust
       * the new-segment and send the buffer.
       *
       * Otherwise, send the buffer before the newsegment, so that it appears
       * in the closing segment.
       */
      if (!update) {
        GST_DEBUG_OBJECT (munge, "Sending newsegment: start %" GST_TIME_FORMAT
            " stop %" GST_TIME_FORMAT " accum now %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
            GST_TIME_ARGS (segment->accum));

        ret = gst_pad_push_event (munge->srcpad, event);
      }

      if (segment->accum >= AUDIO_FILL_THRESHOLD || munge->in_still) {
        g_print ("***********  Sending audio fill: accum = %" GST_TIME_FORMAT
            " still-state=%d\n", GST_TIME_ARGS (segment->accum),
            munge->in_still);

        /* Just generate a 100ms silence buffer for now. FIXME: Fill the gap */
        if (rsn_audiomunge_make_audio (munge, segment->start,
                GST_SECOND / 10) == GST_FLOW_OK)
          munge->have_audio = TRUE;
      } else {
        GST_LOG_OBJECT (munge, "Not sending audio fill buffer: "
            "segment accum below thresh: accum = %" GST_TIME_FORMAT,
            GST_TIME_ARGS (segment->accum));
      }

      if (update) {
        GST_DEBUG_OBJECT (munge, "Sending newsegment: start %" GST_TIME_FORMAT
            " stop %" GST_TIME_FORMAT " accum now %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
            GST_TIME_ARGS (segment->accum));

        ret = gst_pad_push_event (munge->srcpad, event);
      }

      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *s = gst_event_get_structure (event);

      if (s && gst_structure_has_name (s, "application/x-gst-dvd"))
        rsn_audiomunge_handle_dvd_event (munge, event);

      ret = gst_pad_push_event (munge->srcpad, event);
      break;
    }
    default:
      ret = gst_pad_push_event (munge->srcpad, event);
      break;
  }

  return ret;

newseg_wrong_format:

  GST_DEBUG_OBJECT (munge, "received non TIME newsegment");
  gst_event_unref (event);
  gst_object_unref (munge);
  return FALSE;
}
예제 #20
0
static gboolean
gst_raw_parse_sink_event (GstPad * pad, GstEvent * event)
{
  GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad));
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    case GST_EVENT_FLUSH_STOP:
      /* Only happens in push mode */
      gst_raw_parse_reset (rp);
      ret = gst_pad_push_event (rp->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstClockTimeDiff start, stop, time;
      gdouble rate, arate;
      gboolean update;
      GstFormat format;

      /* Only happens in push mode */

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      if (format == GST_FORMAT_TIME) {
        gst_segment_set_newsegment_full (&rp->segment, update, rate, arate,
            GST_FORMAT_TIME, start, stop, time);
        ret = gst_pad_push_event (rp->srcpad, event);
      } else {

        gst_event_unref (event);

        ret =
            gst_raw_parse_convert (rp, format, start, GST_FORMAT_TIME, &start);
        ret &= gst_raw_parse_convert (rp, format, time, GST_FORMAT_TIME, &time);
        ret &= gst_raw_parse_convert (rp, format, stop, GST_FORMAT_TIME, &stop);
        if (!ret) {
          GST_ERROR_OBJECT (rp,
              "Failed converting to GST_FORMAT_TIME format (%d)", format);
          break;
        }

        gst_segment_set_newsegment_full (&rp->segment, update, rate, arate,
            GST_FORMAT_TIME, start, stop, time);

        /* create new segment with the fields converted to time */
        event = gst_event_new_new_segment_full (update, rate, arate,
            GST_FORMAT_TIME, start, stop, time);

        ret = gst_pad_push_event (rp->srcpad, event);
      }
      break;
    }
    default:
      ret = gst_pad_event_default (rp->sinkpad, event);
      break;
  }

  gst_object_unref (rp);

  return ret;
}
예제 #21
0
static gboolean
gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
{
  GstBaseVideoDecoder *base_video_decoder;
  GstBaseVideoDecoderClass *base_video_decoder_class;
  gboolean ret = FALSE;

  base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad));
  base_video_decoder_class =
      GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      GstVideoFrame *frame;

      frame = g_malloc0 (sizeof (GstVideoFrame));
      frame->presentation_frame_number =
          base_video_decoder->presentation_frame_number;
      frame->presentation_duration = 0;
      base_video_decoder->presentation_frame_number++;

      base_video_decoder->frames =
          g_list_append (base_video_decoder->frames, frame);
      if (base_video_decoder_class->finish) {
        base_video_decoder_class->finish (base_video_decoder, frame);
      }

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder),
          event);
    }
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      double rate;
      double applied_rate;
      GstFormat format;
      gint64 start;
      gint64 stop;
      gint64 position;

      gst_event_parse_new_segment_full (event, &update, &rate,
          &applied_rate, &format, &start, &stop, &position);

      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      gst_segment_set_newsegment_full (&base_video_decoder->state.segment,
          update, rate, applied_rate, format, start, stop, position);
      GST_DEBUG ("new segment %" GST_SEGMENT_FORMAT,
          &base_video_decoder->state.segment);

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder),
          event);
    }
      break;
    default:
      /* FIXME this changes the order of events */
      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder),
          event);
      break;
  }

done:
  gst_object_unref (base_video_decoder);
  return ret;

newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (base_video_decoder, "received non TIME newsegment");
    gst_event_unref (event);
    goto done;
  }
}
예제 #22
0
static gboolean
gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event)
{
  GstBaseVideoDecoder *base_video_decoder;
  GstBaseVideoDecoderClass *base_video_decoder_class;
  gboolean ret = FALSE;

  base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad));
  base_video_decoder_class =
      GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      if (!base_video_decoder->packetized)
        gst_base_video_decoder_drain (base_video_decoder, TRUE);

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD
          (base_video_decoder), event);
    }
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      double rate;
      double applied_rate;
      GstFormat format;
      gint64 start;
      gint64 stop;
      gint64 position;
      GstSegment *segment = &base_video_decoder->segment;

      gst_event_parse_new_segment_full (event, &update, &rate,
          &applied_rate, &format, &start, &stop, &position);

      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      if (!update) {
        gst_base_video_decoder_flush (base_video_decoder);
      }

      base_video_decoder->timestamp_offset = start;

      gst_segment_set_newsegment_full (segment,
          update, rate, applied_rate, format, start, stop, position);
      base_video_decoder->have_segment = TRUE;

      GST_WARNING ("new segment: format %d rate %g start %" GST_TIME_FORMAT
          " stop %" GST_TIME_FORMAT
          " position %" GST_TIME_FORMAT
          " update %d",
          format, rate,
          GST_TIME_ARGS (segment->start),
          GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), update);

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD
          (base_video_decoder), event);
    }
      break;

    case GST_EVENT_FLUSH_STOP:
      gst_base_video_decoder_flush (base_video_decoder);
      gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME);

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD
          (base_video_decoder), event);
      break;

    default:
      /* FIXME this changes the order of events */
      ret =
          gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD
          (base_video_decoder), event);
      break;
  }

done:
  gst_object_unref (base_video_decoder);
  return ret;

newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (base_video_decoder, "received non TIME newsegment");
    gst_event_unref (event);
    goto done;
  }
}
예제 #23
0
static GstFlowReturn
gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
{
  GstBaseVideoDecoder *base_video_decoder;
  GstBaseVideoDecoderClass *base_video_decoder_class;
  GstFlowReturn ret;

  GST_DEBUG ("chain %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

#if 0
  /* requiring the pad to be negotiated makes it impossible to use
   * oggdemux or filesrc ! decoder */
  if (!gst_pad_is_negotiated (pad)) {
    GST_DEBUG ("not negotiated");
    return GST_FLOW_NOT_NEGOTIATED;
  }
#endif

  base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad));
  base_video_decoder_class =
      GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder);

  GST_DEBUG_OBJECT (base_video_decoder, "chain");

  if (!base_video_decoder->have_segment) {
    GstEvent *event;
    GstFlowReturn ret;

    GST_WARNING
        ("Received buffer without a new-segment. Assuming timestamps start from 0.");

    gst_segment_set_newsegment_full (&base_video_decoder->segment,
        FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
    base_video_decoder->have_segment = TRUE;

    event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0,
        GST_CLOCK_TIME_NONE, 0);

    ret =
        gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder),
        event);
    if (!ret) {
      GST_ERROR ("new segment event ret=%d", ret);
      return GST_FLOW_ERROR;
    }
  }

  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
    GST_DEBUG_OBJECT (base_video_decoder, "received DISCONT buffer");
    gst_base_video_decoder_flush (base_video_decoder);
  }

  if (base_video_decoder->current_frame == NULL) {
    base_video_decoder->current_frame =
        gst_base_video_decoder_new_frame (base_video_decoder);
  }

  base_video_decoder->input_offset += GST_BUFFER_SIZE (buf);
  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    gst_base_video_decoder_add_timestamp (base_video_decoder, buf);
  }


  if (base_video_decoder->packetized) {
    base_video_decoder->current_frame->sink_buffer = buf;

    ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL);
  } else {

    gst_adapter_push (base_video_decoder->input_adapter, buf);

    ret = gst_base_video_decoder_drain (base_video_decoder, FALSE);
  }

  gst_object_unref (base_video_decoder);
  return ret;
}
예제 #24
0
static gboolean
speex_dec_sink_event (GstPad * pad, GstEvent * event)
{
  GstSpeexDec *dec;
  gboolean ret = FALSE;

  dec = GST_SPEEX_DEC (gst_pad_get_parent (pad));

  GST_LOG_OBJECT (dec, "handling %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:{
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;
      gboolean update;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      if (rate <= 0.0)
        goto newseg_wrong_rate;

      if (update) {
        /* time progressed without data, see if we can fill the gap with
         * some concealment data */
        if (dec->segment.last_stop < start) {
          GstClockTime duration;

          duration = start - dec->segment.last_stop;
          speex_dec_chain_parse_data (dec, NULL, dec->segment.last_stop,
              duration);
        }
      }

      /* now configure the values */
      gst_segment_set_newsegment_full (&dec->segment, update,
          rate, arate, GST_FORMAT_TIME, start, stop, time);

      GST_DEBUG_OBJECT (dec, "segment now: cur = %" GST_TIME_FORMAT " [%"
          GST_TIME_FORMAT " - %" GST_TIME_FORMAT "]",
          GST_TIME_ARGS (dec->segment.last_stop),
          GST_TIME_ARGS (dec->segment.start),
          GST_TIME_ARGS (dec->segment.stop));

      ret = gst_pad_push_event (dec->srcpad, event);
      break;
    }
    default:
      ret = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (dec);
  return ret;

  /* ERRORS */
newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (dec, "received non TIME newsegment");
    gst_object_unref (dec);
    return FALSE;
  }
newseg_wrong_rate:
  {
    GST_DEBUG_OBJECT (dec, "negative rates not supported yet");
    gst_object_unref (dec);
    return FALSE;
  }
}
예제 #25
0
static gboolean
gst_base_video_encoder_sink_event (GstPad * pad, GstEvent * event)
{
  GstBaseVideoEncoder *base_video_encoder;
  GstBaseVideoEncoderClass *base_video_encoder_class;
  gboolean ret = FALSE;

  base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad));
  base_video_encoder_class =
      GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      if (base_video_encoder_class->finish) {
        base_video_encoder_class->finish (base_video_encoder);
      }

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder),
          event);
    }
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      double rate;
      double applied_rate;
      GstFormat format;
      gint64 start;
      gint64 stop;
      gint64 position;

      gst_event_parse_new_segment_full (event, &update, &rate,
          &applied_rate, &format, &start, &stop, &position);

      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      GST_DEBUG ("new segment %" GST_TIME_FORMAT " %" GST_TIME_FORMAT,
          GST_TIME_ARGS (start), GST_TIME_ARGS (position));

      gst_segment_set_newsegment_full (&GST_BASE_VIDEO_CODEC
          (base_video_encoder)->segment, update, rate, applied_rate, format,
          start, stop, position);

      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder),
          event);
    }
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *s;

      s = gst_event_get_structure (event);

      if (gst_structure_has_name (s, "GstForceKeyUnit")) {
        GST_OBJECT_LOCK (base_video_encoder);
        base_video_encoder->force_keyframe = TRUE;
        GST_OBJECT_UNLOCK (base_video_encoder);
        gst_event_unref (event);
        ret = GST_FLOW_OK;
      } else {
        ret =
            gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD
            (base_video_encoder), event);
      }
      break;
    }
    default:
      /* FIXME this changes the order of events */
      ret =
          gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder),
          event);
      break;
  }

done:
  gst_object_unref (base_video_encoder);
  return ret;

newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (base_video_encoder, "received non TIME newsegment");
    gst_event_unref (event);
    goto done;
  }
}
예제 #26
0
static gboolean
gst_selector_pad_event (GstPad * pad, GstEvent * event)
{
  gboolean res = TRUE;
  gboolean forward = TRUE;
  RsnStreamSelector *sel;
  RsnSelectorPad *selpad;
  GstPad *active_sinkpad;

  sel = RSN_STREAM_SELECTOR (gst_pad_get_parent (pad));
  selpad = GST_SELECTOR_PAD_CAST (pad);

  /* only forward if we are dealing with the active sinkpad */
  active_sinkpad = rsn_stream_selector_get_active (sel, pad);
  forward = (active_sinkpad == pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_selector_pad_reset (selpad);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      gboolean update;
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      GST_DEBUG_OBJECT (selpad,
          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
          "format %d, "
          "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);

      gst_segment_set_newsegment_full (&selpad->segment, update,
          rate, arate, format, start, stop, time);
      /* if we are not going to forward the segment, mark the segment as
       * pending */
      if (!forward)
        selpad->segment_pending = TRUE;
      break;
    }
    case GST_EVENT_TAG:
    {
      GstTagList *tags;

      GST_OBJECT_LOCK (selpad);
      if (selpad->tags)
        gst_tag_list_free (selpad->tags);
      gst_event_parse_tag (event, &tags);
      if (tags)
        tags = gst_tag_list_copy (tags);
      selpad->tags = tags;
      GST_DEBUG_OBJECT (sel, "received tags %" GST_PTR_FORMAT, selpad->tags);
      GST_OBJECT_UNLOCK (selpad);
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *structure = gst_event_get_structure (event);
      if (structure != NULL &&
          gst_structure_has_name (structure, "application/x-gst-dvd")) {
        const char *type = gst_structure_get_string (structure, "event");
        if (strcmp (type, "select-pad") == 0) {
          rsn_stream_selector_set_active (sel, pad);
          forward = FALSE;
        }
      }
    }
    case GST_EVENT_EOS:
      selpad->eos = TRUE;
      break;
    default:
      break;
  }
  if (forward)
    res = gst_pad_push_event (sel->srcpad, event);
  else
    gst_event_unref (event);

  gst_object_unref (sel);

  return res;
}
예제 #27
0
static gboolean
gst_audio_rate_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean res;
  GstAudioRate *audiorate;

  audiorate = GST_AUDIO_RATE (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      GST_DEBUG_OBJECT (audiorate, "handling FLUSH_STOP");
      gst_audio_rate_reset (audiorate);
      res = gst_pad_push_event (audiorate->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;
      gboolean update;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      GST_DEBUG_OBJECT (audiorate, "handle NEWSEGMENT");
      /* FIXME:
       * - sparse stream support. For this, the update flag is TRUE and the
       *   start/time positions are updated, meaning that time progressed by
       *   time - old_time amount and we need to fill that gap with empty
       *   samples.
       * - fill the current segment if it has a valid stop position. This
       *   happens when the update flag is FALSE. With the segment helper we can
       *   calculate the accumulated time and compare this to the next_offset.
       */
      if (!update) {
        /* a new segment starts. We need to figure out what will be the next
         * sample offset. We mark the offsets as invalid so that the _chain
         * function will perform this calculation. */
        audiorate->next_offset = -1;
        audiorate->next_ts = -1;
      }

      /* we accept all formats */
      gst_segment_set_newsegment_full (&audiorate->sink_segment, update, rate,
          arate, format, start, stop, time);

      GST_DEBUG_OBJECT (audiorate, "updated segment: %" GST_SEGMENT_FORMAT,
          &audiorate->sink_segment);

      if (format == GST_FORMAT_TIME) {
        /* TIME formats can be copied to src and forwarded */
        res = gst_pad_push_event (audiorate->srcpad, event);
        memcpy (&audiorate->src_segment, &audiorate->sink_segment,
            sizeof (GstSegment));
      } else {
        /* other formats will be handled in the _chain function */
        gst_event_unref (event);
        res = TRUE;
      }
      break;
    }
    case GST_EVENT_EOS:
      /* FIXME, fill last segment */
      res = gst_pad_push_event (audiorate->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (audiorate->srcpad, event);
      break;
  }

  gst_object_unref (audiorate);

  return res;
}
예제 #28
0
static gboolean
vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean ret = FALSE;
  GstVorbisDec *dec;

  dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));

  GST_LOG_OBJECT (dec, "handling event");
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      if (dec->segment.rate < 0.0)
        vorbis_dec_chain_reverse (dec, TRUE, NULL);
      ret = gst_pad_push_event (dec->srcpad, event);
      break;
    case GST_EVENT_FLUSH_START:
      ret = gst_pad_push_event (dec->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      /* here we must clean any state in the decoder */
#ifdef HAVE_VORBIS_SYNTHESIS_RESTART
      vorbis_synthesis_restart (&dec->vd);
#endif
      gst_vorbis_dec_reset (dec);
      ret = gst_pad_push_event (dec->srcpad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time;
      gboolean update;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);

      /* we need time for now */
      if (format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      GST_DEBUG_OBJECT (dec,
          "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
          ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
          update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
          GST_TIME_ARGS (time));

      /* now configure the values */
      gst_segment_set_newsegment_full (&dec->segment, update,
          rate, arate, format, start, stop, time);
      dec->seqnum = gst_event_get_seqnum (event);

      if (dec->initialized)
        /* and forward */
        ret = gst_pad_push_event (dec->srcpad, event);
      else {
        /* store it to send once we're initialized */
        dec->pendingevents = g_list_append (dec->pendingevents, event);
        ret = TRUE;
      }
      break;
    }
    case GST_EVENT_TAG:
    {
      if (dec->initialized)
        /* and forward */
        ret = gst_pad_push_event (dec->srcpad, event);
      else {
        /* store it to send once we're initialized */
        dec->pendingevents = g_list_append (dec->pendingevents, event);
        ret = TRUE;
      }
      break;
    }
    default:
      ret = gst_pad_push_event (dec->srcpad, event);
      break;
  }
done:
  gst_object_unref (dec);

  return ret;

  /* ERRORS */
newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (dec, "received non TIME newsegment");
    goto done;
  }
}
예제 #29
0
static gboolean
gst_jasper_dec_sink_event (GstPad * pad, GstEvent * event)
{
  GstJasperDec *dec;
  gboolean res = FALSE;

  dec = GST_JASPER_DEC (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_jasper_dec_reset_qos (dec);
      gst_segment_init (&dec->segment, GST_FORMAT_TIME);
      dec->discont = TRUE;
      break;
    case GST_EVENT_NEWSEGMENT:{
      gboolean update;
      GstFormat fmt;
      gint64 start, stop, time;
      gdouble rate, arate;

      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
          &start, &stop, &time);

      switch (fmt) {
        case GST_FORMAT_TIME:
          /* great, our native segment format */
          break;
        case GST_FORMAT_BYTES:
          /* hmm .. */
          if (start != 0 || time != 0)
            goto invalid_bytes_segment;
          /* create bogus segment in TIME format, starting from 0 */
          gst_event_unref (event);
          fmt = GST_FORMAT_TIME;
          start = 0;
          stop = -1;
          time = 0;
          event = gst_event_new_new_segment (update, rate, fmt, start, stop,
              time);
          break;
        default:
          /* invalid format */
          goto invalid_format;
      }

      gst_segment_set_newsegment_full (&dec->segment, update, rate, arate,
          fmt, start, stop, time);

      GST_DEBUG_OBJECT (dec, "NEWSEGMENT %" GST_SEGMENT_FORMAT, &dec->segment);
      break;
    }
    default:
      break;
  }

  res = gst_pad_push_event (dec->srcpad, event);

done:

  gst_object_unref (dec);
  return res;

/* ERRORS */
invalid_format:
  {
    GST_WARNING_OBJECT (dec, "unknown format received in NEWSEGMENT event");
    gst_event_unref (event);
    goto done;
  }
invalid_bytes_segment:
  {
    GST_WARNING_OBJECT (dec, "can't handle NEWSEGMENT event in BYTES format "
        "with a non-0 start or non-0 time value");
    gst_event_unref (event);
    goto done;
  }
}
예제 #30
0
static gboolean
gst_au_parse_sink_event (GstPad * pad, GstEvent * event)
{
  GstAuParse *auparse;
  gboolean ret = TRUE;

  auparse = GST_AU_PARSE (gst_pad_get_parent (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate, arate;
      gint64 start, stop, time, offset = 0;
      gboolean update;
      GstSegment segment;
      GstEvent *new_event = NULL;

      gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
          &start, &stop, &time);
      gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
          start, stop, time);

      if (auparse->sample_size > 0) {
        if (start > 0) {
          offset = start;
          start -= auparse->offset;
          start = MAX (start, 0);
        }
        if (stop > 0) {
          stop -= auparse->offset;
          stop = MAX (stop, 0);
        }
        gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, start,
            GST_FORMAT_TIME, &start);
        gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, stop,
            GST_FORMAT_TIME, &stop);
      }

      if (auparse->srcpad) {
        GST_INFO_OBJECT (auparse,
            "new segment: %" GST_TIME_FORMAT " ... %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start), GST_TIME_ARGS (stop));

        new_event = gst_event_new_new_segment_full (update, rate, arate,
            GST_FORMAT_TIME, start, stop, start);

        ret = gst_pad_push_event (auparse->srcpad, new_event);
      }

      auparse->buffer_offset = offset;

      gst_event_unref (event);
      break;
    }
    case GST_EVENT_EOS:
      if (!auparse->srcpad) {
        GST_ELEMENT_ERROR (auparse, STREAM, WRONG_TYPE,
            ("No valid input found before end of stream"), (NULL));
      }
      /* fall-through */
    default:
      ret = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (auparse);
  return ret;
}