diff --git a/configure.ac b/configure.ac index 23b3d1f..f22a863 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,8 @@ PKG_CHECK_MODULES(CHEESE, \ gconf-2.0 >= $GCONF_REQUIRED \ gstreamer-0.10 >= $GSTREAMER_REQUIRED \ gstreamer-plugins-base-0.10 >= $GSTREAMER_REQUIRED \ + gstreamer-base-0.10 >= $GSTREAMER_REQUIRED \ + gstreamer-app-0.10 >= $GSTREAMER_REQUIRED \ cairo >= $CAIRO_REQUIRED \ dbus-1 >= $DBUS_REQUIRED \ dbus-glib-1 >= $DBUS_GLIB_REQUIRED \ diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c index 01a9287..507fb27 100644 --- a/libcheese/cheese-camera.c +++ b/libcheese/cheese-camera.c @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008 Jaap Haitsma - * Copyright © 2007-2009 daniel g. siegel + * Copyright © 2007-2010 daniel g. siegel * Copyright © 2008 Ryan Zeigler * Copyright © 2010 Yuvaraj Pandian T * @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,7 @@ typedef struct GtkWidget *video_window; GstElement *pipeline; + GstElement *app_pipeline; GstBus *bus; /* We build the active pipeline by linking the appropriate pipelines listed below*/ @@ -66,6 +68,11 @@ typedef struct GstElement *audio_enc; GstElement *video_enc; + GstElement *app_src; + GstElement *jpeg_enc; + GstElement *jif_mux; + GstElement *app_filesink; + ClutterTexture *video_texture; GstElement *effect_filter, *csp_post_effect; @@ -149,48 +156,60 @@ cheese_camera_photo_data_cb (GstElement *element, GstBuffer *buffer, GstCaps *caps; const GstStructure *structure; - int width, height, stride; GdkPixbuf *pixbuf; const int bits_per_pixel = 8; guchar *data; caps = gst_buffer_get_caps (buffer); structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - - stride = buffer->size / height; - /* 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) - data = NULL; - else - data = g_memdup (GST_BUFFER_DATA (buffer), buffer->size); - pixbuf = gdk_pixbuf_new_from_data (data ? data : GST_BUFFER_DATA (buffer), - GDK_COLORSPACE_RGB, - FALSE, bits_per_pixel, width, height, stride, - data ? (GdkPixbufDestroyNotify) g_free : NULL, NULL); + { - g_signal_handler_disconnect (G_OBJECT (priv->photo_sink), - priv->photo_handler_signal_id); - priv->photo_handler_signal_id = 0; + printf("%s\n", priv->photo_filename); + g_object_set (G_OBJECT (priv->app_filesink), "location", priv->photo_filename, NULL); +// gst_app_src_set_caps (GST_APP_SRC (priv->app_src), caps); + gst_app_src_push_buffer (GST_APP_SRC (priv->app_src), buffer); + gst_app_src_end_of_stream (GST_APP_SRC (priv->app_src)); - if (priv->photo_filename != NULL) - { - gdk_pixbuf_save (pixbuf, priv->photo_filename, "jpeg", NULL, NULL); - g_object_unref (G_OBJECT (pixbuf)); +// gst_element_set_state (priv->app_pipeline, GST_STATE_NULL); - g_free (priv->photo_filename); +// g_free (priv->photo_filename); priv->photo_filename = NULL; - - g_signal_emit (camera, camera_signals[PHOTO_SAVED], 0); - } - else - { - g_signal_emit (camera, camera_signals[PHOTO_TAKEN], 0, pixbuf); - g_object_unref (pixbuf); } + +// stride = buffer->size / height; +// +// /* 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) +// data = NULL; +// else +// data = g_memdup (GST_BUFFER_DATA (buffer), buffer->size); +// pixbuf = gdk_pixbuf_new_from_data (data ? data : GST_BUFFER_DATA (buffer), +// GDK_COLORSPACE_RGB, +// FALSE, bits_per_pixel, width, height, stride, +// data ? (GdkPixbufDestroyNotify) g_free : NULL, NULL); +// + g_signal_handler_disconnect (G_OBJECT (priv->photo_sink), + priv->photo_handler_signal_id); + priv->photo_handler_signal_id = 0; +// +// if (priv->photo_filename != NULL) +// { +// gdk_pixbuf_save (pixbuf, priv->photo_filename, "jpeg", NULL, NULL); +// g_object_unref (G_OBJECT (pixbuf)); +// +// g_free (priv->photo_filename); +// priv->photo_filename = NULL; +// +// g_signal_emit (camera, camera_signals[PHOTO_SAVED], 0); +// } +// else +// { +// g_signal_emit (camera, camera_signals[PHOTO_TAKEN], 0, pixbuf); +// g_object_unref (pixbuf); +// } } static void @@ -543,6 +562,47 @@ cheese_camera_create_photo_save_bin (CheeseCamera *camera, GError **error) } static gboolean +cheese_camera_create_app_save_bin (CheeseCamera *camera, GError **error) +{ + CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera); + + gboolean ok; + + if ((priv->app_src = gst_element_factory_make ("appsrc", "app_src")) == NULL) + { + cheese_camera_set_error_element_not_found (error, "appsrc"); + } + if ((priv->jpeg_enc = gst_element_factory_make ("jpegenc", "jpeg_enc")) == NULL) + { + cheese_camera_set_error_element_not_found (error, "jpegenc"); + } + if ((priv->jif_mux = gst_element_factory_make ("jifmux", "jif_mux")) == NULL) + { + cheese_camera_set_error_element_not_found (error, "jifmux"); + } + if ((priv->app_filesink = gst_element_factory_make ("filesink", "app_filesink")) == NULL) + { + cheese_camera_set_error_element_not_found (error, "filesink"); + } + + if (error != NULL && *error != NULL) + return FALSE; + + gst_bin_add_many (GST_BIN (priv->app_pipeline), priv->app_src, + priv->jpeg_enc, priv->jif_mux, priv->app_filesink, + NULL); + + ok = gst_element_link_many (priv->app_src, priv->jpeg_enc, priv->jif_mux, + priv->app_filesink, NULL); + + gst_element_set_state (priv->app_pipeline, GST_STATE_PLAYING); + if (!ok) + g_error ("Unable to create app save pipeline"); + + return TRUE; +} + +static gboolean cheese_camera_create_video_save_bin (CheeseCamera *camera, GError **error) { CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera); @@ -1161,11 +1221,14 @@ cheese_camera_setup (CheeseCamera *camera, char *id, GError **error) } priv->pipeline = gst_pipeline_new ("pipeline"); + priv->app_pipeline = gst_pipeline_new ("app_pipeline"); cheese_camera_create_video_display_bin (camera, &tmp_error); cheese_camera_create_photo_save_bin (camera, &tmp_error); + cheese_camera_create_app_save_bin (camera, &tmp_error); + cheese_camera_create_video_save_bin (camera, &tmp_error); if (tmp_error != NULL) {