Proper way to set delay per sink audiomixer/compositor

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Proper way to set delay per sink audiomixer/compositor

Sean DuBois
Currently I use gst_pad_set_offset on the sink pad to delay either
audio/video and it works great. However I can't adjust the delay after
the pipeline has been linked.

Below is a minimal example

```
#include <gst/gst.h>

static GstElement *compositor, *audiomixer;

gboolean timeout_cb(gpointer user_data) {
        g_print("Updating delay \n");
        gst_pad_set_offset((GstPad *)user_data, 0);
        return FALSE;
}

void pad_added(GstElement *object, GstPad *in_pad, gpointer user_data) {
        GstCaps *decodebin_caps = gst_pad_get_current_caps(in_pad);
        g_autofree gchar *pad_name = gst_caps_to_string(decodebin_caps);
        GstPad *out_pad = NULL;

        if (g_str_has_prefix(pad_name, "video")) {
                out_pad = gst_element_get_request_pad(compositor, "sink_%u");
        } else {
                out_pad = gst_element_get_request_pad(audiomixer, "sink_%u");
                gst_pad_set_offset(out_pad, 3000000000);
                g_timeout_add_seconds(5, &timeout_cb, out_pad);
        }

        gst_pad_link(in_pad, out_pad);
}

int main(int argc, char *argv[]) {
        gst_init(&argc, &argv);
        GMainLoop *loop = g_main_loop_new(NULL, FALSE);

        GstElement *pipeline = gst_pipeline_new(NULL);

        compositor = gst_element_factory_make("compositor", NULL);
        audiomixer = gst_element_factory_make("audiomixer", NULL);

        GstElement *filesrc = gst_element_factory_make("filesrc", NULL),
                   *decodebin = gst_element_factory_make("decodebin", NULL),
                   *a_convert = gst_element_factory_make("audioconvert", NULL),
                   *v_convert = gst_element_factory_make("videoconvert", NULL),
                   *a_sink = gst_element_factory_make("autoaudiosink", NULL),
                   *v_sink = gst_element_factory_make("autovideosink", NULL);

        gst_bin_add_many(GST_BIN(pipeline), filesrc, decodebin, a_convert,
                         v_convert, a_sink, v_sink, audiomixer, compositor,
                         NULL);

        g_object_set(filesrc, "location",
                     "/home/sean/Documents/testVideos/doom.mkv", NULL);

        gst_element_link(filesrc, decodebin);
        gst_element_link_many(compositor, v_convert, v_sink, NULL);
        gst_element_link_many(audiomixer, a_convert, a_sink, NULL);

        g_signal_connect(decodebin, "pad-added", G_CALLBACK(&pad_added), NULL);

        gst_element_set_state(pipeline, GST_STATE_PLAYING);
        g_main_loop_run(loop);
}
```
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Proper way to set delay per sink audiomixer/compositor

Nicolas Dufresne-5
Le jeudi 29 juin 2017 à 02:08 -0500, Sean DuBois a écrit :
> Currently I use gst_pad_set_offset on the sink pad to delay either
> audio/video and it works great. However I can't adjust the delay
> after
> the pipeline has been linked.

The pad offset will modify the segment event, which is sent once per
stream. If you need to shift dynamically the synchronization you'd need
to enhance the aggregator pad a bit. you could override the pad offset
property I think.

This isn't trivial though, as it means you may endup with queued buffer
to which you need to apply a different time offset. You could also only
read the offset before aggregating, but that would mean that each time
a pad offset is set, you'll need to wake up the timers so they can
calculate the new deadline.

regards,
Nicolas
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (188 bytes) Download Attachment