gnome: add video preview
Refs #66538
Change-Id: Idb4be5e7a093b56fbb8a3813d1526baa9a1b8c9c
diff --git a/src/video/video_widget.cpp b/src/video/video_widget.cpp
index 44fef61..411c912 100644
--- a/src/video/video_widget.cpp
+++ b/src/video/video_widget.cpp
@@ -35,6 +35,9 @@
#include <clutter-gtk/clutter-gtk.h>
#include <video/renderer.h>
+#define VIDEO_LOCAL_SIZE 150
+#define VIDEO_LOCAL_OPACITY_DEFAULT 150 /* out of 255 */
+
struct _VideoWidgetClass {
GtkBinClass parent_class;
};
@@ -45,22 +48,27 @@
typedef struct _VideoWidgetPrivate VideoWidgetPrivate;
+typedef struct _VideoWidgetRenderer VideoWidgetRenderer;
+
struct _VideoWidgetPrivate {
GtkWidget *clutter_widget;
ClutterActor *stage;
ClutterActor *video_container;
/* remote peer data */
- ClutterActor *actor_remote;
- Video::Renderer *renderer_remote;
- QMetaObject::Connection remote_frame_update;
- QMetaObject::Connection remote_render_stop;
- QMetaObject::Connection remote_render_start;
+ VideoWidgetRenderer *remote;
/* local peer data */
- ClutterActor *actor_local;
- Video::Renderer *renderer_local;
- QMetaObject::Connection local_frame_update;
+ VideoWidgetRenderer *local;
+};
+
+struct _VideoWidgetRenderer {
+ gboolean show;
+ ClutterActor *actor;
+ Video::Renderer *renderer;
+ QMetaObject::Connection frame_update;
+ QMetaObject::Connection render_stop;
+ QMetaObject::Connection render_start;
};
G_DEFINE_TYPE_WITH_PRIVATE(VideoWidget, video_widget, GTK_TYPE_BIN);
@@ -83,16 +91,20 @@
* The dispose function for the video_widget class.
*/
static void
-video_widget_dispose(GObject *gobject)
+video_widget_dispose(GObject *object)
{
- VideoWidget *self = VIDEO_WIDGET(gobject);
+ VideoWidget *self = VIDEO_WIDGET(object);
VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
- QObject::disconnect(priv->remote_frame_update);
- QObject::disconnect(priv->remote_render_stop);
- QObject::disconnect(priv->remote_render_start);
+ QObject::disconnect(priv->remote->frame_update);
+ QObject::disconnect(priv->remote->render_stop);
+ QObject::disconnect(priv->remote->render_start);
- G_OBJECT_CLASS(video_widget_parent_class)->dispose(gobject);
+ QObject::disconnect(priv->local->frame_update);
+ QObject::disconnect(priv->local->render_stop);
+ QObject::disconnect(priv->local->render_start);
+
+ G_OBJECT_CLASS(video_widget_parent_class)->dispose(object);
}
@@ -104,6 +116,12 @@
static void
video_widget_finalize(GObject *object)
{
+ VideoWidget *self = VIDEO_WIDGET(object);
+ VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
+
+ g_free(priv->remote);
+ g_free(priv->local);
+
G_OBJECT_CLASS(video_widget_parent_class)->finalize(object);
}
@@ -153,6 +171,30 @@
clutter_actor_set_background_color(priv->video_container, CLUTTER_COLOR_Black);
clutter_actor_add_child(priv->stage, priv->video_container);
+ /* init the remote and local structs */
+ priv->remote = g_new0(VideoWidgetRenderer, 1);
+ priv->local = g_new0(VideoWidgetRenderer, 1);
+
+ /* arrange remote actors */
+ priv->remote->actor = clutter_actor_new();
+ clutter_actor_insert_child_below(priv->video_container, priv->remote->actor, NULL);
+ /* the remote camera must always fill the container size */
+ ClutterConstraint *constraint = clutter_bind_constraint_new(priv->video_container,
+ CLUTTER_BIND_SIZE, 0);
+ clutter_actor_add_constraint(priv->remote->actor, constraint);
+
+ /* arrange local actor */
+ priv->local->actor = clutter_actor_new();
+ clutter_actor_insert_child_above(priv->video_container, priv->local->actor, NULL);
+ /* set size to square, but it will stay the aspect ratio when the image is rendered */
+ clutter_actor_set_size(priv->local->actor, VIDEO_LOCAL_SIZE, VIDEO_LOCAL_SIZE);
+ /* set position constraint to right cornder */
+ constraint = clutter_align_constraint_new(priv->video_container,
+ CLUTTER_ALIGN_BOTH, 0.99);
+ clutter_actor_add_constraint(priv->local->actor, constraint);
+ clutter_actor_set_opacity(priv->local->actor,
+ VIDEO_LOCAL_OPACITY_DEFAULT);
+
/* TODO: handle button event in screen */
// g_signal_connect(screen, "button-press-event",
// G_CALLBACK(on_button_press_in_screen_event_cb),
@@ -227,27 +269,20 @@
return FALSE; /* we do not want this function to be called again */
}
-static gboolean
-renderer_stop(VideoWidget *self)
+static void
+renderer_stop(VideoWidgetRenderer *renderer)
{
- g_return_val_if_fail(IS_VIDEO_WIDGET(self), FALSE);
-
- VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
-
- QObject::disconnect(priv->remote_frame_update);
-
- return FALSE; /* don't call again */
+ QObject::disconnect(renderer->frame_update);
+ renderer->show = FALSE;
}
-static gboolean
-renderer_start(VideoWidget *self)
+static void
+renderer_start(VideoWidgetRenderer *renderer)
{
- g_return_val_if_fail(IS_VIDEO_WIDGET(self), FALSE);
+ renderer->show = TRUE;
- VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
-
- priv->remote_frame_update = QObject::connect(
- priv->renderer_remote,
+ renderer->frame_update = QObject::connect(
+ renderer->renderer,
&Video::Renderer::frameUpdated,
[=]() {
@@ -257,8 +292,8 @@
*/
/* for now use the video container for the remote image */
- FrameInfo *frame = prepare_framedata(priv->renderer_remote,
- priv->video_container);
+ FrameInfo *frame = prepare_framedata(renderer->renderer,
+ renderer->actor);
g_idle_add_full(G_PRIORITY_HIGH_IDLE,
(GSourceFunc)clutter_render_image,
@@ -266,10 +301,36 @@
(GDestroyNotify)free_framedata);
}
);
-
- return FALSE; /* don't call again */
}
+static void
+video_widget_set_renderer(VideoWidgetRenderer *renderer)
+{
+ if (renderer == NULL) return;
+
+ /* update the renderer */
+ QObject::disconnect(renderer->frame_update);
+ QObject::disconnect(renderer->render_stop);
+ QObject::disconnect(renderer->render_start);
+
+ renderer_start(renderer);
+
+ renderer->render_stop = QObject::connect(
+ renderer->renderer,
+ &Video::Renderer::stopped,
+ [=]() {
+ renderer_stop(renderer);
+ }
+ );
+
+ renderer->render_start = QObject::connect(
+ renderer->renderer,
+ &Video::Renderer::started,
+ [=]() {
+ renderer_start(renderer);
+ }
+ );
+}
/*
* video_widget_new()
@@ -292,32 +353,19 @@
VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
/* update the renderer */
- QObject::disconnect(priv->remote_frame_update);
- QObject::disconnect(priv->remote_render_stop);
- QObject::disconnect(priv->remote_render_start);
- priv->renderer_remote = renderer_remote_new;
+ priv->remote->renderer = renderer_remote_new;
+ video_widget_set_renderer(priv->remote);
+}
- renderer_start(self);
+void
+video_widget_set_local_renderer(VideoWidget *self, Video::Renderer *renderer_local_new)
+{
+ g_return_if_fail(IS_VIDEO_WIDGET(self));
+ if (renderer_local_new == NULL) return;
- priv->remote_render_stop = QObject::connect(
- renderer_remote_new,
- &Video::Renderer::stopped,
- [=]() {
- g_idle_add_full(G_PRIORITY_HIGH_IDLE,
- (GSourceFunc)renderer_stop,
- self,
- NULL);
- }
- );
+ VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
- priv->remote_render_start = QObject::connect(
- renderer_remote_new,
- &Video::Renderer::started,
- [=]() {
- g_idle_add_full(G_PRIORITY_HIGH_IDLE,
- (GSourceFunc)renderer_start,
- self,
- NULL);
- }
- );
+ /* update the renderer */
+ priv->local->renderer = renderer_local_new;
+ video_widget_set_renderer(priv->local);
}