issues: Although source element is paused or source video data is blocked, sink element keeps rendering and writing data to a file
永井知明 via gstreamer-devel <[email protected]>
| Newsgroups | gmane.comp.video.gstreamer.devel |
|---|---|
| Message-ID | <CACVpVDXM=QfF2NXGfmV+4b9nEjN-T8uPfjy7ko1grfZ0M+DhXw@mail.gmail.com> |
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:[email protected] <[email protected]> *******************
main.cpp
(text/plain, 2.7 KB)
#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;
}