예제 #1
0
static void
gst_wrapper_camera_bin_src_init (GstWrapperCameraBinSrc * self,
    GstWrapperCameraBinSrcClass * klass)
{
  self->vfsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->vfsrc);

  self->imgsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->imgsrc);

  self->vidsrc =
      gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME,
      GST_PAD_SRC);
  gst_element_add_pad (GST_ELEMENT (self), self->vidsrc);

  self->srcpad_event_func = GST_PAD_EVENTFUNC (self->vfsrc);

  gst_pad_set_event_function (self->imgsrc, gst_wrapper_camera_bin_src_event);
  gst_pad_set_event_function (self->vidsrc, gst_wrapper_camera_bin_src_event);
  gst_pad_set_event_function (self->vfsrc, gst_wrapper_camera_bin_src_event);

  /* TODO where are variables reset? */
  self->image_capture_count = 0;
  self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
  self->video_renegotiate = FALSE;
  self->image_renegotiate = FALSE;
  self->mode = GST_BASE_CAMERA_SRC_CAST (self)->mode;
}
예제 #2
0
static gboolean gst_a2dp_sink_init_ghost_pad(GstA2dpSink *self)
{
	GstPad *capsfilter_pad;

	/* we search for the capsfilter sinkpad */
	capsfilter_pad = gst_element_get_static_pad(self->capsfilter, "sink");

	/* now we add a ghostpad */
	self->ghostpad = GST_GHOST_PAD(gst_ghost_pad_new("sink",
		capsfilter_pad));
	g_object_unref(capsfilter_pad);

	/* the getcaps of our ghostpad must reflect the device caps */
	gst_pad_set_getcaps_function(GST_PAD(self->ghostpad),
				gst_a2dp_sink_get_caps);
	self->ghostpad_setcapsfunc = GST_PAD_SETCAPSFUNC(self->ghostpad);
	gst_pad_set_setcaps_function(GST_PAD(self->ghostpad),
			GST_DEBUG_FUNCPTR(gst_a2dp_sink_set_caps));

	/* we need to handle events on our own and we also need the eventfunc
	 * of the ghostpad for forwarding calls */
	self->ghostpad_eventfunc = GST_PAD_EVENTFUNC(GST_PAD(self->ghostpad));
	gst_pad_set_event_function(GST_PAD(self->ghostpad),
			gst_a2dp_sink_handle_event);

	if (!gst_element_add_pad(GST_ELEMENT(self), GST_PAD(self->ghostpad)))
		GST_ERROR_OBJECT(self, "failed to add ghostpad");

	return TRUE;
}
예제 #3
0
void
kms_utils_set_pad_event_function_full (GstPad * pad, GstPadEventFunction event,
    gpointer user_data, GDestroyNotify notify, gboolean chain_callbacks)
{
  GstPadEventFunction prev_func;
  KmsEventData *data;

  /* Create new data */
  data = g_slice_new0 (KmsEventData);
  data->user_func = event;
  data->user_data = user_data;
  data->user_notify = notify;

  if (!chain_callbacks) {
    goto set_func;
  }

  prev_func = GST_PAD_EVENTFUNC (pad);

  if (prev_func != kms_event_function) {
    /* Keep first data to chain to it */
    KmsEventData *first;

    first = g_slice_new0 (KmsEventData);
    first->user_func = GST_PAD_EVENTFUNC (pad);
    first->user_data = pad->eventdata;
    first->user_notify = pad->eventnotify;
    data->next = first;
  } else {
    /* Point to previous data to be chained  */
    data->next = pad->eventdata;
  }

  /* Do not destroy previous data when set_event is called */
  pad->eventnotify = NULL;
  pad->eventdata = NULL;

set_func:

  gst_pad_set_event_function_full (pad, kms_event_function, data,
      kms_event_data_destroy);
}
예제 #4
0
static GstPad *
gst_mxf_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * pad_name)
{
  GstMXFMux *mux = GST_MXF_MUX (element);
  GstMXFMuxPad *cpad;
  GstPad *pad = NULL;
  guint pad_number;
  gchar *name = NULL;
  const MXFEssenceElementWriter *writer;

  if (mux->state != GST_MXF_MUX_STATE_HEADER) {
    GST_WARNING_OBJECT (mux, "Can't request pads after writing header");
    return NULL;
  }

  writer = mxf_essence_element_writer_find (templ);
  if (!writer) {
    GST_ERROR_OBJECT (mux, "Not our template");
    return NULL;
  }

  pad_number = g_atomic_int_exchange_and_add ((gint *) & mux->n_pads, 1);
  name = gst_mxf_mux_create_pad_name (templ, pad_number);

  GST_DEBUG_OBJECT (mux, "Creating pad '%s'", name);
  pad = gst_pad_new_from_template (templ, name);
  g_free (name);
  cpad = (GstMXFMuxPad *)
      gst_collect_pads_add_pad (mux->collect, pad, sizeof (GstMXFMuxPad));
  cpad->last_timestamp = 0;
  cpad->adapter = gst_adapter_new ();
  cpad->writer = writer;

  /* FIXME: hacked way to override/extend the event function of
   * GstCollectPads; because it sets its own event function giving the
   * element no access to events.
   */
  mux->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (pad);
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_mxf_mux_handle_sink_event));

  gst_pad_set_setcaps_function (pad, gst_mxf_mux_setcaps);
  gst_pad_use_fixed_caps (pad);
  gst_pad_set_active (pad, TRUE);
  gst_element_add_pad (element, pad);

  return pad;
}
예제 #5
0
static void
gst_frei0r_mixer_init (GstFrei0rMixer * self, GstFrei0rMixerClass * klass)
{
  self->property_cache =
      gst_frei0r_property_cache_init (klass->properties, klass->n_properties);
  gst_video_info_init (&self->info);

  self->collect = gst_collect_pads_new ();
  gst_collect_pads_set_function (self->collect,
      (GstCollectPadsFunction) gst_frei0r_mixer_collected, self);
  gst_collect_pads_set_event_function (self->collect,
      (GstCollectPadsEventFunction) gst_frei0r_mixer_sink_event, self);
  gst_collect_pads_set_query_function (self->collect,
      (GstCollectPadsQueryFunction) gst_frei0r_mixer_sink_query, self);

  self->src =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (GST_ELEMENT_CLASS (klass), "src"), "src");
  gst_pad_set_query_function (self->src,
      GST_DEBUG_FUNCPTR (gst_frei0r_mixer_src_query));
  gst_pad_set_event_function (self->src,
      GST_DEBUG_FUNCPTR (gst_frei0r_mixer_src_event));
  gst_element_add_pad (GST_ELEMENT_CAST (self), self->src);

  self->sink0 =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (GST_ELEMENT_CLASS (klass), "sink_0"), "sink_0");
  gst_collect_pads_add_pad (self->collect, self->sink0,
      sizeof (GstCollectData), NULL, TRUE);
  self->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (self->sink0);
  gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink0);

  self->sink1 =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (GST_ELEMENT_CLASS (klass), "sink_1"), "sink_1");
  gst_collect_pads_add_pad (self->collect, self->sink1,
      sizeof (GstCollectData), NULL, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink1);

  if (klass->info->plugin_type == F0R_PLUGIN_TYPE_MIXER3) {
    self->sink2 =
        gst_pad_new_from_template (gst_element_class_get_pad_template
        (GST_ELEMENT_CLASS (klass), "sink_2"), "sink_2");
    gst_collect_pads_add_pad (self->collect, self->sink2,
        sizeof (GstCollectData), NULL, TRUE);
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink2);
  }

}
static void
gst_aspect_ratio_crop_init (GstAspectRatioCrop * aspect_ratio_crop)
{
  GstPad *link_pad;
  GstPad *src_pad;

  GST_DEBUG_CATEGORY_INIT (aspect_ratio_crop_debug, "aspectratiocrop", 0,
      "aspectratiocrop");

  aspect_ratio_crop->ar_num = 0;
  aspect_ratio_crop->ar_denom = 1;

  g_mutex_init (&aspect_ratio_crop->crop_lock);

  /* add the transform element */
  aspect_ratio_crop->videocrop = gst_element_factory_make ("videocrop", NULL);
  gst_bin_add (GST_BIN (aspect_ratio_crop), aspect_ratio_crop->videocrop);

  /* create ghost pad src */
  link_pad =
      gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop),
      "src");
  src_pad = gst_ghost_pad_new ("src", link_pad);
  gst_pad_set_query_function (src_pad,
      GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_src_query));
  gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop), src_pad);
  gst_object_unref (link_pad);
  /* create ghost pad sink */
  link_pad =
      gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop),
      "sink");
  aspect_ratio_crop->sink = gst_ghost_pad_new ("sink", link_pad);
  gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop),
      aspect_ratio_crop->sink);
  gst_object_unref (link_pad);

  aspect_ratio_crop->sinkpad_old_eventfunc =
      GST_PAD_EVENTFUNC (aspect_ratio_crop->sink);
  gst_pad_set_event_function (aspect_ratio_crop->sink,
      GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_sink_event));
}
예제 #7
0
static void
gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc, GstVP8EncClass * klass)
{

  GST_DEBUG_OBJECT (gst_vp8_enc, "init");

  gst_vp8_enc->bitrate = DEFAULT_BITRATE;
  gst_vp8_enc->mode = DEFAULT_MODE;
  gst_vp8_enc->quality = DEFAULT_QUALITY;
  gst_vp8_enc->error_resilient = DEFAULT_ERROR_RESILIENT;
  gst_vp8_enc->max_latency = DEFAULT_MAX_LATENCY;
  gst_vp8_enc->max_keyframe_distance = DEFAULT_MAX_KEYFRAME_DISTANCE;
  gst_vp8_enc->multipass_mode = DEFAULT_MULTIPASS_MODE;
  gst_vp8_enc->multipass_cache_file = DEFAULT_MULTIPASS_CACHE_FILE;
  gst_vp8_enc->auto_alt_ref_frames = DEFAULT_AUTO_ALT_REF_FRAMES;

  /* FIXME: Add sink/src event vmethods */
  gst_vp8_enc->base_sink_event_func =
      GST_PAD_EVENTFUNC (GST_BASE_VIDEO_CODEC_SINK_PAD (gst_vp8_enc));
  gst_pad_set_event_function (GST_BASE_VIDEO_CODEC_SINK_PAD (gst_vp8_enc),
      gst_vp8_enc_sink_event);
}
예제 #8
0
static void
rsn_dec_init (RsnDec * self, RsnDecClass * klass)
{
  GstPadTemplate *templ;

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_assert (templ != NULL);
  self->sinkpad =
      GST_GHOST_PAD_CAST (gst_ghost_pad_new_no_target_from_template ("sink",
          templ));
  self->sink_event_func = GST_PAD_EVENTFUNC (self->sinkpad);
  gst_pad_set_event_function (GST_PAD_CAST (self->sinkpad),
      GST_DEBUG_FUNCPTR (rsn_dec_sink_event));

  templ = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_assert (templ != NULL);
  self->srcpad =
      GST_GHOST_PAD_CAST (gst_ghost_pad_new_no_target_from_template ("src",
          templ));
  gst_element_add_pad (GST_ELEMENT (self), GST_PAD_CAST (self->sinkpad));
  gst_element_add_pad (GST_ELEMENT (self), GST_PAD_CAST (self->srcpad));
}
예제 #9
0
static GstPad *
gst_interleave_request_new_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * req_name)
{
  GstInterleave *self = GST_INTERLEAVE (element);

  GstPad *new_pad;

  gchar *pad_name;

  gint channels, padnumber;
  GValue val = { 0, };

  if (templ->direction != GST_PAD_SINK)
    goto not_sink_pad;

  channels = g_atomic_int_exchange_and_add (&self->channels, 1);
  padnumber = g_atomic_int_exchange_and_add (&self->padcounter, 1);

  pad_name = g_strdup_printf ("sink%d", padnumber);
  new_pad = GST_PAD_CAST (g_object_new (GST_TYPE_INTERLEAVE_PAD,
          "name", pad_name, "direction", templ->direction,
          "template", templ, NULL));
  GST_INTERLEAVE_PAD_CAST (new_pad)->channel = channels;
  GST_DEBUG_OBJECT (self, "requested new pad %s", pad_name);
  g_free (pad_name);

  gst_pad_set_setcaps_function (new_pad,
      GST_DEBUG_FUNCPTR (gst_interleave_sink_setcaps));
  gst_pad_set_getcaps_function (new_pad,
      GST_DEBUG_FUNCPTR (gst_interleave_sink_getcaps));

  gst_collect_pads_add_pad (self->collect, new_pad, sizeof (GstCollectData));

  /* FIXME: hacked way to override/extend the event function of
   * GstCollectPads; because it sets its own event function giving the
   * element no access to events */
  self->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (new_pad);
  gst_pad_set_event_function (new_pad,
      GST_DEBUG_FUNCPTR (gst_interleave_sink_event));

  if (!gst_element_add_pad (element, new_pad))
    goto could_not_add;

  g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION);
  g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_NONE);
  self->input_channel_positions =
      g_value_array_append (self->input_channel_positions, &val);
  g_value_unset (&val);

  /* Update the src caps if we already have them */
  if (self->sinkcaps) {
    GstCaps *srccaps;

    GstStructure *s;

    /* Take lock to make sure processing finishes first */
    GST_OBJECT_LOCK (self->collect);

    srccaps = gst_caps_copy (self->sinkcaps);
    s = gst_caps_get_structure (srccaps, 0);

    gst_structure_set (s, "channels", G_TYPE_INT, self->channels, NULL);
    gst_interleave_set_channel_positions (self, s);

    gst_pad_set_caps (self->src, srccaps);
    gst_caps_unref (srccaps);

    GST_OBJECT_UNLOCK (self->collect);
  }

  return new_pad;

  /* errors */
not_sink_pad:
  {
    g_warning ("interleave: requested new pad that is not a SINK pad\n");
    return NULL;
  }
could_not_add:
  {
    GST_DEBUG_OBJECT (self, "could not add pad %s", GST_PAD_NAME (new_pad));
    gst_collect_pads_remove_pad (self->collect, new_pad);
    gst_object_unref (new_pad);
    return NULL;
  }
}
예제 #10
0
static GstPad *
gst_ffmpegmux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name)
{
  GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) element;
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GstFFMpegMuxPad *collect_pad;
  gchar *padname;
  GstPad *pad;
  AVStream *st;
  enum CodecType type;
  gint bitrate = 0, framesize = 0;

  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL);
  g_return_val_if_fail (ffmpegmux->opened == FALSE, NULL);

  /* figure out a name that *we* like */
  if (templ == gst_element_class_get_pad_template (klass, "video_%d")) {
    padname = g_strdup_printf ("video_%d", ffmpegmux->videopads++);
    type = CODEC_TYPE_VIDEO;
    bitrate = 64 * 1024;
    framesize = 1152;
  } else if (templ == gst_element_class_get_pad_template (klass, "audio_%d")) {
    padname = g_strdup_printf ("audio_%d", ffmpegmux->audiopads++);
    type = CODEC_TYPE_AUDIO;
    bitrate = 285 * 1024;
  } else {
    g_warning ("ffmux: unknown pad template!");
    return NULL;
  }

  /* create pad */
  pad = gst_pad_new_from_template (templ, padname);
  collect_pad = (GstFFMpegMuxPad *)
      gst_collect_pads_add_pad (ffmpegmux->collect, pad,
      sizeof (GstFFMpegMuxPad));
  collect_pad->padnum = ffmpegmux->context->nb_streams;

  /* small hack to put our own event pad function and chain up to collect pad */
  ffmpegmux->event_function = GST_PAD_EVENTFUNC (pad);
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_ffmpegmux_sink_event));

  gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_ffmpegmux_setcaps));
  gst_element_add_pad (element, pad);

  /* AVStream needs to be created */
  st = av_new_stream (ffmpegmux->context, collect_pad->padnum);
  st->codec->codec_type = type;
  st->codec->codec_id = CODEC_ID_NONE;  /* this is a check afterwards */
  st->stream_copy = 1;          /* we're not the actual encoder */
  st->codec->bit_rate = bitrate;
  st->codec->frame_size = framesize;
  /* we fill in codec during capsnego */

  /* we love debug output (c) (tm) (r) */
  GST_DEBUG ("Created %s pad for ffmux_%s element",
      padname, ((GstFFMpegMuxClass *) klass)->in_plugin->name);
  g_free (padname);

  return pad;
}
예제 #11
0
static void
gst_camera_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCameraBin *camera = GST_CAMERA_BIN_CAST (object);

  switch (prop_id) {
    case PROP_MODE:
      gst_camera_bin_change_mode (camera, g_value_get_enum (value));
      break;
    case PROP_LOCATION:
      gst_camera_bin_set_location (camera, g_value_get_string (value));
      break;
    case PROP_CAMERA_SRC:
      gst_camera_bin_set_camera_src (camera, g_value_get_object (value));
      break;
    case PROP_IMAGE_CAPTURE_CAPS:{
      GstPad *pad = NULL;

      if (camera->src)
        pad =
            gst_element_get_static_pad (camera->src,
            GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);

      GST_DEBUG_OBJECT (camera,
          "Setting image capture caps to %" GST_PTR_FORMAT,
          gst_value_get_caps (value));

      /* set the capsfilter caps and notify the src to renegotiate */
      g_object_set (camera->imagebin_capsfilter, "caps",
          gst_value_get_caps (value), NULL);
      if (pad) {
        GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s",
            GST_PAD_NAME (pad));
        GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ());
        gst_object_unref (pad);
      }
    }
      break;
    case PROP_VIDEO_CAPTURE_CAPS:{
      GstPad *pad = NULL;

      if (camera->src)
        pad =
            gst_element_get_static_pad (camera->src,
            GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);

      GST_DEBUG_OBJECT (camera,
          "Setting video capture caps to %" GST_PTR_FORMAT,
          gst_value_get_caps (value));

      /* set the capsfilter caps and notify the src to renegotiate */
      g_object_set (camera->videobin_capsfilter, "caps",
          gst_value_get_caps (value), NULL);
      if (pad) {
        GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s",
            GST_PAD_NAME (pad));
        GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ());
        gst_object_unref (pad);
      }
    }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}