ges: Add a method to retrieve the 'natural' size of VideoSource

This way the user can easily know how the clip would look like
if no scaling was applied to the clip, this is useful to be able
to properly position the clips with the framepositionner element.
This commit is contained in:
Thibault Saunier 2020-02-19 18:06:26 -03:00
parent c802a40a96
commit 7b3ac927dc
6 changed files with 127 additions and 2 deletions

View file

@ -171,6 +171,8 @@ ges_image_source_class_init (GESImageSourceClass * klass)
GES_TIMELINE_ELEMENT_CLASS (klass)->set_inpoint = NULL;
source_class->create_source = ges_image_source_create_source;
source_class->ABI.abi.get_natural_size =
ges_video_uri_source_get_natural_size;
}
static void

View file

@ -459,6 +459,12 @@ typedef struct GESMultiFileURI
G_GNUC_INTERNAL GESMultiFileURI * ges_multi_file_uri_new (const gchar * uri);
/******************************
* GESUriSource internal API *
******************************/
G_GNUC_INTERNAL gboolean
ges_video_uri_source_get_natural_size(GESVideoSource* source, gint* width, gint* height);
/************************
* Our property masks *
************************/

View file

@ -226,4 +226,33 @@ ges_video_source_init (GESVideoSource * self)
self->priv = ges_video_source_get_instance_private (self);
self->priv->positioner = NULL;
self->priv->capsfilter = NULL;
}
/**
* ges_video_source_get_natural_size:
* @self: A #GESVideoSource
* @width: (out): The natural width of the underlying source
* @height: (out): The natural height of the underlying source
*
* Retrieves the natural size of the video stream. The natural size, is
* the size at which it will be displayed if no scaling is being applied.
*
* NOTE: The sources take into account the potential video rotation applied
* by the #videoflip element that is inside the source, effects applied on
* the clip which potentially also rotate the element are not taken into
* account.
*
* Returns: %TRUE if the object has a natural size, %FALSE otherwise.
*/
gboolean
ges_video_source_get_natural_size (GESVideoSource * self, gint * width,
gint * height)
{
GESVideoSourceClass *klass = GES_VIDEO_SOURCE_GET_CLASS (self);
if (!klass->ABI.abi.get_natural_size)
return FALSE;
return klass->ABI.abi.get_natural_size (self, width, height);
}

View file

@ -85,12 +85,15 @@ struct _GESVideoSourceClass {
struct {
gboolean disable_scale_in_compositor;
gboolean (*needs_converters)(GESVideoSource *self);
gboolean (*get_natural_size)(GESVideoSource* self, gint* width, gint* height);
} abi;
} ABI;
};
GES_API
GType ges_video_source_get_type (void);
GES_API
gboolean ges_video_source_get_natural_size(GESVideoSource* self, gint* width, gint* height);
G_END_DECLS

View file

@ -43,12 +43,22 @@ G_DEFINE_TYPE_WITH_PRIVATE (GESVideoTestSource, ges_video_test_source,
static GstElement *ges_video_test_source_create_source (GESTrackElement * self);
static gboolean
get_natural_size (GESVideoSource * source, gint * width, gint * height)
{
*width = DEFAULT_WIDTH;
*height = DEFAULT_HEIGHT;
return TRUE;
}
static void
ges_video_test_source_class_init (GESVideoTestSourceClass * klass)
{
GESVideoSourceClass *source_class = GES_VIDEO_SOURCE_CLASS (klass);
source_class->create_source = ges_video_test_source_create_source;
source_class->ABI.abi.get_natural_size = get_natural_size;
}
static void
@ -76,7 +86,11 @@ ges_video_test_source_create_source (GESTrackElement * self)
elements = g_ptr_array_new ();
g_ptr_array_add (elements, capsfilter);
caps = gst_caps_new_empty_simple ("video/x-raw");
caps = gst_caps_new_simple ("video/x-raw",
"width", G_TYPE_INT, DEFAULT_WIDTH,
"height", G_TYPE_INT, DEFAULT_HEIGHT,
"framerate", GST_TYPE_FRACTION, DEFAULT_FRAMERATE_N, DEFAULT_FRAMERATE_D,
NULL);
g_object_set (capsfilter, "caps", caps, NULL);
gst_caps_unref (caps);

View file

@ -27,8 +27,9 @@
#include "config.h"
#endif
#include <gst/pbutils/missing-plugins.h>
#include <stdio.h>
#include <gst/pbutils/missing-plugins.h>
#include "ges-utils.h"
#include "ges-internal.h"
#include "ges-track-element.h"
@ -113,6 +114,74 @@ ges_video_uri_source_needs_converters (GESVideoSource * source)
return FALSE;
}
gboolean
ges_video_uri_source_get_natural_size (GESVideoSource * source, gint * width,
gint * height)
{
const GstTagList *tags = NULL;
gchar *rotation_info = NULL;
gint videoflip_method, rotate_angle;
GstDiscovererStreamInfo *info;
GESAsset *asset = ges_extractable_get_asset (GES_EXTRACTABLE (source));
g_assert (GES_IS_URI_SOURCE_ASSET (asset));
info = ges_uri_source_asset_get_stream_info (GES_URI_SOURCE_ASSET (asset));
if (!GST_IS_DISCOVERER_VIDEO_INFO (info)) {
GST_ERROR_OBJECT (source, "Doesn't have a video info (%" GST_PTR_FORMAT
")", info);
return FALSE;
}
*width =
gst_discoverer_video_info_get_width (GST_DISCOVERER_VIDEO_INFO (info));
*height =
gst_discoverer_video_info_get_height (GST_DISCOVERER_VIDEO_INFO (info));
if (!ges_timeline_element_lookup_child (GES_TIMELINE_ELEMENT (source),
"GstVideoFlip::video-direction", NULL, NULL))
goto done;
ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT (source),
"GstVideoFlip::video-direction", &videoflip_method, NULL);
/* Rotating 90 degrees, either way, rotate */
if (videoflip_method == 1 || videoflip_method == 3)
goto rotate;
if (videoflip_method != 8)
goto done;
/* Rotation is automatic, we need to check if the media file is naturally
rotated */
tags =
gst_discoverer_stream_info_get_tags (GST_DISCOVERER_STREAM_INFO (info));
if (!tags)
goto done;
if (!gst_tag_list_get_string (tags, GST_TAG_IMAGE_ORIENTATION,
&rotation_info))
goto done;
if (sscanf (rotation_info, "rotate-%d", &rotate_angle) == 1) {
if (rotate_angle == 90 || rotate_angle == 270)
goto rotate;
}
done:
g_free (rotation_info);
return TRUE;
rotate:
GST_INFO_OBJECT (self, "Stream is rotated, taking that into account");
*width =
gst_discoverer_video_info_get_height (GST_DISCOVERER_VIDEO_INFO (info));
*height =
gst_discoverer_video_info_get_width (GST_DISCOVERER_VIDEO_INFO (info));
goto done;
}
/* Extractable interface implementation */
static gchar *
@ -218,6 +287,8 @@ ges_video_uri_source_class_init (GESVideoUriSourceClass * klass)
source_class->create_source = ges_video_uri_source_create_source;
source_class->ABI.abi.needs_converters =
ges_video_uri_source_needs_converters;
source_class->ABI.abi.get_natural_size =
ges_video_uri_source_get_natural_size;
}
static void