69 #define WIN32_API_ERROR(str)                                            \ 
   70     av_log(s1, AV_LOG_ERROR, str " (error %li)\n", GetLastError()) 
   72 #define REGION_WND_BORDER 3 
   94         hdc = BeginPaint(hwnd, &ps);
 
   96         GetClientRect(hwnd, &rect);
 
   97         FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
 
   99         rect.left++; rect.top++; rect.right--; rect.bottom--;
 
  100         FrameRect(hdc, &rect, GetStockObject(WHITE_BRUSH));
 
  102         rect.left++; rect.top++; rect.right--; rect.bottom--;
 
  103         FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
 
  108         return DefWindowProc(hwnd, msg, wparam, lparam);
 
  126     HRGN region_interior = 
NULL;
 
  128     DWORD style = WS_POPUP | WS_VISIBLE;
 
  129     DWORD ex = WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT;
 
  134     AdjustWindowRectEx(&rect, style, 
FALSE, ex);
 
  138     hwnd = CreateWindowEx(ex, WC_DIALOG, 
NULL, style, rect.left, rect.top,
 
  139             rect.right - rect.left, rect.bottom - rect.top,
 
  147     GetClientRect(hwnd, &rect);
 
  148     region = CreateRectRgn(0, 0,
 
  149             rect.right - rect.left, rect.bottom - rect.top);
 
  153     CombineRgn(region, region, region_interior, RGN_DIFF);
 
  154     if (!SetWindowRgn(hwnd, region, 
FALSE)) {
 
  160     DeleteObject(region_interior);
 
  164     ShowWindow(hwnd, SW_SHOW);
 
  172         DeleteObject(region);
 
  174         DeleteObject(region_interior);
 
  210     while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
 
  211         DispatchMessage(&msg);
 
  233     const char *filename = s1->
filename;
 
  243     if (!strncmp(filename, 
"title=", 6)) {
 
  245         hwnd = FindWindow(
NULL, name);
 
  248                    "Can't find window '%s', aborting.\n", name);
 
  254                     "Can't show region when grabbing a window.\n");
 
  257     } 
else if (!strcmp(filename, 
"desktop")) {
 
  261                "Please use \"desktop\" or \"title=<windowname>\" to specify your target.\n");
 
  267         GetClientRect(hwnd, &virtual_rect);
 
  269         virtual_rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
 
  270         virtual_rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
 
  271         virtual_rect.right = virtual_rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
 
  272         virtual_rect.bottom = virtual_rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
 
  277         clip_rect.left = virtual_rect.left;
 
  278         clip_rect.top = virtual_rect.top;
 
  279         clip_rect.right = virtual_rect.right;
 
  280         clip_rect.bottom = virtual_rect.bottom;
 
  288     if (clip_rect.left < virtual_rect.left ||
 
  289             clip_rect.top < virtual_rect.top ||
 
  290             clip_rect.right > virtual_rect.right ||
 
  291             clip_rect.bottom > virtual_rect.bottom) {
 
  293                     "Capture area (%li,%li),(%li,%li) extends outside window area (%li,%li),(%li,%li)",
 
  294                     clip_rect.left, clip_rect.top,
 
  295                     clip_rect.right, clip_rect.bottom,
 
  296                     virtual_rect.left, virtual_rect.top,
 
  297                     virtual_rect.right, virtual_rect.bottom);
 
  304     source_hdc = GetDC(hwnd);
 
  310     bpp = GetDeviceCaps(source_hdc, BITSPIXEL);
 
  314                "Found window %s, capturing %lix%lix%i at (%li,%li)\n",
 
  316                clip_rect.right - clip_rect.left,
 
  317                clip_rect.bottom - clip_rect.top,
 
  318                bpp, clip_rect.left, clip_rect.top);
 
  321                "Capturing whole desktop as %lix%lix%i at (%li,%li)\n",
 
  322                clip_rect.right - clip_rect.left,
 
  323                clip_rect.bottom - clip_rect.top,
 
  324                bpp, clip_rect.left, clip_rect.top);
 
  327     if (clip_rect.right - clip_rect.left <= 0 ||
 
  328             clip_rect.bottom - clip_rect.top <= 0 || bpp%8) {
 
  334     dest_hdc = CreateCompatibleDC(source_hdc);
 
  342     bmi.bmiHeader.biSize          = 
sizeof(BITMAPINFOHEADER);
 
  343     bmi.bmiHeader.biWidth         = clip_rect.right - clip_rect.left;
 
  344     bmi.bmiHeader.biHeight        = -(clip_rect.bottom - clip_rect.top);
 
  345     bmi.bmiHeader.biPlanes        = 1;
 
  346     bmi.bmiHeader.biBitCount      = bpp;
 
  347     bmi.bmiHeader.biCompression   = BI_RGB;
 
  348     bmi.bmiHeader.biSizeImage     = 0;
 
  349     bmi.bmiHeader.biXPelsPerMeter = 0;
 
  350     bmi.bmiHeader.biYPelsPerMeter = 0;
 
  351     bmi.bmiHeader.biClrUsed       = 0;
 
  352     bmi.bmiHeader.biClrImportant  = 0;
 
  353     hbmp = CreateDIBSection(dest_hdc, &bmi, DIB_RGB_COLORS,
 
  361     if (!SelectObject(dest_hdc, hbmp)) {
 
  368     GetObject(hbmp, 
sizeof(BITMAP), &bmp);
 
  377     gdigrab->
frame_size  = bmp.bmWidthBytes * bmp.bmHeight * bmp.bmPlanes;
 
  378     gdigrab->
header_size = 
sizeof(BITMAPFILEHEADER) + 
sizeof(BITMAPINFOHEADER) +
 
  379                            (bpp <= 8 ? (1 << bpp) : 0) * 
sizeof(RGBQUAD) ;
 
  409         ReleaseDC(hwnd, source_hdc);
 
  415         DeleteDC(source_hdc);
 
  429 #define CURSOR_ERROR(str)                 \ 
  430     if (!gdigrab->cursor_error_printed) {       \ 
  431         WIN32_API_ERROR(str);             \ 
  432         gdigrab->cursor_error_printed = 1;      \ 
  435     ci.cbSize = 
sizeof(ci);
 
  437     if (GetCursorInfo(&ci)) {
 
  438         HCURSOR icon = CopyCursor(ci.hCursor);
 
  444         info.hbmColor = 
NULL;
 
  446         if (ci.flags != CURSOR_SHOWING)
 
  453             icon = CopyCursor(LoadCursor(
NULL, IDC_ARROW));
 
  456         if (!GetIconInfo(icon, &info)) {
 
  461         pos.x = ci.ptScreenPos.x - clip_rect.left - info.xHotspot;
 
  462         pos.y = ci.ptScreenPos.y - clip_rect.top - info.yHotspot;
 
  467             if (GetWindowRect(hwnd, &rect)) {
 
  477                 ci.ptScreenPos.x, ci.ptScreenPos.y, pos.x, pos.y);
 
  479         if (pos.x >= 0 && pos.x <= clip_rect.right - clip_rect.left &&
 
  480                 pos.y >= 0 && pos.y <= clip_rect.bottom - clip_rect.top) {
 
  481             if (!DrawIcon(gdigrab->
dest_hdc, pos.x, pos.y, icon))
 
  487             DeleteObject(info.hbmMask);
 
  489             DeleteObject(info.hbmColor);
 
  514     BITMAPFILEHEADER bfh;
 
  517     int64_t curtime, delay;
 
  520     time_frame += INT64_C(1000000);
 
  529         delay = time_frame * 
av_q2d(time_base) - curtime;
 
  531             if (delay < INT64_C(-1000000) * 
av_q2d(time_base)) {
 
  532                 time_frame += INT64_C(1000000);
 
  548     if (!BitBlt(dest_hdc, 0, 0,
 
  549                 clip_rect.right - clip_rect.left,
 
  550                 clip_rect.bottom - clip_rect.top,
 
  552                 clip_rect.left, clip_rect.top, SRCCOPY | CAPTUREBLT)) {
 
  562     bfh.bfSize = file_size;
 
  567     memcpy(pkt->
data, &bfh, 
sizeof(bfh));
 
  569     memcpy(pkt->
data + 
sizeof(bfh), &gdigrab->
bmi.bmiHeader, 
sizeof(gdigrab->
bmi.bmiHeader));
 
  571     if (gdigrab->
bmi.bmiHeader.biBitCount <= 8)
 
  572         GetDIBColorTable(dest_hdc, 0, 1 << gdigrab->
bmi.bmiHeader.biBitCount,
 
  573                 (RGBQUAD *) (pkt->
data + 
sizeof(bfh) + 
sizeof(gdigrab->
bmi.bmiHeader)));
 
  600         DeleteObject(s->
hbmp);
 
  607 #define OFFSET(x) offsetof(struct gdigrab, x) 
  608 #define DEC AV_OPT_FLAG_DECODING_PARAM 
  630     .priv_data_size = 
sizeof(
struct gdigrab),
 
static int gdigrab_read_packet(AVFormatContext *s1, AVPacket *pkt)
Grabs a frame from gdi (public device demuxer API). 
int show_region
Draw border (private option) 
#define AV_LOG_WARNING
Something somehow does not look correct. 
#define LIBAVUTIL_VERSION_INT
static const AVOption options[]
int frame_size
Size in bytes of the frame pixel data. 
BITMAPINFO bmi
Information describing DIB format. 
int av_usleep(unsigned usec)
Sleep for a period of time. 
HWND region_hwnd
Handle of the region border window. 
static int gdigrab_read_close(AVFormatContext *s1)
Closes gdi frame grabber (public device demuxer API). 
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
static void gdigrab_region_wnd_destroy(AVFormatContext *s1, struct gdigrab *gdigrab)
Cleanup/free the region outline window. 
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file. 
RECT clip_rect
The subarea of the screen or window to clip. 
static LRESULT CALLBACK gdigrab_region_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Callback to handle Windows messages for the region outline window. 
static double av_q2d(AVRational a)
Convert rational to double. 
int flags
Flags modifying the (de)muxer behaviour. 
AVInputFormat ff_gdigrab_demuxer
gdi grabber device demuxer declaration 
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values. 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered. 
static int gdigrab_read_header(AVFormatContext *s1)
Initializes the gdi grab device demuxer (public device demuxer API). 
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
HBITMAP hbmp
Information on the bitmap captured. 
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers. 
AVRational framerate
Capture framerate (private option) 
int64_t time_frame
Current time. 
static void paint_mouse_pointer(AVFormatContext *s1, struct gdigrab *gdigrab)
Paints a mouse pointer in a Win32 image. 
static const AVClass gdigrab_class
int height
Height of the grab frame (private option) 
AVCodecContext * codec
Codec context associated with this stream. 
AVRational time_base
Time base. 
int header_size
Size in bytes of the DIB header. 
int bit_rate
the average bitrate 
char filename[1024]
input or output filename 
HDC dest_hdc
Destination, source-compatible DC. 
#define REGION_WND_BORDER
GDI Device Demuxer context. 
void * buffer
The buffer containing the bitmap image data. 
#define WIN32_API_ERROR(str)
int64_t av_gettime(void)
Get the current time in microseconds. 
HWND hwnd
Handle of the window for the grab. 
#define AV_LOG_INFO
Standard information. 
enum AVMediaType codec_type
int offset_y
Capture y offset (private option) 
Describe the class of an AVClass context structure. 
rational number numerator/denominator 
HDC source_hdc
Source device context. 
offset must point to AVRational 
offset must point to two consecutive integers 
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational. 
int width
Width of the grab frame (private option) 
int draw_mouse
Draw mouse cursor (private option) 
static int gdigrab_region_wnd_init(AVFormatContext *s1, struct gdigrab *gdigrab)
Initialize the region outline window. 
void * priv_data
Format private data. 
int offset_x
Capture x offset (private option) 
#define CURSOR_ERROR(str)
This structure stores compressed data. 
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
static void gdigrab_region_wnd_update(AVFormatContext *s1, struct gdigrab *gdigrab)
Process the Windows message queue.