예제 #1
0
static gboolean
gst_rpi_cam_src_event (GstBaseSrc * parent, GstEvent * event)
{
  GstRpiCamSrc *src = GST_RPICAMSRC (parent);
  gboolean ret;
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    case GST_EVENT_CUSTOM_UPSTREAM:
      if (gst_video_event_is_force_key_unit (event)) {
        if (src->started) {
          ret = raspi_capture_request_i_frame (src->capture_state);
        } else {
          ret = FALSE;
        }
        gst_event_unref (event);
      } else {
        ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event);
      }
      break;
    default:
      ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event);
      break;
  }
  return ret;
}
예제 #2
0
static GstPadProbeReturn encoder_appsink_event_probe (GstPad *pad, GstPadProbeInfo *info, gpointer data)
{
        GstEvent *event = gst_pad_probe_info_get_event (info);
        Encoder *encoder = data;
        GstClockTime timestamp, running_time, stream_time;
        gboolean all_headers;
        guint count;

        if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
                GST_ERROR ("End of Stream of encoder %s", encoder->name);
                *(encoder->output->eos) = TRUE;
                return GST_PAD_PROBE_OK;
        }

        if (!gst_video_event_is_force_key_unit (event)) {
                return GST_PAD_PROBE_OK;
        }

        /* force key unit event */
        gst_video_event_parse_downstream_force_key_unit (event, &timestamp, &stream_time, &running_time, &all_headers, &count);
        if (encoder->last_segment_duration != 0) {
                encoder->last_running_time = timestamp;
        }

        return GST_PAD_PROBE_OK;
}
예제 #3
0
static gboolean
mpegtsmux_sink_event (GstPad * pad, GstEvent * event)
{
  MpegTsMux *mux = GST_MPEG_TSMUX (gst_pad_get_parent (pad));
  MpegTsPadData *ts_data;
  gboolean res = TRUE;
  gboolean forward = TRUE;

  ts_data = (MpegTsPadData *) gst_pad_get_element_private (pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      GstClockTime timestamp, stream_time, running_time;
      gboolean all_headers;
      guint count;

      if (!gst_video_event_is_force_key_unit (event))
        goto out;

      forward = FALSE;

      gst_video_event_parse_downstream_force_key_unit (event,
          &timestamp, &stream_time, &running_time, &all_headers, &count);
      GST_INFO_OBJECT (mux, "have downstream force-key-unit event on pad %s, "
          "seqnum %d, running-time %" GST_TIME_FORMAT " count %d",
          gst_pad_get_name (pad), gst_event_get_seqnum (event),
          GST_TIME_ARGS (running_time), count);

      if (mux->force_key_unit_event != NULL) {
        GST_INFO_OBJECT (mux, "skipping downstream force key unit event "
            "as an upstream force key unit is already queued");
        goto out;
      }

      if (!all_headers)
        goto out;

      mux->pending_key_unit_ts = running_time;
      gst_event_replace (&mux->force_key_unit_event, event);
      break;
    }
    default:
      break;
  }

out:
  if (forward)
    res = ts_data->eventfunc (pad, event);

  gst_object_unref (mux);
  return res;
}
예제 #4
0
static GstPadProbeReturn
control_duplicates (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);

  if (gst_video_event_is_force_key_unit (event)) {
    if (check_last_request_time (pad)) {
      GST_TRACE_OBJECT (pad, "Sending keyframe request");
      return GST_PAD_PROBE_OK;
    } else {
      GST_TRACE_OBJECT (pad, "Dropping keyframe request");
      return GST_PAD_PROBE_DROP;
    }
  }

  return GST_PAD_PROBE_OK;
}
예제 #5
0
static GstPadProbeReturn
gst_hls_sink_ghost_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (data);
  GstEvent *event = gst_pad_probe_info_get_event (info);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &sink->segment);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&sink->segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      GstClockTime timestamp;
      GstClockTime running_time, stream_time;
      gboolean all_headers;
      guint count;

      if (!gst_video_event_is_force_key_unit (event))
        break;

      gst_event_replace (&sink->force_key_unit_event, event);
      gst_video_event_parse_downstream_force_key_unit (event,
          &timestamp, &stream_time, &running_time, &all_headers, &count);
      GST_INFO_OBJECT (sink, "setting index %d", count);
      sink->index = count;
      break;
    }
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}
예제 #6
0
static gboolean
gst_multi_file_sink_event (GstBaseSink * sink, GstEvent * event)
{
  GstMultiFileSink *multifilesink;
  gchar *filename;

  multifilesink = GST_MULTI_FILE_SINK (sink);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      GstClockTime timestamp, duration;
      GstClockTime running_time, stream_time;
      guint64 offset, offset_end;
      gboolean all_headers;
      guint count;

      if (multifilesink->next_file != GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT ||
          !gst_video_event_is_force_key_unit (event))
        goto out;

      gst_video_event_parse_downstream_force_key_unit (event, &timestamp,
          &stream_time, &running_time, &all_headers, &count);

      if (multifilesink->force_key_unit_count != -1 &&
          multifilesink->force_key_unit_count == count)
        goto out;

      multifilesink->force_key_unit_count = count;

      if (multifilesink->file) {
        duration = GST_CLOCK_TIME_NONE;
        offset = offset_end = -1;
        filename = g_strdup_printf (multifilesink->filename,
            multifilesink->index);

        gst_multi_file_sink_close_file (multifilesink, NULL);

        gst_multi_file_sink_post_message_full (multifilesink, timestamp,
            duration, offset, offset_end, running_time, stream_time, filename);
        g_free (filename);
      }

      if (multifilesink->file == NULL) {
        if (!gst_multi_file_sink_open_next_file (multifilesink))
          goto stdio_write_error;
      }

      break;
    }
    case GST_EVENT_EOS:
      if (multifilesink->aggregate_gops) {
        GstBuffer *buf = gst_buffer_new ();

        /* push key unit buffer to force writing out the pending GOP data */
        GST_INFO_OBJECT (sink, "EOS, write pending GOP data");
        GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
        gst_multi_file_sink_render (sink, buf);
        gst_buffer_unref (buf);
      }
      if (multifilesink->file) {
        gchar *filename;

        filename = g_strdup_printf (multifilesink->filename,
            multifilesink->index);

        gst_multi_file_sink_close_file (multifilesink, NULL);

        gst_multi_file_sink_post_message_from_time (multifilesink,
            GST_BASE_SINK (multifilesink)->segment.position, -1, filename);
        g_free (filename);
      }
      break;
    default:
      break;
  }

out:
  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);

  /* ERRORS */
stdio_write_error:
  {
    GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE,
        ("Error while writing to file."), (NULL));
    gst_event_unref (event);
    return FALSE;
  }
}
예제 #7
0
static gboolean
mpegtsmux_src_event (GstPad * pad, GstEvent * event)
{
  MpegTsMux *mux = GST_MPEG_TSMUX (gst_pad_get_parent (pad));
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_UPSTREAM:
    {
      GstIterator *iter;
      GstIteratorResult iter_ret;
      GstPad *sinkpad;
      GstClockTime running_time;
      gboolean all_headers, done;
      guint count;

      if (!gst_video_event_is_force_key_unit (event))
        break;

      gst_video_event_parse_upstream_force_key_unit (event,
          &running_time, &all_headers, &count);

      GST_INFO_OBJECT (mux, "received upstream force-key-unit event, "
          "seqnum %d running_time %" GST_TIME_FORMAT " all_headers %d count %d",
          gst_event_get_seqnum (event), GST_TIME_ARGS (running_time),
          all_headers, count);

      if (!all_headers)
        break;

      mux->pending_key_unit_ts = running_time;
      gst_event_replace (&mux->force_key_unit_event, event);

      iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (mux));
      done = FALSE;
      while (!done) {
        gboolean res = FALSE, tmp;
        iter_ret = gst_iterator_next (iter, (gpointer *) & sinkpad);

        switch (iter_ret) {
          case GST_ITERATOR_DONE:
            done = TRUE;
            break;
          case GST_ITERATOR_OK:
            GST_INFO_OBJECT (mux, "forwarding to %s",
                gst_pad_get_name (sinkpad));
            tmp = gst_pad_push_event (sinkpad, gst_event_ref (event));
            GST_INFO_OBJECT (mux, "result %d", tmp);
            /* succeed if at least one pad succeeds */
            res |= tmp;
            gst_object_unref (sinkpad);
            break;
          case GST_ITERATOR_ERROR:
            done = TRUE;
            break;
          case GST_ITERATOR_RESYNC:
            break;
        }
      }

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

  gst_object_unref (mux);
  return res;
}