283 lines
9.7 KiB
Diff
283 lines
9.7 KiB
Diff
diff -ruN a/configure.ac b/configure.ac
|
|
--- a/configure.ac 2013-10-16 15:10:22.237511846 +0000
|
|
+++ b/configure.ac 2013-10-16 15:00:45.501321091 +0000
|
|
@@ -44,15 +44,15 @@
|
|
|
|
# We need at least this, since gst_plugin_register_static() was added
|
|
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
|
-GSTREAMER_MIN_VERSION=0.10.16
|
|
+GSTREAMER_MIN_VERSION=0.11.92
|
|
|
|
recorder_modules=
|
|
build_recorder=false
|
|
AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
|
|
-if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
|
|
+if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
|
|
AC_MSG_RESULT(yes)
|
|
build_recorder=true
|
|
- recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
|
|
+ recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11"
|
|
PKG_CHECK_MODULES(TEST_CINNAMON_RECORDER, $recorder_modules clutter-1.0 xfixes)
|
|
else
|
|
AC_MSG_RESULT(no)
|
|
diff -ruN a/src/cinnamon-recorder.c b/src/cinnamon-recorder.c
|
|
--- a/src/cinnamon-recorder.c 2013-10-16 15:10:22.344177808 +0000
|
|
+++ b/src/cinnamon-recorder.c 2013-10-16 15:26:42.801040167 +0000
|
|
@@ -8,6 +8,7 @@
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
+#define GST_USE_UNSTABLE_API
|
|
#include <gst/gst.h>
|
|
|
|
#include "cinnamon-recorder-src.h"
|
|
@@ -147,7 +148,7 @@
|
|
* (Theora does have some support for frames at non-uniform times, but
|
|
* things seem to break down if there are large gaps.)
|
|
*/
|
|
-#define DEFAULT_PIPELINE "videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux"
|
|
+#define DEFAULT_PIPELINE "vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! queue ! webmmux"
|
|
|
|
/* The default filename pattern. Example cinnamon-20090311b-2.webm
|
|
*/
|
|
@@ -446,6 +447,7 @@
|
|
recorder_draw_cursor (CinnamonRecorder *recorder,
|
|
GstBuffer *buffer)
|
|
{
|
|
+ GstMapInfo info;
|
|
cairo_surface_t *surface;
|
|
cairo_t *cr;
|
|
|
|
@@ -464,7 +466,8 @@
|
|
if (!recorder->cursor_image)
|
|
return;
|
|
|
|
- surface = cairo_image_surface_create_for_data (GST_BUFFER_DATA(buffer),
|
|
+ gst_buffer_map (buffer, &info, GST_MAP_WRITE);
|
|
+ surface = cairo_image_surface_create_for_data (info.data,
|
|
CAIRO_FORMAT_ARGB32,
|
|
recorder->stage_width,
|
|
recorder->stage_height,
|
|
@@ -479,6 +482,7 @@
|
|
|
|
cairo_destroy (cr);
|
|
cairo_surface_destroy (surface);
|
|
+ gst_buffer_unmap (buffer, &info);
|
|
}
|
|
|
|
/* Draw an overlay indicating how much of the target memory is used
|
|
@@ -541,10 +545,11 @@
|
|
data = g_malloc (size);
|
|
|
|
buffer = gst_buffer_new();
|
|
- GST_BUFFER_SIZE(buffer) = size;
|
|
- GST_BUFFER_MALLOCDATA(buffer) = GST_BUFFER_DATA(buffer) = data;
|
|
+ gst_buffer_insert_memory (buffer, -1,
|
|
+ gst_memory_new_wrapped (0, data, size, 0,
|
|
+ size, data, g_free));
|
|
|
|
- GST_BUFFER_TIMESTAMP(buffer) = get_wall_time() - recorder->start_time;
|
|
+ GST_BUFFER_PTS(buffer) = get_wall_time() - recorder->start_time;
|
|
|
|
cogl_read_pixels (0, 0,
|
|
recorder->stage_width, recorder->stage_height,
|
|
@@ -1042,23 +1047,18 @@
|
|
{
|
|
GstCaps *caps;
|
|
|
|
- /* The data is always native-endian xRGB; ffmpegcolorspace
|
|
+ /* The data is always native-endian xRGB; videoconvert
|
|
* doesn't support little-endian xRGB, but does support
|
|
* big-endian BGRx.
|
|
*/
|
|
- caps = gst_caps_new_simple ("video/x-raw-rgb",
|
|
- "bpp", G_TYPE_INT, 32,
|
|
- "depth", G_TYPE_INT, 24,
|
|
+ caps = gst_caps_new_simple ("video/x-raw",
|
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
- "red_mask", G_TYPE_INT, 0x0000ff00,
|
|
- "green_mask", G_TYPE_INT, 0x00ff0000,
|
|
- "blue_mask", G_TYPE_INT, 0xff000000,
|
|
+ "format", G_TYPE_STRING, "BGRx",
|
|
#else
|
|
- "red_mask", G_TYPE_INT, 0xff0000,
|
|
- "green_mask", G_TYPE_INT, 0x00ff00,
|
|
- "blue_mask", G_TYPE_INT, 0x0000ff,
|
|
+ "format", G_TYPE_STRING, "xRGB",
|
|
#endif
|
|
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
|
|
+ "bpp", G_TYPE_INT, 32,
|
|
+ "depth", G_TYPE_INT, 24,
|
|
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
|
"width", G_TYPE_INT, pipeline->recorder->stage_width,
|
|
"height", G_TYPE_INT, pipeline->recorder->stage_height,
|
|
@@ -1076,7 +1076,7 @@
|
|
{
|
|
GstPad *sink_pad = NULL, *src_pad = NULL;
|
|
gboolean result = FALSE;
|
|
- GstElement *ffmpegcolorspace;
|
|
+ GstElement *videoconvert;
|
|
|
|
sink_pad = gst_bin_find_unlinked_pad (GST_BIN (pipeline->pipeline), GST_PAD_SINK);
|
|
if (sink_pad == NULL)
|
|
@@ -1095,19 +1095,19 @@
|
|
|
|
recorder_pipeline_set_caps (pipeline);
|
|
|
|
- /* The ffmpegcolorspace element is a generic converter; it will convert
|
|
+ /* The videoconvert element is a generic converter; it will convert
|
|
* our supplied fixed format data into whatever the encoder wants
|
|
*/
|
|
- ffmpegcolorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
|
|
- if (!ffmpegcolorspace)
|
|
+ videoconvert = gst_element_factory_make ("videoconvert", NULL);
|
|
+ if (!videoconvert)
|
|
{
|
|
- g_warning("Can't create ffmpegcolorspace element");
|
|
+ g_warning("Can't create videoconvert element");
|
|
goto out;
|
|
}
|
|
- gst_bin_add (GST_BIN (pipeline->pipeline), ffmpegcolorspace);
|
|
+ gst_bin_add (GST_BIN (pipeline->pipeline), videoconvert);
|
|
|
|
- gst_element_link_many (pipeline->src, ffmpegcolorspace, NULL);
|
|
- src_pad = gst_element_get_static_pad (ffmpegcolorspace, "src");
|
|
+ gst_element_link_many (pipeline->src, videoconvert, NULL);
|
|
+ src_pad = gst_element_get_static_pad (videoconvert, "src");
|
|
|
|
if (!src_pad)
|
|
{
|
|
@@ -1637,7 +1637,7 @@
|
|
* might be used to send the output to an icecast server
|
|
* via shout2send or similar.
|
|
*
|
|
- * The default value is 'videorate ! theoraenc ! oggmux'
|
|
+ * The default value is 'vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! queue ! webmmux'
|
|
*/
|
|
void
|
|
cinnamon_recorder_set_pipeline (CinnamonRecorder *recorder,
|
|
diff -ruN a/src/cinnamon-recorder-src.c b/src/cinnamon-recorder-src.c
|
|
--- a/src/cinnamon-recorder-src.c 2013-10-16 15:10:22.347511119 +0000
|
|
+++ b/src/cinnamon-recorder-src.c 2013-10-16 15:33:41.581609206 +0000
|
|
@@ -2,6 +2,7 @@
|
|
|
|
#include "config.h"
|
|
|
|
+#define GST_USE_UNSTABLE_API
|
|
#include <gst/base/gstpushsrc.h>
|
|
|
|
#include "cinnamon-recorder-src.h"
|
|
@@ -12,6 +13,9 @@
|
|
|
|
GMutex *mutex;
|
|
|
|
+ GstClock *clock;
|
|
+ GstClockTime last_frame_time;
|
|
+
|
|
GstCaps *caps;
|
|
GAsyncQueue *queue;
|
|
gboolean closed;
|
|
@@ -33,21 +37,21 @@
|
|
/* Special marker value once the source is closed */
|
|
#define RECORDER_QUEUE_END ((GstBuffer *)1)
|
|
|
|
-GST_BOILERPLATE(CinnamonRecorderSrc, cinnamon_recorder_src, GstPushSrc, GST_TYPE_PUSH_SRC);
|
|
+G_DEFINE_TYPE(CinnamonRecorderSrc, cinnamon_recorder_src, GST_TYPE_PUSH_SRC);
|
|
|
|
static void
|
|
-cinnamon_recorder_src_init (CinnamonRecorderSrc *src,
|
|
- CinnamonRecorderSrcClass *klass)
|
|
+cinnamon_recorder_src_init (CinnamonRecorderSrc *src)
|
|
{
|
|
+ gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
|
+ gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
|
+
|
|
+ src->clock = gst_system_clock_obtain ();
|
|
+ src->last_frame_time = 0;
|
|
+
|
|
src->queue = g_async_queue_new ();
|
|
src->mutex = g_mutex_new ();
|
|
}
|
|
|
|
-static void
|
|
-cinnamon_recorder_src_base_init (gpointer klass)
|
|
-{
|
|
-}
|
|
-
|
|
static gboolean
|
|
cinnamon_recorder_src_memory_used_update_idle (gpointer data)
|
|
{
|
|
@@ -87,21 +91,28 @@
|
|
GstBuffer *buffer;
|
|
|
|
if (src->closed)
|
|
- return GST_FLOW_UNEXPECTED;
|
|
+ return GST_FLOW_EOS;
|
|
|
|
buffer = g_async_queue_pop (src->queue);
|
|
+ if (src->last_frame_time == 0)
|
|
+ src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
|
|
+
|
|
if (buffer == RECORDER_QUEUE_END)
|
|
{
|
|
/* Returning UNEXPECTED here will cause a EOS message to be sent */
|
|
src->closed = TRUE;
|
|
- return GST_FLOW_UNEXPECTED;
|
|
+ return GST_FLOW_EOS;
|
|
}
|
|
|
|
cinnamon_recorder_src_update_memory_used (src,
|
|
- - (int)(GST_BUFFER_SIZE(buffer) / 1024));
|
|
+ - (int)(gst_buffer_get_size(buffer) / 1024));
|
|
|
|
*buffer_out = buffer;
|
|
|
|
+ GST_BUFFER_DURATION(*buffer_out) = GST_CLOCK_DIFF (src->last_frame_time, gst_clock_get_time (GST_CLOCK (src->clock)));
|
|
+
|
|
+ src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
|
|
+
|
|
return GST_FLOW_OK;
|
|
}
|
|
|
|
@@ -142,7 +153,9 @@
|
|
|
|
g_mutex_free (src->mutex);
|
|
|
|
- G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
+ gst_object_unref (src->clock);
|
|
+
|
|
+ G_OBJECT_CLASS (cinnamon_recorder_src_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
@@ -246,9 +259,9 @@
|
|
g_return_if_fail (CINNAMON_IS_RECORDER_SRC (src));
|
|
g_return_if_fail (src->caps != NULL);
|
|
|
|
- gst_buffer_set_caps (buffer, src->caps);
|
|
+ gst_base_src_set_caps (GST_BASE_SRC (src), src->caps);
|
|
cinnamon_recorder_src_update_memory_used (src,
|
|
- (int) (GST_BUFFER_SIZE(buffer) / 1024));
|
|
+ (int)(gst_buffer_get_size(buffer) / 1024));
|
|
|
|
g_async_queue_push (src->queue, gst_buffer_ref (buffer));
|
|
}
|
|
diff -ruN a/src/test-recorder.c b/src/test-recorder.c
|
|
--- a/src/test-recorder.c 2013-10-16 15:10:22.240845159 +0000
|
|
+++ b/src/test-recorder.c 2013-10-16 15:48:03.685915756 +0000
|
|
@@ -1,5 +1,6 @@
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
+#define GST_USE_UNSTABLE_API
|
|
#include "cinnamon-recorder.h"
|
|
#include <clutter/clutter.h>
|
|
#include <gst/gst.h>
|
|
@@ -29,7 +30,6 @@
|
|
ClutterAnimation *animation;
|
|
ClutterColor red, green, blue;
|
|
|
|
- g_thread_init (NULL);
|
|
gst_init (&argc, &argv);
|
|
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
|
|
return 1;
|