44 #include <X11/cursorfont.h>
47 #include <X11/Xlibint.h>
48 #include <X11/Xproto.h>
49 #include <X11/Xutil.h>
51 #include <X11/extensions/shape.h>
52 #include <X11/extensions/Xfixes.h>
53 #include <X11/extensions/XShm.h>
91 #define REGION_WIN_BORDER 3
100 Display *dpy = s->
dpy;
102 int screen = DefaultScreen(dpy);
103 GC gc = XCreateGC(dpy, win, 0, 0);
105 XSetForeground(dpy, gc, WhitePixel(dpy, screen));
106 XSetBackground(dpy, gc, BlackPixel(dpy, screen));
108 XDrawRectangle(dpy, win, gc, 1, 1,
121 Display *dpy = s->
dpy;
123 XSetWindowAttributes attribs = { .override_redirect = True };
124 int screen = DefaultScreen(dpy);
126 s->
region_win = XCreateWindow(dpy, RootWindow(dpy, screen),
132 InputOutput, CopyFromParent,
133 CWOverrideRedirect, &attribs);
136 rect.width = s->
width;
140 &rect, 1, ShapeSubtract, 0);
142 XSelectInput(dpy, s->
region_win, ExposureMask | StructureNotifyMask);
149 int scr = XDefaultScreen(dpy);
150 XImage *
img = XShmCreateImage(dpy, DefaultVisual(dpy, scr),
151 DefaultDepth(dpy, scr), ZPixmap,
NULL,
154 g->
shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height,
165 if (!XShmAttach(dpy, &g->
shminfo)) {
179 if (XFixesQueryExtension(dpy, &ev_ret, &ev_err)) {
180 Window root = RootWindow(dpy, screen);
181 XFixesSelectCursorInput(dpy, root, XFixesDisplayCursorNotifyMask);
191 "Image r 0x%.6lx g 0x%.6lx b 0x%.6lx and depth %i\n",
195 image->bits_per_pixel);
199 switch (image->bits_per_pixel) {
204 if (image->red_mask == 0xf800 &&
205 image->green_mask == 0x07e0 &&
206 image->blue_mask == 0x001f) {
208 }
else if (image->red_mask == 0x7c00 &&
209 image->green_mask == 0x03e0 &&
210 image->blue_mask == 0x001f) {
215 if (image->red_mask == 0xff0000 &&
216 image->green_mask == 0x00ff00 &&
217 image->blue_mask == 0x0000ff) {
219 }
else if (image->red_mask == 0x0000ff &&
220 image->green_mask == 0x00ff00 &&
221 image->blue_mask == 0xff0000) {
226 if (image->red_mask == 0xff0000 &&
227 image->green_mask == 0x00ff00 &&
228 image->blue_mask == 0x0000ff ) {
235 "XImages with RGB mask 0x%.6lx 0x%.6lx 0x%.6lx and depth %i "
236 "are currently not supported.\n",
240 image->bits_per_pixel);
264 int x_off = 0, y_off = 0,
ret = 0,
screen, use_shm = 0;
274 offset = strchr(dpyname,
'+');
276 sscanf(offset,
"%d,%d", &x_off, &y_off);
277 if (strstr(offset,
"nomouse")) {
279 "'nomouse' specification in argument is deprecated: "
280 "use 'draw_mouse' option with value 0 instead\n");
287 "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
290 dpy = XOpenDisplay(dpyname);
305 screen = DefaultScreen(dpy);
308 int screen_w, screen_h;
311 screen_w = DisplayWidth(dpy,
screen);
312 screen_h = DisplayHeight(dpy,
screen);
313 XQueryPointer(dpy, RootWindow(dpy,
screen), &w, &w, &x_off, &y_off,
315 x_off -= x11grab->
width / 2;
316 y_off -= x11grab->
height / 2;
320 "followmouse is enabled, resetting grabbing region to x: %d y: %d\n",
325 use_shm = XShmQueryExtension(dpy);
327 "shared memory extension %sfound\n", use_shm ?
"" :
"not ");
330 if (use_shm &&
setup_shm(s1, dpy, &image) < 0) {
336 image = XGetImage(dpy, RootWindow(dpy,
screen),
344 "XFixes not available, cannot draw the mouse cursor\n");
352 x11grab->
x_off = x_off;
353 x11grab->
y_off = y_off;
354 x11grab->
image = image;
362 color_map = DefaultColormap(dpy,
screen);
363 for (i = 0; i < 256; ++i)
365 XQueryColors(dpy, color_map, color, 256);
366 for (i = 0; i < 256; ++i)
367 x11grab->
palette[i] = (color[i].red & 0xFF00) << 8 |
368 (color[i].green & 0xFF00) |
369 (color[i].blue & 0xFF00) >> 8;
396 int x_off = s->
x_off;
397 int y_off = s->
y_off;
400 Display *dpy = s->
dpy;
401 XFixesCursorImage *xcim;
404 int to_line, to_column;
405 int pixstride = image->bits_per_pixel >> 3;
412 XSetWindowAttributes attr;
415 if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
419 s->
c = XCreateFontCursor(dpy, XC_left_ptr);
420 root = DefaultRootWindow(dpy);
422 XChangeWindowAttributes(dpy, root, CWCursor, &attr);
424 xcim = XFixesGetCursorImage(dpy);
427 "XFixesGetCursorImage failed\n");
431 x = xcim->x - xcim->xhot;
432 y = xcim->y - xcim->yhot;
434 to_line =
FFMIN((y + xcim->height), (height + y_off));
435 to_column =
FFMIN((x + xcim->width), (width + x_off));
437 for (line =
FFMAX(y, y_off); line < to_line; line++) {
438 for (column =
FFMAX(x, x_off); column < to_column; column++) {
439 int xcim_addr = (line -
y) * xcim->width + column - x;
440 int image_addr = ((line - y_off) * width + column - x_off) * pixstride;
441 int r = (
uint8_t)(xcim->pixels[xcim_addr] >> 0);
442 int g = (
uint8_t)(xcim->pixels[xcim_addr] >> 8);
443 int b = (
uint8_t)(xcim->pixels[xcim_addr] >> 16);
444 int a = (
uint8_t)(xcim->pixels[xcim_addr] >> 24);
447 pix[image_addr + 0] =
r;
448 pix[image_addr + 1] =
g;
449 pix[image_addr + 2] =
b;
452 pix[image_addr + 0] = r + (pix[image_addr + 0] * (255 -
a) + 255 / 2) / 255;
453 pix[image_addr + 1] = g + (pix[image_addr + 1] * (255 -
a) + 255 / 2) / 255;
454 pix[image_addr + 2] = b + (pix[image_addr + 2] * (255 -
a) + 255 / 2) / 255;
473 static int xget_zpixmap(Display *dpy, Drawable d, XImage *image,
int x,
int y)
483 GetReq(GetImage, req);
489 req->width = image->width;
490 req->height = image->height;
491 req->planeMask = (
unsigned int)AllPlanes;
492 req->format = ZPixmap;
494 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) {
500 nbytes = (long)rep.length << 2;
501 _XReadPad(dpy, image->data, nbytes);
518 Display *dpy = s->
dpy;
519 XImage *image = s->
image;
520 int x_off = s->
x_off;
521 int y_off = s->
y_off;
523 int screen, pointer_x, pointer_y,
_, same_screen = 1;
525 int64_t curtime, delay;
540 ts.tv_sec = delay / 1000000;
541 ts.tv_nsec = (delay % 1000000) * 1000;
542 nanosleep(&ts,
NULL);
546 pkt->
data = image->data;
560 screen = DefaultScreen(dpy);
561 root = RootWindow(dpy, screen);
564 same_screen = XQueryPointer(dpy, root, &w, &w,
565 &pointer_x, &pointer_y, &_, &_, &_);
567 if (follow_mouse && same_screen) {
568 int screen_w, screen_h;
570 screen_w = DisplayWidth(dpy, screen);
571 screen_h = DisplayHeight(dpy, screen);
572 if (follow_mouse == -1) {
574 x_off += pointer_x - s->
width / 2 - x_off;
575 y_off += pointer_y - s->
height / 2 - y_off;
579 if (pointer_x > x_off + s->
width - follow_mouse)
580 x_off += pointer_x - (x_off + s->
width - follow_mouse);
581 else if (pointer_x < x_off + follow_mouse)
582 x_off -= (x_off + follow_mouse) - pointer_x;
583 if (pointer_y > y_off + s->
height - follow_mouse)
584 y_off += pointer_y - (y_off + s->
height - follow_mouse);
585 else if (pointer_y < y_off + follow_mouse)
586 y_off -= (y_off + follow_mouse) - pointer_y;
600 XEvent evt = { .type = NoEventMask };
602 while (XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask,
613 if (!XShmGetImage(dpy, root, image, x_off, y_off, AllPlanes))
639 shmdt(x11grab->
shminfo.shmaddr);
644 if (x11grab->
image) {
645 XDestroyImage(x11grab->
image);
653 XCloseDisplay(x11grab->
dpy);
657 #define OFFSET(x) offsetof(X11GrabContext, x)
658 #define DEC AV_OPT_FLAG_DECODING_PARAM
664 {
"follow_mouse",
"move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region",
666 {
"centered",
"keep the mouse pointer at the center of grabbing region when following",
693 .priv_class = &x11_class,
static int x11grab_read_header(AVFormatContext *s1)
Initialize the x11 grab device demuxer (public device demuxer API).
static enum AVPixelFormat pix_fmt
static int setup_shm(AVFormatContext *s, Display *dpy, XImage **image)
AVInputFormat ff_x11grab_demuxer
x11 grabber device demuxer declaration
#define AV_LOG_WARNING
Something somehow does not look correct.
#define LIBAVUTIL_VERSION_INT
packed RGB 8:8:8, 24bpp, RGBRGB...
#define REGION_WIN_BORDER
int x_off
Horizontal top-left corner coordinate.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int show_region
set by a private option.
Window region_win
This is used by show_region option.
static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
Grab a frame from x11 (public device demuxer API).
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static void x11grab_draw_region_win(X11GrabContext *s)
Draw grabbing region window.
8 bit with PIX_FMT_RGB32 palette
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
static double av_q2d(AVRational a)
Convert rational to double.
static av_cold int read_close(AVFormatContext *ctx)
static void x11grab_region_win_init(X11GrabContext *s)
Initialize grabbing region window.
Main libavdevice API header.
static const AVOption options[]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int pixfmt_from_image(AVFormatContext *s, XImage *image, int *pix_fmt)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static const AVClass x11_class
static const uint8_t offset[127][2]
static int x11grab_read_close(AVFormatContext *s1)
Close x11 frame grabber (public device demuxer API).
AVRational time_base
Time base.
AVCodecContext * codec
Codec context associated with this stream.
int64_t time_frame
Current time.
static SDL_Surface * screen
static int xget_zpixmap(Display *dpy, Drawable d, XImage *image, int x, int y)
Read new data in the image structure.
int bit_rate
the average bitrate
char filename[1024]
input or output filename
int height
Height of the grab frame.
int width
picture width / height.
int use_shm
!0 when using XShm extension
packed RGB 8:8:8, 24bpp, BGRBGR...
static void paint_mouse_pointer(XImage *image, AVFormatContext *s1)
Paint a mouse pointer in an X11 image.
static int read_header(FFV1Context *f)
int64_t av_gettime(void)
Get the current time in microseconds.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
X11 device demuxer context.
#define AV_LOG_INFO
Standard information.
XShmSegmentInfo shminfo
When using XShm, keeps track of XShm infos.
enum AVMediaType codec_type
char * av_strdup(const char *s)
Duplicate the string s.
static int setup_mouse(Display *dpy, int screen)
int frame_size
Size in bytes of a grabbed frame.
BYTE int const BYTE int int int height
Describe the class of an AVClass context structure.
rational number numerator/denominator
XImage * image
X11 image holding the grab.
offset must point to AVRational
int width
Width of the grab frame.
offset must point to two consecutive integers
int follow_mouse
Set by a private option.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
#define AV_PIX_FMT_RGB555
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
int draw_mouse
Set by a private option.
int y_off
Vertical top-left corner coordinate.
Display * dpy
X11 display from which x11grab grabs frames.
void * priv_data
Format private data.
#define AV_PIX_FMT_RGB565
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
AVRational framerate
Set by a private option.
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_PIX_FMT_0RGB32