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; }
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); }
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); }
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)); } }
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); } }
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); }
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); }
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)); }
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)); }
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; }
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); }
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); }
/** * 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)); }
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); } }
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; }
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)); } }
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)); } } }
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; } }
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; } }
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)); } }
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; }
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 } }
/****************************** * 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); }
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; }