From 4a28d5f4780ec680ab53579630830a59d862457a Mon Sep 17 00:00:00 2001 From: Teemu Katajisto Date: Tue, 14 Dec 2010 14:28:49 +0200 Subject: [PATCH] camerabin2: add videorecordingbin::video-muxer property --- gst/camerabin2/gstvideorecordingbin.c | 64 ++++++++++++++++++++++++++------ gst/camerabin2/gstvideorecordingbin.h | 2 + tests/check/elements/videorecordingbin.c | 49 ++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 11 deletions(-) diff --git a/gst/camerabin2/gstvideorecordingbin.c b/gst/camerabin2/gstvideorecordingbin.c index a3ac745..7426375 100644 --- a/gst/camerabin2/gstvideorecordingbin.c +++ b/gst/camerabin2/gstvideorecordingbin.c @@ -44,7 +44,8 @@ enum { PROP_0, PROP_LOCATION, - PROP_VIDEO_ENCODER + PROP_VIDEO_ENCODER, + PROP_MUXER }; #define DEFAULT_LOCATION "vidcap" @@ -92,6 +93,22 @@ gst_video_recording_bin_set_video_encoder (GstVideoRecordingBin * videobin, } static void +gst_video_recording_bin_set_muxer (GstVideoRecordingBin * videobin, + GstElement * muxer) +{ + GST_DEBUG_OBJECT (GST_OBJECT (videobin), + "Setting video muxer %" GST_PTR_FORMAT, muxer); + + if (videobin->user_muxer) + g_object_unref (videobin->user_muxer); + + if (muxer) + g_object_ref (muxer); + + videobin->user_muxer = muxer; +} + +static void gst_video_recording_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { @@ -111,6 +128,9 @@ gst_video_recording_bin_set_property (GObject * object, guint prop_id, gst_video_recording_bin_set_video_encoder (videobin, g_value_get_object (value)); break; + case PROP_MUXER: + gst_video_recording_bin_set_muxer (videobin, g_value_get_object (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -130,6 +150,9 @@ gst_video_recording_bin_get_property (GObject * object, guint prop_id, case PROP_VIDEO_ENCODER: g_value_set_object (value, videobin->video_encoder); break; + case PROP_MUXER: + g_value_set_object (value, videobin->muxer); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -176,6 +199,11 @@ gst_video_recording_bin_class_init (GstVideoRecordingBinClass * klass) g_param_spec_object ("video-encoder", "Video encoder", "Video encoder GstElement (default is theoraenc).", GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_MUXER, + g_param_spec_object ("video-muxer", "Video muxer", + "Video muxer GstElement (default is oggmux).", + GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -190,6 +218,8 @@ gst_video_recording_bin_init (GstVideoRecordingBin * videobin, videobin->location = g_strdup (DEFAULT_LOCATION); videobin->video_encoder = NULL; videobin->user_video_encoder = NULL; + videobin->muxer = NULL; + videobin->user_muxer = NULL; } static void @@ -202,6 +232,11 @@ gst_video_recording_bin_dispose (GObject * object) videobin->user_video_encoder = NULL; } + if (videobin->user_muxer) { + gst_object_unref (videobin->user_muxer); + videobin->user_muxer = NULL; + } + G_OBJECT_CLASS (parent_class)->dispose ((GObject *) videobin); } @@ -221,8 +256,6 @@ static gboolean gst_video_recording_bin_create_elements (GstVideoRecordingBin * videobin) { GstElement *colorspace; - GstElement *muxer; - GstElement *sink; GstPad *pad = NULL; if (videobin->elements_created) @@ -249,18 +282,26 @@ gst_video_recording_bin_create_elements (GstVideoRecordingBin * videobin) goto error; } - muxer = gst_camerabin_create_and_add_element (GST_BIN (videobin), - DEFAULT_MUXER); - if (!muxer) - goto error; + if (videobin->user_muxer) { + videobin->muxer = videobin->user_muxer; + if (!gst_camerabin_add_element (GST_BIN (videobin), videobin->muxer)) { + goto error; + } + } else { + videobin->muxer = + gst_camerabin_create_and_add_element (GST_BIN (videobin), + DEFAULT_MUXER); + if (!videobin->muxer) + goto error; + } - sink = gst_camerabin_create_and_add_element (GST_BIN (videobin), + videobin->sink = gst_camerabin_create_and_add_element (GST_BIN (videobin), DEFAULT_SINK); - if (!sink) + if (!videobin->sink) goto error; - videobin->sink = gst_object_ref (sink); - g_object_set (sink, "location", videobin->location, "async", FALSE, NULL); + g_object_set (videobin->sink, "location", videobin->location, "async", FALSE, + NULL); /* add ghostpad */ pad = gst_element_get_static_pad (colorspace, "sink"); @@ -271,6 +312,7 @@ gst_video_recording_bin_create_elements (GstVideoRecordingBin * videobin) return TRUE; error: + GST_DEBUG_OBJECT (videobin, "Create elements failed"); if (pad) gst_object_unref (pad); return FALSE; diff --git a/gst/camerabin2/gstvideorecordingbin.h b/gst/camerabin2/gstvideorecordingbin.h index afa7db2..167da29 100644 --- a/gst/camerabin2/gstvideorecordingbin.h +++ b/gst/camerabin2/gstvideorecordingbin.h @@ -44,6 +44,8 @@ struct _GstVideoRecordingBin gchar *location; GstElement *video_encoder; GstElement *user_video_encoder; + GstElement *muxer; + GstElement *user_muxer; gboolean elements_created; }; diff --git a/tests/check/elements/videorecordingbin.c b/tests/check/elements/videorecordingbin.c index 1f35dd1..96ed351 100644 --- a/tests/check/elements/videorecordingbin.c +++ b/tests/check/elements/videorecordingbin.c @@ -154,6 +154,54 @@ GST_START_TEST (test_setting_video_encoder) GST_END_TEST; +GST_START_TEST (test_setting_video_muxer) +{ + GstVideoRecordingBinTestContext ctx; + GstBus *bus; + GstMessage *msg; + GstElement *encoder; + GstElement *muxer; + gchar *test_file_name; + FILE *f; + + gstvideorecordingbin_init_test_context (&ctx, N_BUFFERS); + bus = gst_element_get_bus (ctx.pipe); + + test_file_name = make_test_file_name (0); + g_object_set (ctx.vrbin, "location", test_file_name, NULL); + + encoder = gst_element_factory_make ("theoraenc", NULL); + g_object_set (ctx.vrbin, "video-encoder", encoder, NULL); + + muxer = gst_element_factory_make ("oggmux", NULL); + g_object_set (ctx.vrbin, "video-muxer", muxer, NULL); + + fail_if (gst_element_set_state (ctx.pipe, GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE); + + msg = gst_bus_timed_pop_filtered (bus, GST_SECOND * 10, + GST_MESSAGE_EOS | GST_MESSAGE_ERROR); + fail_unless (msg != NULL); + fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS); + + /* check there is a recorded file */ + fail_unless (g_file_test (test_file_name, G_FILE_TEST_EXISTS)); + fail_unless (g_file_test (test_file_name, G_FILE_TEST_IS_REGULAR)); + fail_if (g_file_test (test_file_name, G_FILE_TEST_IS_SYMLINK)); + + /* check the file isn't empty */ + f = fopen (test_file_name, "r"); + fseek (f, 0, SEEK_END); + fail_unless (ftell (f) > 0); + fclose (f); + + gstvideorecordingbin_unset_test_context (&ctx); + gst_object_unref (bus); + g_free (test_file_name); +} + +GST_END_TEST; + static Suite * videorecordingbin_suite (void) { @@ -163,6 +211,7 @@ videorecordingbin_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_simple_recording); tcase_add_test (tc_chain, test_setting_video_encoder); + tcase_add_test (tc_chain, test_setting_video_muxer); return s; } -- 2.7.4