recorder: Port to GStreamer 1.0 API
GStreamer developers are currently finishing the 0.11 version, which will become 1.0. Port the screen recorder to the new API. https://bugzilla.gnome.org/show_bug.cgi?id=679445
This commit is contained in:
parent
2d913578e1
commit
460cda2aa1
@ -44,15 +44,15 @@ AC_SUBST(PYTHON)
|
|||||||
|
|
||||||
# We need at least this, since gst_plugin_register_static() was added
|
# 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.
|
# 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=
|
recorder_modules=
|
||||||
build_recorder=false
|
build_recorder=false
|
||||||
AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
|
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)
|
AC_MSG_RESULT(yes)
|
||||||
build_recorder=true
|
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_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
|
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes gl)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#define GST_USE_UNSTABLE_API
|
||||||
#include <gst/base/gstpushsrc.h>
|
#include <gst/base/gstpushsrc.h>
|
||||||
|
|
||||||
#include "shell-recorder-src.h"
|
#include "shell-recorder-src.h"
|
||||||
@ -85,18 +86,18 @@ shell_recorder_src_create (GstPushSrc *push_src,
|
|||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
if (src->closed)
|
if (src->closed)
|
||||||
return GST_FLOW_UNEXPECTED;
|
return GST_FLOW_EOS;
|
||||||
|
|
||||||
buffer = g_async_queue_pop (src->queue);
|
buffer = g_async_queue_pop (src->queue);
|
||||||
if (buffer == RECORDER_QUEUE_END)
|
if (buffer == RECORDER_QUEUE_END)
|
||||||
{
|
{
|
||||||
/* Returning UNEXPECTED here will cause a EOS message to be sent */
|
/* Returning UNEXPECTED here will cause a EOS message to be sent */
|
||||||
src->closed = TRUE;
|
src->closed = TRUE;
|
||||||
return GST_FLOW_UNEXPECTED;
|
return GST_FLOW_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
shell_recorder_src_update_memory_used (src,
|
shell_recorder_src_update_memory_used (src,
|
||||||
- (int)(GST_BUFFER_SIZE(buffer) / 1024));
|
- (int)(gst_buffer_get_size(buffer) / 1024));
|
||||||
|
|
||||||
*buffer_out = buffer;
|
*buffer_out = buffer;
|
||||||
|
|
||||||
@ -244,9 +245,9 @@ shell_recorder_src_add_buffer (ShellRecorderSrc *src,
|
|||||||
g_return_if_fail (SHELL_IS_RECORDER_SRC (src));
|
g_return_if_fail (SHELL_IS_RECORDER_SRC (src));
|
||||||
g_return_if_fail (src->caps != NULL);
|
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);
|
||||||
shell_recorder_src_update_memory_used (src,
|
shell_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));
|
g_async_queue_push (src->queue, gst_buffer_ref (buffer));
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define GST_USE_UNSTABLE_API
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include "shell-recorder-src.h"
|
#include "shell-recorder-src.h"
|
||||||
@ -434,6 +435,7 @@ static void
|
|||||||
recorder_draw_cursor (ShellRecorder *recorder,
|
recorder_draw_cursor (ShellRecorder *recorder,
|
||||||
GstBuffer *buffer)
|
GstBuffer *buffer)
|
||||||
{
|
{
|
||||||
|
GstMapInfo info;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
|
||||||
@ -452,7 +454,8 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
|||||||
if (!recorder->cursor_image)
|
if (!recorder->cursor_image)
|
||||||
return;
|
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,
|
CAIRO_FORMAT_ARGB32,
|
||||||
recorder->stage_width,
|
recorder->stage_width,
|
||||||
recorder->stage_height,
|
recorder->stage_height,
|
||||||
@ -467,6 +470,7 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
|||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
gst_buffer_unmap (buffer, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw an overlay indicating how much of the target memory is used
|
/* Draw an overlay indicating how much of the target memory is used
|
||||||
@ -551,10 +555,11 @@ recorder_record_frame (ShellRecorder *recorder)
|
|||||||
0, 0, recorder->stage_width, recorder->stage_height);
|
0, 0, recorder->stage_width, recorder->stage_height);
|
||||||
|
|
||||||
buffer = gst_buffer_new();
|
buffer = gst_buffer_new();
|
||||||
GST_BUFFER_SIZE(buffer) = size;
|
gst_buffer_insert_memory (buffer, -1,
|
||||||
GST_BUFFER_MALLOCDATA(buffer) = GST_BUFFER_DATA(buffer) = data;
|
gst_memory_new_wrapped (0, data, size, 0,
|
||||||
|
size, data, g_free));
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP(buffer) = now - recorder->start_time;
|
GST_BUFFER_PTS(buffer) = now - recorder->start_time;
|
||||||
|
|
||||||
recorder_draw_cursor (recorder, buffer);
|
recorder_draw_cursor (recorder, buffer);
|
||||||
|
|
||||||
@ -1046,23 +1051,18 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
|
|||||||
{
|
{
|
||||||
GstCaps *caps;
|
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
|
* doesn't support little-endian xRGB, but does support
|
||||||
* big-endian BGRx.
|
* big-endian BGRx.
|
||||||
*/
|
*/
|
||||||
caps = gst_caps_new_simple ("video/x-raw-rgb",
|
caps = gst_caps_new_simple ("video/x-raw",
|
||||||
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||||
|
"format", G_TYPE_STRING, "BGRx",
|
||||||
|
#else
|
||||||
|
"format", G_TYPE_STRING, "xRGB",
|
||||||
|
#endif
|
||||||
"bpp", G_TYPE_INT, 32,
|
"bpp", G_TYPE_INT, 32,
|
||||||
"depth", G_TYPE_INT, 24,
|
"depth", G_TYPE_INT, 24,
|
||||||
#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,
|
|
||||||
#else
|
|
||||||
"red_mask", G_TYPE_INT, 0xff0000,
|
|
||||||
"green_mask", G_TYPE_INT, 0x00ff00,
|
|
||||||
"blue_mask", G_TYPE_INT, 0x0000ff,
|
|
||||||
#endif
|
|
||||||
"endianness", G_TYPE_INT, G_BIG_ENDIAN,
|
|
||||||
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
||||||
"width", G_TYPE_INT, pipeline->recorder->stage_width,
|
"width", G_TYPE_INT, pipeline->recorder->stage_width,
|
||||||
"height", G_TYPE_INT, pipeline->recorder->stage_height,
|
"height", G_TYPE_INT, pipeline->recorder->stage_height,
|
||||||
@ -1080,7 +1080,7 @@ recorder_pipeline_add_source (RecorderPipeline *pipeline)
|
|||||||
{
|
{
|
||||||
GstPad *sink_pad = NULL, *src_pad = NULL;
|
GstPad *sink_pad = NULL, *src_pad = NULL;
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
GstElement *ffmpegcolorspace;
|
GstElement *videoconvert;
|
||||||
|
|
||||||
sink_pad = gst_bin_find_unlinked_pad (GST_BIN (pipeline->pipeline), GST_PAD_SINK);
|
sink_pad = gst_bin_find_unlinked_pad (GST_BIN (pipeline->pipeline), GST_PAD_SINK);
|
||||||
if (sink_pad == NULL)
|
if (sink_pad == NULL)
|
||||||
@ -1099,19 +1099,19 @@ recorder_pipeline_add_source (RecorderPipeline *pipeline)
|
|||||||
|
|
||||||
recorder_pipeline_set_caps (pipeline);
|
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
|
* our supplied fixed format data into whatever the encoder wants
|
||||||
*/
|
*/
|
||||||
ffmpegcolorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
|
videoconvert = gst_element_factory_make ("videoconvert", NULL);
|
||||||
if (!ffmpegcolorspace)
|
if (!videoconvert)
|
||||||
{
|
{
|
||||||
g_warning("Can't create ffmpegcolorspace element");
|
g_warning("Can't create videoconvert element");
|
||||||
goto out;
|
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);
|
gst_element_link_many (pipeline->src, videoconvert, NULL);
|
||||||
src_pad = gst_element_get_static_pad (ffmpegcolorspace, "src");
|
src_pad = gst_element_get_static_pad (videoconvert, "src");
|
||||||
|
|
||||||
if (!src_pad)
|
if (!src_pad)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
#define GST_USE_UNSTABLE_API
|
||||||
#include "shell-recorder.h"
|
#include "shell-recorder.h"
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user