mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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:
parent
c802a40a96
commit
7b3ac927dc
6 changed files with 127 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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 *
|
||||
************************/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue