issues: Although source element is paused or source video data is blocked, sink element keeps rendering and writing data to a file

永井知明 nagait at photron.co.jp
Wed Aug 2 23:50:26 UTC 2023


Hi

I wonder why the autovideosink element keeps displaying and the filesink
element keeps writing the last input frame even though the source element
is paused and the video data is not flowing.

When the source element is paused, I think that the sink element displaying
or writing a blank frame is correct behavior.

I tried to insert a valve element which drops the frame buffer between the
source element and sink element, but the result was the same.

An example source code which keeps displaying the last input frame even
though the video source element is paused attached to this mail.

For some additional context, this is running in a Windows 11 and Gstreamer
version 1.22.4.
Kind regards,
Nagai
-- 
*******************
 永井 知明
フォトロン M&E ソリューションズ株式会社
〒101-0051
東京都千代田区神田神保町1-105
神保町三井ビルディング 21F
TEL:03-3518-6282
FAX:03-3518-6279
E-Mail:nagait at photron.co.jp <itimura at photron.co.jp>
*******************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20230803/a185fe66/attachment.htm>
-------------- next part --------------
#include <gst/gst.h>
#include <cstdio>

enum class STATE
{
    WAITING,
    RECORDING,
    PAUSING,
};

typedef struct _CustomData
{
    GstElement* pipeline;
    GstElement* src;
    GstElement* rendersink;
    GMainLoop* loop;
    STATE state;
} CustomData;

static gboolean handle_keyboard(GIOChannel* source, GIOCondition cond, CustomData* data)
{
    gchar* str = NULL;
    GstBus* bus = NULL;
    GstMessage* msg = NULL;

    if (g_io_channel_read_line(source, &str, NULL, NULL,NULL) != G_IO_STATUS_NORMAL) {
        return TRUE;
    }

    switch (g_ascii_tolower(str[0])) {
    case 'p':
        if (data->state == STATE::RECORDING)
        {
            g_print("Setting state to %s\n", "PAUSE");
            data->state = STATE::PAUSING;
            gst_element_set_state(data->src, GST_STATE_PAUSED);
        }
        else if (data->state == STATE::PAUSING)
        {
            g_print("Setting state to %s\n", "PLAYING");
            data->state = STATE::RECORDING;
            gst_element_set_state(data->src, GST_STATE_PLAYING);
        }
        break;
    case 'q':
        g_print("Finish\n");
        g_main_loop_quit(data->loop);
        break;
    default:
        break;
    }

    g_free(str);

    return TRUE;
}

int main(int argc, char* argv[])
{
    CustomData data;
    GstStateChangeReturn ret;

	gst_init(&argc, &argv);

	data.pipeline = gst_pipeline_new("pipeline");
	data.src = gst_element_factory_make("dshowvideosrc", "src");
	data.rendersink = gst_element_factory_make("autovideosink", "autovideosink");

	if (!data.pipeline || !data.src || !data.rendersink)
	{
		g_printerr("Failed to create elements\n");
		return -1;
	}

	gst_bin_add_many(GST_BIN(data.pipeline), data.src, data.rendersink, NULL);

	g_object_set(G_OBJECT(data.src), "device-index", 0, "do-timestamp", true, NULL);

	if (!gst_element_link_filtered(data.src, data.rendersink, gst_caps_new_simple("video/x-raw",
		"width", G_TYPE_INT, 1920,
		"height", G_TYPE_INT, 1080,
		"framerate", GST_TYPE_FRACTION, 30, 1,
		NULL))) {
		g_printerr("Failed to link src1 and comp\n");
		gst_object_unref(data.pipeline);
		return -1;
	}

	g_print("USAGE: Choose one of the following options, then press enter:\n"
		" 'P' to toggle between PAUSE and PLAY\n"
		" 'Q' to quit\n");

	GIOChannel* io_stdin = g_io_channel_unix_new(_fileno(stdin));
	g_io_add_watch(io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);

	ret = gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
	data.state = STATE::RECORDING;

	data.loop = g_main_loop_new(NULL, FALSE);
	g_main_loop_run(data.loop);

	gst_element_set_state(data.pipeline, GST_STATE_NULL);
	gst_object_unref(data.pipeline);
	return 0;
}


More information about the gstreamer-devel mailing list