mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-01 06:01:04 +00:00
122a7bd556
As video recording bin's state is locked, we should always remember of setting it to NULL when camerabin2 goes to NULL Be more careful when using elements that might not have been created yet And do not set location property recursively on videorecordingbin
235 lines
6.2 KiB
C
235 lines
6.2 KiB
C
/* GStreamer
|
|
* Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
|
|
*
|
|
* 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.
|
|
*
|
|
* <refsect2>
|
|
* <title>Example launch line</title>
|
|
* |[
|
|
* gst-launch -v videotestsrc num-buffers=3 ! videorecordingbin
|
|
* ]|
|
|
* FIXME Describe what the pipeline does.
|
|
* </refsect2>
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "gstvideorecordingbin.h"
|
|
|
|
/* prototypes */
|
|
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_LOCATION
|
|
};
|
|
|
|
#define DEFAULT_LOCATION "vidcap"
|
|
|
|
/* 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_set_property (GObject * object, guint prop_id,
|
|
const GValue * value, GParamSpec * pspec)
|
|
{
|
|
GstVideoRecordingBin *vidbin = GST_VIDEO_RECORDING_BIN_CAST (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_LOCATION:
|
|
vidbin->location = g_value_dup_string (value);
|
|
if (vidbin->sink) {
|
|
g_object_set (vidbin->sink, "location", vidbin->location, NULL);
|
|
}
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_video_recording_bin_get_property (GObject * object, guint prop_id,
|
|
GValue * value, GParamSpec * pspec)
|
|
{
|
|
GstVideoRecordingBin *vidbin = GST_VIDEO_RECORDING_BIN_CAST (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_LOCATION:
|
|
g_value_set_string (value, vidbin->location);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
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 <thiago.sousa.santos@collabora.co.uk>");
|
|
}
|
|
|
|
static void
|
|
gst_video_recording_bin_class_init (GstVideoRecordingBinClass * klass)
|
|
{
|
|
GObjectClass *gobject_class;
|
|
GstElementClass *element_class;
|
|
|
|
gobject_class = G_OBJECT_CLASS (klass);
|
|
element_class = GST_ELEMENT_CLASS (klass);
|
|
|
|
gobject_class->set_property = gst_video_recording_bin_set_property;
|
|
gobject_class->get_property = gst_video_recording_bin_get_property;
|
|
|
|
element_class->change_state =
|
|
GST_DEBUG_FUNCPTR (gst_video_recording_bin_change_state);
|
|
|
|
g_object_class_install_property (gobject_class, PROP_LOCATION,
|
|
g_param_spec_string ("location", "Location",
|
|
"Location to save the captured files.",
|
|
DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
}
|
|
|
|
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);
|
|
|
|
video_recordingbin->location = g_strdup (DEFAULT_LOCATION);
|
|
}
|
|
|
|
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;
|
|
|
|
vrbin->sink = gst_object_ref (sink);
|
|
g_object_set (sink, "location", vrbin->location, "async", FALSE, 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 ());
|
|
}
|