[longomatch/camera_capturer: 2/3] WIP
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch/camera_capturer: 2/3] WIP
- Date: Wed, 3 Oct 2012 00:23:38 +0000 (UTC)
commit 585465576c5552e74dbc2f337a6411ff5a8598d6
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Wed Oct 3 01:45:27 2012 +0200
WIP
libcesarplayer/common.h | 7 +
libcesarplayer/gst-camera-capturer.c | 215 +++++++++++++++++++++-------------
libcesarplayer/gst-camera-capturer.h | 14 +--
libcesarplayer/main.c | 11 ++-
4 files changed, 151 insertions(+), 96 deletions(-)
---
diff --git a/libcesarplayer/common.h b/libcesarplayer/common.h
index de7999b..4c9ada2 100644
--- a/libcesarplayer/common.h
+++ b/libcesarplayer/common.h
@@ -134,4 +134,11 @@ typedef enum
VIDEO_MUXER_WEBM
} VideoMuxerType;
+typedef enum
+{
+ CAPTURE_SOURCE_TYPE_NONE = 0,
+ CAPTURE_SOURCE_TYPE_DV = 1,
+ CAPTURE_SOURCE_TYPE_SYSTEM = 2,
+} CaptureSourceType;
+
#endif
diff --git a/libcesarplayer/gst-camera-capturer.c b/libcesarplayer/gst-camera-capturer.c
index 823781e..5d07bed 100644
--- a/libcesarplayer/gst-camera-capturer.c
+++ b/libcesarplayer/gst-camera-capturer.c
@@ -87,7 +87,7 @@ struct GstCameraCapturerPrivate
VideoEncoderType video_encoder_type;
AudioEncoderType audio_encoder_type;
VideoMuxerType video_muxer_type;
- GstCameraCaptureSourceType source_type;
+ CaptureSourceType source_type;
/*Video input info */
gint video_width; /* Movie width */
@@ -162,8 +162,8 @@ static void gst_camera_capturer_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec);
static void gcc_element_msg_sync (GstBus * bus, GstMessage * msg,
gpointer data);
-static void gcc_update_interface_implementations (GstCameraCapturer * gcc);
static int gcc_get_video_stream_info (GstCameraCapturer * gcc);
+static void gcc_get_xoverlay (GstCameraCapturer * gcc);
G_DEFINE_TYPE (GstCameraCapturer, gst_camera_capturer, GTK_TYPE_EVENT_BOX);
@@ -481,7 +481,7 @@ gst_camera_capturer_expose_event (GtkWidget * widget, GdkEventExpose * event)
g_mutex_lock (gcc->priv->lock);
xoverlay = gcc->priv->xoverlay;
if (xoverlay == NULL && gcc->priv->preview_bin != NULL) {
- gcc_update_interface_implementations (gcc);
+ gcc_get_xoverlay (gcc);
resize_video_window (gcc);
xoverlay = gcc->priv->xoverlay;
}
@@ -606,6 +606,11 @@ gst_camera_capturer_init (GstCameraCapturer * object)
priv->is_recording = FALSE;
priv->recording_lock = g_mutex_new();
+ priv->video_encoder_type = VIDEO_ENCODER_VP8;
+ priv->audio_encoder_type = AUDIO_ENCODER_VORBIS;
+ priv->video_muxer_type = VIDEO_MUXER_WEBM;
+ priv->source_type = CAPTURE_SOURCE_TYPE_SYSTEM;
+
priv->lock = g_mutex_new ();
}
@@ -669,12 +674,6 @@ static void
gst_camera_capturer_set_video_bit_rate (GstCameraCapturer * gcc, gint bitrate)
{
gcc->priv->video_bitrate = bitrate;
- if (gcc->priv->video_encoder_type == VIDEO_ENCODER_MPEG4 ||
- gcc->priv->video_encoder_type == VIDEO_ENCODER_XVID)
- g_object_set (gcc->priv->video_enc, "bitrate", bitrate * 1000, NULL);
- else
- g_object_set (gcc->priv->video_enc, "bitrate", gcc->priv->video_bitrate,
- NULL);
GST_INFO_OBJECT (gcc, "Changed video bitrate to: %d",
gcc->priv->video_bitrate);
}
@@ -684,13 +683,8 @@ gst_camera_capturer_set_audio_bit_rate (GstCameraCapturer * gcc, gint bitrate)
{
gcc->priv->audio_bitrate = bitrate;
- if (gcc->priv->audio_encoder_type == AUDIO_ENCODER_MP3)
- g_object_set (gcc->priv->audio_enc, "bitrate", bitrate, NULL);
- else
- g_object_set (gcc->priv->audio_enc, "bitrate", 1000 * bitrate, NULL);
GST_INFO_OBJECT (gcc, "Changed audio bitrate to: %d",
gcc->priv->audio_bitrate);
-
}
static void
@@ -713,16 +707,7 @@ static void
gst_camera_capturer_set_device_id (GstCameraCapturer * gcc,
const gchar * device_id)
{
- gchar *prop_name;
-
gcc->priv->device_id = g_strdup (device_id);
- if (!g_strcmp0 (gcc->priv->source_element_name, "dv1394src"))
- prop_name = "guid";
- else if (!g_strcmp0 (gcc->priv->source_element_name, "v4l2src"))
- prop_name = "device";
- else
- prop_name = "device-name";
- g_object_set(gcc->priv->source, prop_name, gcc->priv->device_id, NULL);
GST_INFO_OBJECT (gcc, "Changed device id/name to: %s", gcc->priv->device_id);
}
@@ -913,7 +898,15 @@ gst_camera_capture_videosrc_buffer_probe (GstPad * pad, GstBuffer * buf,
static void
gst_camera_capturer_update_device_id (GstCameraCapturer *gcc)
{
- /*FIXME */
+ gchar *prop_name;
+
+ if (!g_strcmp0 (gcc->priv->source_element_name, "dv1394src"))
+ prop_name = "guid";
+ else if (!g_strcmp0 (gcc->priv->source_element_name, "v4l2src"))
+ prop_name = "device";
+ else
+ prop_name = "device-name";
+ g_object_set(gcc->priv->source, prop_name, gcc->priv->device_id, NULL);
}
static void
@@ -945,7 +938,7 @@ cb_new_pad (GstElement * element, GstPad * pad, GstCameraCapturer *gcc)
static void
gst_camera_capturer_create_encoder_bin (GstCameraCapturer *gcc)
{
- GstElement *colorspace, *videoscale, *videorate;
+ GstElement *colorspace, *videoscale;//, *videorate;
GstCaps *caps;
GstPad *v_sink_pad;
gchar *caps_str;
@@ -955,7 +948,7 @@ gst_camera_capturer_create_encoder_bin (GstCameraCapturer *gcc)
colorspace = gst_element_factory_make("ffmpegcolorspace", NULL);
videoscale = gst_element_factory_make("videoscale", NULL);
- videorate = gst_element_factory_make("videorate", NULL);
+ //videorate = gst_element_factory_make("videorate", NULL);
gcc->priv->video_filter = gst_element_factory_make("capsfilter", NULL);
gcc->priv->filesink = gst_element_factory_make("filesink", NULL);
@@ -967,13 +960,13 @@ gst_camera_capturer_create_encoder_bin (GstCameraCapturer *gcc)
gst_caps_unref(caps);
g_free(caps_str);
- g_object_set(videorate, "skip-to-first", TRUE, NULL);
+ //g_object_set(videorate, "skip-to-first", TRUE, NULL);
- gst_bin_add_many(GST_BIN(gcc->priv->encoder_bin), videoscale, videorate,
+ gst_bin_add_many(GST_BIN(gcc->priv->encoder_bin), videoscale, //videorate,
colorspace, gcc->priv->video_filter, gcc->priv->video_enc,
gcc->priv->muxer, gcc->priv->filesink, NULL);
- gst_element_link_many(videoscale, videorate, colorspace, gcc->priv->video_filter,
+ gst_element_link_many(videoscale, /* videorate, */ colorspace, gcc->priv->video_filter,
gcc->priv->video_enc, gcc->priv->muxer, NULL);
gst_element_link(gcc->priv->muxer, gcc->priv->filesink);
@@ -1228,6 +1221,7 @@ gst_camera_capturer_encoding_retimestamper (GstCameraCapturer *gcc,
/* Clip buffers that are not in the segment */
if (buf_ts < gcc->priv->current_recording_start_ts) {
+ GST_WARNING_OBJECT (gcc, "Discarding buffer out of segment");
ret = FALSE;
goto done;
}
@@ -1258,8 +1252,8 @@ gst_camera_capturer_encoding_retimestamper (GstCameraCapturer *gcc,
/* We don't want to overwrite timestamps of the preview branch */
buf = gst_buffer_make_metadata_writable(buf);
+ GST_BUFFER_TIMESTAMP (buf) = new_buf_ts;
data = (GstMiniObject*) buf;
- GST_BUFFER_TIMESTAMP(buf) = new_buf_ts;
GST_LOG_OBJECT(gcc, "Pushing %s frame to the encoder in ts:% " GST_TIME_FORMAT
" out ts: %" GST_TIME_FORMAT, is_video ? "video": "audio",
@@ -1548,7 +1542,7 @@ gst_camera_capturer_have_type_cb (GstElement *typefind, guint prob,
static gboolean
gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
- GstCameraCaptureSourceType type, GError ** err)
+ CaptureSourceType type, GError ** err)
{
GstElement *typefind;
const gchar *source_desc = "";
@@ -1558,12 +1552,12 @@ gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
g_return_val_if_fail (GST_IS_CAMERA_CAPTURER (gcc), FALSE);
switch (type) {
- case GST_CAMERA_CAPTURE_SOURCE_TYPE_DV:
+ case CAPTURE_SOURCE_TYPE_DV:
GST_INFO_OBJECT(gcc, "Creating dv video source");
source_desc = DVVIDEOSRC;
gcc->priv->source_element_name = source_desc;
break;
- case GST_CAMERA_CAPTURE_SOURCE_TYPE_SYSTEM:
+ case CAPTURE_SOURCE_TYPE_SYSTEM:
GST_INFO_OBJECT(gcc, "Creating system video source");
source_desc = SYSVIDEOSRC;
gcc->priv->source_element_name = source_desc;
@@ -1584,8 +1578,8 @@ gst_camera_capturer_create_video_source (GstCameraCapturer * gcc,
"Please check your GStreamer installation.", source_desc);
return FALSE;
}
- gcc->priv->source_type = type;
+ gcc->priv->source = gst_bin_get_by_name (GST_BIN(gcc->priv->source_bin), "source");
typefind = gst_bin_get_by_name (GST_BIN(gcc->priv->source_bin), "typefind");
g_signal_connect (typefind, "have-type",
G_CALLBACK (gst_camera_capturer_have_type_cb), gcc);
@@ -1658,6 +1652,13 @@ gst_camera_capturer_create_video_encoder (GstCameraCapturer * gcc,
return FALSE;
}
+ if (gcc->priv->video_encoder_type == VIDEO_ENCODER_MPEG4 ||
+ gcc->priv->video_encoder_type == VIDEO_ENCODER_XVID)
+ g_object_set (gcc->priv->video_enc, "bitrate", gcc->priv->video_bitrate * 1000, NULL);
+ else
+ g_object_set (gcc->priv->video_enc, "bitrate", gcc->priv->video_bitrate,
+ NULL);
+
GST_INFO_OBJECT(gcc, "Video encoder %s created", name);
gcc->priv->video_encoder_type = type;
return TRUE;
@@ -1702,7 +1703,13 @@ gst_camera_capturer_create_audio_encoder (GstCameraCapturer * gcc,
return FALSE;
}
+ if (gcc->priv->audio_encoder_type == AUDIO_ENCODER_MP3)
+ g_object_set (gcc->priv->audio_enc, "bitrate", gcc->priv->audio_bitrate, NULL);
+ else
+ g_object_set (gcc->priv->audio_enc, "bitrate", 1000 * gcc->priv->audio_bitrate, NULL);
+
GST_INFO_OBJECT(gcc, "Audio encoder %s created", name);
+
gcc->priv->audio_encoder_type = type;
return TRUE;
}
@@ -1755,6 +1762,54 @@ gst_camera_capturer_create_video_muxer (GstCameraCapturer * gcc,
}
static void
+gst_camera_capturer_initialize (GstCameraCapturer *gcc)
+{
+ GError *err= NULL;
+
+ GST_INFO_OBJECT (gcc, "Initializing encoders");
+ if (!gst_camera_capturer_create_video_encoder(gcc,
+ gcc->priv->video_encoder_type, &err))
+ goto missing_plugin;
+ if (!gst_camera_capturer_create_audio_encoder(gcc,
+ gcc->priv->audio_encoder_type, &err))
+ goto missing_plugin;
+ if (!gst_camera_capturer_create_video_muxer(gcc,
+ gcc->priv->video_muxer_type, &err))
+ goto missing_plugin;
+
+ GST_INFO_OBJECT (gcc, "Initializing source");
+ if (!gst_camera_capturer_create_video_source(gcc,
+ gcc->priv->source_type, &err))
+ goto missing_plugin;
+
+ /* add the source element */
+ gst_bin_add(GST_BIN(gcc->priv->main_pipeline), gcc->priv->source_bin);
+ return;
+
+missing_plugin:
+ g_signal_emit (gcc, gcc_signals[SIGNAL_ERROR], 0, err->message);
+ g_error_free (err);
+}
+
+static void
+gcc_encoder_send_event (GstCameraCapturer *gcc, GstEvent *event)
+{
+ GstPad *video_pad, *audio_pad;
+
+ if (gcc->priv->audio_enabled) {
+ gst_event_ref(event);
+ audio_pad = gst_element_get_static_pad(gcc->priv->encoder_bin, "audio");
+ gst_pad_send_event(audio_pad, event);
+ gst_object_unref(audio_pad);
+ }
+
+ video_pad = gst_element_get_static_pad(gcc->priv->encoder_bin, "video");
+ gst_pad_send_event(video_pad, event);
+ gst_object_unref(video_pad);
+
+}
+
+static void
gcc_bus_message_cb (GstBus * bus, GstMessage * message, gpointer data)
{
GstCameraCapturer *gcc = (GstCameraCapturer *) data;
@@ -1867,32 +1922,12 @@ gcc_error_msg (GstCameraCapturer * gcc, GstMessage * msg)
g_free (dbg);
}
-static gboolean
-gcc_update_interfaces_delayed (GstCameraCapturer * gcc)
-{
- GST_DEBUG_OBJECT (gcc, "Delayed updating interface implementations");
- g_mutex_lock (gcc->priv->lock);
- gcc_update_interface_implementations (gcc);
- gcc->priv->interface_update_id = 0;
- g_mutex_unlock (gcc->priv->lock);
-
- return FALSE;
-}
-
static void
-gcc_update_interface_implementations (GstCameraCapturer * gcc)
+gcc_get_xoverlay (GstCameraCapturer * gcc)
{
GstElement *element = NULL;
- if (g_thread_self () != gui_thread) {
- if (gcc->priv->interface_update_id)
- g_source_remove (gcc->priv->interface_update_id);
- gcc->priv->interface_update_id =
- g_idle_add ((GSourceFunc) gcc_update_interfaces_delayed, gcc);
- return;
- }
-
GST_DEBUG_OBJECT (gcc, "Retrieving xoverlay from bin ...");
element = gst_bin_get_by_interface (GST_BIN (gcc->priv->preview_bin),
GST_TYPE_X_OVERLAY);
@@ -1918,7 +1953,7 @@ gcc_element_msg_sync (GstBus * bus, GstMessage * msg, gpointer data)
* chance to set it before the video sink will create its own window */
if (gst_structure_has_name (msg->structure, "prepare-xwindow-id")) {
g_mutex_lock (gcc->priv->lock);
- gcc_update_interface_implementations (gcc);
+ gcc_get_xoverlay (gcc);
g_mutex_unlock (gcc->priv->lock);
if (gcc->priv->xoverlay == NULL) {
@@ -1941,7 +1976,7 @@ gcc_get_video_stream_info (GstCameraCapturer * gcc)
GstCaps *caps;
GstStructure *s;
- sourcepad = gst_element_get_pad (gcc->priv->source, "src");
+ sourcepad = gst_element_get_pad (gcc->priv->source_bin, "src");
caps = gst_pad_get_negotiated_caps (sourcepad);
if (!(caps)) {
@@ -2043,6 +2078,7 @@ gst_camera_capturer_run (GstCameraCapturer * gcc)
g_return_if_fail (gcc != NULL);
g_return_if_fail (GST_IS_CAMERA_CAPTURER (gcc));
+ gst_camera_capturer_initialize (gcc);
gst_element_set_state (gcc->priv->main_pipeline, GST_STATE_PLAYING);
}
@@ -2090,6 +2126,42 @@ gst_camera_capturer_toggle_pause (GstCameraCapturer * gcc)
GST_INFO_OBJECT(gcc, "Capture state changed to %s", gcc->priv->is_recording ? "recording": "paused");
}
+void
+gst_camera_capturer_set_source (GstCameraCapturer * gcc, CaptureSourceType source)
+{
+ g_return_if_fail (gcc != NULL);
+ g_return_if_fail (GST_IS_CAMERA_CAPTURER (gcc));
+
+ gcc->priv->source_type = source;
+}
+
+void
+gst_camera_capturer_set_video_encoder (GstCameraCapturer * gcc, VideoEncoderType encoder)
+{
+ g_return_if_fail (gcc != NULL);
+ g_return_if_fail (GST_IS_CAMERA_CAPTURER (gcc));
+
+ gcc->priv->video_encoder_type = encoder;
+}
+
+void
+gst_camera_capturer_set_audio_encoder (GstCameraCapturer * gcc, AudioEncoderType encoder)
+{
+ g_return_if_fail (gcc != NULL);
+ g_return_if_fail (GST_IS_CAMERA_CAPTURER (gcc));
+
+ gcc->priv->audio_encoder_type = encoder;
+}
+
+void
+gst_camera_capturer_set_video_muxer (GstCameraCapturer * gcc, VideoMuxerType muxer)
+{
+ g_return_if_fail (gcc != NULL);
+ g_return_if_fail (GST_IS_CAMERA_CAPTURER (gcc));
+
+ gcc->priv->video_muxer_type = muxer;
+}
+
gboolean
gst_camera_capturer_can_get_frames (GstCameraCapturer * gcc, GError ** error)
{
@@ -2241,22 +2313,11 @@ gst_camera_capturer_stop (GstCameraCapturer * gcc)
gcc->priv->closing_recording = TRUE;
g_mutex_unlock(gcc->priv->recording_lock);
- video_pad = gst_element_get_static_pad(gcc->priv->encoder_bin, "video");
- gst_pad_send_event(video_pad, gst_event_new_eos());
- gst_object_unref(video_pad);
-
- if (gcc->priv->audio_enabled) {
- GstPad *audio_pad;
-
- audio_pad = gst_element_get_static_pad(gcc->priv->encoder_bin, "audio");
- gst_pad_send_event(audio_pad, gst_event_new_eos());
- gst_object_unref(audio_pad);
- }
+ gcc_encoder_send_event(gcc, gst_event_new_eos());
}
GstCameraCapturer *
-gst_camera_capturer_new (gchar * filename, GstCameraCaptureSourceType source,
- VideoEncoderType venc, AudioEncoderType aenc, VideoMuxerType muxer, GError ** err)
+gst_camera_capturer_new (gchar * filename, GError ** err)
{
GstCameraCapturer *gcc = NULL;
@@ -2280,20 +2341,6 @@ gst_camera_capturer_new (gchar * filename, GstCameraCaptureSourceType source,
goto missing_plugin;
}
- /* Setup */
- GST_INFO_OBJECT (gcc, "Initializing encoders");
- if (!gst_camera_capturer_create_video_encoder(gcc, venc, err))
- goto missing_plugin;
- if (!gst_camera_capturer_create_audio_encoder(gcc, aenc, err))
- goto missing_plugin;
- if (!gst_camera_capturer_create_video_muxer(gcc, muxer, err))
- goto missing_plugin;
- if (!gst_camera_capturer_create_video_source(gcc, source, err))
- goto missing_plugin;
-
- /* add the source element */
- gst_bin_add(GST_BIN(gcc->priv->main_pipeline), gcc->priv->source_bin);
-
/* assume we're always called from the main Gtk+ GUI thread */
gui_thread = g_thread_self ();
diff --git a/libcesarplayer/gst-camera-capturer.h b/libcesarplayer/gst-camera-capturer.h
index c1227e3..b2ca89f 100644
--- a/libcesarplayer/gst-camera-capturer.h
+++ b/libcesarplayer/gst-camera-capturer.h
@@ -64,25 +64,21 @@ struct _GstCameraCapturer
GstCameraCapturerPrivate *priv;
};
-typedef enum
-{
- GST_CAMERA_CAPTURE_SOURCE_TYPE_NONE = 0,
- GST_CAMERA_CAPTURE_SOURCE_TYPE_DV = 1,
- GST_CAMERA_CAPTURE_SOURCE_TYPE_SYSTEM = 2,
-} GstCameraCaptureSourceType;
-
EXPORT GType
gst_camera_capturer_get_type (void)
G_GNUC_CONST;
void gst_camera_capturer_init_backend (int *argc, char ***argv);
-GstCameraCapturer *gst_camera_capturer_new (gchar * filename, GstCameraCaptureSourceType source,
- VideoEncoderType venc, AudioEncoderType aenc, VideoMuxerType muxer, GError ** err);
+GstCameraCapturer *gst_camera_capturer_new (gchar *filename, GError ** err);
void gst_camera_capturer_run (GstCameraCapturer * gcc);
void gst_camera_capturer_close (GstCameraCapturer * gcc);
void gst_camera_capturer_start (GstCameraCapturer * gcc);
void gst_camera_capturer_toggle_pause (GstCameraCapturer * gcc);
void gst_camera_capturer_stop (GstCameraCapturer * gcc);
+void gst_camera_capturer_set_source (GstCameraCapturer * gcc, CaptureSourceType source);
+void gst_camera_capturer_set_video_encoder (GstCameraCapturer * gcc, VideoEncoderType encoder);
+void gst_camera_capturer_set_audio_encoder (GstCameraCapturer * gcc, AudioEncoderType encoder);
+void gst_camera_capturer_set_video_muxer (GstCameraCapturer * gcc, VideoMuxerType muxer);
GList *gst_camera_capturer_enum_audio_devices (void);
GList *gst_camera_capturer_enum_video_devices (void);
GdkPixbuf *gst_camera_capturer_get_current_frame (GstCameraCapturer
diff --git a/libcesarplayer/main.c b/libcesarplayer/main.c
index 0f1dad6..ff51aab 100644
--- a/libcesarplayer/main.c
+++ b/libcesarplayer/main.c
@@ -39,10 +39,10 @@ window_state_event (GtkWidget * widget, GdkEventWindowState * event,
}
if (i == 5)
- gst_camera_capturer_stop (GST_CAMERA_CAPTURER (gvc));
- if (i == 6)
gst_camera_capturer_toggle_pause (GST_CAMERA_CAPTURER (gvc));
if (i == 7)
+ gst_camera_capturer_toggle_pause (GST_CAMERA_CAPTURER (gvc));
+ if (i == 9)
gst_camera_capturer_stop (GST_CAMERA_CAPTURER (gvc));
return TRUE;
}
@@ -77,7 +77,12 @@ main (int argc, char *argv[])
/*Create GstVideoCapturer */
gst_camera_capturer_init_backend (&argc, &argv);
- gvc = gst_camera_capturer_new ("test", 2, 3, 1, 1, &error);
+ gvc = gst_camera_capturer_new ("test", &error);
+
+ gst_camera_capturer_set_source (gvc, CAPTURE_SOURCE_TYPE_SYSTEM);
+ gst_camera_capturer_set_video_encoder (gvc, VIDEO_ENCODER_H264);
+ gst_camera_capturer_set_audio_encoder (gvc, AUDIO_ENCODER_AAC);
+ gst_camera_capturer_set_video_muxer (gvc, VIDEO_MUXER_MP4);
g_object_set (gvc, "output_file", "/home/andoni/jander.avi", NULL);
window = create_window (gvc);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]