*
* You can use the following children properties through the
* #ges_track_element_set_child_property and alike set of methods:
- *
+ *
* - #gdouble `alpha`: The desired alpha for the stream.
* - #gint `posx`: The desired x position for the stream.
* - #gint `posy`: The desired y position for the stream
#include "ges-video-source.h"
#include "ges-layer.h"
#include "gstframepositioner.h"
+#include "ges-extractable.h"
#define parent_class ges_video_source_parent_class
GstElement *capsfilter;
};
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GESVideoSource, ges_video_source,
- GES_TYPE_SOURCE);
+static void
+ges_video_source_set_asset (GESExtractable * extractable, GESAsset * asset)
+{
+ GESVideoSource *self = GES_VIDEO_SOURCE (extractable);
+
+ ges_video_source_get_natural_size (self,
+ &self->priv->positioner->natural_width,
+ &self->priv->positioner->natural_height);
+}
+
+static void
+ges_extractable_interface_init (GESExtractableInterface * iface)
+{
+ iface->set_asset = ges_video_source_set_asset;
+}
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GESVideoSource, ges_video_source,
+ GES_TYPE_SOURCE, G_ADD_PRIVATE (GESVideoSource)
+ G_IMPLEMENT_INTERFACE (GES_TYPE_EXTRACTABLE,
+ ges_extractable_interface_init));
/* TrackElement VMethods */
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;
+ ges_video_source_get_natural_size (self,
+ &self->priv->positioner->natural_width,
+ &self->priv->positioner->natural_height);
+
self->priv->capsfilter = capsfilter;
return topbin;
self->priv = ges_video_source_get_instance_private (self);
self->priv->positioner = NULL;
self->priv->capsfilter = NULL;
-
}
/**
GstDiscovererStreamInfo *info;
GESAsset *asset = ges_extractable_get_asset (GES_EXTRACTABLE (source));
- g_assert (GES_IS_URI_SOURCE_ASSET (asset));
+ if (!asset) {
+ GST_DEBUG_OBJECT (source, "No asset set yet");
+ return FALSE;
+ }
+
info = ges_uri_source_asset_get_stream_info (GES_URI_SOURCE_ASSET (asset));
if (!GST_IS_DISCOVERER_VIDEO_INFO (info)) {
return TRUE;
rotate:
- GST_INFO_OBJECT (self, "Stream is rotated, taking that into account");
+ GST_INFO_OBJECT (source, "Stream is rotated, taking that into account");
*width =
gst_discoverer_video_info_get_height (GST_DISCOVERER_VIDEO_INFO (info));
*height =
static void
extractable_set_asset (GESExtractable * extractable, GESAsset * asset)
{
+ GESExtractableInterface *piface, *iface;
/* FIXME That should go into #GESTrackElement, but
* some work is needed to make sure it works properly */
ges_track_element_asset_get_track_type (GES_TRACK_ELEMENT_ASSET
(asset)));
}
+
+ iface = G_TYPE_INSTANCE_GET_INTERFACE (extractable, GES_TYPE_EXTRACTABLE,
+ GESExtractableInterface);
+ piface = g_type_interface_peek_parent (iface);
+ piface->set_asset (extractable, asset);
}
static void
pos->current_track = NULL;
}
+static gboolean
+auto_position (GstFramePositioner * self)
+{
+ gint scaled_width = -1, scaled_height = -1, x, y;
+
+ if (self->user_positioned) {
+ GST_DEBUG_OBJECT (self, "Was positioned by the user, not touching anymore");
+ return FALSE;
+ }
+
+ if (!self->natural_width || !self->natural_height)
+ return FALSE;
+
+ if (!self->track_width || !self->track_height) {
+ GST_INFO_OBJECT (self, "Track doesn't have a proper size, not "
+ "positioning the source");
+ return FALSE;
+ }
+
+ if (self->track_width == self->natural_width &&
+ self->track_height == self->natural_height)
+ return TRUE;
+
+ scaled_height =
+ gst_util_uint64_scale_int (self->natural_height, self->track_width,
+ self->natural_width);
+ scaled_width = self->track_width;
+ if (scaled_height > self->track_height) {
+ scaled_height = self->track_height;
+ scaled_width =
+ gst_util_uint64_scale_int (self->natural_width, self->track_height,
+ self->natural_height);
+ }
+
+ x = MAX (0, gst_util_uint64_scale_int_round (1,
+ self->track_width - scaled_width, 2));
+ y = MAX (0, gst_util_uint64_scale_int_round (1,
+ self->track_height - scaled_height, 2));
+
+ GST_INFO_OBJECT (self, "Scalling video to match track size from "
+ "%dx%d to %dx%d",
+ self->natural_width, self->natural_height, scaled_width, scaled_height);
+ self->width = scaled_width;
+ self->height = scaled_height;
+ self->posx = x;
+ self->posy = y;
+
+ return TRUE;
+}
+
static void
gst_frame_positioner_update_properties (GstFramePositioner * pos,
gboolean track_mixing, gint old_track_width, gint old_track_height)
gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
pos->par_n, pos->par_d, NULL);
- if (old_track_width && pos->width == old_track_width &&
- old_track_height && pos->height == old_track_height &&
- pos->track_height && pos->track_width &&
- ((float) old_track_width / (float) old_track_height) ==
- ((float) pos->track_width / (float) pos->track_height)) {
+ if (!auto_position (pos)) {
- GST_DEBUG_OBJECT (pos, "Following track size width old_track: %d -- pos: %d"
- " || height, old_track %d -- pos: %d",
- old_track_width, pos->width, old_track_height, pos->height);
+ if (old_track_width && pos->width == old_track_width &&
+ old_track_height && pos->height == old_track_height &&
+ pos->track_height && pos->track_width &&
+ ((float) old_track_width / (float) old_track_height) ==
+ ((float) pos->track_width / (float) pos->track_height)) {
- pos->width = pos->track_width;
- pos->height = pos->track_height;
+ GST_DEBUG_OBJECT (pos,
+ "Following track size width old_track: %d -- pos: %d"
+ " || height, old_track %d -- pos: %d", old_track_width, pos->width,
+ old_track_height, pos->height);
+
+ pos->width = pos->track_width;
+ pos->height = pos->track_height;
+ }
}
GST_DEBUG_OBJECT (caps, "setting caps");
GstBaseTransformClass *base_transform_class =
GST_BASE_TRANSFORM_CLASS (klass);
+ GST_DEBUG_CATEGORY_INIT (framepositioner, "framepositioner",
+ GST_DEBUG_FG_YELLOW, "ges frame positioner");
+
gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
&gst_frame_positioner_src_template);
gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
break;
case PROP_POSX:
framepositioner->posx = g_value_get_int (value);
+ framepositioner->user_positioned = TRUE;
break;
case PROP_POSY:
framepositioner->posy = g_value_get_int (value);
+ framepositioner->user_positioned = TRUE;
break;
case PROP_ZORDER:
framepositioner->zorder = g_value_get_uint (value);
break;
case PROP_WIDTH:
+ framepositioner->user_positioned = TRUE;
framepositioner->width = g_value_get_int (value);
gst_frame_positioner_update_properties (framepositioner, track_mixing,
0, 0);
break;
case PROP_HEIGHT:
+ framepositioner->user_positioned = TRUE;
framepositioner->height = g_value_get_int (value);
gst_frame_positioner_update_properties (framepositioner, track_mixing,
0, 0);