Message ID | 59E47B81-05C3-4C9E-A7DE-7A498A5B871D@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] avdevice/gdigrab: client_only option to discard decorations such as titlebar or borders | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/configure | warning | Failed to apply patch |
On Fri, Jun 19, 2020 at 10:33:00 +0200, Sergio Acereda wrote: > +static int > +calc_titlebar_height(HWND hwnd) { Nit: the opening bracket of a function belongs in the next line. > GetClientRect(hwnd, &virtual_rect); > + if (gdigrab->client_only) { > + int cxborder = GetSystemMetrics(SM_CXBORDER); > + int cyborder = GetSystemMetrics(SM_CYBORDER); > + int titlebar_height = calc_titlebar_height(hwnd); > + virtual_rect.left += cxborder; > + virtual_rect.right += -cxborder; > + virtual_rect.top += cxborder + titlebar_height; > + virtual_rect.bottom += -cyborder; > + } Does this actually work correctly? Just wondering, as I read this: https://stackoverflow.com/a/11707312/3974309 I can't test, sorry. > + { "client_only", "client only", OFFSET(client_only), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC }, Please also update the documentation (doc/indevs.texi). Thanks, Moritz
On Fri, 2020-06-19 at 10:33 +0200, Sergio Acereda wrote: > +/** > + * Fetch titlebar height from handle. > + * > + * @param hwnd Handle of the window. > + * @return titlebar height > + */ > +static int > +calc_titlebar_height(HWND hwnd) { > + TITLEBARINFOEX tinfo; > + tinfo.cbSize = sizeof(tinfo); > + SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, (LPARAM)&tinfo); > + return tinfo.rcTitleBar.bottom - tinfo.rcTitleBar.top; > +} > + > /** > * Initializes the gdi grab device demuxer (public device demuxer > API). > * > @@ -284,6 +299,15 @@ gdigrab_read_header(AVFormatContext *s1) > > if (hwnd) { > GetClientRect(hwnd, &virtual_rect); > + if (gdigrab->client_only) { > + int cxborder = GetSystemMetrics(SM_CXBORDER); > + int cyborder = GetSystemMetrics(SM_CYBORDER); > + int titlebar_height = calc_titlebar_height(hwnd); > + virtual_rect.left += cxborder; > + virtual_rect.right += -cxborder; > + virtual_rect.top += cxborder + titlebar_height; > + virtual_rect.bottom += -cyborder; > + } This seems fine - my only comment is that you need to test this with high DPI support (display scale values >100%) on both native high-dpi applications and legacy (scaled by windows) applications to ensure the correct adjustments are being applied where needed.
diff --git a/libavdevice/gdigrab.c b/libavdevice/gdigrab.c index f4444406fa..b09c88d94d 100644 --- a/libavdevice/gdigrab.c +++ b/libavdevice/gdigrab.c @@ -52,6 +52,7 @@ struct gdigrab { int height; /**< Height of the grab frame (private option) */ int offset_x; /**< Capture x offset (private option) */ int offset_y; /**< Capture y offset (private option) */ + int client_only; /**< Discard decorations, such as titlebar (private option) */ HWND hwnd; /**< Handle of the window for the grab */ HDC source_hdc; /**< Source device context */ @@ -212,6 +213,20 @@ gdigrab_region_wnd_update(AVFormatContext *s1, struct gdigrab *gdigrab) } } +/** + * Fetch titlebar height from handle. + * + * @param hwnd Handle of the window. + * @return titlebar height + */ +static int +calc_titlebar_height(HWND hwnd) { + TITLEBARINFOEX tinfo; + tinfo.cbSize = sizeof(tinfo); + SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, (LPARAM)&tinfo); + return tinfo.rcTitleBar.bottom - tinfo.rcTitleBar.top; +} + /** * Initializes the gdi grab device demuxer (public device demuxer API). * @@ -284,6 +299,15 @@ gdigrab_read_header(AVFormatContext *s1) if (hwnd) { GetClientRect(hwnd, &virtual_rect); + if (gdigrab->client_only) { + int cxborder = GetSystemMetrics(SM_CXBORDER); + int cyborder = GetSystemMetrics(SM_CYBORDER); + int titlebar_height = calc_titlebar_height(hwnd); + virtual_rect.left += cxborder; + virtual_rect.right += -cxborder; + virtual_rect.top += cxborder + titlebar_height; + virtual_rect.bottom += -cyborder; + } /* window -- get the right height and width for scaling DPI */ virtual_rect.left = virtual_rect.left * desktophorzres / horzres; virtual_rect.right = virtual_rect.right * desktophorzres / horzres; @@ -639,6 +663,7 @@ static const AVOption options[] = { { "video_size", "set video frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, { "offset_x", "capture area x offset", OFFSET(offset_x), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC }, { "offset_y", "capture area y offset", OFFSET(offset_y), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC }, + { "client_only", "client only", OFFSET(client_only), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC }, { NULL }, };