C++ 在GStreamer上更改视频格式
我正试图在gstreamer-1.0上为我正在编写的应用程序覆盖一个.png图像(带有alpha通道),但是,在搜索了大量web和阅读文档之后,我仍然对使用的方法感到有些困惑 我使用的方法是: filesrc->pngdec->imagefreeze->videoconvert->videoscale->videomixer->u bin的输出 输入\u bin->videoconvert->videoscale->| 这是大型应用程序的一小部分 我的问题是设置videoscale和videoconvert元素的属性,我认为应该使用GSTCAP,但是这不起作用。我试过很多方法。这是提供覆盖的类中的成员函数。我为代码的混乱道歉,但这是实验性的C++ 在GStreamer上更改视频格式,c++,c,video,gstreamer,image-resizing,C++,C,Video,Gstreamer,Image Resizing,我正试图在gstreamer-1.0上为我正在编写的应用程序覆盖一个.png图像(带有alpha通道),但是,在搜索了大量web和阅读文档之后,我仍然对使用的方法感到有些困惑 我使用的方法是: filesrc->pngdec->imagefreeze->videoconvert->videoscale->videomixer->u bin的输出 输入\u bin->videoconvert->videoscale->| 这是大型应用程序的一小部分 我的问题是设置videoscale和videoc
bool ImageOverlay::CreateElement()
{
GstPad *source_pad, *sink_pad;
GstElement *file_source, *png_decoder, *freeze, *colorspace,
*video_mixer, *identity, * colorspace2, *video_scale_1, *video_scale_2;
/* Create gstreamer elements */
_image_overlay_element = gst_bin_new("image-player");
if(!_image_overlay_element)
{
g_printerr ("Pipeline could not be created. Exiting.\n");
return false;
}
// Create file source
file_source = gst_element_factory_make ("multifilesrc", "file-source");
g_object_set (G_OBJECT (file_source), "location", "../Template1.png", NULL);
if(!file_source)
{
g_printerr ("File could not be created. Exiting.\n");
return false;
}
// Decode file
png_decoder = gst_element_factory_make ("pngdec", "png-decoder");
if(!png_decoder)
{
g_printerr ("png-decoder could not be created. Exiting.\n");
return false;
}
// Create colour space convertor
colorspace = gst_element_factory_make("videoconvert", "colorspace");
if(!colorspace)
{
g_printerr ("Colorspace could not be created. Exiting.\n");
return false;
}
// Create colour space convertor
colorspace2 = gst_element_factory_make("videoconvert", "colorspace2");
if(!colorspace)
{
g_printerr ("Colorspace could not be created. Exiting.\n");
return false;
}
// Create idenentiy component, does nothing but is useful for debug
identity = gst_element_factory_make("identity", "identity");
if(!identity)
{
g_printerr ("Colorspace could not be created. Exiting.\n");
return false;
}
// Create a video mixer
video_mixer = gst_element_factory_make("videomixer", "mixer");
if(!video_mixer)
{
g_printerr ("videomixer could not be created. Exiting.\n");
return false;
}
// Create a freeze element
freeze = gst_element_factory_make("imagefreeze", "freeze");
if(!freeze)
{
g_printerr ("ImageFreeze could not be created. Exiting.\n");
return false;
}
video_scale_1 = gst_element_factory_make("videoscale", NULL);
if(!video_scale_1)
{
g_printerr ("video_scale_1 could not be created. Exiting.\n");
return false;
}
video_scale_2 = gst_element_factory_make("videoscale", NULL);
if(!video_scale_2)
{
g_printerr ("video_scale_2 could not be created. Exiting.\n");
return false;
}
// Add to the bin
gst_bin_add_many (GST_BIN (_image_overlay_element),
file_source,
png_decoder,
colorspace,
colorspace2,
freeze,
video_mixer,
identity,
video_scale_1,
video_scale_2,
NULL);
if (!gst_element_link_many (file_source, png_decoder, video_scale_1, freeze, NULL))
{
std::cout << "Could not link" << std::endl;
}
GstCaps * caps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, "ARGB",
NULL);
GstCaps * caps2 = gst_caps_new_simple("width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
gst_element_link_filtered(video_scale_1, freeze, caps2);
gst_element_link_filtered(video_scale_2, freeze, caps2);
if (!gst_element_link_many(freeze, video_scale_2, colorspace, NULL))
{
std::cout << "Could not link" << std::endl;
}
// Link pads to video mixer
GstPad * sink_pad_1 = gst_element_get_request_pad (video_mixer, "sink_%u");
GstPad * sink_pad_2 = gst_element_get_request_pad (video_mixer, "sink_%u");
GstPad * source_2 = gst_element_get_static_pad (identity, "src");
GstPad * source_1 = gst_element_get_static_pad (colorspace, "src");
gst_pad_set_caps(source_2, caps);
gst_pad_set_caps(source_1, caps);
gst_caps_unref(caps);
if (!gst_pad_link ( source_1, sink_pad_1) == GST_PAD_LINK_OK)
{
std::cout << "Could not link pads" << std::endl;
return false;
}
if (!gst_pad_link ( source_2, sink_pad_2) == GST_PAD_LINK_OK)
{
std::cout << "Could not link pads" << std::endl;
return false;
}
gst_pad_set_active(source_1, true);
gst_pad_set_active(sink_pad_1, true);
gst_pad_set_active(source_2, true);
gst_pad_set_active(sink_pad_2, true);
// Add pad to this element
source_pad = gst_element_get_static_pad (video_mixer, "src");
sink_pad = gst_element_get_static_pad(identity, "sink");
gst_element_add_pad (_image_overlay_element, gst_ghost_pad_new ("src", source_pad));
gst_element_add_pad (_image_overlay_element, gst_ghost_pad_new ("sink", sink_pad));
return true;
}
bool ImageOverlay::CreateElement()
{
GstPad*源焊盘,*汇焊盘;
GstElement*文件源、*png解码、*冻结、*色彩空间、,
*视频混合器,*标识,*色彩空间2,*视频比例1,*视频比例2;
/*创建gstreamer元素*/
_image_overlay_element=gst_bin_new(“图像播放器”);
if(!\u图像\u覆盖\u元素)
{
g_printerr(“无法创建管道。正在退出。\n”);
返回false;
}
//创建文件源
文件来源=gst元素工厂制造(“多文件来源”);
g_object_set(g_object(文件源),“location”,“./Template1.png”,NULL);
如果(!文件\源)
{
g_printerr(“无法创建文件。正在退出。\n”);
返回false;
}
//解码文件
png_解码器=gst_元素_工厂制造(“pngdec”,“png解码器”);
if(!png_解码器)
{
g_printerr(“无法创建png解码器。正在退出。\n”);
返回false;
}
//创建颜色空间转换器
颜色空间=gst元素工厂制造(“视频转换”、“颜色空间”);
if(!颜色空间)
{
g_printerr(“无法创建颜色空间。正在退出。\n”);
返回false;
}
//创建颜色空间转换器
colorspace2=gst元素工厂制造(“视频转换”、“colorspace2”);
if(!颜色空间)
{
g_printerr(“无法创建颜色空间。正在退出。\n”);
返回false;
}
//创建identity组件,不执行任何操作,但对调试非常有用
标识=商品及服务税、要素、工厂制造(“标识”、“标识”);
如果(!标识)
{
g_printerr(“无法创建颜色空间。正在退出。\n”);
返回false;
}
//创建一个视频混合器
视频混合器=gst元素工厂制造(“视频混合器”、“混合器”);
如果(!视频_混音器)
{
g_printerr(“无法创建视频混合器。正在退出。\n”);
返回false;
}
//创建冻结元素
冻结=商品及服务税要素工厂制造(“图像冻结”、“冻结”);
如果(!冻结)
{
g_printerr(“无法创建ImageFreeze。正在退出。\n”);
返回false;
}
video_scale_1=gst_元素_工厂制造(“video scale”,空);
如果(!视频比例1)
{
g_printerr(“无法创建视频_比例_1。正在退出。\n”);
返回false;
}
video_scale_2=gst_元素_工厂制造(“video scale”,空);
如果(!视频比例2)
{
g_printerr(“无法创建视频缩放2。正在退出。\n”);
返回false;
}
//添加到垃圾箱
gst_bin_add_many(gst_bin(_image_overlay_element)),
文件来源:,
png_解码器,
色彩空间,
色彩空间2,
冻结
视频混合器,
身份,
视频比例尺1,
视频比例尺2,
无效);
如果(!gst\u元素\u链接\u多(文件\u源、png\u解码器、视频\u比例\u 1、冻结、空))
{
std::cout从gstreamer 1.2开始,视频转换由混频器承担,如果其中一个接收器垫具有alpha,它将自动选择alpha格式
如果可以更新到1.2,则需要使用的管道将具有以下形式:
gst-launch-1.0 uridecodebin uri=file:///home/meh/Pictures/pitivi/nicetext.png ! imagefreeze ! videomixer name=m sink_0::zorder=0 ! videoconvert ! autovideosink videotestsrc ! videoscale ! video/x-raw, width=640, height=400 ! m.
其中nicetext.png是一个(png)640 x 400图像文件,具有透明背景和一些随机文本
videoscale后面的部分是capsfilter,您可以使用以下工具创建它:
gst\u元素\u工厂制造(“capsfilter”、“随机名称”)
然后将其caps属性设置为所需的宽度和高度。如果事先不知道这一点,则需要在需要复制宽度和高度的焊盘上设置焊盘探针,截取caps事件并在此时在capsfilter上设置caps
如果由于某种原因您不能使用1.2,那么您将需要在两个分支上使用videoconvert和capsfilter,并指定您所需的格式。我不知道为什么您的代码不起作用,因为它是更大结构的一部分,恐怕我无法回答。如果您设法为我提供一些显示此问题的独立C代码,我可以抛出一个e叶:)我升级到了gstreamer-1.2,但牺牲了一些其他问题(ubuntu 13.10中有一些bug),然后成功了。谢谢你的帮助。没问题,我在videomixer中实现了转换支持,很高兴它起到了作用。我想你可以接受我的答案:)
gst-launch-1.0 uridecodebin uri=file:///home/meh/Pictures/pitivi/nicetext.png ! imagefreeze ! videomixer name=m sink_0::zorder=0 ! videoconvert ! autovideosink videotestsrc ! videoscale ! video/x-raw, width=640, height=400 ! m.