On Sun, Jul 31, 2011 at 14:25, Anton Khirnov <[email protected]> wrote:
>
> On Sun, 31 Jul 2011 14:06:02 +0800, Yu-Jie Lin <[email protected]> wrote:
>> "-show_region 1" actually looks weird if considering from the
>> perspective of a normal user.
>>
>> However, I still want to keep it as "1" or at least some common
>> understandable name in libav (which I don't know if any other already
>> have) like
>
> 1 is fine for now. You can always add named constants later if there's a
> reason for it.

Then, 1 is.

And an updated patch attached.
From 5249178dd6703dbc83cebc8cf9721e251266d51a Mon Sep 17 00:00:00 2001
From: Yu-Jie Lin <[email protected]>
Date: Sat, 30 Jul 2011 19:13:43 +0800
Subject: [PATCH 2/2] x11grab: add show_region AVOption.

Draw the current grabbing region for indication.

Signed-off-by: Yu-Jie Lin <[email protected]>
---
 doc/ffmpeg.texi       |   13 +++++++
 doc/indevs.texi       |   19 +++++++++++
 libavdevice/x11grab.c |   87 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index eb3bd89..c130af9 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -916,6 +916,19 @@ ffmpeg -f x11grab -follow_mouse 100 -s cif -r 25 -i :0.0 /tmp/out.mpg
 Only follows when mouse pointer reaches within 100 pixels to the edge of
 region.
 
+@example
+ffmpeg -f x11grab -show_region 1 -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
+@end example
+
+The grabbing region will be indicated on screen.
+
+@example
+ffmpeg -f x11grab -follow_mouse centered -show_region 1 -s cif -r 25 -i :0.0 /tmp/out.mpg
+@end example
+
+The grabbing region indication will follow the mouse pointer.
+
+
 @section Video and Audio file format conversion
 
 Any supported file format and protocol can serve as input to ffmpeg:
diff --git a/doc/indevs.texi b/doc/indevs.texi
index aa001cd..fa21c09 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -271,4 +271,23 @@ ffmpeg -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 out.mpg
 ffmpeg -f x11grab -follow_mouse 100 -r 25 -s cif -i :0.0 out.mpg
 @end example
 
+@subsection @var{show_region} AVOption
+
+The syntax is:
+@example
+-show_region 1
+@end example
+
+If @var{show_region} AVOption is specified with @var{1}, then the grabbing
+region will be indicated on screen. With this option, it's easy to know what is
+being grabbed if only a portion of the screen is grabbed.
+
+For example:
+@example
+ffmpeg -f x11grab -show_region 1 -r 25 -s cif -i :0.0+10,20 out.mpg
+
+# With follow_mouse
+ffmpeg -f x11grab -follow_mouse centered -show_region 1  -r 25 -s cif -i :0.0 out.mpg
+@end example
+
 @c man end INPUT DEVICES
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index 70a64c6..d40c24f 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -47,6 +47,7 @@
 #include <X11/Xproto.h>
 #include <X11/Xutil.h>
 #include <sys/shm.h>
+#include <X11/extensions/shape.h>
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/Xfixes.h>
 
@@ -72,9 +73,73 @@ struct x11_grab
     XShmSegmentInfo shminfo; /**< When using XShm, keeps track of XShm infos */
     int  draw_mouse;         /**< Set by a private option. */
     int  follow_mouse;       /**< Set by a private option. */
+    int  show_region;        /**< set by a private option. */
     char *framerate;         /**< Set by a private option. */
+
+    Window region_win;       /**< This is used by show_region option. */
 };
 
+#define REGION_WIN_BORDER 3
+/**
+ * Draw grabbing region window
+ *
+ * @param s x11_grab context
+ */
+static void
+x11grab_draw_region_win(struct x11_grab *s)
+{
+    Display *dpy = s->dpy;
+    int screen;
+    Window win = s->region_win;
+    GC gc;
+
+    screen = DefaultScreen(dpy);
+    gc = XCreateGC(dpy, win, 0, 0);
+    XSetForeground(dpy, gc, WhitePixel(dpy, screen));
+    XSetBackground(dpy, gc, BlackPixel(dpy, screen));
+    XSetLineAttributes(dpy, gc, REGION_WIN_BORDER, LineDoubleDash, 0, 0);
+    XDrawRectangle(dpy, win, gc,
+                   1, 1,
+                   (s->width  + REGION_WIN_BORDER * 2) - 1 * 2 - 1,
+                   (s->height + REGION_WIN_BORDER * 2) - 1 * 2 - 1);
+    XFreeGC(dpy, gc);
+}
+
+/**
+ * Initialize grabbing region window
+ *
+ * @param s x11_grab context
+ */
+static void
+x11grab_region_win_init(struct x11_grab *s)
+{
+    Display *dpy = s->dpy;
+    int screen;
+    XSetWindowAttributes attribs;
+    XRectangle rect;
+
+    screen = DefaultScreen(dpy);
+    attribs.override_redirect = True;
+    s->region_win = XCreateWindow(dpy, RootWindow(dpy, screen),
+                                  s->x_off  - REGION_WIN_BORDER,
+                                  s->y_off  - REGION_WIN_BORDER,
+                                  s->width  + REGION_WIN_BORDER * 2,
+                                  s->height + REGION_WIN_BORDER * 2,
+                                  0, CopyFromParent,
+                                  InputOutput, CopyFromParent,
+                                  CWOverrideRedirect, &attribs);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width  = s->width;
+    rect.height = s->height;
+    XShapeCombineRectangles(dpy, s->region_win,
+                            ShapeBounding, REGION_WIN_BORDER, REGION_WIN_BORDER,
+                            &rect, 1, ShapeSubtract, 0);
+    XMapWindow(dpy, s->region_win);
+    XSelectInput(dpy, s->region_win, ExposureMask | StructureNotifyMask);
+    x11grab_draw_region_win(s);
+}
+
 /**
  * Initialize the x11 grab device demuxer (public device demuxer API).
  *
@@ -451,6 +516,23 @@ x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
         // adjust grabbing region position if it goes out of screen.
         s->x_off = x_off = FFMIN(FFMAX(x_off, 0), screen_w - s->width);
         s->y_off = y_off = FFMIN(FFMAX(y_off, 0), screen_h - s->height);
+
+        if (s->show_region && s->region_win)
+            XMoveWindow(dpy, s->region_win,
+                        s->x_off - REGION_WIN_BORDER,
+                        s->y_off - REGION_WIN_BORDER);
+    }
+
+    if (s->show_region) {
+        if (s->region_win) {
+            XEvent evt;
+            // clean up the events, and do the initinal draw or redraw.
+            for (evt.type = NoEventMask; XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask, &evt); );
+            if (evt.type)
+                x11grab_draw_region_win(s);
+        } else {
+            x11grab_region_win_init(s);
+        }
     }
 
     if(s->use_shm) {
@@ -494,6 +576,10 @@ x11grab_read_close(AVFormatContext *s1)
         x11grab->image = NULL;
     }
 
+    if (x11grab->region_win) {
+        XDestroyWindow(x11grab->dpy, x11grab->region_win);
+    }
+
     /* Free X11 display */
     XCloseDisplay(x11grab->dpy);
     return 0;
@@ -507,6 +593,7 @@ static const AVOption options[] = {
     { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), FF_OPT_TYPE_INT, { 1 }, 0, 1, DEC },
     { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region. Or \"centered\" can be used, the pointer is kept at the center of the region.", OFFSET(follow_mouse), FF_OPT_TYPE_INT, { 0 }, -1, INT_MAX, DEC, "follow_mouse" },
     { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, DEC, "follow_mouse" },
+    { "show_region", "Show the grabbing region. Use value \"1\" to enable.", OFFSET(show_region), FF_OPT_TYPE_INT, { 0 }, 0, 1, DEC },
     { NULL },
 };
 
-- 
1.7.3.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to