C++ 在GStreamer上更改视频格式

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

我正试图在gstreamer-1.0上为我正在编写的应用程序覆盖一个.png图像(带有alpha通道),但是,在搜索了大量web和阅读文档之后,我仍然对使用的方法感到有些困惑

我使用的方法是:

filesrc->pngdec->imagefreeze->videoconvert->videoscale->videomixer->u bin的输出 输入\u bin->videoconvert->videoscale->|

这是大型应用程序的一小部分

我的问题是设置videoscale和videoconvert元素的属性,我认为应该使用GSTCAP,但是这不起作用。我试过很多方法。这是提供覆盖的类中的成员函数。我为代码的混乱道歉,但这是实验性的

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.