提问人:永井知明 提问时间:8/2/2023 最后编辑:永井知明 更新时间:8/3/2023 访问量:25
尽管源元素已暂停或源视频数据被阻止,但接收器元素会继续呈现数据并将其写入文件
Although source element is paused or source video data is blocked, sink element keeps rendering and writing data to a file
问:
我想知道为什么 autovideosink 元素一直显示而 filesink 元素继续写入最后一个输入帧,即使源元素暂停并且视频数据没有流动。
当源元素暂停时,我认为 sink 元素显示或写入空白帧是正确的行为。
我尝试插入 valve 元素,该元素在源元素和接收器元素之间放置帧缓冲区,但结果是一样的。
一个示例源代码,即使视频源元素暂停,它也会继续显示最后一个输入帧,如下所示。
对于一些额外的上下文,这在 Windows 11 和 Gstreamer 版本 1.22.4 中运行。
#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;
}
答: 暂无答案
评论