[cheese/camerabin] cheese-camera: Use camerabin as pipeline base
- From: Luciana Fujii Pontello <lufujii src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cheese/camerabin] cheese-camera: Use camerabin as pipeline base
- Date: Wed, 12 Jan 2011 22:49:35 +0000 (UTC)
commit 6c0e53040b287bb39e1e4932fccf0eb3e4f1adc1
Author: Luciana Fujii Pontello <luciana fujii eti br>
Date: Tue Jan 11 13:54:31 2011 -0200
cheese-camera: Use camerabin as pipeline base
Changed Cheese-Camera to use camerabin as its base. Camerabin implements
view-finder, image capture and video recording.
Applying effects is not working at the moment.
libcheese/cheese-camera.c | 447 ++++++++++++++------------------------------
1 files changed, 142 insertions(+), 305 deletions(-)
---
diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
index ced9a4f..14095ff 100644
--- a/libcheese/cheese-camera.c
+++ b/libcheese/cheese-camera.c
@@ -45,18 +45,21 @@ G_DEFINE_TYPE (CheeseCamera, cheese_camera, G_TYPE_OBJECT)
#define CHEESE_CAMERA_ERROR cheese_camera_error_quark ()
+typedef enum
+{
+ MODE_IMAGE = 0,
+ MODE_VIDEO
+} GstCameraBinMode;
+
typedef struct
{
GtkWidget *video_window;
- GstElement *pipeline;
GstBus *bus;
- /* We build the active pipeline by linking the appropriate pipelines listed below*/
+ GstElement *camerabin;
GstElement *camera_source_bin;
- GstElement *video_display_bin;
- GstElement *photo_save_bin;
- GstElement *video_save_bin;
+ GstElement *video_filter_bin;
GstElement *video_source;
GstElement *capsfilter;
@@ -122,26 +125,6 @@ cheese_camera_error_quark (void)
}
static void
-cheese_camera_change_sink (CheeseCamera *camera, GstElement *src,
- GstElement *new_sink, GstElement *old_sink)
-{
- CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- gboolean is_playing = priv->pipeline_is_playing;
-
- cheese_camera_stop (camera);
-
- gst_element_unlink (src, old_sink);
- gst_object_ref (old_sink);
- gst_bin_remove (GST_BIN (priv->pipeline), old_sink);
-
- gst_bin_add (GST_BIN (priv->pipeline), new_sink);
- gst_element_link (src, new_sink);
-
- if (is_playing)
- cheese_camera_play (camera);
-}
-
-static void
cheese_camera_photo_data_cb (GstElement *element, GstBuffer *buffer,
GstPad *pad, CheeseCamera *camera)
{
@@ -188,7 +171,7 @@ cheese_camera_photo_data_cb (GstElement *element, GstBuffer *buffer,
}
else
{
- g_signal_emit (camera, camera_signals[PHOTO_TAKEN], 0, pixbuf);
+ g_signal_emit (camera, camera_signals[PHOTO_TAKEN], 0);
g_object_unref (pixbuf);
}
}
@@ -196,35 +179,44 @@ cheese_camera_photo_data_cb (GstElement *element, GstBuffer *buffer,
static void
cheese_camera_bus_message_cb (GstBus *bus, GstMessage *message, CheeseCamera *camera)
{
- CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
-
- if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS)
+ switch (GST_MESSAGE_TYPE (message))
{
- if (priv->is_recording)
+ case GST_MESSAGE_WARNING:
{
- GST_DEBUG ("Received EOS message");
-
- g_source_remove (priv->eos_timeout_id);
+ GError *err;
+ gchar *debug;
- /* emit signal by name here as the camera_signals array is empty in this thread */
- /* TODO: really understand how threads and static works and why this is needed */
- g_signal_emit_by_name (camera, "video-saved", NULL);
+ gst_message_parse_warning (message, &err, &debug);
+ g_warning ("%s\n", err->message);
+ g_error_free (err);
+ g_free (debug);
+ break;
+ }
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err;
+ gchar *debug;
- cheese_camera_change_sink (camera, priv->video_display_bin,
- priv->photo_save_bin, priv->video_save_bin);
- priv->is_recording = FALSE;
+ gst_message_parse_error (message, &err, &debug);
+ g_warning ("%s\n", err->message);
+ g_error_free (err);
+ g_free (debug);
+ break;
}
- }
- else if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED)
- {
- if (strcmp (GST_MESSAGE_SRC_NAME (message), "pipeline") == 0)
+ case GST_MESSAGE_STATE_CHANGED:
{
- GstState old, new;
- gst_message_parse_state_changed (message, &old, &new, NULL);
- if (new == GST_STATE_PLAYING)
+ if (strcmp (GST_MESSAGE_SRC_NAME (message), "camerabin") == 0)
{
- g_signal_emit (camera, camera_signals[STATE_CHANGED], 0, new);
+ GstState old, new;
+ gst_message_parse_state_changed (message, &old, &new, NULL);
+ if (new == GST_STATE_PLAYING)
+ g_signal_emit (camera, camera_signals[STATE_CHANGED], 0, new);
}
+ break;
+ }
+ default:
+ {
+ break;
}
}
}
@@ -362,19 +354,15 @@ cheese_camera_set_error_element_not_found (GError **error, const char *factoryna
}
static gboolean
-cheese_camera_create_video_display_bin (CheeseCamera *camera, GError **error)
+cheese_camera_create_video_filter_bin (CheeseCamera *camera, GError **error)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- GstElement *save_tee, *video_display_queue, *video_scale, *video_sink, *save_queue;
-
- gboolean ok;
+ gboolean ok = TRUE;
GstPad *pad;
GError *err = NULL;
- priv->video_display_bin = gst_bin_new ("video_display_bin");
-
- cheese_camera_create_camera_source_bin (camera);
+ priv->video_filter_bin = gst_bin_new ("video_filter_bin");
if ((priv->camera_tee = gst_element_factory_make ("tee", "camera_tee")) == NULL)
{
@@ -419,65 +407,33 @@ cheese_camera_create_video_display_bin (CheeseCamera *camera, GError **error)
return FALSE;
}
- if ((save_tee = gst_element_factory_make ("tee", "save_tee")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "tee");
- }
-
- if ((save_queue = gst_element_factory_make ("queue", "save_queue")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "queue");
- }
-
- if ((video_display_queue = gst_element_factory_make ("queue", "video_display_queue")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "queue");
- }
-
- if ((video_scale = gst_element_factory_make ("videoscale", "video_scale")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "videoscale");
- }
- else
- {
- /* Use bilinear scaling */
- g_object_set (video_scale, "method", 1, NULL);
- }
-
- if ((video_sink = clutter_gst_video_sink_new (priv->video_texture)) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "cluttervideosink");
- }
- g_object_set (G_OBJECT (video_sink), "async", FALSE, NULL);
-
if (error != NULL && *error != NULL)
return FALSE;
- gst_bin_add_many (GST_BIN (priv->video_display_bin), priv->camera_source_bin,
- priv->camera_tee, priv->effects_downscaler, priv->effects_tee,
- priv->effects_valve, priv->main_valve,
- priv->effect_filter, priv->csp_post_effect,
- priv->video_balance, priv->csp_post_balance,
- save_tee, save_queue,
- video_display_queue, video_scale, video_sink, NULL);
+ gst_bin_add_many (GST_BIN (priv->video_filter_bin), priv->camera_tee,
+ priv->effects_downscaler, priv->effects_tee,
+ priv->effects_valve, priv->main_valve, priv->effect_filter,
+ priv->csp_post_effect, priv->video_balance,
+ priv->csp_post_balance, NULL);
- ok = gst_element_link_many (priv->camera_source_bin, priv->camera_tee, NULL);
ok &= gst_element_link_many (priv->camera_tee, priv->main_valve, priv->effect_filter,
- priv->csp_post_effect,
- priv->video_balance, priv->csp_post_balance,
- save_tee, NULL);
+ priv->csp_post_effect, priv->video_balance,
+ priv->csp_post_balance, NULL);
ok &= gst_element_link_many (priv->camera_tee, priv->effects_valve,
priv->effects_downscaler, priv->effects_tee, NULL);
- ok &= gst_element_link_many (save_tee, save_queue, NULL);
- ok &= gst_element_link_many (save_tee, video_display_queue, video_scale, video_sink, NULL);
- /* add ghostpad */
- pad = gst_element_get_pad (save_queue, "src");
- gst_element_add_pad (priv->video_display_bin, gst_ghost_pad_new ("src", pad));
+ /* add ghostpads */
+
+ pad = gst_element_get_static_pad (priv->csp_post_balance, "src");
+ gst_element_add_pad (priv->video_filter_bin, gst_ghost_pad_new ("src", pad));
+ gst_object_unref (GST_OBJECT (pad));
+
+ pad = gst_element_get_static_pad (priv->camera_tee, "sink");
+ gst_element_add_pad (priv->video_filter_bin, gst_ghost_pad_new ("sink", pad));
gst_object_unref (GST_OBJECT (pad));
if (!ok)
- g_error ("Unable to create display pipeline");
+ g_error ("Unable to create filter bin");
return TRUE;
}
@@ -487,160 +443,9 @@ cheese_camera_relink_camera_source_bin (CheeseCamera *camera)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- gst_element_unlink (priv->camera_source_bin, priv->camera_tee);
- gst_bin_remove (GST_BIN (priv->video_display_bin), priv->camera_source_bin);
-
cheese_camera_create_camera_source_bin (camera);
- gst_bin_add (GST_BIN (priv->video_display_bin), priv->camera_source_bin);
- gst_element_link (priv->camera_source_bin, priv->camera_tee);
-}
-
-static gboolean
-cheese_camera_create_photo_save_bin (CheeseCamera *camera, GError **error)
-{
- CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
-
- GstElement *csp_photo_save_bin;
-
- gboolean ok;
- GstPad *pad;
- GstCaps *caps;
-
- priv->photo_save_bin = gst_bin_new ("photo_save_bin");
-
- if ((csp_photo_save_bin = gst_element_factory_make ("ffmpegcolorspace", "csp_photo_save_bin")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "ffmpegcolorspace");
- }
- if ((priv->photo_sink = gst_element_factory_make ("fakesink", "photo_sink")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "fakesink");
- }
-
- if (error != NULL && *error != NULL)
- return FALSE;
-
- gst_bin_add_many (GST_BIN (priv->photo_save_bin), csp_photo_save_bin,
- priv->photo_sink, NULL);
-
- /* add ghostpad */
- pad = gst_element_get_pad (csp_photo_save_bin, "sink");
- gst_element_add_pad (priv->photo_save_bin, gst_ghost_pad_new ("sink", pad));
- gst_object_unref (GST_OBJECT (pad));
-
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "bpp", G_TYPE_INT, 24,
- "depth", G_TYPE_INT, 24,
- NULL);
- ok = gst_element_link_filtered (csp_photo_save_bin, priv->photo_sink, caps);
- gst_caps_unref (caps);
-
- g_object_set (G_OBJECT (priv->photo_sink), "signal-handoffs", TRUE, NULL);
-
- if (!ok)
- g_error ("Unable to create photo save pipeline");
-
- return TRUE;
-}
-
-static gboolean
-cheese_camera_create_video_save_bin (CheeseCamera *camera, GError **error)
-{
- CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
-
- GstElement *audio_queue, *audio_convert, *audio_enc;
- GstElement *video_save_csp, *video_save_rate, *video_save_scale, *video_enc;
- GstElement *mux;
- GstPad *pad;
- gboolean ok;
-
- priv->video_save_bin = gst_bin_new ("video_save_bin");
-
- if ((priv->audio_source = gst_element_factory_make ("gconfaudiosrc", "audio_source")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "gconfaudiosrc");
- }
- if ((audio_queue = gst_element_factory_make ("queue", "audio_queue")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "queue");
- }
- if ((audio_convert = gst_element_factory_make ("audioconvert", "audio_convert")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "audioconvert");
- }
- if ((audio_enc = gst_element_factory_make ("vorbisenc", "audio_enc")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "vorbisenc");
- }
-
- if ((video_save_csp = gst_element_factory_make ("ffmpegcolorspace", "video_save_csp")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "ffmpegcolorspace");
- }
- if ((video_enc = gst_element_factory_make ("theoraenc", "video_enc")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "theoraenc");
- }
- else
- {
- g_object_set (video_enc, "keyframe-force", 1, NULL);
- }
-
- if ((video_save_rate = gst_element_factory_make ("videorate", "video_save_rate")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "videorate");
- }
- if ((video_save_scale = gst_element_factory_make ("videoscale", "video_save_scale")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "videoscale");
- }
- else
- {
- /* Use bilinear scaling */
- g_object_set (video_save_scale, "method", 1, NULL);
- }
-
- if ((mux = gst_element_factory_make ("oggmux", "mux")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "oggmux");
- }
- else
- {
- g_object_set (G_OBJECT (mux),
- "max-delay", (guint64) 10000000,
- "max-page-delay", (guint64) 10000000, NULL);
- }
-
- if ((priv->video_file_sink = gst_element_factory_make ("filesink", "video_file_sink")) == NULL)
- {
- cheese_camera_set_error_element_not_found (error, "filesink");
- }
-
- if (error != NULL && *error != NULL)
- return FALSE;
-
- gst_bin_add_many (GST_BIN (priv->video_save_bin), priv->audio_source, audio_queue,
- audio_convert, audio_enc, video_save_csp, video_save_rate, video_save_scale, video_enc,
- mux, priv->video_file_sink, NULL);
-
- /* add ghostpad */
- pad = gst_element_get_pad (video_save_csp, "sink");
- gst_element_add_pad (priv->video_save_bin, gst_ghost_pad_new ("sink", pad));
- gst_object_unref (GST_OBJECT (pad));
-
-
- ok = gst_element_link_many (priv->audio_source, audio_queue, audio_convert,
- audio_enc, mux, priv->video_file_sink, NULL);
-
- ok &= gst_element_link_many (video_save_csp, video_save_rate, video_save_scale, video_enc,
- NULL);
- ok &= gst_element_link (video_enc, mux);
-
- if (!ok)
- g_error ("Unable to create video save pipeline");
-
- return TRUE;
+ g_object_set (priv->camerabin, "video-source", priv->camera_source_bin, NULL);
}
int
@@ -724,7 +529,7 @@ cheese_camera_play (CheeseCamera *camera)
g_object_set (priv->capsfilter, "caps", caps, NULL);
gst_caps_unref (caps);
- gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
+ gst_element_set_state (priv->camerabin, GST_STATE_PLAYING);
priv->pipeline_is_playing = TRUE;
}
@@ -733,8 +538,8 @@ cheese_camera_stop (CheeseCamera *camera)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- if (priv->pipeline != NULL)
- gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+ if (priv->camerabin != NULL)
+ gst_element_set_state (priv->camerabin, GST_STATE_NULL);
priv->pipeline_is_playing = FALSE;
}
@@ -750,11 +555,11 @@ cheese_camera_change_effect_filter (CheeseCamera *camera, GstElement *new_filter
priv->csp_post_effect, NULL);
g_object_ref (priv->effect_filter);
- gst_bin_remove (GST_BIN (priv->video_display_bin), priv->effect_filter);
+ gst_bin_remove (GST_BIN (priv->video_filter_bin), priv->effect_filter);
gst_element_set_state (priv->effect_filter, GST_STATE_NULL);
g_object_unref (priv->effect_filter);
- gst_bin_add (GST_BIN (priv->video_display_bin), new_filter);
+ gst_bin_add (GST_BIN (priv->video_filter_bin), new_filter);
ok = gst_element_link_many (priv->main_valve, new_filter,
priv->csp_post_effect, NULL);
gst_element_set_state (new_filter, GST_STATE_PAUSED);
@@ -831,7 +636,7 @@ cheese_camera_connect_effect_texture (CheeseCamera *camera, CheeseEffect *effect
GstElement *display_element;
GstElement *display_queue;
GstElement *control_valve;
- gboolean ok;
+ gboolean ok = TRUE;
g_object_set (G_OBJECT (priv->effects_valve), "drop", TRUE, NULL);
@@ -845,9 +650,7 @@ cheese_camera_connect_effect_texture (CheeseCamera *camera, CheeseEffect *effect
display_element = clutter_gst_video_sink_new (texture);
g_object_set (G_OBJECT (display_element), "async", FALSE, NULL);
- gst_bin_add_many (GST_BIN (priv->pipeline), control_valve, effect_filter, display_queue, display_element, NULL);
-
-
+ gst_bin_add_many (GST_BIN (priv->video_filter_bin), control_valve, effect_filter, display_queue, display_element, NULL);
ok = gst_element_link_many (priv->effects_tee, control_valve, effect_filter, display_queue, display_element, NULL);
@@ -857,6 +660,9 @@ cheese_camera_connect_effect_texture (CheeseCamera *camera, CheeseEffect *effect
gst_element_set_state (display_queue, GST_STATE_PLAYING);
gst_element_set_state (display_element, GST_STATE_PLAYING);
+ if (!ok)
+ g_warning ("Could not create effects pipeline");
+
g_object_set (G_OBJECT (priv->effects_valve), "drop", FALSE, NULL);
}
@@ -865,9 +671,9 @@ cheese_camera_start_video_recording (CheeseCamera *camera, char *filename)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- g_object_set (CHEESE_CAMERA_GET_PRIVATE (camera)->video_file_sink, "location", filename, NULL);
- cheese_camera_change_sink (camera, priv->video_display_bin,
- priv->video_save_bin, priv->photo_save_bin);
+ g_object_set (priv->camerabin, "mode", MODE_VIDEO, NULL);
+ g_object_set (priv->camerabin, "filename", filename, NULL);
+ g_signal_emit_by_name (priv->camerabin, "capture-start", 0);
priv->is_recording = TRUE;
}
@@ -882,8 +688,8 @@ cheese_camera_force_stop_video_recording (gpointer data)
GST_WARNING ("Cannot cleanly shutdown recording pipeline, forcing");
g_signal_emit (camera, camera_signals[VIDEO_SAVED], 0);
- cheese_camera_change_sink (camera, priv->video_display_bin,
- priv->photo_save_bin, priv->video_save_bin);
+ cheese_camera_stop (camera);
+ g_object_set (priv->camerabin, "mode", MODE_IMAGE, NULL);
priv->is_recording = FALSE;
}
@@ -896,15 +702,13 @@ cheese_camera_stop_video_recording (CheeseCamera *camera)
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
GstState state;
- gst_element_get_state (priv->pipeline, &state, NULL, 0);
+ gst_element_get_state (priv->camerabin, &state, NULL, 0);
if (state == GST_STATE_PLAYING)
{
- /* Send EOS message down the pipeline by stopping video and audio source*/
- GST_DEBUG ("Sending EOS event down the recording pipeline");
- gst_element_send_event (priv->video_source, gst_event_new_eos ());
- gst_element_send_event (priv->audio_source, gst_event_new_eos ());
- priv->eos_timeout_id = g_timeout_add (3000, cheese_camera_force_stop_video_recording, camera);
+ g_signal_emit_by_name (priv->camerabin, "capture-stop", 0);
+ g_object_set (priv->camerabin, "mode", MODE_IMAGE, NULL);
+ priv->is_recording = FALSE;
}
else
{
@@ -912,6 +716,16 @@ cheese_camera_stop_video_recording (CheeseCamera *camera)
}
}
+static void
+cheese_camera_image_done_cb (GstElement *camerabin, gchar *filename,
+ CheeseCamera *camera)
+{
+ CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
+ g_signal_handler_disconnect (G_OBJECT (priv->camerabin),
+ priv->photo_handler_signal_id);
+ priv->photo_handler_signal_id = 0;
+}
+
gboolean
cheese_camera_take_photo (CheeseCamera *camera, char *filename)
{
@@ -922,15 +736,31 @@ cheese_camera_take_photo (CheeseCamera *camera, char *filename)
GST_WARNING ("Still waiting for previous photo data, ignoring new request");
return FALSE;
}
+ priv->photo_handler_signal_id = g_signal_connect (G_OBJECT (priv->camerabin),
+ "image-done",
+ G_CALLBACK (cheese_camera_image_done_cb),
+ camera);
g_free (priv->photo_filename);
priv->photo_filename = g_strdup (filename);
- /* Take the photo by connecting the handoff signal */
- priv->photo_handler_signal_id = g_signal_connect (G_OBJECT (priv->photo_sink),
- "handoff",
- G_CALLBACK (cheese_camera_photo_data_cb),
- camera);
+ /* Take the photo*/
+
+ /* Only copy the data if we're giving away a pixbuf,
+ * not if we're throwing everything away straight away */
+
+ if (priv->photo_filename != NULL)
+ {
+ g_object_set (priv->camerabin, "filename", priv->photo_filename, NULL);
+ g_object_set (priv->camerabin, "mode", MODE_IMAGE, NULL);
+ g_signal_emit_by_name (priv->camerabin, "capture-start", 0);
+ g_signal_emit (camera, camera_signals[PHOTO_SAVED], 0);
+ }
+ else
+ {
+ g_signal_emit (camera, camera_signals[PHOTO_TAKEN], 0);
+ }
+
return TRUE;
}
@@ -946,10 +776,10 @@ cheese_camera_take_photo_pixbuf (CheeseCamera *camera)
}
/* Take the photo by connecting the handoff signal */
- priv->photo_handler_signal_id = g_signal_connect (G_OBJECT (priv->photo_sink),
- "handoff",
- G_CALLBACK (cheese_camera_photo_data_cb),
- camera);
+ priv->photo_handler_signal_id = g_signal_connect (G_OBJECT (priv->photo_sink),
+ "handoff",
+ G_CALLBACK (cheese_camera_photo_data_cb),
+ camera);
return TRUE;
}
@@ -962,13 +792,11 @@ cheese_camera_finalize (GObject *object)
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
cheese_camera_stop (camera);
- if (priv->pipeline != NULL)
- gst_object_unref (priv->pipeline);
+ if (priv->camerabin != NULL)
+ gst_object_unref (priv->camerabin);
- if (priv->is_recording && priv->photo_save_bin != NULL)
- gst_object_unref (priv->photo_save_bin);
- else if (priv->video_save_bin != NULL)
- gst_object_unref (priv->video_save_bin);
+ if (priv->video_filter_bin != NULL)
+ gst_object_unref (priv->video_filter_bin);
g_free (priv->photo_filename);
g_free (priv->device_name);
@@ -1064,7 +892,7 @@ cheese_camera_class_init (CheeseCameraClass *klass)
G_STRUCT_OFFSET (CheeseCameraClass, photo_taken),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, GDK_TYPE_PIXBUF);
+ G_TYPE_NONE, 0);
camera_signals[VIDEO_SAVED] = g_signal_new ("video-saved", G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
@@ -1148,8 +976,8 @@ cheese_camera_setup (CheeseCamera *camera, char *id, GError **error)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
- gboolean ok = TRUE;
GError *tmp_error = NULL;
+ GstElement *video_sink;
cheese_camera_detect_camera_devices (camera);
@@ -1164,34 +992,43 @@ cheese_camera_setup (CheeseCamera *camera, char *id, GError **error)
cheese_camera_set_device_by_dev_udi (camera, id);
}
- priv->pipeline = gst_pipeline_new ("pipeline");
+ cheese_camera_create_camera_source_bin (camera);
- cheese_camera_create_video_display_bin (camera, &tmp_error);
+ if ((priv->camerabin = gst_element_factory_make ("camerabin", "camerabin")) == NULL)
+ {
+ cheese_camera_set_error_element_not_found (error, "camerabin");
+ }
+ g_object_set (priv->camerabin, "video-source", priv->camera_source_bin, NULL);
- cheese_camera_create_photo_save_bin (camera, &tmp_error);
+ /* Create a clutter-gst sink and set it as camerabin sink*/
- cheese_camera_create_video_save_bin (camera, &tmp_error);
- if (tmp_error != NULL)
+ if ((video_sink = clutter_gst_video_sink_new (priv->video_texture)) == NULL)
+ {
+ cheese_camera_set_error_element_not_found (error, "cluttervideosink");
+ }
+ g_object_set (G_OBJECT (video_sink), "async", FALSE, NULL);
+ g_object_set (G_OBJECT (priv->camerabin), "viewfinder-sink", video_sink, NULL);
+
+ /* Set flags to enable conversions*/
+
+ g_object_set (G_OBJECT (priv->camerabin), "flags", 0xd9, NULL);
+
+ cheese_camera_create_video_filter_bin (camera, &tmp_error);
+
+ if (tmp_error != NULL || (error != NULL && *error != NULL))
{
g_propagate_prefixed_error (error, tmp_error,
_("One or more needed GStreamer elements are missing: "));
GST_WARNING ("%s", (*error)->message);
return;
}
+ g_object_set (G_OBJECT (priv->camerabin), "video-source-filter", priv->video_filter_bin, NULL);
- gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_display_bin,
- priv->photo_save_bin, NULL);
-
- ok = gst_element_link (priv->video_display_bin, priv->photo_save_bin);
-
- priv->bus = gst_element_get_bus (priv->pipeline);
+ priv->bus = gst_element_get_bus (priv->camerabin);
gst_bus_add_signal_watch (priv->bus);
g_signal_connect (G_OBJECT (priv->bus), "message",
G_CALLBACK (cheese_camera_bus_message_cb), camera);
-
- if (!ok)
- g_error ("Unable link pipeline for photo");
}
GPtrArray *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]