mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
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:
parent
5720ae4f25
commit
5bb5f60043
2 changed files with 42 additions and 28 deletions
|
@ -87,24 +87,14 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
||||||
return res;
|
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
|
static gboolean
|
||||||
ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
|
ges_video_source_create_filters (GESVideoSource * self, GPtrArray * elements,
|
||||||
gboolean needs_converters)
|
gboolean needs_converters)
|
||||||
{
|
{
|
||||||
GESTrackElement *trksrc = GES_TRACK_ELEMENT (self);
|
GESTrackElement *trksrc = GES_TRACK_ELEMENT (self);
|
||||||
GstElement *positioner, *videoflip, *capsfilter, *deinterlace;
|
GstElement *positioner, *videoflip, *capsfilter;
|
||||||
const gchar *positioner_props[] =
|
const gchar *positioner_props[]
|
||||||
{ "alpha", "posx", "posy", "width", "height", NULL };
|
= { "alpha", "posx", "posy", "width", "height", NULL };
|
||||||
const gchar *deinterlace_props[] = { "mode", "fields", "tff", NULL };
|
|
||||||
const gchar *videoflip_props[] = { "video-direction", NULL };
|
const gchar *videoflip_props[] = { "video-direction", NULL };
|
||||||
|
|
||||||
g_ptr_array_add (elements, gst_element_factory_make ("queue", 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_MAXUINT - GES_TIMELINE_ELEMENT_PRIORITY (self), NULL);
|
||||||
g_ptr_array_add (elements, positioner);
|
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
|
/* If there's image-orientation tag, make sure the image is correctly oriented
|
||||||
* before we scale it. */
|
* before we scale it. */
|
||||||
videoflip = gst_element_factory_make ("videoflip", "track-element-videoflip");
|
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",
|
g_ptr_array_add (elements, gst_element_factory_make ("videorate",
|
||||||
"track-element-videorate"));
|
"track-element-videorate"));
|
||||||
|
|
||||||
capsfilter =
|
capsfilter =
|
||||||
gst_element_factory_make ("capsfilter", "track-element-capsfilter");
|
gst_element_factory_make ("capsfilter", "track-element-capsfilter");
|
||||||
g_ptr_array_add (elements, 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,
|
ges_track_element_add_children_props (trksrc, videoflip, NULL, NULL,
|
||||||
videoflip_props);
|
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 = GST_FRAME_POSITIONNER (positioner);
|
||||||
self->priv->positioner->scale_in_compositor =
|
self->priv->positioner->scale_in_compositor =
|
||||||
!GES_VIDEO_SOURCE_GET_CLASS (self)->ABI.abi.disable_scale_in_compositor;
|
!GES_VIDEO_SOURCE_GET_CLASS (self)->ABI.abi.disable_scale_in_compositor;
|
||||||
|
|
|
@ -223,6 +223,14 @@ _find_positioner (GstElement * a, GstElement * b)
|
||||||
"framepositioner");
|
"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 */
|
/* GObject VMethods */
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -230,12 +238,39 @@ ges_video_uri_source_create_filters (GESVideoSource * source,
|
||||||
GPtrArray * elements, gboolean needs_converters)
|
GPtrArray * elements, gboolean needs_converters)
|
||||||
{
|
{
|
||||||
GESAsset *asset = ges_extractable_get_asset (GES_EXTRACTABLE (source));
|
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));
|
g_assert (GES_IS_URI_SOURCE_ASSET (asset));
|
||||||
if (!GES_VIDEO_SOURCE_CLASS (ges_video_uri_source_parent_class)
|
if (!GES_VIDEO_SOURCE_CLASS (ges_video_uri_source_parent_class)
|
||||||
->ABI.abi.create_filters (source, elements, needs_converters))
|
->ABI.abi.create_filters (source, elements, needs_converters))
|
||||||
return FALSE;
|
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))) {
|
if (ges_uri_source_asset_is_image (GES_URI_SOURCE_ASSET (asset))) {
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue