示例#1
0
static GstBusSyncReply
bus_sync_signal_handler (GstBus * bus, GstMessage * msg, gpointer data)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (data);

  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    ErrorData *data;

    GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (self),
        GST_DEBUG_GRAPH_SHOW_ALL, GST_ELEMENT_NAME (self));
    kms_base_media_muxer_dot_file (self->priv->mux);

    GST_ERROR_OBJECT (self, "Message %" GST_PTR_FORMAT, msg);

    data = create_error_data (self, msg);

    GST_ERROR_OBJECT (self, "Error: %" GST_PTR_FORMAT, msg);

    gst_task_pool_push (self->priv->pool, kms_recorder_endpoint_post_error,
        data, NULL);
  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) {
    gst_task_pool_push (self->priv->pool, kms_recorder_endpoint_on_eos_message,
        self, NULL);
  } else if ((GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STATE_CHANGED)
      && (GST_OBJECT_CAST (KMS_BASE_MEDIA_MUXER_GET_PIPELINE (self->
                  priv->mux)) == GST_MESSAGE_SRC (msg))) {
    GstState new_state, pending;

    gst_message_parse_state_changed (msg, NULL, &new_state, &pending);

    if (pending == GST_STATE_VOID_PENDING || (pending == GST_STATE_NULL
            && new_state == GST_STATE_READY)) {
      GST_DEBUG_OBJECT (self, "Pipeline changed state to %d", new_state);

      switch (new_state) {
        case GST_STATE_PLAYING:
          kms_recorder_endpoint_state_changed (self,
              KMS_URI_ENDPOINT_STATE_START);
          break;
        case GST_STATE_READY:
          kms_recorder_endpoint_state_changed (self,
              KMS_URI_ENDPOINT_STATE_STOP);
          break;
        default:
          GST_DEBUG_OBJECT (self, "Not raising event");
          break;
      }
    }
  }
  return GST_BUS_PASS;
}
static void
kms_recorder_endpoint_started (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  kms_recorder_endpoint_create_parent_directories (self);

  kms_recorder_endpoint_change_state (self);

  /* Set internal pipeline to playing */
  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PLAYING);

  BASE_TIME_LOCK (self);

  if (GST_CLOCK_TIME_IS_VALID (self->priv->paused_start)) {
    self->priv->paused_time +=
        gst_clock_get_time (kms_base_media_muxer_get_clock (self->priv->mux)) -
        self->priv->paused_start;
    self->priv->paused_start = GST_CLOCK_TIME_NONE;
  }

  BASE_TIME_UNLOCK (self);

  kms_recorder_generate_pads (self);

  kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_START);
}
static void
kms_recorder_endpoint_stopped (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  kms_recorder_endpoint_change_state (self);

  if (kms_base_media_muxer_get_state (self->priv->mux) >= GST_STATE_PAUSED) {
    kms_recorder_endpoint_send_eos_to_appsrcs (self);
    self->priv->stopping = TRUE;
  }

  kms_recorder_endpoint_remove_pads (self);

  // Reset base time data
  BASE_TIME_LOCK (self);

  g_object_set_data_full (G_OBJECT (self), BASE_TIME_DATA, NULL, NULL);

  self->priv->paused_time = G_GUINT64_CONSTANT (0);
  self->priv->paused_start = GST_CLOCK_TIME_NONE;

  BASE_TIME_UNLOCK (self);

  if (kms_base_media_muxer_get_state (self->priv->mux) < GST_STATE_PAUSED &&
      !self->priv->stopping) {
    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);
    kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
  }
}
static void
kms_recorder_endpoint_dispose (GObject * object)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (object);

  GST_DEBUG_OBJECT (self, "dispose");

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  if (self->priv->mux != NULL) {
    if (kms_base_media_muxer_get_state (self->priv->mux) != GST_STATE_NULL) {
      GST_ELEMENT_WARNING (self, RESOURCE, BUSY,
          ("Recorder may have buffers to save"),
          ("Disposing recorder when it isn't stopped."));
    }

    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);

    if (self->priv->stopping) {
      GST_WARNING_OBJECT (self, "Forcing pending stop operation to finish");
      kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
      self->priv->stopping = FALSE;
    }
  }

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  g_mutex_clear (&self->priv->base_time_lock);

  /* clean up as possible.  may be called multiple times */

  G_OBJECT_CLASS (kms_recorder_endpoint_parent_class)->dispose (object);
}
static void
kms_recorder_endpoint_send_eos_to_appsrcs (KmsRecorderEndpoint * self)
{
  GstElement *audiosrc, *videosrc;

  g_object_get (self->priv->mux, KMS_MUXING_PIPELINE_AUDIO_APPSRC,
      &audiosrc, NULL);
  g_object_get (self->priv->mux, KMS_MUXING_PIPELINE_VIDEO_APPSRC,
      &videosrc, NULL);

  if (audiosrc == NULL && videosrc == NULL) {
    kms_muxing_pipeline_set_state (self->priv->mux, GST_STATE_NULL);
    kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
    return;
  }

  kms_muxing_pipeline_set_state (self->priv->mux, GST_STATE_PLAYING);

  if (audiosrc != NULL) {
    send_eos (audiosrc);
    g_object_unref (audiosrc);
  }

  if (videosrc != NULL) {
    send_eos (videosrc);
    g_object_unref (videosrc);
  }
}
static void
kms_recorder_endpoint_started (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  kms_recorder_endpoint_change_state (self);

  /* Set internal pipeline to playing */
  gst_element_set_state (self->priv->pipeline, GST_STATE_PLAYING);

  KMS_ELEMENT_LOCK (self);

  if (GST_CLOCK_TIME_IS_VALID (self->priv->paused_start)) {
    self->priv->paused_time +=
        gst_clock_get_time (GST_ELEMENT (self->priv->pipeline)->clock) -
        self->priv->paused_start;
    self->priv->paused_start = GST_CLOCK_TIME_NONE;
  }

  KMS_ELEMENT_UNLOCK (self);

  /* Open valves */
  kms_recorder_endpoint_open_valves (self);

  kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_START);
}
static void
kms_recorder_endpoint_send_eos_to_appsrcs (KmsRecorderEndpoint * self)
{
  GstElement *audiosrc =
      gst_bin_get_by_name (GST_BIN (self->priv->pipeline), AUDIO_APPSRC);
  GstElement *videosrc =
      gst_bin_get_by_name (GST_BIN (self->priv->pipeline), VIDEO_APPSRC);

  if (audiosrc == NULL && videosrc == NULL) {
    gst_element_set_state (self->priv->pipeline, GST_STATE_NULL);
    kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
    return;
  }

  gst_element_set_state (self->priv->pipeline, GST_STATE_PLAYING);

  if (audiosrc != NULL) {
    send_eos (audiosrc);
    g_object_unref (audiosrc);
  }

  if (videosrc != NULL) {
    send_eos (videosrc);
    g_object_unref (videosrc);
  }
}
示例#8
0
static void
kms_recorder_endpoint_paused (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);
  GstClock *clk;

  kms_recorder_endpoint_change_state (self, KMS_URI_ENDPOINT_STATE_PAUSE);

  kms_recorder_endpoint_remove_pads (self);

  KMS_ELEMENT_UNLOCK (self);

  /* Set internal pipeline to GST_STATE_PAUSED */
  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PAUSED);

  KMS_ELEMENT_LOCK (self);

  clk = kms_base_media_muxer_get_clock (self->priv->mux);

  if (clk) {
    self->priv->paused_start = gst_clock_get_time (clk);
  }

  kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_PAUSE);
}
static gboolean
set_to_null_state_on_EOS (gpointer data)
{
  KmsRecorderEndpoint *recorder = KMS_RECORDER_ENDPOINT (data);

  GST_DEBUG ("Received EOS in pipeline, setting NULL state");

  KMS_ELEMENT_LOCK (KMS_ELEMENT (recorder));

  kms_muxing_pipeline_set_state (recorder->priv->mux, GST_STATE_NULL);

  kms_recorder_endpoint_state_changed (recorder, KMS_URI_ENDPOINT_STATE_STOP);

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (recorder));

  return G_SOURCE_REMOVE;
}
示例#10
0
static void
kms_recorder_endpoint_send_eos_to_appsrcs (KmsRecorderEndpoint * self)
{
  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  if (g_hash_table_size (self->priv->srcs) == 0) {
    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);
    kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
    goto end;
  }

  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PLAYING);

  g_hash_table_foreach (self->priv->srcs, (GHFunc) send_eos_cb, NULL);

end:
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
static void
kms_recorder_endpoint_stopped (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);
  GstElement *audio_src, *video_src;

  kms_recorder_endpoint_change_state (self);

  /* Close valves */
  kms_recorder_endpoint_close_valves (self);

  // Reset base time data
  audio_src =
      gst_bin_get_by_name (GST_BIN (self->priv->pipeline), AUDIO_APPSRC);
  video_src =
      gst_bin_get_by_name (GST_BIN (self->priv->pipeline), VIDEO_APPSRC);

  KMS_ELEMENT_LOCK (self);

  if (audio_src != NULL) {
    g_object_set_data_full (G_OBJECT (audio_src), BASE_TIME_DATA, NULL, NULL);
    g_object_unref (audio_src);
  }

  if (video_src != NULL) {
    g_object_set_data_full (G_OBJECT (video_src), BASE_TIME_DATA, NULL, NULL);
    g_object_unref (video_src);
  }

  self->priv->paused_time = G_GUINT64_CONSTANT (0);
  self->priv->paused_start = GST_CLOCK_TIME_NONE;

  KMS_ELEMENT_UNLOCK (self);

  if (GST_STATE (self->priv->pipeline) >= GST_STATE_PAUSED) {
    kms_recorder_endpoint_send_eos_to_appsrcs (self);
  } else {
    gst_element_set_state (self->priv->pipeline, GST_STATE_NULL);
    kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
  }
}
static void
kms_recorder_endpoint_paused (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  kms_recorder_endpoint_change_state (self);

  /* Close valves */
  kms_recorder_endpoint_remove_pads (self);

  /* Set internal pipeline to GST_STATE_PAUSED */
  kms_muxing_pipeline_set_state (self->priv->mux, GST_STATE_PAUSED);

  KMS_ELEMENT_LOCK (self);

  self->priv->paused_start =
      gst_clock_get_time (kms_muxing_pipeline_get_clock (self->priv->mux));

  KMS_ELEMENT_UNLOCK (self);

  kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_PAUSE);
}
示例#13
0
static void
kms_recorder_endpoint_on_eos (KmsBaseMediaMuxer * obj, gpointer user_data)
{
  KmsRecorderEndpoint *recorder = KMS_RECORDER_ENDPOINT (user_data);

  GST_DEBUG_OBJECT (recorder,
      "Received EOS in muxing pipeline, setting NULL state");

  KMS_ELEMENT_LOCK (KMS_ELEMENT (recorder));

  kms_base_media_muxer_set_state (recorder->priv->mux, GST_STATE_NULL);
  kms_recorder_endpoint_state_changed (recorder, KMS_URI_ENDPOINT_STATE_STOP);

  if (recorder->priv->stopping) {
    GST_WARNING_OBJECT (recorder, "Releasing pending pads");
    g_slist_foreach (recorder->priv->pending_pads,
        (GFunc) kms_recorder_release_pending_pad, recorder);
    g_slist_free_full (recorder->priv->pending_pads, g_free);
    recorder->priv->pending_pads = NULL;
    recorder->priv->stopping = FALSE;
  }

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (recorder));
}