ges: Fix interlaced stream playback

Negotiation was failling as `videoflip` was not allowing not
progressive interlacing.

Also avoid adding a deinterlace element when it is useless.
This commit is contained in:
Thibault Saunier 2020-04-17 12:35:26 -04:00
parent 5720ae4f25
commit 5bb5f60043
2 changed files with 42 additions and 28 deletions

View file

@ -87,24 +87,14 @@ _set_priority (GESTimelineElement * element, guint32 priority)
return res;
}
static void
post_missing_element_message (GstElement * element, const gchar * name)
{
GstMessage *msg;
msg = gst_missing_element_message_new (element, name);
gst_element_post_message (element, msg);
}
static gboolean
ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
gboolean needs_converters)
{
GESTrackElement *trksrc = GES_TRACK_ELEMENT (self);
GstElement *positioner, *videoflip, *capsfilter, *deinterlace;
const gchar *positioner_props[] =
{ "alpha", "posx", "posy", "width", "height", NULL };
const gchar *deinterlace_props[] = { "mode", "fields", "tff", NULL };
GstElement *positioner, *videoflip, *capsfilter;
const gchar *positioner_props[]
= { "alpha", "posx", "posy", "width", "height", NULL };
const gchar *videoflip_props[] = { "video-direction", NULL };
g_ptr_array_add (elements, gst_element_factory_make ("queue", NULL));
@ -116,6 +106,9 @@ ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
G_MAXUINT - GES_TIMELINE_ELEMENT_PRIORITY (self), NULL);
g_ptr_array_add (elements, positioner);
if (needs_converters)
g_ptr_array_add (elements, gst_element_factory_make ("videoconvert", NULL));
/* If there's image-orientation tag, make sure the image is correctly oriented
* before we scale it. */
videoflip = gst_element_factory_make ("videoflip", "track-element-videoflip");
@ -130,6 +123,7 @@ ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
}
g_ptr_array_add (elements, gst_element_factory_make ("videorate",
"track-element-videorate"));
capsfilter =
gst_element_factory_make ("capsfilter", "track-element-capsfilter");
g_ptr_array_add (elements, capsfilter);
@ -142,21 +136,6 @@ ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
ges_track_element_add_children_props (trksrc, videoflip, NULL, NULL,
videoflip_props);
deinterlace = gst_element_factory_make ("deinterlace", "deinterlace");
if (deinterlace == NULL) {
post_missing_element_message (ges_track_element_get_nleobject (trksrc),
"deinterlace");
GST_ELEMENT_WARNING (ges_track_element_get_nleobject (trksrc), CORE,
MISSING_PLUGIN,
("Missing element '%s' - check your GStreamer installation.",
"deinterlace"), ("deinterlacing won't work"));
} else {
g_ptr_array_add (elements, deinterlace);
ges_track_element_add_children_props (trksrc, deinterlace, NULL, NULL,
deinterlace_props);
}
self->priv->positioner = GST_FRAME_POSITIONNER (positioner);
self->priv->positioner->scale_in_compositor =
!GES_VIDEO_SOURCE_GET_CLASS (self)->ABI.abi.disable_scale_in_compositor;

View file

@ -223,6 +223,14 @@ _find_positioner (GstElement * a, GstElement * b)
"framepositioner");
}
static void
post_missing_element_message (GstElement * element, const gchar * name)
{
GstMessage *msg;
msg = gst_missing_element_message_new (element, name);
gst_element_post_message (element, msg);
}
/* GObject VMethods */
static gboolean
@ -230,12 +238,39 @@ ges_video_uri_source_create_filters (GESVideoSource * source,
GPtrArray * elements, gboolean needs_converters)
{
GESAsset *asset = ges_extractable_get_asset (GES_EXTRACTABLE (source));
GstDiscovererVideoInfo *info =
GST_DISCOVERER_VIDEO_INFO (ges_uri_source_asset_get_stream_info
(GES_URI_SOURCE_ASSET (asset)));
g_assert (GES_IS_URI_SOURCE_ASSET (asset));
if (!GES_VIDEO_SOURCE_CLASS (ges_video_uri_source_parent_class)
->ABI.abi.create_filters (source, elements, needs_converters))
return FALSE;
if (gst_discoverer_video_info_is_interlaced (info)) {
const gchar *deinterlace_props[] = { "mode", "fields", "tff", NULL };
GstElement *deinterlace =
gst_element_factory_make ("deinterlace", "deinterlace");
if (deinterlace == NULL) {
post_missing_element_message (ges_track_element_get_nleobject
(GES_TRACK_ELEMENT (source)), "deinterlace");
GST_ELEMENT_WARNING (ges_track_element_get_nleobject (GES_TRACK_ELEMENT
(source)), CORE, MISSING_PLUGIN,
("Missing element '%s' - check your GStreamer installation.",
"deinterlace"), ("deinterlacing won't work"));
} else {
/* Right after the queue */
g_ptr_array_insert (elements, 1, gst_element_factory_make ("videoconvert",
NULL));
g_ptr_array_insert (elements, 2, deinterlace);
ges_track_element_add_children_props (GES_TRACK_ELEMENT (source),
deinterlace, NULL, NULL, deinterlace_props);
}
}
if (ges_uri_source_asset_is_image (GES_URI_SOURCE_ASSET (asset))) {
guint i;