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");
}
Beispiel #5
0
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);
}