예제 #1
0
static GstPad *
dvb_base_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name)
{
  GstPad *pad;
  GstPad *ghost;
  gchar *pad_name;

  if (name == NULL)
    name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);

  pad =
      gst_element_get_request_pad (GST_DVB_BASE_BIN (element)->mpegtsparse,
      name);
  if (pad == NULL)
    return NULL;

  pad_name = gst_pad_get_name (pad);
  ghost = gst_ghost_pad_new (pad_name, pad);
  g_free (pad_name);
  gst_element_add_pad (element, ghost);
  gst_element_no_more_pads (element);

  return ghost;
}
예제 #2
0
static void
dvb_base_bin_pad_added_cb (GstElement * mpegtsparse,
    GstPad * pad, DvbBaseBin * dvbbasebin)
{
  DvbBaseBinProgram *program;
  gint program_number;
  gchar *padname;

  program_number = get_pad_program_number (pad);
  if (program_number == -1)
    return;

  program = dvb_base_bin_get_program (dvbbasebin, program_number);
  if (program == NULL)
    program = dvb_base_bin_add_program (dvbbasebin, program_number);
  program->selected = TRUE;
  padname = gst_pad_get_name (pad);
  program->ghost = gst_ghost_pad_new (padname, pad);
  gst_pad_set_active (program->ghost, TRUE);
  gst_element_add_pad (GST_ELEMENT (dvbbasebin), program->ghost);
  gst_element_no_more_pads (GST_ELEMENT (dvbbasebin));
  /* if the program has a pmt, activate it now, otherwise it will get activated
   * when there's a PMT */
  if (!program->active && program->pmt_pid != G_MAXUINT16)
    dvb_base_bin_activate_program (dvbbasebin, program);
  g_free (padname);
}
예제 #3
0
void PlaybackPipeline::markEndOfStream(MediaSourcePrivate::EndOfStreamStatus)
{
    WebKitMediaSrcPrivate* priv = m_webKitMediaSrc->priv;

    GST_DEBUG_OBJECT(m_webKitMediaSrc.get(), "Have EOS");

    GST_OBJECT_LOCK(m_webKitMediaSrc.get());
    bool allTracksConfigured = priv->allTracksConfigured;
    if (!allTracksConfigured)
        priv->allTracksConfigured = true;
    GST_OBJECT_UNLOCK(m_webKitMediaSrc.get());

    if (!allTracksConfigured) {
        gst_element_no_more_pads(GST_ELEMENT(m_webKitMediaSrc.get()));
        webKitMediaSrcDoAsyncDone(m_webKitMediaSrc.get());
    }

    Vector<GstAppSrc*> appsrcs;

    GST_OBJECT_LOCK(m_webKitMediaSrc.get());
    for (Stream* stream : priv->streams) {
        if (stream->appsrc)
            appsrcs.append(GST_APP_SRC(stream->appsrc));
    }
    GST_OBJECT_UNLOCK(m_webKitMediaSrc.get());

    for (GstAppSrc* appsrc : appsrcs)
        gst_app_src_end_of_stream(appsrc);
}
예제 #4
0
static void
dvdbin_pad_blocked_cb (GstPad * pad, gboolean blocked, RsnDvdBin * dvdbin)
{
  gboolean changed = FALSE;
  if (!blocked)
    return;

  if (pad == dvdbin->subpicture_pad) {
    if (!dvdbin->subpicture_added) {
      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad);
      dvdbin->subpicture_added = TRUE;
      changed = TRUE;
    }

    gst_pad_set_blocked_async (pad, FALSE,
        (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
  } else if (pad == dvdbin->audio_pad) {
    if (!dvdbin->audio_added) {
      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad);
      dvdbin->audio_added = TRUE;
      changed = TRUE;
    }

    gst_pad_set_blocked_async (pad, FALSE,
        (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
  }

  if (changed &&
      dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
    gst_element_no_more_pads (GST_ELEMENT (dvdbin));
  }
}
예제 #5
0
static void
switch_pads (GstHLSDemux * demux, GstCaps * newcaps)
{
  GstPad *oldpad = demux->srcpad;

  GST_DEBUG ("Switching pads (oldpad:%p)", oldpad);

  /* First create and activate new pad */
  demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL);
  gst_pad_set_event_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_event));
  gst_pad_set_query_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_query));
  gst_pad_set_element_private (demux->srcpad, demux);
  gst_pad_set_active (demux->srcpad, TRUE);
  gst_pad_set_caps (demux->srcpad, newcaps);
  gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad);

  gst_element_no_more_pads (GST_ELEMENT (demux));

  if (oldpad) {
    /* Push out EOS */
    gst_pad_push_event (oldpad, gst_event_new_eos ());
    gst_pad_set_active (oldpad, FALSE);
    gst_element_remove_pad (GST_ELEMENT (demux), oldpad);
  }
}
예제 #6
0
static void
gst_deinterlace2_init (GstDeinterlace2 * self, GstDeinterlace2Class * klass)
{
  self->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
  gst_pad_set_chain_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_chain));
  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_sink_event));
  gst_pad_set_setcaps_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_setcaps));
  gst_pad_set_getcaps_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_getcaps));
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

  self->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
  gst_pad_set_event_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_src_event));
  gst_pad_set_query_type_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_src_query_types));
  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_src_query));
  gst_pad_set_setcaps_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_setcaps));
  gst_pad_set_getcaps_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace2_getcaps));
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);

  gst_element_no_more_pads (GST_ELEMENT (self));

  gst_deinterlace2_set_method (self, DEFAULT_METHOD);
  self->fields = DEFAULT_FIELDS;
  self->field_layout = DEFAULT_FIELD_LAYOUT;

  gst_deinterlace2_reset (self);
}
void PlaybackPipeline::markEndOfStream(MediaSourcePrivate::EndOfStreamStatus)
{
    WebKitMediaSrcPrivate* priv = m_webKitMediaSrc->priv;
    GList *l;

    GST_DEBUG_OBJECT(m_webKitMediaSrc.get(), "Have EOS");

    GST_OBJECT_LOCK(m_webKitMediaSrc.get());
    bool allTracksConfigured = priv->allTracksConfigured;
    if (!allTracksConfigured) {
        priv->allTracksConfigured = true;
    }
    GST_OBJECT_UNLOCK(m_webKitMediaSrc.get());

    if (!allTracksConfigured) {
        gst_element_no_more_pads(GST_ELEMENT(m_webKitMediaSrc.get()));
        webKitMediaSrcDoAsyncDone(m_webKitMediaSrc.get());
    }

    Vector<GstAppSrc*> appSrcs;

    GST_OBJECT_LOCK(m_webKitMediaSrc.get());
    for (l = priv->streams; l; l = l->next) {
        Stream *stream = static_cast<Stream*>(l->data);
        if (stream->appsrc)
            appSrcs.append(GST_APP_SRC(stream->appsrc));
    }
    GST_OBJECT_UNLOCK(m_webKitMediaSrc.get());

    for (Vector<GstAppSrc*>::iterator it = appSrcs.begin(); it != appSrcs.end(); ++it)
        gst_app_src_end_of_stream(*it);
}
예제 #8
0
static void
_ghost_pad_added_cb (GstElement * element, GstPad * srcpad, GstElement * bin)
{
  GstPad *ghost;

  ghost = gst_ghost_pad_new ("src", srcpad);
  gst_pad_set_active (ghost, TRUE);
  gst_element_add_pad (bin, ghost);
  gst_element_no_more_pads (element);
}
예제 #9
0
static void
gst_nuv_demux_create_pads (GstNuvDemux * nuv)
{
  if (nuv->h->i_video_blocks != 0) {
    GstCaps *video_caps = NULL;

    nuv->src_video_pad =
        gst_pad_new_from_static_template (&video_src_template, "video_src");

    video_caps = gst_caps_new_simple ("video/x-divx",
        "divxversion", G_TYPE_INT, 4,
        "width", G_TYPE_INT, nuv->h->i_width,
        "height", G_TYPE_INT, nuv->h->i_height,
        "framerate", GST_TYPE_FRACTION, (gint) (nuv->h->d_fps * 1000.0f), 1000,
        "pixel-aspect-ratio", GST_TYPE_FRACTION,
        (gint) (nuv->h->d_aspect * 1000.0f), 1000, NULL);

    gst_pad_use_fixed_caps (nuv->src_video_pad);
    gst_pad_set_active (nuv->src_video_pad, TRUE);
    gst_pad_set_caps (nuv->src_video_pad, video_caps);

    gst_pad_set_event_function (nuv->src_video_pad,
        gst_nuv_demux_handle_src_event);
    gst_pad_set_active (nuv->src_video_pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);

    gst_caps_unref (video_caps);
  }

  if (nuv->h->i_audio_blocks != 0) {
    GstCaps *audio_caps = NULL;

    nuv->src_audio_pad =
        gst_pad_new_from_static_template (&audio_src_template, "audio_src");

    audio_caps = gst_caps_new_simple ("audio/mpeg",
        "rate", G_TYPE_INT, nuv->eh->i_audio_sample_rate,
        "format", GST_TYPE_FOURCC, nuv->eh->i_audio_fcc,
        "channels", G_TYPE_INT, nuv->eh->i_audio_channels,
        "mpegversion", G_TYPE_INT, nuv->eh->i_version, NULL);

    gst_pad_use_fixed_caps (nuv->src_audio_pad);
    gst_pad_set_active (nuv->src_audio_pad, TRUE);
    gst_pad_set_caps (nuv->src_audio_pad, audio_caps);
    gst_pad_set_active (nuv->src_audio_pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_audio_pad);

    gst_pad_set_event_function (nuv->src_audio_pad,
        gst_nuv_demux_handle_src_event);

    gst_caps_unref (audio_caps);
  }

  gst_element_no_more_pads (GST_ELEMENT (nuv));
}
예제 #10
0
static void
rsn_dvdbin_no_more_pads (RsnDvdBin * dvdbin)
{
  if (dvdbin->did_no_more_pads)
    return;
  dvdbin->did_no_more_pads = TRUE;

  GST_DEBUG_OBJECT (dvdbin, "Firing no more pads");
  /* Shrink subpicture queue to smaller size */
  g_object_set (dvdbin->pieces[DVD_ELEM_SPUQ],
      "max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0,
      "max-size-buffers", 1, NULL);
  gst_element_no_more_pads (GST_ELEMENT (dvdbin));
}
예제 #11
0
static gboolean
gst_au_parse_add_srcpad (GstAuParse * auparse, GstCaps * new_caps)
{
  GstPad *srcpad = NULL;

  if (auparse->src_caps && gst_caps_is_equal (new_caps, auparse->src_caps)) {
    GST_LOG_OBJECT (auparse, "same caps, nothing to do");
    return TRUE;
  }

  gst_caps_replace (&auparse->src_caps, new_caps);
  if (auparse->srcpad != NULL) {
    GST_DEBUG_OBJECT (auparse, "Changing src pad caps to %" GST_PTR_FORMAT,
        auparse->src_caps);
    gst_pad_set_caps (auparse->srcpad, auparse->src_caps);
  }

  if (auparse->srcpad == NULL) {
    srcpad = auparse->srcpad =
        gst_pad_new_from_static_template (&src_template, "src");
    g_return_val_if_fail (auparse->srcpad != NULL, FALSE);

#if 0
    gst_pad_set_query_type_function (auparse->srcpad,
        GST_DEBUG_FUNCPTR (gst_au_parse_src_get_query_types));
#endif
    gst_pad_set_query_function (auparse->srcpad,
        GST_DEBUG_FUNCPTR (gst_au_parse_src_query));
    gst_pad_set_event_function (auparse->srcpad,
        GST_DEBUG_FUNCPTR (gst_au_parse_src_event));

    gst_pad_use_fixed_caps (auparse->srcpad);
    gst_pad_set_active (auparse->srcpad, TRUE);

    if (auparse->src_caps)
      gst_pad_set_caps (auparse->srcpad, auparse->src_caps);

    GST_DEBUG_OBJECT (auparse, "Adding src pad with caps %" GST_PTR_FORMAT,
        auparse->src_caps);

    gst_object_ref (auparse->srcpad);
    if (!gst_element_add_pad (GST_ELEMENT (auparse), auparse->srcpad))
      return FALSE;
    gst_element_no_more_pads (GST_ELEMENT (auparse));
  }

  return TRUE;
}
예제 #12
0
static void
gst_deinterleave_add_new_pads (GstDeinterleave * self, GstCaps * caps)
{
  GstPad *pad;

  guint i;

  for (i = 0; i < self->channels; i++) {
    gchar *name = g_strdup_printf ("src%d", i);

    GstCaps *srccaps;

    GstStructure *s;

    pad = gst_pad_new_from_static_template (&src_template, name);
    g_free (name);

    /* Set channel position if we know it */
    if (self->keep_positions) {
      GstAudioChannelPosition pos[1] = { GST_AUDIO_CHANNEL_POSITION_NONE };

      srccaps = gst_caps_copy (caps);
      s = gst_caps_get_structure (srccaps, 0);
      if (self->pos)
        gst_audio_set_channel_positions (s, &self->pos[i]);
      else
        gst_audio_set_channel_positions (s, pos);
    } else {
      srccaps = caps;
    }

    gst_pad_set_caps (pad, srccaps);
    gst_pad_use_fixed_caps (pad);
    gst_pad_set_query_function (pad,
        GST_DEBUG_FUNCPTR (gst_deinterleave_src_query));
    gst_pad_set_active (pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (self), pad);
    self->srcpads = g_list_prepend (self->srcpads, gst_object_ref (pad));

    if (self->keep_positions)
      gst_caps_unref (srccaps);
  }

  gst_element_no_more_pads (GST_ELEMENT (self));
  self->srcpads = g_list_reverse (self->srcpads);
}
예제 #13
0
static void
gst_deinterleave_add_new_pads (GstDeinterleave * self, GstCaps * caps)
{
  GstPad *pad;
  guint i;

  for (i = 0; i < GST_AUDIO_INFO_CHANNELS (&self->audio_info); i++) {
    gchar *name = g_strdup_printf ("src_%u", i);
    GstCaps *srccaps;
    GstAudioInfo info;
    GstAudioFormat format = GST_AUDIO_INFO_FORMAT (&self->audio_info);
    gint rate = GST_AUDIO_INFO_RATE (&self->audio_info);
    GstAudioChannelPosition position = GST_AUDIO_CHANNEL_POSITION_MONO;
    CopyStickyEventsData data;

    /* Set channel position if we know it */
    if (self->keep_positions)
      position = GST_AUDIO_INFO_POSITION (&self->audio_info, i);

    gst_audio_info_init (&info);
    gst_audio_info_set_format (&info, format, rate, 1, &position);

    srccaps = gst_audio_info_to_caps (&info);

    pad = gst_pad_new_from_static_template (&src_template, name);
    g_free (name);

    gst_pad_use_fixed_caps (pad);
    gst_pad_set_query_function (pad,
        GST_DEBUG_FUNCPTR (gst_deinterleave_src_query));
    gst_pad_set_active (pad, TRUE);

    data.pad = pad;
    data.caps = srccaps;
    gst_pad_sticky_events_foreach (self->sink, copy_sticky_events, &data);
    if (data.caps)
      gst_pad_set_caps (pad, data.caps);
    gst_element_add_pad (GST_ELEMENT (self), pad);
    self->srcpads = g_list_prepend (self->srcpads, gst_object_ref (pad));

    gst_caps_unref (srccaps);
  }

  gst_element_no_more_pads (GST_ELEMENT (self));
  self->srcpads = g_list_reverse (self->srcpads);
}
예제 #14
0
/**
 * progress_buffer_create_sourcepad()
 *
 */
static void progress_buffer_create_sourcepad(ProgressBuffer *element)
{
    element->srcpad = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS(element), "src"), "src");

    gst_pad_set_activatemode_function  (element->srcpad, GST_DEBUG_FUNCPTR(progress_buffer_activatemode));
    gst_pad_set_event_function         (element->srcpad, GST_DEBUG_FUNCPTR(progress_buffer_src_event));
    gst_pad_set_getrange_function      (element->srcpad, GST_DEBUG_FUNCPTR(progress_buffer_getrange));
    GST_PAD_UNSET_FLUSHING(element->srcpad);

    // Add pad
    gst_element_add_pad (GST_ELEMENT (element), element->srcpad);

    // Activate pad
    gst_pad_set_active (element->srcpad, TRUE);

    // Send "no-more-pads"
    gst_element_no_more_pads(GST_ELEMENT (element));
}
예제 #15
0
static void
switch_pads (GstHLSDemux * demux, GstCaps * newcaps)
{
  GstPad *oldpad = demux->srcpad;

  GST_DEBUG ("Switching pads (oldpad:%p)", oldpad);

  /* FIXME: This is a workaround for a bug in playsink.
   * If we're switching from an audio-only or video-only fragment
   * to an audio-video segment, the new sink doesn't know about
   * the current running time and audio/video will go out of sync.
   *
   * This should be fixed in playsink by distributing the
   * current running time to newly created sinks and is
   * fixed in 0.11 with the new segments.
   */
  if (demux->srcpad)
    gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop ());

  /* First create and activate new pad */
  demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL);
  gst_pad_set_event_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_event));
  gst_pad_set_query_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_query));
  gst_pad_set_element_private (demux->srcpad, demux);
  gst_pad_set_active (demux->srcpad, TRUE);
  gst_pad_set_caps (demux->srcpad, newcaps);
  gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad);

  gst_element_no_more_pads (GST_ELEMENT (demux));

  if (oldpad) {
    /* Push out EOS */
    gst_pad_push_event (oldpad, gst_event_new_eos ());
    gst_pad_set_active (oldpad, FALSE);
    gst_element_remove_pad (GST_ELEMENT (demux), oldpad);
  }
}
예제 #16
0
static gboolean
gst_icydemux_add_srcpad (GstICYDemux * icydemux, GstCaps * new_caps)
{
  if (icydemux->src_caps == NULL ||
      !gst_caps_is_equal (new_caps, icydemux->src_caps)) {
    gst_caps_replace (&(icydemux->src_caps), new_caps);
    if (icydemux->srcpad != NULL) {
      GST_DEBUG_OBJECT (icydemux, "Changing src pad caps to %" GST_PTR_FORMAT,
          icydemux->src_caps);

      gst_pad_set_caps (icydemux->srcpad, icydemux->src_caps);
    }
  } else {
    /* Caps never changed */
    gst_caps_unref (new_caps);
  }

  if (icydemux->srcpad == NULL) {
    icydemux->srcpad =
        gst_pad_new_from_template (gst_element_class_get_pad_template
        (GST_ELEMENT_GET_CLASS (icydemux), "src"), "src");
    g_return_val_if_fail (icydemux->srcpad != NULL, FALSE);

    gst_pad_use_fixed_caps (icydemux->srcpad);

    if (icydemux->src_caps)
      gst_pad_set_caps (icydemux->srcpad, icydemux->src_caps);

    GST_DEBUG_OBJECT (icydemux, "Adding src pad with caps %" GST_PTR_FORMAT,
        icydemux->src_caps);

    gst_pad_set_active (icydemux->srcpad, TRUE);
    if (!(gst_element_add_pad (GST_ELEMENT (icydemux), icydemux->srcpad)))
      return FALSE;
    gst_element_no_more_pads (GST_ELEMENT (icydemux));
  }

  return TRUE;
}
예제 #17
0
파일: resindvdbin.c 프로젝트: zsx/ossbuild
static void
demux_no_more_pads (GstElement * element, RsnDvdBin * dvdbin)
{
  gboolean no_more_pads = FALSE;
  guint n_audio_pads = 0;

  DVDBIN_PREROLL_LOCK (dvdbin);

  g_object_get (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "n-pads", &n_audio_pads,
      NULL);
  if (n_audio_pads == 0) {
    no_more_pads = dvdbin->video_added && dvdbin->subpicture_added;
    dvdbin->audio_broken = TRUE;
  }

  DVDBIN_PREROLL_UNLOCK (dvdbin);

  if (no_more_pads) {
    GST_DEBUG_OBJECT (dvdbin,
        "Firing no more pads from demuxer no-more-pads cb");
    gst_element_no_more_pads (GST_ELEMENT (dvdbin));
  }
}
예제 #18
0
static void
viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
    RsnDvdBin * dvdbin)
{
  GstPad *q_pad;

  GST_DEBUG_OBJECT (dvdbin, "New video pad: %" GST_PTR_FORMAT, pad);

  q_pad = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "sink");
  gst_pad_link (pad, q_pad);

  gst_object_unref (q_pad);

  if (!dvdbin->video_added) {
    gst_pad_set_active (dvdbin->video_pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
    dvdbin->video_added = TRUE;

    if (dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
      gst_element_no_more_pads (GST_ELEMENT (dvdbin));
    }
  }
}
예제 #19
0
static GstMultipartPad *
gst_multipart_find_pad_by_mime (GstMultipartDemux * demux, gchar * mime,
    gboolean * created)
{
  GSList *walk;

  walk = demux->srcpads;
  while (walk) {
    GstMultipartPad *pad = (GstMultipartPad *) walk->data;

    if (!strcmp (pad->mime, mime)) {
      if (created) {
        *created = FALSE;
      }
      return pad;
    }

    walk = walk->next;
  }
  /* pad not found, create it */
  {
    GstPad *pad;
    GstMultipartPad *mppad;
    gchar *name;
    const gchar *capsname;
    GstCaps *caps;

    mppad = g_new0 (GstMultipartPad, 1);

    GST_DEBUG_OBJECT (demux, "creating pad with mime: %s", mime);

    name = g_strdup_printf ("src_%u", demux->numpads);
    pad =
        gst_pad_new_from_static_template (&multipart_demux_src_template_factory,
        name);
    g_free (name);

    mppad->pad = pad;
    mppad->mime = g_strdup (mime);
    mppad->last_ret = GST_FLOW_OK;
    mppad->last_ts = GST_CLOCK_TIME_NONE;
    mppad->discont = TRUE;

    demux->srcpads = g_slist_prepend (demux->srcpads, mppad);
    demux->numpads++;

    /* take the mime type, convert it to the caps name */
    capsname = gst_multipart_demux_get_gstname (demux, mime);
    caps = gst_caps_from_string (capsname);
    GST_DEBUG_OBJECT (demux, "caps for pad: %s", capsname);
    gst_pad_use_fixed_caps (pad);
    gst_pad_set_active (pad, TRUE);
    gst_pad_set_caps (pad, caps);
    gst_caps_unref (caps);

    gst_element_add_pad (GST_ELEMENT_CAST (demux), pad);

    if (created) {
      *created = TRUE;
    }

    if (demux->singleStream) {
      gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
    }

    return mppad;
  }
}
예제 #20
0
static void
gst_wavpack_enc_set_wp_config (GstWavpackEnc * enc)
{
  enc->wp_config = g_new0 (WavpackConfig, 1);
  /* set general stream informations in the WavpackConfig */
  enc->wp_config->bytes_per_sample = GST_ROUND_UP_8 (enc->depth) / 8;
  enc->wp_config->bits_per_sample = enc->depth;
  enc->wp_config->num_channels = enc->channels;
  enc->wp_config->channel_mask = enc->channel_mask;
  enc->wp_config->sample_rate = enc->samplerate;

  /*
   * Set parameters in WavpackConfig
   */

  /* Encoding mode */
  switch (enc->mode) {
#if 0
    case GST_WAVPACK_ENC_MODE_VERY_FAST:
      enc->wp_config->flags |= CONFIG_VERY_FAST_FLAG;
      enc->wp_config->flags |= CONFIG_FAST_FLAG;
      break;
#endif
    case GST_WAVPACK_ENC_MODE_FAST:
      enc->wp_config->flags |= CONFIG_FAST_FLAG;
      break;
    case GST_WAVPACK_ENC_MODE_DEFAULT:
      break;
    case GST_WAVPACK_ENC_MODE_HIGH:
      enc->wp_config->flags |= CONFIG_HIGH_FLAG;
      break;
#ifndef WAVPACK_OLD_API
    case GST_WAVPACK_ENC_MODE_VERY_HIGH:
      enc->wp_config->flags |= CONFIG_HIGH_FLAG;
      enc->wp_config->flags |= CONFIG_VERY_HIGH_FLAG;
      break;
#endif
  }

  /* Bitrate, enables lossy mode */
  if (enc->bitrate) {
    enc->wp_config->flags |= CONFIG_HYBRID_FLAG;
    enc->wp_config->flags |= CONFIG_BITRATE_KBPS;
    enc->wp_config->bitrate = enc->bitrate / 1000.0;
  } else if (enc->bps) {
    enc->wp_config->flags |= CONFIG_HYBRID_FLAG;
    enc->wp_config->bitrate = enc->bps;
  }

  /* Correction Mode, only in lossy mode */
  if (enc->wp_config->flags & CONFIG_HYBRID_FLAG) {
    if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) {
      GstCaps *caps = gst_caps_new_simple ("audio/x-wavpack-correction",
          "framed", G_TYPE_BOOLEAN, TRUE, NULL);

      enc->wvcsrcpad =
          gst_pad_new_from_static_template (&wvcsrc_factory, "wvcsrc");

      /* try to add correction src pad, don't set correction mode on failure */
      GST_DEBUG_OBJECT (enc, "Adding correction pad with caps %"
          GST_PTR_FORMAT, caps);
      if (!gst_pad_set_caps (enc->wvcsrcpad, caps)) {
        enc->correction_mode = 0;
        GST_WARNING_OBJECT (enc, "setting correction caps failed");
      } else {
        gst_pad_use_fixed_caps (enc->wvcsrcpad);
        gst_pad_set_active (enc->wvcsrcpad, TRUE);
        gst_element_add_pad (GST_ELEMENT (enc), enc->wvcsrcpad);
        enc->wp_config->flags |= CONFIG_CREATE_WVC;
        if (enc->correction_mode == GST_WAVPACK_CORRECTION_MODE_OPTIMIZED) {
          enc->wp_config->flags |= CONFIG_OPTIMIZE_WVC;
        }
      }
      gst_caps_unref (caps);
    }
  } else {
    if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) {
      enc->correction_mode = 0;
      GST_WARNING_OBJECT (enc, "setting correction mode only has "
          "any effect if a bitrate is provided.");
    }
  }
  gst_element_no_more_pads (GST_ELEMENT (enc));

  /* MD5, setup MD5 context */
  if ((enc->md5) && !(enc->md5_context)) {
    enc->wp_config->flags |= CONFIG_MD5_CHECKSUM;
    enc->md5_context = g_checksum_new (G_CHECKSUM_MD5);
  }

  /* Extra encode processing */
  if (enc->extra_processing) {
    enc->wp_config->flags |= CONFIG_EXTRA_MODE;
    enc->wp_config->xmode = enc->extra_processing;
  }

  /* Joint stereo mode */
  switch (enc->joint_stereo_mode) {
    case GST_WAVPACK_JS_MODE_AUTO:
      break;
    case GST_WAVPACK_JS_MODE_LEFT_RIGHT:
      enc->wp_config->flags |= CONFIG_JOINT_OVERRIDE;
      enc->wp_config->flags &= ~CONFIG_JOINT_STEREO;
      break;
    case GST_WAVPACK_JS_MODE_MID_SIDE:
      enc->wp_config->flags |= (CONFIG_JOINT_OVERRIDE | CONFIG_JOINT_STEREO);
      break;
  }
}
예제 #21
0
파일: resindvdbin.c 프로젝트: zsx/ossbuild
static void
dvdbin_pad_blocked_cb (GstPad * opad, gboolean blocked,
    RsnDvdBinPadBlockCtx * ctx)
{
  RsnDvdBin *dvdbin;
  GstPad *pad;
  gboolean added_last_pad = FALSE;
  gboolean added = FALSE;

  /* If not blocked ctx is NULL! */
  if (!blocked) {
    GST_DEBUG_OBJECT (opad, "Pad unblocked");
    return;
  }

  dvdbin = ctx->dvdbin;
  pad = ctx->pad;

  if (pad == dvdbin->subpicture_pad) {
    GST_DEBUG_OBJECT (opad, "Pad block -> subpicture pad");
    DVDBIN_PREROLL_LOCK (dvdbin);
    added = dvdbin->subpicture_added;
    dvdbin->subpicture_added = TRUE;

    if (!added) {
      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad);
      added_last_pad = ((dvdbin->audio_broken || dvdbin->audio_added)
          && dvdbin->video_added);
    }
    DVDBIN_PREROLL_UNLOCK (dvdbin);

    gst_pad_set_blocked_async (opad, FALSE,
        (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL);
  } else if (pad == dvdbin->audio_pad) {
    GST_DEBUG_OBJECT (opad, "Pad block -> audio pad");
    DVDBIN_PREROLL_LOCK (dvdbin);
    added = dvdbin->audio_added;
    dvdbin->audio_added = TRUE;

    if (!added) {
      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad);
      added_last_pad = (dvdbin->subpicture_added && dvdbin->video_added);
    }
    DVDBIN_PREROLL_UNLOCK (dvdbin);

    gst_pad_set_blocked_async (opad, FALSE,
        (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL);
  } else if (pad == dvdbin->video_pad) {
    GST_DEBUG_OBJECT (opad, "Pad block -> video pad");

    DVDBIN_PREROLL_LOCK (dvdbin);
    added = dvdbin->video_added;
    dvdbin->video_added = TRUE;

    if (!added) {
      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
      added_last_pad = (dvdbin->subpicture_added && (dvdbin->audio_added
              || dvdbin->audio_broken));
    }
    DVDBIN_PREROLL_UNLOCK (dvdbin);

    gst_pad_set_blocked_async (opad, FALSE,
        (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL);
  }

  if (added_last_pad) {
    GST_DEBUG_OBJECT (dvdbin, "Firing no more pads from pad-blocked cb");
    gst_element_no_more_pads (GST_ELEMENT (dvdbin));
  }
}
예제 #22
0
파일: resindvdbin.c 프로젝트: zsx/ossbuild
static gboolean
create_elements (RsnDvdBin * dvdbin)
{
  GstPadTemplate *src_templ = NULL;
  GstPad *src = NULL;
  GstPad *sink = NULL;
  RsnDvdBinPadBlockCtx *bctx = NULL;

  if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL,
          RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) {
    return FALSE;
  }

  /* FIXME: Locking */
  if (dvdbin->device) {
    g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_SOURCE]),
        "device", dvdbin->device, NULL);
  }

  if (!try_create_piece (dvdbin, DVD_ELEM_DEMUX,
          NULL, GST_TYPE_FLUPS_DEMUX, "dvddemux", "DVD demuxer"))
    return FALSE;

  if (gst_element_link (dvdbin->pieces[DVD_ELEM_SOURCE],
          dvdbin->pieces[DVD_ELEM_DEMUX]) == FALSE)
    goto failed_connect;

  /* Listen for new pads from the demuxer */
  g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "pad-added",
      G_CALLBACK (demux_pad_added), dvdbin);

  g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "no-more-pads",
      G_CALLBACK (demux_no_more_pads), dvdbin);

  if (!try_create_piece (dvdbin, DVD_ELEM_MQUEUE, "multiqueue", 0, "mq",
          "multiqueue"))
    return FALSE;

  g_object_set (dvdbin->pieces[DVD_ELEM_MQUEUE],
      "max-size-time", (7 * GST_SECOND / 10), "max-size-bytes", 0,
      "max-size-buffers", 0, NULL);

  /* Decodebin will throw a missing element message to find an MPEG decoder */
  if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, NULL, RSN_TYPE_VIDEODEC,
          "viddec", "video decoder"))
    return FALSE;

  if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER,
          "rsnparsetter", "Aspect ratio adjustment"))
    return FALSE;

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDDEC], "src");
  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "sink");
  if (src == NULL || sink == NULL)
    goto failed_viddec_connect;
  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
    goto failed_viddec_connect;
  gst_object_unref (src);
  gst_object_unref (sink);
  src = sink = NULL;

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src");
  if (src == NULL)
    goto failed_video_ghost;
  src_templ = gst_static_pad_template_get (&video_src_template);
  dvdbin->video_pad = gst_ghost_pad_new_from_template ("video", src, src_templ);
  gst_object_unref (src_templ);
  if (dvdbin->video_pad == NULL)
    goto failed_video_ghost;
  gst_pad_set_active (dvdbin->video_pad, TRUE);
  bctx = g_slice_new (RsnDvdBinPadBlockCtx);
  bctx->dvdbin = gst_object_ref (dvdbin);
  bctx->pad = gst_object_ref (dvdbin->video_pad);
  gst_pad_set_blocked_async_full (src, TRUE,
      (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify)
      _pad_block_destroy_notify);
  gst_object_unref (src);
  src = NULL;

  if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL,
          RSN_TYPE_STREAM_SELECTOR, "subpselect", "Subpicture stream selector"))
    return FALSE;

  /* Add a single standalone queue to hold a single buffer of SPU data */
  if (!try_create_piece (dvdbin, DVD_ELEM_SPUQ, "queue", 0, "spu_q",
          "subpicture decoder buffer"))
    return FALSE;
  g_object_set (dvdbin->pieces[DVD_ELEM_SPUQ],
      "max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0,
      "max-size-buffers", 1, NULL);

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT], "src");
  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPUQ], "sink");
  if (src == NULL || sink == NULL)
    goto failed_spuq_connect;
  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
    goto failed_spuq_connect;
  gst_object_unref (src);
  gst_object_unref (sink);
  src = sink = NULL;

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPUQ], "src");
  if (src == NULL)
    goto failed_spu_ghost;
  src_templ = gst_static_pad_template_get (&subpicture_src_template);
  dvdbin->subpicture_pad =
      gst_ghost_pad_new_from_template ("subpicture", src, src_templ);
  gst_object_unref (src_templ);
  if (dvdbin->subpicture_pad == NULL)
    goto failed_spu_ghost;
  gst_pad_set_active (dvdbin->subpicture_pad, TRUE);
  bctx = g_slice_new (RsnDvdBinPadBlockCtx);
  bctx->dvdbin = gst_object_ref (dvdbin);
  bctx->pad = gst_object_ref (dvdbin->subpicture_pad);
  gst_pad_set_blocked_async_full (src, TRUE,
      (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify)
      _pad_block_destroy_notify);
  gst_object_unref (src);
  src = NULL;

  if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL,
          RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector"))
    return FALSE;

  if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL,
          RSN_TYPE_AUDIODEC, "auddec", "audio decoder"))
    return FALSE;

  /* rsnaudiomunge goes after the audio decoding to regulate the stream */
  if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL,
          RSN_TYPE_AUDIOMUNGE, "audiomunge", "Audio output filter"))
    return FALSE;

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src");
  sink =
      gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink");
  if (src == NULL || sink == NULL)
    goto failed_aud_connect;
  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
    goto failed_aud_connect;
  gst_object_unref (sink);
  gst_object_unref (src);
  src = sink = NULL;

  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src");
  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink");
  if (src == NULL || sink == NULL)
    goto failed_aud_connect;
  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
    goto failed_aud_connect;
  gst_object_unref (sink);
  gst_object_unref (src);
  src = sink = NULL;

  /* ghost audio munge output pad onto bin */
  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
  if (src == NULL)
    goto failed_aud_ghost;
  src_templ = gst_static_pad_template_get (&audio_src_template);
  dvdbin->audio_pad = gst_ghost_pad_new_from_template ("audio", src, src_templ);
  gst_object_unref (src_templ);
  if (dvdbin->audio_pad == NULL)
    goto failed_aud_ghost;
  gst_pad_set_active (dvdbin->audio_pad, TRUE);
  bctx = g_slice_new (RsnDvdBinPadBlockCtx);
  bctx->dvdbin = gst_object_ref (dvdbin);
  bctx->pad = gst_object_ref (dvdbin->audio_pad);
  gst_pad_set_blocked_async_full (src, TRUE,
      (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify)
      _pad_block_destroy_notify);
  gst_object_unref (src);
  src = NULL;

  if (dvdbin->video_added && (dvdbin->audio_added || dvdbin->audio_broken)
      && dvdbin->subpicture_added) {
    GST_DEBUG_OBJECT (dvdbin, "Firing no more pads");
    gst_element_no_more_pads (GST_ELEMENT (dvdbin));
  }

  return TRUE;

failed_connect:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not connect DVD source and demuxer elements"));
  goto error_out;
failed_viddec_connect:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not connect DVD video decoder and aspect ratio adjuster"));
  goto error_out;
failed_video_ghost:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not ghost video output pad"));
  goto error_out;
failed_spuq_connect:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not connect DVD subpicture selector and buffer elements"));
  goto error_out;
failed_spu_ghost:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not ghost SPU output pad"));
  goto error_out;
failed_aud_connect:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not connect DVD audio decoder"));
  goto error_out;
failed_aud_ghost:
  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
      ("Could not ghost audio output pad"));
  goto error_out;
error_out:
  if (src != NULL)
    gst_object_unref (src);
  if (sink != NULL)
    gst_object_unref (sink);
  return FALSE;
}
예제 #23
0
static void mpegts_demuxer_check_streams(MpegTSDemuxer *demuxer)
{
    MpegTSDemuxerClass *demuxer_class = MPEGTS_DEMUXER_GET_CLASS(demuxer);
    int i;
    for (i = 0; i < demuxer->context->nb_streams; i++)
    {
        switch (demuxer->context->streams[i]->codec->codec_type)
        {
            case AVMEDIA_TYPE_VIDEO:

                if (demuxer->video.stream_index < 0)
                {
                    AVStream *stream = demuxer->context->streams[i];
#if NEW_CODEC_ID
                    if (stream->codec->codec_id == AV_CODEC_ID_H264)
#else
                    if (stream->codec->codec_id == CODEC_ID_H264)
#endif
                    {
                        demuxer->video.stream_index = i;
                        demuxer->video.codec_id = stream->codec->codec_id;

#ifdef ENABLE_VIDEO
                        gchar *name = g_strdup_printf ("video%02d", i);
                        GstCaps *caps = gst_caps_new_simple ("video/x-h264",
                                                             "hls", G_TYPE_BOOLEAN, TRUE, NULL);

                        GstBuffer *codec_data = get_codec_extradata(stream->codec);
                        if (codec_data)
                            gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);

                        demuxer->video.sourcepad = gst_pad_new_from_template (demuxer_class->video_source_template, name);
                        mpegts_demuxer_add_pad(demuxer, demuxer->video.sourcepad, caps);
                        g_free(name);
#endif // ENABLE_VIDEO
                        demuxer->numpads++;
                    }
                }
                break;

            case AVMEDIA_TYPE_AUDIO:
                if (demuxer->audio.stream_index < 0)
                {
                    AVStream *stream = demuxer->context->streams[i];
#if NEW_CODEC_ID
                    if (stream->codec->codec_id == AV_CODEC_ID_AAC)
#else
                    if (stream->codec->codec_id == CODEC_ID_AAC)
#endif
                    {
                        demuxer->audio.stream_index = i;
                        demuxer->audio.codec_id = stream->codec->codec_id;

                        gchar *name = g_strdup_printf ("audio%02d", i);
                        GstCaps *caps = gst_caps_new_simple ("audio/mpeg",
                                                    "mpegversion", G_TYPE_INT, 4,
                                                    "channels", G_TYPE_INT, stream->codec->channels,
                                                    "rate", G_TYPE_INT, stream->codec->sample_rate,
                                                    "bitrate", G_TYPE_INT, stream->codec->bit_rate,
                                                    "hls", G_TYPE_BOOLEAN, TRUE, NULL);

                        GstBuffer *codec_data = get_codec_extradata(stream->codec);
                        if (codec_data)
                            gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);

                        demuxer->audio.sourcepad = gst_pad_new_from_template (demuxer_class->audio_source_template, name);
                        mpegts_demuxer_add_pad(demuxer, demuxer->audio.sourcepad, caps);
                        g_free(name);

                        demuxer->numpads++;
                    }
                }
                break;

            default:
                break;
        }
    }

    if (!mpegts_demuxer_expect_more_pads(demuxer))
    {
        gst_element_no_more_pads(GST_ELEMENT(demuxer));
#ifdef DEBUG_OUTPUT
        g_print("MpegTS: All pads added, no more pads\n");
#endif
    }
}
예제 #24
0
/******************************
 *   Internal helper methods  *
 ******************************/
static void
_pad_added_cb (GstElement * element, GstPad * srcpad, GstPad * sinkpad)
{
  gst_element_no_more_pads (element);
  gst_pad_link (srcpad, sinkpad);
}
예제 #25
0
static gboolean
gst_wavpack_parse_create_src_pad (GstWavpackParse * wvparse, GstBuffer * buf,
    WavpackHeader * header)
{
  GstWavpackMetadata meta;

  GstCaps *caps = NULL;

  guchar *bufptr;

  g_assert (wvparse->srcpad == NULL);

  bufptr = GST_BUFFER_DATA (buf) + sizeof (WavpackHeader);

  while (gst_wavpack_read_metadata (&meta, GST_BUFFER_DATA (buf), &bufptr)) {
    switch (meta.id) {
      case ID_WVC_BITSTREAM:{
        caps = gst_caps_new_simple ("audio/x-wavpack-correction",
            "framed", G_TYPE_BOOLEAN, TRUE, NULL);
        wvparse->srcpad =
            gst_pad_new_from_template (gst_element_class_get_pad_template
            (GST_ELEMENT_GET_CLASS (wvparse), "wvcsrc"), "wvcsrc");
        break;
      }
      case ID_WV_BITSTREAM:
      case ID_WVX_BITSTREAM:{
        WavpackStreamReader *stream_reader = gst_wavpack_stream_reader_new ();

        WavpackContext *wpc;

        gchar error_msg[80];

        read_id rid;

        gint channel_mask;

        rid.buffer = GST_BUFFER_DATA (buf);
        rid.length = GST_BUFFER_SIZE (buf);
        rid.position = 0;

        wpc =
            WavpackOpenFileInputEx (stream_reader, &rid, NULL, error_msg, 0, 0);

        if (!wpc)
          return FALSE;

        wvparse->samplerate = WavpackGetSampleRate (wpc);
        wvparse->channels = WavpackGetNumChannels (wpc);
        wvparse->total_samples =
            (header->total_samples ==
            0xffffffff) ? G_GINT64_CONSTANT (-1) : header->total_samples;

        caps = gst_caps_new_simple ("audio/x-wavpack",
            "width", G_TYPE_INT, WavpackGetBitsPerSample (wpc),
            "channels", G_TYPE_INT, wvparse->channels,
            "rate", G_TYPE_INT, wvparse->samplerate,
            "framed", G_TYPE_BOOLEAN, TRUE, NULL);
#ifdef WAVPACK_OLD_API
        channel_mask = wpc->config.channel_mask;
#else
        channel_mask = WavpackGetChannelMask (wpc);
#endif
        if (channel_mask == 0)
          channel_mask =
              gst_wavpack_get_default_channel_mask (wvparse->channels);

        if (channel_mask != 0) {
          if (!gst_wavpack_set_channel_layout (caps, channel_mask)) {
            GST_WARNING_OBJECT (wvparse, "Failed to set channel layout");
            gst_caps_unref (caps);
            caps = NULL;
            WavpackCloseFile (wpc);
            g_free (stream_reader);
            break;
          }
        }

        wvparse->srcpad =
            gst_pad_new_from_template (gst_element_class_get_pad_template
            (GST_ELEMENT_GET_CLASS (wvparse), "src"), "src");
        WavpackCloseFile (wpc);
        g_free (stream_reader);
        break;
      }
      default:{
        GST_LOG_OBJECT (wvparse, "unhandled ID: 0x%02x", meta.id);
        break;
      }
    }
    if (caps != NULL)
      break;
  }

  if (caps == NULL || wvparse->srcpad == NULL)
    return FALSE;

  GST_DEBUG_OBJECT (wvparse, "Added src pad with caps %" GST_PTR_FORMAT, caps);

  gst_pad_set_query_function (wvparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_wavpack_parse_src_query));
  gst_pad_set_query_type_function (wvparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_wavpack_parse_get_src_query_types));
  gst_pad_set_event_function (wvparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_wavpack_parse_src_event));

  gst_pad_set_caps (wvparse->srcpad, caps);
  gst_caps_unref (caps);
  gst_pad_use_fixed_caps (wvparse->srcpad);

  gst_object_ref (wvparse->srcpad);
  gst_pad_set_active (wvparse->srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT (wvparse), wvparse->srcpad);
  gst_element_no_more_pads (GST_ELEMENT (wvparse));

  return TRUE;
}