Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
e3b53937
Commit
e3b53937
authored
Jun 28, 2011
by
Rafaël Carré
Browse files
* #6180 #6267
Implement preview widget using cairo Exchange shared memory keys through DBus
parent
b2f72b91
Changes
15
Hide whitespace changes
Inline
Side-by-side
sflphone-client-gnome/src/config/Makefile.am
View file @
e3b53937
...
...
@@ -18,12 +18,12 @@ libconfig_la_SOURCES = \
libconfig_la_LDFLAGS
=
$(DBUSGLIB_LDFLAGS)
$(LIBNOTIFY_LDFLAGS)
\
$(SFLGTK_LDFLAGS)
$(SFLGLIB_LDFLAGS)
$(WEBKIT_LDFLAGS)
$(LIBGNOMEUI_LDFLAGS)
\
$(GNOMEDOCUTILS_LDFLAGS)
$(GNOMEDOCUTILS_LDFLAGS)
@CLUTTER_LIBS@
libconfig_la_LIBADD
=
$(DBUSGLIB_LIBS)
$(LIBNOTIFY_LIBSI)
\
$(SFLGTK_LIBS)
$(SFLGLIB_LIBS)
$(WEBKIT_LIBS)
$(LIBGNOMEUI_LIBS)
\
$(GNOMEDOCUTILS_LIBS)
$(GNOMEDOCUTILS_LIBS)
@CLUTTER_LIBS@
libconfig_la_CFLAGS
=
$(DBUSGLIB_CFLAGS)
$(LIBNOTIFY_CFLAGS)
\
$(SFLGTK_CFLAGS)
$(SFLGLIB_CFLAGS)
$(WEBKIT_CFLAGS)
$(LIBGNOMEUI_CFLAGS)
\
$(GNOMEDOCUTILS_CFLAGS)
$(GNOMEDOCUTILS_CFLAGS)
@CLUTTER_CFLAGS@
sflphone-client-gnome/src/config/videoconf.c
View file @
e3b53937
...
...
@@ -36,6 +36,8 @@
#include
"dbus.h"
#include
"video/video_preview.h"
#include
<clutter/clutter.h>
static
GtkWidget
*
v4l2Device
;
static
GtkWidget
*
v4l2Input
;
static
GtkWidget
*
v4l2Size
;
...
...
@@ -110,12 +112,21 @@ preview_is_running_cb(GObject *obj, GParamSpec *pspec, gpointer user_data)
static
VideoPreview
*
preview
=
NULL
;
static
GtkWidget
*
preview_button
=
NULL
;
static
GtkWidget
*
drawarea
=
NULL
;
static
int
drawWidth
=
20
*
16
;
static
int
drawHeight
=
20
*
9
;
static
const
char
*
drawFormat
;
void
video_started_cb
()
video_started_cb
(
DBusGProxy
*
proxy
,
gint
OUT_shmId
,
gint
OUT_semId
,
gint
OUT_videoBufferSize
,
GError
*
error
,
gpointer
userdata
)
{
(
void
)
proxy
;
(
void
)
error
;
(
void
)
userdata
;
DEBUG
(
"Preview started"
);
if
(
preview
==
NULL
)
{
preview
=
video_preview_new
();
preview
=
video_preview_new
(
drawarea
,
drawWidth
,
drawHeight
,
drawFormat
,
OUT_shmId
,
OUT_semId
,
OUT_videoBufferSize
);
g_signal_connect
(
preview
,
"notify::running"
,
G_CALLBACK
(
preview_is_running_cb
),
preview_button
);
...
...
@@ -138,7 +149,15 @@ preview_button_clicked(GtkButton *button, gpointer data UNUSED)
preview_button
=
GTK_WIDGET
(
button
);
if
(
g_strcmp0
(
gtk_button_get_label
(
button
),
"_Start preview"
)
==
0
)
{
gtk_button_set_label
(
button
,
"_Stop preview"
);
dbus_start_video_preview
();
static
const
char
*
formats
[
2
]
=
{
"rgb24"
,
"bgra"
};
if
(
clutter_init
(
NULL
,
NULL
)
==
CLUTTER_INIT_SUCCESS
)
{
drawFormat
=
formats
[
0
];
}
else
{
drawFormat
=
formats
[
1
];
}
dbus_start_video_preview
(
drawWidth
,
drawHeight
,
drawFormat
);
}
else
{
/* user clicked stop */
...
...
@@ -147,7 +166,6 @@ preview_button_clicked(GtkButton *button, gpointer data UNUSED)
}
}
GtkWidget
*
create_video_configuration
()
{
// Main widget
...
...
@@ -171,6 +189,11 @@ GtkWidget* create_video_configuration()
g_signal_connect
(
G_OBJECT
(
preview_button
),
"clicked"
,
G_CALLBACK
(
preview_button_clicked
),
NULL
);
gtk_widget_show
(
GTK_WIDGET
(
preview_button
));
drawarea
=
gtk_drawing_area_new
();
gtk_widget_set_size_request
(
drawarea
,
drawWidth
,
drawHeight
);
gtk_table_attach
(
GTK_TABLE
(
table
),
drawarea
,
1
,
2
,
0
,
1
,
GTK_EXPAND
|
GTK_FILL
,
GTK_EXPAND
|
GTK_FILL
,
0
,
6
);
gtk_widget_show
(
GTK_WIDGET
(
drawarea
));
gnome_main_section_new_with_table
(
_
(
"Video4Linux2"
),
&
frame
,
&
table
,
1
,
4
);
gtk_box_pack_start
(
GTK_BOX
(
ret
),
frame
,
FALSE
,
FALSE
,
0
);
GtkWidget
*
v4l2box
=
v4l2_box
();
...
...
sflphone-client-gnome/src/config/videoconf.h
View file @
e3b53937
...
...
@@ -32,11 +32,12 @@
#define __VIDEO_CONF_H__
#include
<gtk/gtk.h>
#include
<dbus.h>
GtkWidget
*
create_video_configuration
();
GtkWidget
*
videocodecs_box
();
GtkWidget
*
v4l2_box
();
void
video_started_cb
();
void
video_started_cb
(
DBusGProxy
*
proxy
,
gint
OUT_shmId
,
gint
OUT_semId
,
gint
OUT_videoBufferSize
,
GError
*
error
,
gpointer
userdata
);
void
video_stopped_cb
();
#endif // __VIDEO_CONF_H__
sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
View file @
e3b53937
...
...
@@ -1011,20 +1011,41 @@
<annotation
name=
"com.trolltech.QtDBus.QtTypeName.In0"
value=
"MapStringString"
/>
<tp:docstring>
</tp:docstring>
<arg
type=
"a{ss}"
name=
"shortcutsMap"
direction=
"in"
>
<tp:docstring>
<arg
type=
"a{ss}"
name=
"shortcutsMap"
direction=
"in"
>
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method
name=
"startVideoPreview"
tp:name-for-bindings=
"startVideoPreview"
>
<arg
type=
"i"
name=
"width"
direction=
"in"
>
<tp:docstring>
</tp:docstring>
</arg>
<arg
type=
"i"
name=
"height"
direction=
"in"
>
<tp:docstring>
</tp:docstring>
</arg>
<arg
type=
"s"
name=
"format"
direction=
"in"
>
<tp:docstring>
</tp:docstring>
</arg>
<arg
type=
"i"
name=
"shmId"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
<arg
type=
"i"
name=
"semId"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
<arg
type=
"i"
name=
"videoBufferSize"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method
name=
"stopVideoPreview"
tp:name-for-bindings=
"stopVideoPreview"
>
</method>
<signal
name=
"videoStarted"
tp:name-for-bindings=
"videoStarted"
>
</signal>
<signal
name=
"videoStopped"
tp:name-for-bindings=
"videoStopped"
>
</signal>
...
...
sflphone-client-gnome/src/dbus/dbus.c
View file @
e3b53937
...
...
@@ -2729,11 +2729,11 @@ dbus_send_text_message (const gchar* callID, const gchar *message)
}
void
dbus_start_video_preview
()
dbus_start_video_preview
(
int
width
,
int
height
,
const
char
*
format
)
{
GError
*
error
=
NULL
;
org_sflphone_SFLphone_ConfigurationManager_start_video_preview_async
(
configurationManagerProxy
,
video_started_cb
,
&
error
);
configurationManagerProxy
,
width
,
height
,
format
,
video_started_cb
,
&
error
);
if
(
error
)
{
ERROR
(
"Failed to call start_video_preview () on ConfigurationManager: %s"
,
...
...
sflphone-client-gnome/src/video/video_preview.c
View file @
e3b53937
...
...
@@ -38,7 +38,11 @@
#include
<sys/sem.h>
/* semaphore functions and structs. */
#include
<sys/shm.h>
#include
<assert.h>
#include
<string.h>
#include
<clutter/clutter.h>
#include
<cairo.h>
#define VIDEO_PREVIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
VIDEO_PREVIEW_TYPE, VideoPreviewPrivate))
...
...
@@ -51,6 +55,13 @@ enum
{
PROP_0
,
PROP_RUNNING
,
PROP_WIDTH
,
PROP_HEIGHT
,
PROP_FORMAT
,
PROP_DRAWAREA
,
PROP_SHMKEY
,
PROP_SEMKEY
,
PROP_VIDEO_BUFFER_SIZE
,
PROP_LAST
};
...
...
@@ -59,23 +70,30 @@ static GParamSpec *properties[PROP_LAST];
static
void
video_preview_finalize
(
GObject
*
gobject
);
static
void
video_preview_get_property
(
GObject
*
object
,
guint
prop_id
,
GValue
*
value
,
GParamSpec
*
pspec
);
static
void
video_preview_set_property
(
GObject
*
object
,
guint
prop_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
);
/* Our private member structure */
struct
_VideoPreviewPrivate
{
guint
width
;
guint
height
;
gchar
*
format
;
gchar
*
shm_buffer
;
gint
sem_set_id
;
gint
sem_key
;
gint
shm_key
;
gint
videobuffersize
;
gboolean
using_clutter
;
ClutterActor
*
texture
;
gpointer
drawarea
;
cairo_t
*
cairo
;
gboolean
is_running
;
};
typedef
struct
_FrameInfo
{
unsigned
size
;
unsigned
width
;
unsigned
height
;
}
FrameInfo
;
/* See /bits/sem.h line 55 for why this is necessary */
#if _SEM_SEMUN_UNDEFINED
union
semun
...
...
@@ -87,40 +105,23 @@ union semun
};
#endif
#define TEMPFILE "/tmp/frame.txt"
/* FIXME: this will be replaced by a dbus call */
static
FrameInfo
*
getFrameInfo
()
{
FrameInfo
*
info
;
FILE
*
tmp
=
fopen
(
TEMPFILE
,
"r"
);
if
(
tmp
==
NULL
)
{
g_print
(
"Error: Could not open file %s
\n
"
,
TEMPFILE
);
/* FIXME: this should error out gracefully */
return
NULL
;
}
info
=
(
FrameInfo
*
)
g_malloc
(
sizeof
(
FrameInfo
));
if
(
fscanf
(
tmp
,
"%u
\n
%u
\n
%u
\n
"
,
&
info
->
size
,
&
info
->
width
,
&
info
->
height
)
<=
0
)
g_print
(
"Error: Could not read %s
\n
"
,
TEMPFILE
);
return
info
;
}
/* join and/or create a shared memory segment */
static
int
getShm
(
unsigned
numBytes
)
getShm
(
unsigned
numBytes
,
int
shmKey
)
{
key_t
key
;
key_t
key
=
shmKey
;
int
shm_id
;
/* connect to a segment with 600 permissions
(r--r--r--) */
key
=
ftok
(
"/tmp"
,
'c'
);
shm_id
=
shmget
(
key
,
numBytes
,
0644
);
if
(
shm_id
==
-
1
)
perror
(
"shmget"
);
return
shm_id
;
}
/* attach a shared memory segment */
static
char
*
attachShm
(
int
shm_id
)
...
...
@@ -147,11 +148,11 @@ detachShm(char *data)
}
static
int
get_sem_set
()
get_sem_set
(
int
semKey
)
{
/* this variable will contain the semaphore set. */
int
sem_set_id
;
key_t
key
=
ftok
(
"/tmp"
,
'b'
)
;
key_t
key
=
semKey
;
/* semaphore value, for semctl(). */
union
semun
sem_val
;
...
...
@@ -168,28 +169,49 @@ get_sem_set()
return
sem_set_id
;
}
static
void
video_preview_class_init
(
VideoPreviewClass
*
klass
)
{
int
i
;
GObjectClass
*
gobject_class
;
gobject_class
=
G_OBJECT_CLASS
(
klass
);
g_type_class_add_private
(
klass
,
sizeof
(
VideoPreviewPrivate
));
gobject_class
->
finalize
=
video_preview_finalize
;
gobject_class
->
get_property
=
video_preview_get_property
;
gobject_class
->
set_property
=
video_preview_set_property
;
properties
[
PROP_RUNNING
]
=
g_param_spec_boolean
(
"running"
,
"Running"
,
"True if preview is running"
,
FALSE
,
G_PARAM_READABLE
);
g_object_class_install_property
(
gobject_class
,
PROP_RUNNING
,
properties
[
PROP_RUNNING
]);
properties
[
PROP_DRAWAREA
]
=
g_param_spec_pointer
(
"drawarea"
,
"DrawArea"
,
"Pointer to the drawing area"
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
properties
[
PROP_WIDTH
]
=
g_param_spec_int
(
"width"
,
"Width"
,
"Width of preview video"
,
G_MININT
,
G_MAXINT
,
-
1
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
properties
[
PROP_HEIGHT
]
=
g_param_spec_int
(
"height"
,
"Height"
,
"Height of preview video"
,
G_MININT
,
G_MAXINT
,
-
1
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
/* Initialize Clutter */
if
(
clutter_init
(
NULL
,
NULL
)
!=
CLUTTER_INIT_SUCCESS
)
g_print
(
"Error: could not initialize clutter!
\n
"
);
properties
[
PROP_FORMAT
]
=
g_param_spec_pointer
(
"format"
,
"Format"
,
"Pixel format of preview video"
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
properties
[
PROP_SHMKEY
]
=
g_param_spec_int
(
"shmkey"
,
"ShmKey"
,
"Unique key for shared memory identifier"
,
G_MININT
,
G_MAXINT
,
-
1
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
properties
[
PROP_SEMKEY
]
=
g_param_spec_int
(
"semkey"
,
"SemKey"
,
"Unique key for semaphore identifier"
,
G_MININT
,
G_MAXINT
,
-
1
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
properties
[
PROP_VIDEO_BUFFER_SIZE
]
=
g_param_spec_int
(
"vbsize"
,
"VideoBufferSize"
,
"Size of shared memory buffer"
,
G_MININT
,
G_MAXINT
,
-
1
,
G_PARAM_READABLE
|
G_PARAM_WRITABLE
|
G_PARAM_CONSTRUCT_ONLY
);
for
(
i
=
PROP_0
+
1
;
i
<
PROP_LAST
;
i
++
)
{
g_object_class_install_property
(
gobject_class
,
i
,
properties
[
i
]);
}
}
static
void
...
...
@@ -207,6 +229,68 @@ video_preview_get_property (GObject *object, guint prop_id,
case
PROP_RUNNING
:
g_value_set_boolean
(
value
,
priv
->
is_running
);
break
;
case
PROP_DRAWAREA
:
g_value_set_pointer
(
value
,
priv
->
drawarea
);
break
;
case
PROP_WIDTH
:
g_value_set_int
(
value
,
priv
->
width
);
break
;
case
PROP_HEIGHT
:
g_value_set_int
(
value
,
priv
->
height
);
break
;
case
PROP_FORMAT
:
g_value_set_pointer
(
value
,
priv
->
format
);
break
;
case
PROP_SHMKEY
:
g_value_set_int
(
value
,
priv
->
shm_key
);
break
;
case
PROP_SEMKEY
:
g_value_set_int
(
value
,
priv
->
sem_key
);
break
;
case
PROP_VIDEO_BUFFER_SIZE
:
g_value_set_int
(
value
,
priv
->
videobuffersize
);
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
prop_id
,
pspec
);
break
;
}
}
static
void
video_preview_set_property
(
GObject
*
object
,
guint
prop_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
)
{
VideoPreview
*
preview
;
VideoPreviewPrivate
*
priv
;
preview
=
VIDEO_PREVIEW
(
object
);
priv
=
preview
->
priv
;
switch
(
prop_id
)
{
case
PROP_DRAWAREA
:
priv
->
drawarea
=
g_value_get_pointer
(
value
);
break
;
case
PROP_WIDTH
:
priv
->
width
=
g_value_get_int
(
value
);
break
;
case
PROP_HEIGHT
:
priv
->
height
=
g_value_get_int
(
value
);
break
;
case
PROP_FORMAT
:
priv
->
format
=
g_value_get_pointer
(
value
);
break
;
case
PROP_SHMKEY
:
priv
->
shm_key
=
g_value_get_int
(
value
);
break
;
case
PROP_SEMKEY
:
priv
->
sem_key
=
g_value_get_int
(
value
);
break
;
case
PROP_VIDEO_BUFFER_SIZE
:
priv
->
videobuffersize
=
g_value_get_int
(
value
);
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
prop_id
,
pspec
);
break
;
...
...
@@ -221,25 +305,8 @@ video_preview_init (VideoPreview *self)
self
->
priv
=
priv
=
VIDEO_PREVIEW_GET_PRIVATE
(
self
);
/* update the object state depending on constructor properties */
int
shm_id
=
-
1
;
FrameInfo
*
info
=
getFrameInfo
();
if
(
info
)
{
priv
->
width
=
info
->
width
;
priv
->
height
=
info
->
height
;
shm_id
=
getShm
(
info
->
size
);
g_free
(
info
);
}
if
(
shm_id
!=
-
1
)
{
priv
->
shm_buffer
=
attachShm
(
shm_id
);
priv
->
sem_set_id
=
get_sem_set
();
}
else
{
priv
->
shm_buffer
=
NULL
;
priv
->
sem_set_id
=
-
1
;
}
priv
->
texture
=
NULL
;
priv
->
cairo
=
NULL
;
}
static
void
...
...
@@ -280,35 +347,68 @@ sem_wait(int sem_set_id)
return
semop
(
sem_set_id
,
&
sem_op
,
1
);
}
/* round int
eger
value up to next multiple of 4 */
/* round int value up to next multiple of 4 */
static
int
round_up_4
(
int
value
)
align
(
int
value
)
{
return
(
value
+
3
)
&~
3
;
}
static
void
readFrameFromShm
(
int
width
,
int
height
,
char
*
data
,
int
sem_set_id
,
ClutterActor
*
texture
)
readFrameFromShm
(
VideoPreviewPrivate
*
priv
)
{
if
(
sem_set_id
!=
-
1
)
{
if
(
sem_wait
(
sem_set_id
)
!=
-
1
)
{
clutter_texture_set_from_rgb_data
(
CLUTTER_TEXTURE
(
texture
),
(
void
*
)
data
,
FALSE
,
width
,
height
,
round_up_4
(
3
*
width
),
3
,
0
,
NULL
);
int
width
=
priv
->
width
;
int
height
=
priv
->
height
;
void
*
data
=
priv
->
shm_buffer
;
int
sem_set_id
=
priv
->
sem_set_id
;
ClutterActor
*
texture
=
priv
->
texture
;
if
(
sem_set_id
==
-
1
)
return
;
if
(
sem_wait
(
sem_set_id
)
==
-
1
)
{
if
(
errno
!=
EAGAIN
)
{
g_print
(
"Could not read from shared memory!
\n
"
);
perror
(
"shm: "
);
}
return
;
}
if
(
priv
->
using_clutter
)
{
if
(
strcmp
(
priv
->
format
,
"rgb24"
))
{
g_print
(
"clutter render: Unknown pixel format `%s'
\n
"
,
priv
->
format
);
}
clutter_texture_set_from_rgb_data
(
CLUTTER_TEXTURE
(
texture
),
(
void
*
)
data
,
FALSE
,
width
,
height
,
align
(
3
/* bytes per pixel */
*
width
),
// stride
3
,
0
,
NULL
);
}
else
{
cairo_format_t
format
;
if
(
!
strcmp
(
priv
->
format
,
"bgra"
))
format
=
CAIRO_FORMAT_RGB24
;
else
{
g_print
(
"cairo render: Unknown pixel format `%s'
\n
"
,
priv
->
format
);
return
;
}
else
{
if
(
errno
!=
EAGAIN
)
{
g_print
(
"Could not read from shared memory!
\n
"
);
perror
(
"shm: "
);
}
int
stride
=
cairo_format_stride_for_width
(
format
,
width
);
assert
(
stride
==
align
(
4
*
width
));
cairo_surface_t
*
surface
=
cairo_image_surface_create_for_data
(
data
,
format
,
width
,
height
,
stride
);
if
(
surface
)
{
cairo_set_source_surface
(
priv
->
cairo
,
surface
,
0
,
0
);
cairo_paint
(
priv
->
cairo
);
cairo_surface_destroy
(
surface
);
}
}
}
...
...
@@ -318,9 +418,9 @@ updateTexture(gpointer data)
{
VideoPreview
*
preview
=
(
VideoPreview
*
)
data
;
VideoPreviewPrivate
*
priv
=
VIDEO_PREVIEW_GET_PRIVATE
(
preview
);
if
(
priv
->
shm_buffer
!=
NULL
)
{
readFrameFromShm
(
priv
->
width
,
priv
->
height
,
priv
->
shm_buffer
,
priv
->
sem_set_id
,
priv
->
texture
);
readFrameFromShm
(
priv
);
return
TRUE
;
}
else
...
...
@@ -333,11 +433,19 @@ updateTexture(gpointer data)
* Create a new #VideoPreview instance.
*/
VideoPreview
*
video_preview_new
(
void
)
video_preview_new
(
GtkWidget
*
drawarea
,
int
width
,
int
height
,
const
char
*
format
,
int
semkey
,
int
shmkey
,
int
vbsize
)
{
VideoPreview
*
result
;
result
=
g_object_new
(
VIDEO_PREVIEW_TYPE
,
NULL
);
result
=
g_object_new
(
VIDEO_PREVIEW_TYPE
,
"drawarea"
,
(
gpointer
)
drawarea
,
"width"
,
(
gint
)
width
,
"height"
,
(
gint
)
height
,
"format"
,
(
gpointer
)
format
,
"semkey"
,
(
gint
)
semkey
,
"shmkey"
,
(
gint
)
shmkey
,
"vbsize"
,
(
gint
)
vbsize
,
NULL
);
return
result
;
}
...
...
@@ -358,31 +466,48 @@ video_preview_run(VideoPreview *preview)
{
VideoPreviewPrivate
*
priv
=
VIDEO_PREVIEW_GET_PRIVATE
(
preview
);
ClutterActor
*
stage
;
int
shm_id
=
getShm
(
priv
->
videobuffersize
,
priv
->
sem_key
);
priv
->
shm_buffer
=
attachShm
(
shm_id
);
priv
->
sem_set_id
=
get_sem_set
(
priv
->
shm_key
);
/* Get a stage */
stage
=
clutter_stage_new
();
g_signal_connect
(
stage
,
"delete-event"
,
G_CALLBACK
(
on_stage_delete
),
preview
);
clutter_actor_set_size
(
stage
,
priv
->
width
,
priv
->
height
);
priv
->
using_clutter
=
!
strcmp
(
priv
->
format
,
"rgb24"
);
g_print
(
"Preview: using %s render
\n
"
,
priv
->
using_clutter
?
"clutter"
:
"cairo"
);
priv
->
texture
=
clutter_texture_new
();
if
(
priv
->
using_clutter
)
{
ClutterActor
*
stage
;
clutter_stage_set_title
(
CLUTTER_STAGE
(
stage
),
"Video Test"
);
/* Add ClutterTexture to the stage */
clutter_container_add
(
CLUTTER_CONTAINER
(
stage
),
priv
->
texture
,
NULL
);
/* Get a stage */
stage
=
clutter_stage_new
();
g_signal_connect
(
stage
,
"delete-event"
,
G_CALLBACK
(
on_stage_delete
),
preview
);
clutter_actor_set_size
(
stage
,
priv
->
width
,
priv
->
height
);
priv
->
texture
=
clutter_texture_new
();
clutter_stage_set_title
(
CLUTTER_STAGE
(
stage
),
"Video Test"
);
/* Add ClutterTexture to the stage */
clutter_container_add
(
CLUTTER_CONTAINER
(
stage
),
priv
->
texture
,
NULL
);
clutter_actor_show_all
(
stage
);
}
else
{
if
(
!
priv
->
cairo
)
{