From 0dce17a4e8e7d93f3246eab3d25b079d0eb25f6c Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 25 Nov 2010 14:57:13 -0300 Subject: [PATCH] camerabin2: Adds video recording bin Adds an bin that is responsible for encoding and saving video streams to files. For now it is simply a ffmpegcolorspace ! theoraenc ! oggmux ! filesink bin. Still uncapable of recording audio. --- gst/camerabin2/Makefile.am | 2 + gst/camerabin2/gstplugin.c | 3 + gst/camerabin2/gstvideorecordingbin.c | 184 ++++++++++++++++++++++++++ gst/camerabin2/gstvideorecordingbin.h | 55 ++++++++ 4 files changed, 244 insertions(+) create mode 100644 gst/camerabin2/gstvideorecordingbin.c create mode 100644 gst/camerabin2/gstvideorecordingbin.h diff --git a/gst/camerabin2/Makefile.am b/gst/camerabin2/Makefile.am index 25b1e61ed6..e1278f4bbe 100644 --- a/gst/camerabin2/Makefile.am +++ b/gst/camerabin2/Makefile.am @@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgstcamerabin2.la libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \ gstimagecapturebin.c \ + gstvideorecordingbin.c \ camerabingeneral.c \ gstbasecamerasrc.c \ gstcamerabin-enum.c \ @@ -23,6 +24,7 @@ libgstcamerabin2_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = gstviewfinderbin.h \ gstimagecapturebin.h \ + gstvideorecordingbin.h \ camerabingeneral.h \ gstbasecamerasrc.h \ gstv4l2camerasrc.h \ diff --git a/gst/camerabin2/gstplugin.c b/gst/camerabin2/gstplugin.c index c88ad8d038..872ad1e637 100644 --- a/gst/camerabin2/gstplugin.c +++ b/gst/camerabin2/gstplugin.c @@ -25,6 +25,7 @@ #include "gstviewfinderbin.h" #include "gstimagecapturebin.h" +#include "gstvideorecordingbin.h" #include "gstv4l2camerasrc.h" static gboolean @@ -34,6 +35,8 @@ plugin_init (GstPlugin * plugin) return FALSE; if (!gst_image_capture_bin_plugin_init (plugin)) return FALSE; + if (!gst_video_recording_bin_plugin_init (plugin)) + return FALSE; if (!gst_v4l2_camera_src_plugin_init (plugin)) return FALSE; diff --git a/gst/camerabin2/gstvideorecordingbin.c b/gst/camerabin2/gstvideorecordingbin.c new file mode 100644 index 0000000000..4e5a8782d5 --- /dev/null +++ b/gst/camerabin2/gstvideorecordingbin.c @@ -0,0 +1,184 @@ +/* GStreamer + * Copyright (C) 2010 Thiago Santos + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/** + * SECTION:element-gstvideorecordingbin + * + * The gstvideorecordingbin element does FIXME stuff. + * + * + * Example launch line + * |[ + * gst-launch -v videotestsrc num-buffers=3 ! videorecordingbin + * ]| + * FIXME Describe what the pipeline does. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvideorecordingbin.h" + +/* prototypes */ + + +enum +{ + PROP_0 +}; + +/* pad templates */ + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv; video/x-raw-rgb") + ); + +/* class initialization */ + +GST_BOILERPLATE (GstVideoRecordingBin, gst_video_recording_bin, GstBin, + GST_TYPE_BIN); + +/* Element class functions */ +static GstStateChangeReturn +gst_video_recording_bin_change_state (GstElement * element, + GstStateChange trans); + +static void +gst_video_recording_bin_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + + gst_element_class_set_details_simple (element_class, "Video Recording Bin", + "Sink/Video", "Video Recording Bin used in camerabin2", + "Thiago Santos "); +} + +static void +gst_video_recording_bin_class_init (GstVideoRecordingBinClass * klass) +{ + GstElementClass *element_class; + + element_class = GST_ELEMENT_CLASS (klass); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_video_recording_bin_change_state); +} + +static void +gst_video_recording_bin_init (GstVideoRecordingBin * video_recordingbin, + GstVideoRecordingBinClass * video_recordingbin_class) +{ + video_recordingbin->ghostpad = + gst_ghost_pad_new_no_target_from_template ("sink", + gst_static_pad_template_get (&sink_template)); + gst_element_add_pad (GST_ELEMENT_CAST (video_recordingbin), + video_recordingbin->ghostpad); +} + +static gboolean +gst_video_recording_bin_create_elements (GstVideoRecordingBin * vrbin) +{ + GstElement *csp; + GstElement *enc; + GstElement *mux; + GstElement *sink; + GstPad *pad = NULL; + + if (vrbin->elements_created) + return TRUE; + + /* create elements */ + csp = gst_element_factory_make ("ffmpegcolorspace", "vrbin-csp"); + if (!csp) + goto error; + + enc = gst_element_factory_make ("theoraenc", "vrbin-enc"); + if (!enc) + goto error; + + mux = gst_element_factory_make ("oggmux", "vrbin-mux"); + if (!mux) + goto error; + + sink = gst_element_factory_make ("filesink", "vrbin-sink"); + if (!sink) + goto error; + + g_object_set (sink, "location", "cap.ogg", NULL); + + /* add and link */ + gst_bin_add_many (GST_BIN_CAST (vrbin), csp, enc, mux, sink, NULL); + if (!gst_element_link_many (csp, enc, mux, sink, NULL)) + goto error; + + /* add ghostpad */ + pad = gst_element_get_static_pad (csp, "sink"); + if (!gst_ghost_pad_set_target (GST_GHOST_PAD (vrbin->ghostpad), pad)) + goto error; + + vrbin->elements_created = TRUE; + return TRUE; + +error: + if (pad) + gst_object_unref (pad); + return FALSE; +} + +static GstStateChangeReturn +gst_video_recording_bin_change_state (GstElement * element, + GstStateChange trans) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstVideoRecordingBin *vrbin = GST_VIDEO_RECORDING_BIN_CAST (element); + + switch (trans) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!gst_video_recording_bin_create_elements (vrbin)) { + return GST_STATE_CHANGE_FAILURE; + } + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, trans); + + switch (trans) { + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +gboolean +gst_video_recording_bin_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "videorecordingbin", GST_RANK_NONE, + gst_video_recording_bin_get_type ()); +} diff --git a/gst/camerabin2/gstvideorecordingbin.h b/gst/camerabin2/gstvideorecordingbin.h new file mode 100644 index 0000000000..88651fad56 --- /dev/null +++ b/gst/camerabin2/gstvideorecordingbin.h @@ -0,0 +1,55 @@ +/* GStreamer + * Copyright (C) 2010 Thiago Santos + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _GST_VIDEO_RECORDING_BIN_H_ +#define _GST_VIDEO_RECORDING_BIN_H_ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VIDEO_RECORDING_BIN (gst_video_recording_bin_get_type()) +#define GST_VIDEO_RECORDING_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_RECORDING_BIN,GstVideoRecordingBin)) +#define GST_VIDEO_RECORDING_BIN_CAST(obj) ((GstVideoRecordingBin *) obj) +#define GST_VIDEO_RECORDING_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEO_RECORDING_BIN,GstVideoRecordingBinClass)) +#define GST_IS_VIDEO_RECORDING_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_RECORDING_BIN)) +#define GST_IS_VIDEO_RECORDING_BIN_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_RECORDING_BIN)) + +typedef struct _GstVideoRecordingBin GstVideoRecordingBin; +typedef struct _GstVideoRecordingBinClass GstVideoRecordingBinClass; + +struct _GstVideoRecordingBin +{ + GstBin bin; + + GstPad *ghostpad; + + gboolean elements_created; +}; + +struct _GstVideoRecordingBinClass +{ + GstBinClass bin_class; +}; + +GType gst_video_recording_bin_get_type (void); +gboolean gst_video_recording_bin_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif