J'essaie de superposer une image .png (avec un canal alpha) sur GStreamer-1.0 pour une application que je suis en train d'écrire, mais, après beaucoup de recherche sur le Web et la lecture de la documentation I » Je suis encore un peu confus avec la méthode à utiliser.Changer le format vidéo sur GStreamer
La méthode que je me sers est:
filesrc -> pngdec -> imagefreeze -> videoconvert -> videoscale -> videomixer -> output_of_bin input_of_bin -> videoconvert -> videoscale -> |
Ceci est une petite section d'une application plus large.
Ma question est la définition des propriétés sur les éléments videoscale et videoconvert, je pense que vous êtes censé utiliser GSTCaps, mais cela ne fonctionne pas. J'ai essayé plusieurs façons. C'est une fonction membre dans une classe qui fournit la superposition. Je m'excuse à l'avance pour le désordre du code, mais c'est expérimental.
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;
}
Je voudrais prendre les deux sources les redimensionner à la même taille et la superposition de l'image png sur la vidéo. Le bloc fonctionne principalement, mais je ne peux pas faire fonctionner le redimensionnement ou le canal alpha.
Merci,
Edit:
J'ai maintenant modifié mon code et avoir une compréhension un peu mieux, il semble toutefois que le problème est que le capfilter ne sera pas un lien si elle utilise RGBA certains d'autres formats fonctionnent mais ne servent à rien. Je ne sais pas pourquoi.
bool ImageOverlay::MakeElements()
{
try
{
// Creates the bin at this level
CreatePipeline();
GstElement *file_source, *png_decoder, *freeze, *colorspace,
*video_mixer, *identity, * colorspace2, *video_scale_1, *video_scale_2, *caps_filter1, *caps_filter2;
// Create elements
file_source = CreateElementAndAddToBin("multifilesrc", "file-source");
png_decoder = CreateElementAndAddToBin("pngdec", "png-decoder");
colorspace = CreateElementAndAddToBin("videoconvert", "colorspace");
colorspace2 = CreateElementAndAddToBin("videoconvert", "colorspace2");
identity = CreateElementAndAddToBin("identity", "identity");
video_mixer = CreateElementAndAddToBin("videomixer", "mixer");
freeze = CreateElementAndAddToBin("imagefreeze", "freeze");
video_scale_1 = CreateElementAndAddToBin("videoscale", "scale1");
video_scale_2 = CreateElementAndAddToBin("videoscale", "scale2");
caps_filter1 = CreateElementAndAddToBin("capsfilter", "caps_filter1");
caps_filter2 = CreateElementAndAddToBin("capsfilter", "caps_filter2");
// Set input file
g_object_set (G_OBJECT (file_source), "location", "../Template1.png", NULL);
// Create caps
GstCaps *caps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, "YV12", //<<< IF THIS IS SET TO ARGB (THE FORMAT I WANT IT FAILS ON LINKING)
"framerate", GST_TYPE_FRACTION, 25, 1,
"pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
// Set caps on cap filter
g_object_set(G_OBJECT(caps_filter2), "caps", caps, NULL);
g_object_set(G_OBJECT(caps_filter1), "caps", caps, NULL);
// Link up elements
if (!gst_element_link_many (identity, video_scale_2, colorspace2, caps_filter2, video_mixer, NULL))
{
std::cout << "Could not link input branch" << std::endl; //<<<< IF ARGB OR OTHER FORMATS SUCH AS RGBA ARE USED
} // IN CAP FILTER, THIS FAILS, SAME WITH BELOW. IT WORKS WITH YV12!
if (!gst_element_link_many (file_source, png_decoder, freeze, video_scale_1, colorspace, caps_filter1, video_mixer, NULL))
{
std::cout << "Could not link image source branch" << std::endl;
}
// Add ghost pads to this bin, allowing it to be used as an element
SetInputElement(identity);
SetOutputElement(video_mixer);
}
catch(...)
{
std::cout << "Overlay generator failed to build, exception thrown" << std::endl;
// TODO - Clear up in here
return false;
}
return true;
}
Merci s'il vous plaît pouvez-vous voir le modifier à ma question – robby987
Je ne sais pas pourquoi votre code ne fonctionne pas, faisant partie d'une structure plus grande, je crains que je ne peux pas répondre. Si vous parvenez à me fournir un code C autonome qui présente la question que je peux jeter un oeil :) –
je suis passé à GStreamer-1.2 au détriment de certaines autres questions (ubuntu 13.10 a quelques bugs dans), il a ensuite travaillé. Merci de votre aide. – robby987