예제 #1
0
static void
gst_amrmux_init( GstAmrMux * amrmux, GstAmrMuxClass *amrmux_klass)
{  
   GstElementClass *klass = GST_ELEMENT_CLASS (amrmux_klass);
   
   //By default we have to write header   
   amrmux->writeheader= TRUE;
   
   //Add Sink pad to this element
      
   amrmux->sinkpad = gst_pad_new_from_template (
    gst_element_class_get_pad_template (klass, "sink"), "sink");  
  
  gst_element_add_pad (GST_ELEMENT (amrmux), amrmux->sinkpad);

    
  //Add Src pad to this element
  amrmux->srcpad = gst_pad_new_from_template (
    gst_element_class_get_pad_template (klass, "src"), "src");

  gst_element_add_pad (GST_ELEMENT (amrmux), amrmux->srcpad);  
    
  gst_pad_set_chain_function (amrmux->sinkpad, gst_amrmux_chain);

}
예제 #2
0
파일: gstwildmidi.c 프로젝트: zsx/ossbuild
/* initialize the new element
 * instantiate pads and add them to element
 * set functions
 * initialize structure
 */
static void
gst_wildmidi_init (GstWildmidi * filter, GstWildmidiClass * g_class)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);

  filter->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");

  gst_pad_set_activatepull_function (filter->sinkpad,
      gst_wildmidi_activatepull);
  gst_pad_set_activate_function (filter->sinkpad, gst_wildmidi_activate);
  gst_pad_set_event_function (filter->sinkpad, gst_wildmidi_sink_event);
  gst_pad_set_chain_function (filter->sinkpad, gst_wildmidi_chain);
  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);

  filter->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "src"), "src");

  gst_pad_set_query_function (filter->srcpad, gst_wildmidi_src_query);
  gst_pad_set_event_function (filter->srcpad, gst_wildmidi_src_event);
  gst_pad_use_fixed_caps (filter->srcpad);

  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);

  gst_segment_init (filter->o_segment, GST_FORMAT_DEFAULT);

  filter->adapter = gst_adapter_new ();

  filter->bytes_per_frame = WILDMIDI_BPS;
}
static void
gst_base_rtp_depayload_init (GstBaseRTPDepayload * filter,
    GstBaseRTPDepayloadClass * klass)
{
  GstPadTemplate *pad_template;
  GstBaseRTPDepayloadPrivate *priv;

  priv = GST_BASE_RTP_DEPAYLOAD_GET_PRIVATE (filter);
  filter->priv = priv;

  GST_DEBUG_OBJECT (filter, "init");

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);
  filter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  gst_pad_set_setcaps_function (filter->sinkpad,
      gst_base_rtp_depayload_setcaps);
  gst_pad_set_chain_function (filter->sinkpad, gst_base_rtp_depayload_chain);
  gst_pad_set_event_function (filter->sinkpad,
      gst_base_rtp_depayload_handle_sink_event);
  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_return_if_fail (pad_template != NULL);
  filter->srcpad = gst_pad_new_from_template (pad_template, "src");
  gst_pad_use_fixed_caps (filter->srcpad);
  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);

  filter->queue = g_queue_new ();
  filter->queue_delay = DEFAULT_QUEUE_DELAY;

  gst_segment_init (&filter->segment, GST_FORMAT_UNDEFINED);
}
static void
gst_video_parse_init (GstVideoParse * vp)
{
  GstPad *inner_pad;
  GstPad *ghostpad;

  vp->rawvideoparse =
      gst_element_factory_make ("rawvideoparse", "inner_rawvideoparse");
  g_assert (vp->rawvideoparse != NULL);

  gst_bin_add (GST_BIN (vp), vp->rawvideoparse);

  inner_pad = gst_element_get_static_pad (vp->rawvideoparse, "sink");
  ghostpad =
      gst_ghost_pad_new_from_template ("sink", inner_pad,
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (vp), "sink"));
  gst_element_add_pad (GST_ELEMENT (vp), ghostpad);
  gst_object_unref (GST_OBJECT (inner_pad));

  inner_pad = gst_element_get_static_pad (vp->rawvideoparse, "src");
  ghostpad =
      gst_ghost_pad_new_from_template ("src", inner_pad,
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (vp), "src"));
  gst_element_add_pad (GST_ELEMENT (vp), ghostpad);
  gst_object_unref (GST_OBJECT (inner_pad));
}
예제 #5
0
static void
gst_base_video_codec_init (GstBaseVideoCodec * base_video_codec,
    GstBaseVideoCodecClass * klass)
{
  GstPadTemplate *pad_template;

  GST_DEBUG ("gst_base_video_codec_init");

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);

  base_video_codec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  //gst_pad_set_query_function (base_video_codec->sinkpad,
  //    gst_base_video_codec_sink_query);
  gst_element_add_pad (GST_ELEMENT (base_video_codec),
      base_video_codec->sinkpad);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_return_if_fail (pad_template != NULL);

  base_video_codec->srcpad = gst_pad_new_from_template (pad_template, "src");
  gst_element_add_pad (GST_ELEMENT (base_video_codec),
      base_video_codec->srcpad);

  gst_segment_init (&base_video_codec->segment, GST_FORMAT_TIME);

}
static void
gst_tta_parse_init (GstTtaParse * ttaparse)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (ttaparse);

  ttaparse->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");

  ttaparse->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "src"), "src");
  gst_pad_use_fixed_caps (ttaparse->srcpad);
  gst_pad_set_query_type_function (ttaparse->srcpad,
      gst_tta_parse_get_query_types);
  gst_pad_set_query_function (ttaparse->srcpad, gst_tta_parse_query);
  gst_pad_set_event_function (ttaparse->srcpad, gst_tta_parse_src_event);

  gst_element_add_pad (GST_ELEMENT (ttaparse), ttaparse->sinkpad);
  gst_element_add_pad (GST_ELEMENT (ttaparse), ttaparse->srcpad);
  gst_pad_set_activate_function (ttaparse->sinkpad, gst_tta_parse_activate);
  gst_pad_set_activatepull_function (ttaparse->sinkpad,
      gst_tta_parse_activate_pull);

  gst_tta_parse_reset (ttaparse);
}
예제 #7
0
KmsElementPadType
kms_element_get_pad_type (KmsElement * self, GstPad * pad)
{
  KmsElementPadType type;
  GstPadTemplate *templ;

  g_return_val_if_fail (self != NULL, KMS_ELEMENT_PAD_TYPE_DATA);

  templ = gst_pad_get_pad_template (pad);

  if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (self)), AUDIO_SRC_PAD) ||
      g_strstr_len (GST_OBJECT_NAME (pad), -1, "audio")) {
    type = KMS_ELEMENT_PAD_TYPE_AUDIO;
  } else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (self)), VIDEO_SRC_PAD) ||
      g_strstr_len (GST_OBJECT_NAME (pad), -1, "video")) {
    type = KMS_ELEMENT_PAD_TYPE_VIDEO;
  } else {
    type = KMS_ELEMENT_PAD_TYPE_DATA;
  }

  gst_object_unref (templ);

  return type;
}
예제 #8
0
static void
gst_vtenc_init (GstVTEnc * self)
{
  GstVTEncClass *klass = (GstVTEncClass *) G_OBJECT_GET_CLASS (self);
  GstElementClass *element_klass = GST_ELEMENT_CLASS (klass);
  GstElement *element = GST_ELEMENT (self);

  self->details = GST_VTENC_CLASS_GET_CODEC_DETAILS (klass);

  self->sinkpad = gst_pad_new_from_template
      (gst_element_class_get_pad_template (element_klass, "sink"), "sink");
  gst_element_add_pad (element, self->sinkpad);
  gst_pad_set_event_function (self->sinkpad, gst_vtenc_sink_event);
  gst_pad_set_chain_function (self->sinkpad, gst_vtenc_chain);

  self->srcpad = gst_pad_new_from_template
      (gst_element_class_get_pad_template (element_klass, "src"), "src");
  gst_pad_set_event_function (self->srcpad, gst_vtenc_src_event);
  gst_element_add_pad (element, self->srcpad);

  /* These could be controlled by properties later */
  self->dump_properties = FALSE;
  self->dump_attributes = FALSE;

  self->session = NULL;
}
static void
gst_unaligned_audio_parse_init (GstUnalignedAudioParse * unaligned_audio_parse)
{
  GstPad *inner_pad;
  GstPad *ghostpad;

  unaligned_audio_parse->inner_parser =
      gst_element_factory_make ("rawaudioparse", "inner_parser");
  g_assert (unaligned_audio_parse->inner_parser != NULL);

  g_object_set (G_OBJECT (unaligned_audio_parse->inner_parser),
      "use-sink-caps", TRUE, NULL);

  gst_bin_add (GST_BIN (unaligned_audio_parse),
      unaligned_audio_parse->inner_parser);

  inner_pad =
      gst_element_get_static_pad (unaligned_audio_parse->inner_parser, "sink");
  ghostpad =
      gst_ghost_pad_new_from_template ("sink", inner_pad,
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS
          (unaligned_audio_parse), "sink"));
  gst_element_add_pad (GST_ELEMENT (unaligned_audio_parse), ghostpad);
  gst_object_unref (GST_OBJECT (inner_pad));

  inner_pad = gst_element_get_static_pad (unaligned_audio_parse->inner_parser,
      "src");
  ghostpad =
      gst_ghost_pad_new_from_template ("src", inner_pad,
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS
          (unaligned_audio_parse), "src"));
  gst_element_add_pad (GST_ELEMENT (unaligned_audio_parse), ghostpad);
  gst_object_unref (GST_OBJECT (inner_pad));
}
예제 #10
0
static void
gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux)
{
    GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);

    demux->rtp_sink =
        gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
                                   "sink"), "sink");
    gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain);
    gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event);
    gst_pad_set_iterate_internal_links_function (demux->rtp_sink,
            gst_rtp_ssrc_demux_iterate_internal_links_sink);
    gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink);

    demux->rtcp_sink =
        gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
                                   "rtcp_sink"), "rtcp_sink");
    gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain);
    gst_pad_set_event_function (demux->rtcp_sink, gst_rtp_ssrc_demux_sink_event);
    gst_pad_set_iterate_internal_links_function (demux->rtcp_sink,
            gst_rtp_ssrc_demux_iterate_internal_links_sink);
    gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink);

    g_rec_mutex_init (&demux->padlock);
}
static void
gst_rtp_rtx_receive_init (GstRtpRtxReceive * rtx)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (rtx);

  rtx->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "src"), "src");
  GST_PAD_SET_PROXY_CAPS (rtx->srcpad);
  GST_PAD_SET_PROXY_ALLOCATION (rtx->srcpad);
  gst_pad_set_event_function (rtx->srcpad,
      GST_DEBUG_FUNCPTR (gst_rtp_rtx_receive_src_event));
  gst_element_add_pad (GST_ELEMENT (rtx), rtx->srcpad);

  rtx->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");
  GST_PAD_SET_PROXY_CAPS (rtx->sinkpad);
  GST_PAD_SET_PROXY_ALLOCATION (rtx->sinkpad);
  gst_pad_set_chain_function (rtx->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_rtx_receive_chain));
  gst_element_add_pad (GST_ELEMENT (rtx), rtx->sinkpad);

  rtx->ssrc2_ssrc1_map = g_hash_table_new (g_direct_hash, g_direct_equal);
  rtx->seqnum_ssrc1_map = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, (GDestroyNotify) ssrc_assoc_free);

  rtx->rtx_pt_map = g_hash_table_new (g_direct_hash, g_direct_equal);
}
예제 #12
0
static void
gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux,
    GstRtpSsrcDemuxClass * g_class)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);

  demux->rtp_sink =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");
  gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain);
  gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event);
  gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink);

  demux->rtcp_sink =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "rtcp_sink"), "rtcp_sink");
  gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain);
  gst_pad_set_event_function (demux->rtcp_sink,
      gst_rtp_ssrc_demux_rtcp_sink_event);
  gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink);

  demux->padlock = g_mutex_new ();

  gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
}
예제 #13
0
static GstPad *
gst_rdt_manager_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstRDTManager *rdtmanager;
  GstElementClass *klass;
  GstPad *result;

  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (GST_IS_RDT_MANAGER (element), NULL);

  rdtmanager = GST_RDT_MANAGER (element);
  klass = GST_ELEMENT_GET_CLASS (element);

  /* figure out the template */
  if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u")) {
    result = create_recv_rtp (rdtmanager, templ, name);
  } else if (templ == gst_element_class_get_pad_template (klass,
          "recv_rtcp_sink_%u")) {
    result = create_recv_rtcp (rdtmanager, templ, name);
  } else if (templ == gst_element_class_get_pad_template (klass, "rtcp_src_%u")) {
    result = create_rtcp (rdtmanager, templ, name);
  } else
    goto wrong_template;

  return result;

  /* ERRORS */
wrong_template:
  {
    g_warning ("rdtmanager: this is not our template");
    return NULL;
  }
}
static void
mfw_gst_vpuenc_init(GstVPU_Enc * vpu_enc, GstVPU_EncClass * gclass)
{
	GST_DEBUG("mfw_gst_vpuenc_init");

	GstElementClass *klass = GST_ELEMENT_GET_CLASS(vpu_enc);

	/* create the sink and src pads */
	vpu_enc->sinkpad =
	    gst_pad_new_from_template(gst_element_class_get_pad_template
				      (klass, "sink"), "sink");
	vpu_enc->srcpad =
	    gst_pad_new_from_template(gst_element_class_get_pad_template
				      (klass, "src"), "src");
	gst_element_add_pad(GST_ELEMENT(vpu_enc), vpu_enc->sinkpad);
	gst_element_add_pad(GST_ELEMENT(vpu_enc), vpu_enc->srcpad);
	vpu_enc->parent_class = g_type_class_peek_parent(gclass);
	gst_pad_set_chain_function(vpu_enc->sinkpad, mfw_gst_vpuenc_chain);
	gst_pad_set_event_function(vpu_enc->sinkpad,
				   GST_DEBUG_FUNCPTR
				   (mfw_gst_vpuenc_sink_event));

	gst_pad_set_setcaps_function(vpu_enc->sinkpad, mfw_gst_vpuenc_setcaps);

	vpu_enc->codec = STD_AVC;
	vpu_enc->device = g_strdup(VPU_DEVICE);
	vpu_enc->framerate = DEFAULT_FRAME_RATE;
	vpu_enc->bitrate = 0;
	vpu_enc->gopsize = 0;
	vpu_enc->codecTypeProvided = FALSE;
	vpu_enc->memory = V4L2_MEMORY_USERPTR;
	vpu_enc->mjpeg_quality = 50;
}
예제 #15
0
static void
gst_segment_clip_init (GstSegmentClip * self, GstSegmentClipClass * g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  GstPadTemplate *templ;

  templ = gst_element_class_get_pad_template (element_class, "sink");
  g_assert (templ);

  self->sinkpad = gst_pad_new_from_template (templ, "sink");
  gst_pad_set_chain_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_segment_clip_sink_chain));
  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_segment_clip_event));
  gst_pad_set_query_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_segment_clip_query));
  GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad);
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

  gst_object_unref (templ);

  templ = gst_element_class_get_pad_template (element_class, "src");
  g_assert (templ);

  self->srcpad = gst_pad_new_from_template (templ, "src");
  gst_pad_set_event_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_segment_clip_event));
  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_segment_clip_query));
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);

  gst_segment_clip_reset (self);
}
static void
type_instance_init (GTypeInstance *instance,
                    gpointer g_class)
{
    GstOmxBaseFilter21 *self;
    GstElementClass *element_class;
    GstOmxBaseFilter21Class *bclass;
	int i;
	char srcname[10];

    element_class = GST_ELEMENT_CLASS (g_class);
    bclass = GST_OMX_BASE_FILTER21_CLASS (g_class);

    self = GST_OMX_BASE_FILTER21 (instance);

    GST_LOG_OBJECT (self, "begin");


    self->gomx = g_omx_core_new (self, g_class);
    for (i = 0; i < NUM_INPUTS; i++) {
		sprintf(srcname, "in_%02x", i);
		self->input_port_index[i] = OMX_VSWMOSAIC_INPUT_PORT_START_INDEX + i;
		self->in_port[i] = g_omx_core_get_port (self->gomx, srcname, self->input_port_index[i]);
		self->in_port[i]->omx_allocate = TRUE;
		self->in_port[i]->share_buffer = FALSE;
		self->in_port[i]->port_index = self->input_port_index[i];
	}
	self->output_port_index = OMX_VSWMOSAIC_OUTPUT_PORT_START_INDEX;
	self->out_port = g_omx_core_get_port (self->gomx, "out", self->output_port_index);
	self->out_port->buffer_alloc = buffer_alloc;
	self->out_port->omx_allocate = TRUE;
	self->out_port->share_buffer = FALSE;
	self->out_port->port_index = self->output_port_index;
	self->number_eos = 2;
    self->ready_lock = g_mutex_new ();
    self->collectpads = gst_collect_pads_new();
    gst_collect_pads_set_function(self->collectpads, &collected_pads, self);
	for (i = 0; i < NUM_INPUTS; i++) {
		sprintf(srcname, "sink_%02x", i);
		self->sinkpad[i] =	gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, srcname), srcname);

		gst_pad_set_chain_function (self->sinkpad[i], bclass->pad_chain);
		gst_pad_set_event_function (self->sinkpad[i], bclass->pad_event);
		gst_pad_set_setcaps_function (self->sinkpad[i], GST_DEBUG_FUNCPTR (sink_setcaps));
		gst_element_add_pad (GST_ELEMENT (self), self->sinkpad[i]);
		gst_collect_pads_add_pad(self->collectpads, self->sinkpad[i], sizeof(GstCollectData));
	}
	self->srcpad=
		gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, "src"), "src");
	gst_pad_set_activatepush_function (self->srcpad, activate_push);
	gst_pad_set_setcaps_function (self->srcpad, GST_DEBUG_FUNCPTR (src_setcaps));
	gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
    self->duration = GST_CLOCK_TIME_NONE;
    self->sink_camera_timestamp = GST_CLOCK_TIME_NONE;
    self->out_framerate = NULL;

    GST_LOG_OBJECT (self, "end");
}
예제 #17
0
static void
gst_dshowaudiodec_init (GstDshowAudioDec * adec,
    GstDshowAudioDecClass * adec_class)
{
  GstElementClass *element_class = GST_ELEMENT_GET_CLASS (adec);

  /* setup pads */
  adec->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (element_class, "sink"), "sink");

  gst_pad_set_setcaps_function (adec->sinkpad, gst_dshowaudiodec_sink_setcaps);
  gst_pad_set_event_function (adec->sinkpad, gst_dshowaudiodec_sink_event);
  gst_pad_set_chain_function (adec->sinkpad, gst_dshowaudiodec_chain);
  gst_element_add_pad (GST_ELEMENT (adec), adec->sinkpad);

  adec->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (element_class, "src"), "src");
  gst_element_add_pad (GST_ELEMENT (adec), adec->srcpad);

  adec->fakesrc = NULL;
  adec->fakesink = NULL;

  adec->decfilter = 0;
  adec->filtergraph = 0;
  adec->mediafilter = 0;

  adec->timestamp = GST_CLOCK_TIME_NONE;
  adec->segment = gst_segment_new ();
  adec->setup = FALSE;
  adec->depth = 0;
  adec->bitrate = 0;
  adec->block_align = 0;
  adec->channels = 0;
  adec->rate = 0;
  adec->layer = 0;
  adec->codec_data = NULL;

  adec->last_ret = GST_FLOW_OK;

  adec->com_init_lock = g_mutex_new();
  adec->com_deinit_lock = g_mutex_new();
  adec->com_initialized = g_cond_new();
  adec->com_uninitialize = g_cond_new();
  adec->com_uninitialized = g_cond_new();

  g_mutex_lock (adec->com_init_lock);

  /* create the COM initialization thread */
  g_thread_create ((GThreadFunc)gst_dshowaudiodec_com_thread,
      adec, FALSE, NULL);

  /* wait until the COM thread signals that COM has been initialized */
  g_cond_wait (adec->com_initialized, adec->com_init_lock);
  g_mutex_unlock (adec->com_init_lock);
}
예제 #18
0
static void
gst_base_video_decoder_init (GstBaseVideoDecoder * base_video_decoder,
    GstBaseVideoDecoderClass * base_video_decoder_class)
{
  GstPadTemplate *pad_template;
  GstPad *pad;

  GST_DEBUG ("gst_base_video_decoder_init");

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS
      (base_video_decoder_class), "sink");
  g_return_if_fail (pad_template != NULL);

  base_video_decoder->sinkpad = pad =
      gst_pad_new_from_template (pad_template, "sink");
  gst_element_add_pad (GST_ELEMENT (base_video_decoder), pad);

  gst_pad_set_chain_function (pad, gst_base_video_decoder_chain);
  gst_pad_set_event_function (pad, gst_base_video_decoder_sink_event);
  gst_pad_set_setcaps_function (pad, gst_base_video_decoder_sink_setcaps);
  gst_pad_set_query_function (pad, gst_base_video_decoder_sink_query);

  if (base_video_decoder_class->create_srcpad) {
    base_video_decoder->srcpad = pad =
        base_video_decoder_class->create_srcpad (base_video_decoder,
        base_video_decoder_class);
  } else {
    pad_template =
        gst_element_class_get_pad_template (GST_ELEMENT_CLASS
        (base_video_decoder_class), "src");
    g_return_if_fail (pad_template != NULL);

    base_video_decoder->srcpad = pad =
        gst_pad_new_from_template (pad_template, "src");
  }
  gst_element_add_pad (GST_ELEMENT (base_video_decoder), pad);

  gst_pad_set_event_function (pad, gst_base_video_decoder_src_event);
  gst_pad_set_query_type_function (pad, gst_base_video_decoder_get_query_types);
  gst_pad_set_query_function (pad, gst_base_video_decoder_src_query);
  gst_pad_use_fixed_caps (pad);

  base_video_decoder->input_adapter = gst_adapter_new ();

  gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME);

  base_video_decoder->current_frame =
      gst_base_video_decoder_new_frame (base_video_decoder);

  /* properties */
  base_video_decoder->packetized = FALSE;
  base_video_decoder->sink_clipping = TRUE;
}
예제 #19
0
static void
gst_rtp_base_payload_init (GstRTPBasePayload * rtpbasepayload, gpointer g_class)
{
  GstPadTemplate *templ;
  GstRTPBasePayloadPrivate *priv;

  rtpbasepayload->priv = priv =
      GST_RTP_BASE_PAYLOAD_GET_PRIVATE (rtpbasepayload);

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
  g_return_if_fail (templ != NULL);

  rtpbasepayload->srcpad = gst_pad_new_from_template (templ, "src");
  gst_element_add_pad (GST_ELEMENT (rtpbasepayload), rtpbasepayload->srcpad);

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
  g_return_if_fail (templ != NULL);

  rtpbasepayload->sinkpad = gst_pad_new_from_template (templ, "sink");
  gst_pad_set_chain_function (rtpbasepayload->sinkpad,
      gst_rtp_base_payload_chain);
  gst_pad_set_event_function (rtpbasepayload->sinkpad,
      gst_rtp_base_payload_sink_event);
  gst_pad_set_query_function (rtpbasepayload->sinkpad,
      gst_rtp_base_payload_query);
  gst_element_add_pad (GST_ELEMENT (rtpbasepayload), rtpbasepayload->sinkpad);

  rtpbasepayload->mtu = DEFAULT_MTU;
  rtpbasepayload->pt = DEFAULT_PT;
  rtpbasepayload->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
  rtpbasepayload->ssrc = DEFAULT_SSRC;
  rtpbasepayload->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
  priv->seqnum_offset_random = (rtpbasepayload->seqnum_offset == -1);
  priv->ts_offset_random = (rtpbasepayload->ts_offset == -1);
  priv->ssrc_random = (rtpbasepayload->ssrc == -1);

  rtpbasepayload->max_ptime = DEFAULT_MAX_PTIME;
  rtpbasepayload->min_ptime = DEFAULT_MIN_PTIME;
  rtpbasepayload->priv->perfect_rtptime = DEFAULT_PERFECT_RTPTIME;
  rtpbasepayload->ptime_multiple = DEFAULT_PTIME_MULTIPLE;
  rtpbasepayload->priv->base_offset = GST_BUFFER_OFFSET_NONE;
  rtpbasepayload->priv->base_rtime = GST_BUFFER_OFFSET_NONE;

  rtpbasepayload->media = NULL;
  rtpbasepayload->encoding_name = NULL;

  rtpbasepayload->clock_rate = 0;

  rtpbasepayload->priv->caps_max_ptime = DEFAULT_MAX_PTIME;
  rtpbasepayload->priv->prop_max_ptime = DEFAULT_MAX_PTIME;
}
예제 #20
0
static void
gst_dshowvideodec_init (GstDshowVideoDec * vdec,
    GstDshowVideoDecClass * vdec_class)
{
  GstElementClass *element_class = GST_ELEMENT_GET_CLASS (vdec);

  /* setup pads */
  vdec->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (element_class, "sink"), "sink");

  gst_pad_set_setcaps_function (vdec->sinkpad, gst_dshowvideodec_sink_setcaps);
  gst_pad_set_event_function (vdec->sinkpad, gst_dshowvideodec_sink_event);
  gst_pad_set_chain_function (vdec->sinkpad, gst_dshowvideodec_chain);
  gst_element_add_pad (GST_ELEMENT (vdec), vdec->sinkpad);

  vdec->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template
      (element_class, "src"), "src");
/* needed to implement caps negociation on our src pad */
/*  gst_pad_set_getcaps_function (vdec->srcpad, gst_dshowvideodec_src_getcaps);
  gst_pad_set_setcaps_function (vdec->srcpad, gst_dshowvideodec_src_setcaps);*/
  gst_element_add_pad (GST_ELEMENT (vdec), vdec->srcpad);

  vdec->fakesrc = NULL;
  vdec->fakesink = NULL;
  vdec->decfilter = NULL;

  vdec->last_ret = GST_FLOW_OK;

  vdec->filtergraph = NULL;
  vdec->mediafilter = NULL;
  vdec->srccaps = NULL;
  vdec->segment = gst_segment_new ();

  vdec->setup = FALSE;

  vdec->com_init_lock = g_mutex_new();
  vdec->com_deinit_lock = g_mutex_new();
  vdec->com_initialized = g_cond_new();
  vdec->com_uninitialize = g_cond_new();
  vdec->com_uninitialized = g_cond_new();

  g_mutex_lock (vdec->com_init_lock);

  /* create the COM initialization thread */
  g_thread_create ((GThreadFunc)gst_dshowvideodec_com_thread,
      vdec, FALSE, NULL);

  /* wait until the COM thread signals that COM has been initialized */
  g_cond_wait (vdec->com_initialized, vdec->com_init_lock);
  g_mutex_unlock (vdec->com_init_lock);
}
static void
type_instance_init (GTypeInstance *instance,
                    gpointer g_class)
{
    GstOmxBaseFilter2 *self;
    GstElementClass *element_class;
    GstOmxBaseFilter2Class *bclass;
	int i;
	char srcname[10];

    element_class = GST_ELEMENT_CLASS (g_class);
    bclass = GST_OMX_BASE_FILTER2_CLASS (g_class);

    self = GST_OMX_BASE_FILTER2 (instance);

    GST_LOG_OBJECT (self, "begin");

    /* GOmx */
    self->gomx = g_omx_core_new (self, g_class);
    self->in_port = g_omx_core_get_port (self->gomx, "in", 0);
    self->in_port->omx_allocate = TRUE;
    self->in_port->share_buffer = FALSE;

	for (i = 0; i < NUM_OUTPUTS; i++) {
		sprintf(srcname, "out_%02x", i);
		self->out_port[i] = g_omx_core_get_port (self->gomx, srcname, 1+i);
		self->out_port[i]->buffer_alloc = buffer_alloc;
		self->out_port[i]->omx_allocate = TRUE;
		self->out_port[i]->share_buffer = FALSE;
	}
    self->ready_lock = g_mutex_new ();

    self->sinkpad =
        gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, "sink"), "sink");

    gst_pad_set_chain_function (self->sinkpad, bclass->pad_chain);
    gst_pad_set_event_function (self->sinkpad, bclass->pad_event);

    gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

	for (i = 0; i < NUM_OUTPUTS; i++) {
		sprintf(srcname, "src_%02x", i);
		self->srcpad[i] =
			gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, srcname), srcname);
		gst_pad_set_activatepush_function (self->srcpad[i], activate_push);
		gst_pad_use_fixed_caps (self->srcpad[i]);
		gst_element_add_pad (GST_ELEMENT (self), self->srcpad[i]);
	}
    self->duration = GST_CLOCK_TIME_NONE;
	self->input_fields_separately = FALSE;

    GST_LOG_OBJECT (self, "end");
}
예제 #22
0
static void
type_instance_init (GTypeInstance *instance,
                    gpointer g_class)
{
    GstOmxBaseFilter *self;
    GstElementClass *element_class;

    element_class = GST_ELEMENT_CLASS (g_class);

    self = GST_OMX_BASE_FILTER (instance);

    GST_LOG_OBJECT (self, "begin");

    self->use_timestamps = TRUE;

    /* GOmx */
    {
        GOmxCore *gomx;
        self->gomx = gomx = g_omx_core_new ();
        gomx->object = self;
    }

    self->ready_lock = g_mutex_new ();

    self->sinkpad =
        gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, "sink"), "sink");

    gst_pad_set_chain_function (self->sinkpad, pad_chain);
    gst_pad_set_event_function (self->sinkpad, pad_event);

    self->srcpad =
        gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, "src"), "src");

    gst_pad_set_activatepush_function (self->srcpad, activate_push);

    gst_pad_use_fixed_caps (self->srcpad);

    gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
    gst_element_add_pad (GST_ELEMENT (self), self->srcpad);

    {
        const char *tmp;
        tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class),
                                g_quark_from_static_string ("library-name"));
        self->omx_library = g_strdup (tmp);
        tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class),
                                g_quark_from_static_string ("component-name"));
        self->omx_component = g_strdup (tmp);
    }

    GST_LOG_OBJECT (self, "end");
}
예제 #23
0
static void
gst_basertppayload_init (GstBaseRTPPayload * basertppayload, gpointer g_class)
{
  GstPadTemplate *templ;
  GstBaseRTPPayloadPrivate *priv;

  basertppayload->priv = priv =
      GST_BASE_RTP_PAYLOAD_GET_PRIVATE (basertppayload);

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
  g_return_if_fail (templ != NULL);

  basertppayload->srcpad = gst_pad_new_from_template (templ, "src");
  gst_element_add_pad (GST_ELEMENT (basertppayload), basertppayload->srcpad);

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
  g_return_if_fail (templ != NULL);

  basertppayload->sinkpad = gst_pad_new_from_template (templ, "sink");
  gst_pad_set_setcaps_function (basertppayload->sinkpad,
      gst_basertppayload_sink_setcaps);
  gst_pad_set_getcaps_function (basertppayload->sinkpad,
      gst_basertppayload_sink_getcaps);
  gst_pad_set_event_function (basertppayload->sinkpad,
      gst_basertppayload_event);
  gst_pad_set_chain_function (basertppayload->sinkpad,
      gst_basertppayload_chain);
  gst_element_add_pad (GST_ELEMENT (basertppayload), basertppayload->sinkpad);

  basertppayload->seq_rand = g_rand_new ();
  basertppayload->ssrc_rand = g_rand_new ();
  basertppayload->ts_rand = g_rand_new ();

  basertppayload->mtu = DEFAULT_MTU;
  basertppayload->pt = DEFAULT_PT;
  basertppayload->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
  basertppayload->ssrc = DEFAULT_SSRC;
  basertppayload->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
  priv->seqnum_offset_random = (basertppayload->seqnum_offset == -1);
  priv->ts_offset_random = (basertppayload->ts_offset == -1);
  priv->ssrc_random = (basertppayload->ssrc == -1);

  basertppayload->max_ptime = DEFAULT_MAX_PTIME;
  basertppayload->min_ptime = DEFAULT_MIN_PTIME;

  basertppayload->media = NULL;
  basertppayload->encoding_name = NULL;

  basertppayload->clock_rate = 0;
}
예제 #24
0
static GstPad *
kms_hub_port_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstElement *output = NULL;

  if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), HUB_AUDIO_SINK_PAD)) {

    if (g_strcmp0 (name, HUB_AUDIO_SINK_PAD) != 0) {
      GST_ERROR_OBJECT (element,
          "Invalid pad name %s for template %" GST_PTR_FORMAT, name, templ);
      return NULL;
    }

    output = kms_element_get_audio_agnosticbin (KMS_ELEMENT (element));
  }
  else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), HUB_VIDEO_SINK_PAD)) {
    if (g_strcmp0 (name, HUB_VIDEO_SINK_PAD) != 0) {
      GST_ERROR_OBJECT (element,
          "Invalid pad name %s for template %" GST_PTR_FORMAT, name, templ);
      return NULL;
    }

    output = kms_element_get_video_agnosticbin (KMS_ELEMENT (element));
  }
  else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), HUB_DATA_SINK_PAD)) {
    if (g_strcmp0 (name, HUB_DATA_SINK_PAD) != 0) {
      GST_ERROR_OBJECT (element,
          "Invalid pad name %s for template %" GST_PTR_FORMAT, name, templ);
      return NULL;
    }

    output = kms_element_get_data_tee (KMS_ELEMENT (element));
  }

  if (output == NULL) {
    GST_WARNING_OBJECT (element, "No agnosticbin got for template %"
        GST_PTR_FORMAT, templ);
    return NULL;
  } else {
    return kms_hub_port_generate_sink_pad (element, templ, name, caps, output);
  }
}
예제 #25
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);
  }

}
예제 #26
0
static GstEncodingContainerProfile *
kms_recording_profile_create_ksr_profile (gboolean has_audio,
    gboolean has_video)
{
  GstEncodingContainerProfile *cprof;
  GstPadTemplate *templ;
  GstElement *mux;
  GstCaps *pc;

  pc = gst_caps_from_string ("application/x-ksr");
  cprof = gst_encoding_container_profile_new ("Ksr", NULL, pc, NULL);
  gst_caps_unref (pc);

  /* Use matroska caps to define this profile */
  mux = gst_element_factory_make ("matroskamux", NULL);

  if (has_audio) {
    GstCaps *ac;

    templ =
        gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mux),
        "audio_%u");
    ac = gst_pad_template_get_caps (templ);

    gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *)
        gst_encoding_audio_profile_new (ac, NULL, NULL, 0));

    gst_caps_unref (ac);
  }

  if (has_video) {
    GstCaps *vc;

    templ =
        gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mux),
        "video_%u");
    vc = gst_pad_template_get_caps (templ);

    gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *)
        gst_encoding_video_profile_new (vc, NULL, NULL, 0));

    gst_caps_unref (vc);
  }

  g_object_unref (mux);

  return cprof;
}
예제 #27
0
static void
gst_test_element_class_init (GstTestElementClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstPadTemplate *templ;

  gst_element_class_set_metadata (element_class, "Test element",
      "Element", "Does nothing", "Foo Bar <*****@*****.**>");

  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
          (element_class)), 0);

  fail_unless (gst_element_class_get_pad_template (element_class,
          "test") == NULL);

  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_ANY));

  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
          (element_class)), 1);

  fail_unless ((templ =
          gst_element_class_get_pad_template (element_class, "test")) != NULL);
  fail_unless (gst_caps_is_any (templ->caps));

  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("test2", GST_PAD_SRC, GST_PAD_ALWAYS,
          GST_CAPS_ANY));

  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
          (element_class)), 2);

  fail_unless ((templ =
          gst_element_class_get_pad_template (element_class, "test2")) != NULL);
  fail_unless (gst_caps_is_any (templ->caps));

  /* Add "test" again, with NONE caps this time */
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS,
          GST_CAPS_NONE));

  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
          (element_class)), 2);

  fail_unless ((templ =
          gst_element_class_get_pad_template (element_class, "test")) != NULL);
  fail_unless (gst_caps_is_empty (templ->caps));
}
static void
gst_tag_lib_mux_init (GstTagLibMux * mux, GstTagLibMuxClass * mux_class)
{
  GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class);
  GstPadTemplate *tmpl;

  /* pad through which data comes in to the element */
  mux->sinkpad =
      gst_pad_new_from_static_template (&gst_tag_lib_mux_sink_template, "sink");
  gst_pad_set_chain_function (mux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_tag_lib_mux_chain));
  gst_pad_set_event_function (mux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_tag_lib_mux_sink_event));
  gst_element_add_pad (GST_ELEMENT (mux), mux->sinkpad);

  /* pad through which data goes out of the element */
  tmpl = gst_element_class_get_pad_template (element_klass, "src");
  if (tmpl) {
    mux->srcpad = gst_pad_new_from_template (tmpl, "src");
    gst_pad_use_fixed_caps (mux->srcpad);
    gst_pad_set_caps (mux->srcpad, gst_pad_template_get_caps (tmpl));
    gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad);
  }

  mux->render_tag = TRUE;
}
예제 #29
0
static gboolean
kms_base_hub_create_and_link_ghost_pad (KmsBaseHub * mixer,
    GstPad * src_pad, const gchar * gp_name, const gchar * gp_template_name,
    GstPad * target)
{
  GstPadTemplate *templ;
  GstPad *gp;
  gboolean ret;

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS
      (G_OBJECT_GET_CLASS (mixer)), gp_template_name);
  gp = gst_ghost_pad_new_from_template (gp_name, target, templ);

  if (GST_STATE (mixer) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (mixer) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (mixer) >= GST_STATE_PAUSED) {
    gst_pad_set_active (gp, TRUE);
  }

  ret = gst_element_add_pad (GST_ELEMENT (mixer), gp);

  if (ret) {
    gst_pad_link (src_pad, gp);
  } else {
    g_object_unref (gp);
  }

  return ret;
}
예제 #30
0
static GstCaps *
gst_alsasink_getcaps (GstBaseSink * bsink)
{
    GstElementClass *element_class;
    GstPadTemplate *pad_template;
    GstAlsaSink *sink = GST_ALSA_SINK (bsink);
    GstCaps *caps;

    if (sink->handle == NULL) {
        GST_DEBUG_OBJECT (sink, "device not open, using template caps");
        return NULL;                /* base class will get template caps for us */
    }

    if (sink->cached_caps) {
        GST_LOG_OBJECT (sink, "Returning cached caps");
        return gst_caps_ref (sink->cached_caps);
    }

    element_class = GST_ELEMENT_GET_CLASS (sink);
    pad_template = gst_element_class_get_pad_template (element_class, "sink");
    g_return_val_if_fail (pad_template != NULL, NULL);

    caps = gst_alsa_probe_supported_formats (GST_OBJECT (sink), sink->device,
            sink->handle, gst_pad_template_get_caps (pad_template));

    if (caps) {
        sink->cached_caps = gst_caps_ref (caps);
    }

    GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);

    return caps;
}