[gnome-shell/gnome-3-8] shell-recorder: Support specifying the recorded area
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/gnome-3-8] shell-recorder: Support specifying the recorded area
- Date: Fri, 10 May 2013 17:52:23 +0000 (UTC)
commit 52dd030087806661bd927ecbc2657cf2a6a1d410
Author: Florian Müllner <fmuellner gnome org>
Date: Wed May 8 19:24:19 2013 +0200
shell-recorder: Support specifying the recorded area
Currently we will always record the entire screen. It has been requested
to support recording a specified area analogous to the screenshot API as
well, so add a set_area() method which allows this.
https://bugzilla.gnome.org/show_bug.cgi?id=696247
src/shell-recorder.c | 68 ++++++++++++++++++++++++++++++++++++++-----------
src/shell-recorder.h | 5 +++
2 files changed, 57 insertions(+), 16 deletions(-)
---
diff --git a/src/shell-recorder.c b/src/shell-recorder.c
index aaf585b..7c7fe85 100644
--- a/src/shell-recorder.c
+++ b/src/shell-recorder.c
@@ -50,6 +50,8 @@ struct _ShellRecorder {
RecorderState state;
ClutterStage *stage;
+ gboolean custom_area;
+ cairo_rectangle_int_t area;
int stage_width;
int stage_height;
@@ -429,10 +431,10 @@ recorder_draw_cursor (ShellRecorder *recorder,
/* We don't show a cursor unless the hot spot is in the frame; this
* means that sometimes we aren't going to draw a cursor even when
* there is a little bit overlapping within the stage */
- if (recorder->pointer_x < 0 ||
- recorder->pointer_y < 0 ||
- recorder->pointer_x >= recorder->stage_width ||
- recorder->pointer_y >= recorder->stage_height)
+ if (recorder->pointer_x < recorder->area.x ||
+ recorder->pointer_y < recorder->area.y ||
+ recorder->pointer_x >= recorder->area.x + recorder->area.width ||
+ recorder->pointer_y >= recorder->area.y + recorder->area.height)
return;
if (!recorder->cursor_image)
@@ -444,15 +446,15 @@ recorder_draw_cursor (ShellRecorder *recorder,
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,
- recorder->stage_width * 4);
+ recorder->area.width,
+ recorder->area.height,
+ recorder->area.width * 4);
cr = cairo_create (surface);
cairo_set_source_surface (cr,
recorder->cursor_image,
- recorder->pointer_x - recorder->cursor_hot_x,
- recorder->pointer_y - recorder->cursor_hot_y);
+ recorder->pointer_x - recorder->cursor_hot_x - recorder->area.x,
+ recorder->pointer_y - recorder->cursor_hot_y - recorder->area.y);
cairo_paint (cr);
cairo_destroy (cr);
@@ -555,12 +557,13 @@ recorder_record_frame (ShellRecorder *recorder)
recorder->last_frame_time = now;
- size = recorder->stage_width * recorder->stage_height * 4;
+ size = recorder->area.width * recorder->area.height * 4;
- data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
- cogl_read_pixels (0, 0, /* x/y */
- recorder->stage_width,
- recorder->stage_height,
+ data = g_malloc (recorder->area.width * 4 * recorder->area.height);
+ cogl_read_pixels (recorder->area.x,
+ recorder->area.y,
+ recorder->area.width,
+ recorder->area.height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
@@ -616,6 +619,14 @@ recorder_update_size (ShellRecorder *recorder)
clutter_actor_get_allocation_box (CLUTTER_ACTOR (recorder->stage), &allocation);
recorder->stage_width = (int)(0.5 + allocation.x2 - allocation.x1);
recorder->stage_height = (int)(0.5 + allocation.y2 - allocation.y1);
+
+ if (!recorder->custom_area)
+ {
+ recorder->area.x = 0;
+ recorder->area.y = 0;
+ recorder->area.width = recorder->stage_width;
+ recorder->area.height = recorder->stage_height;
+ }
}
static void
@@ -1126,8 +1137,8 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
"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,
+ "width", G_TYPE_INT, pipeline->recorder->area.width,
+ "height", G_TYPE_INT, pipeline->recorder->area.height,
NULL);
g_object_set (pipeline->src, "caps", caps, NULL);
gst_caps_unref (caps);
@@ -1705,6 +1716,31 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
recorder_set_pipeline (recorder, pipeline);
}
+void
+shell_recorder_set_area (ShellRecorder *recorder,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ g_return_if_fail (SHELL_IS_RECORDER (recorder));
+
+ recorder->custom_area = TRUE;
+ recorder->area.x = CLAMP (x, 0, recorder->stage_width);
+ recorder->area.y = CLAMP (y, 0, recorder->stage_height);
+ recorder->area.width = CLAMP (width,
+ 0, recorder->stage_width - recorder->area.x);
+ recorder->area.height = CLAMP (height,
+ 0, recorder->stage_height - recorder->area.y);
+
+ /* This breaks the recording but tweaking the GStreamer pipeline a bit
+ * might make it work, at least if the codec can handle a stream where
+ * the frame size changes in the middle.
+ */
+ if (recorder->current_pipeline)
+ recorder_pipeline_set_caps (recorder->current_pipeline);
+}
+
/**
* shell_recorder_record:
* @recorder: the #ShellRecorder
diff --git a/src/shell-recorder.h b/src/shell-recorder.h
index a94d59c..f2fb12e 100644
--- a/src/shell-recorder.h
+++ b/src/shell-recorder.h
@@ -36,6 +36,11 @@ void shell_recorder_set_file_template (ShellRecorder *recorder,
const char *file_template);
void shell_recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline);
+void shell_recorder_set_area (ShellRecorder *recorder,
+ int x,
+ int y,
+ int width,
+ int height);
gboolean shell_recorder_record (ShellRecorder *recorder,
char **filename_used);
void shell_recorder_close (ShellRecorder *recorder);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]