static void maybe_start_renderer(OwrMediaRenderer *renderer) { OwrMediaRendererPrivate *priv; GstPad *sinkpad, *srcpad; GstElement *src; GstCaps *caps; GstPadLinkReturn pad_link_return; priv = renderer->priv; if (!priv->sink || !priv->source) return; sinkpad = gst_element_get_static_pad(priv->sink, "sink"); g_assert(sinkpad); caps = OWR_MEDIA_RENDERER_GET_CLASS(renderer)->get_caps(renderer); src = _owr_media_source_request_source(priv->source, caps); gst_caps_unref(caps); g_assert(src); srcpad = gst_element_get_static_pad(src, "src"); g_assert(srcpad); priv->src = src; /* The sink is always inside the bin already */ gst_bin_add_many(GST_BIN(priv->pipeline), priv->src, NULL); pad_link_return = gst_pad_link(srcpad, sinkpad); gst_object_unref(sinkpad); gst_object_unref(srcpad); if (pad_link_return != GST_PAD_LINK_OK) { GST_ERROR("Failed to link source with renderer (%d)", pad_link_return); return; } gst_element_set_state(priv->pipeline, GST_STATE_PLAYING); }
gboolean owr_media_renderer_set_source(OwrMediaRenderer *renderer, OwrMediaSource *source) { OwrMediaRendererPrivate *priv; gboolean ret = TRUE; GstPad *srcpad, *sinkpad; GstCaps *caps; GstPadLinkReturn pad_link_return; g_assert(renderer); g_assert(source); priv = renderer->priv; g_mutex_lock(&priv->media_renderer_lock); if (priv->source) { unlink_source(renderer); g_object_unref(priv->source); priv->source = NULL; } g_mutex_unlock(&priv->media_renderer_lock); /* FIXME - too much locking/unlocking of the same lock across private API? */ sinkpad = _owr_media_renderer_get_pad(renderer); g_assert(sinkpad); caps = OWR_MEDIA_RENDERER_GET_CLASS(renderer)->get_caps(renderer); srcpad = _owr_media_source_get_pad(source, caps); gst_caps_unref(caps); g_assert(srcpad); g_mutex_lock(&priv->media_renderer_lock); pad_link_return = gst_pad_link(srcpad, sinkpad); if (pad_link_return != GST_PAD_LINK_OK) { GST_ERROR("Failed to link source with renderer (%d)", pad_link_return); ret = FALSE; goto done; } gst_element_post_message(_owr_get_pipeline(), gst_message_new_latency(GST_OBJECT(_owr_get_pipeline()))); priv->source = g_object_ref(source); done: priv->srcpad = srcpad; priv->sinkpad = sinkpad; g_mutex_unlock(&priv->media_renderer_lock); return ret; }
static GstElement *owr_audio_renderer_get_element(OwrMediaRenderer *renderer) { GstElement *renderer_bin; GstElement *audioresample, *audioconvert, *capsfilter, *volume, *sink; GstCaps *filter_caps; GstPad *ghostpad, *sinkpad; gchar *bin_name; g_assert(renderer); bin_name = g_strdup_printf("audio-renderer-bin-%u", g_atomic_int_add(&unique_bin_id, 1)); renderer_bin = gst_bin_new(bin_name); g_free(bin_name); audioresample = gst_element_factory_make("audioresample", "audio-renderer-resample"); audioconvert = gst_element_factory_make("audioconvert", "audio-renderer-convert"); capsfilter = gst_element_factory_make("capsfilter", "audio-renderer-capsfilter"); filter_caps = gst_caps_new_simple("audio/x-raw", "format", G_TYPE_STRING, "S16LE", NULL); g_object_set(capsfilter, "caps", filter_caps, NULL); volume = gst_element_factory_make("volume", "audio-renderer-volume"); g_object_bind_property(renderer, "disabled", volume, "mute", G_BINDING_SYNC_CREATE); sink = OWR_MEDIA_RENDERER_GET_CLASS(renderer)->get_sink(renderer); g_assert(sink); gst_bin_add_many(GST_BIN(renderer_bin), audioresample, audioconvert, capsfilter, volume, sink, NULL); LINK_ELEMENTS(volume, sink); LINK_ELEMENTS(capsfilter, volume); LINK_ELEMENTS(audioconvert, capsfilter); LINK_ELEMENTS(audioresample, audioconvert); sinkpad = gst_element_get_static_pad(audioresample, "sink"); g_assert(sinkpad); ghostpad = gst_ghost_pad_new("sink", sinkpad); gst_pad_set_active(ghostpad, TRUE); gst_element_add_pad(renderer_bin, ghostpad); gst_object_unref(sinkpad); return renderer_bin; }
GstPad *_owr_media_renderer_get_pad(OwrMediaRenderer *renderer) { GstElement *sink = NULL; OwrMediaRendererPrivate *priv; g_assert(renderer); priv = renderer->priv; g_mutex_lock(&priv->media_renderer_lock); if (priv->sink) { sink = priv->sink; goto done; } sink = OWR_MEDIA_RENDERER_GET_CLASS(renderer)->get_element(renderer); g_assert(sink); priv->sink = sink; done: g_mutex_unlock(&priv->media_renderer_lock); return gst_element_get_static_pad(sink, "sink"); }
void _owr_media_renderer_reconfigure_element(OwrMediaRenderer *renderer) { g_return_if_fail(OWR_IS_MEDIA_RENDERER(renderer)); OWR_MEDIA_RENDERER_GET_CLASS(renderer)->reconfigure_element(renderer); }