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>
92 #define REGION_WIN_BORDER 3
101 Display *dpy = s->
dpy;
103 int screen = DefaultScreen(dpy);
104 GC gc = XCreateGC(dpy, win, 0, 0);
106 XSetForeground(dpy, gc, WhitePixel(dpy, screen));
107 XSetBackground(dpy, gc, BlackPixel(dpy, screen));
109 XDrawRectangle(dpy, win, gc, 1, 1,
122 Display *dpy = s->
dpy;
124 XSetWindowAttributes attribs = { .override_redirect = True };
125 int screen = DefaultScreen(dpy);
127 s->
region_win = XCreateWindow(dpy, RootWindow(dpy, screen),
133 InputOutput, CopyFromParent,
134 CWOverrideRedirect, &attribs);
137 rect.width = s->
width;
141 &rect, 1, ShapeSubtract, 0);
143 XSelectInput(dpy, s->
region_win, ExposureMask | StructureNotifyMask);
150 int scr = XDefaultScreen(dpy);
151 XImage *
img = XShmCreateImage(dpy, DefaultVisual(dpy, scr),
152 DefaultDepth(dpy, scr), ZPixmap,
NULL,
155 g->
shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height,
166 if (!XShmAttach(dpy, &g->
shminfo)) {
180 if (XFixesQueryExtension(dpy, &ev_ret, &ev_err)) {
181 Window root = RootWindow(dpy, screen);
182 XFixesSelectCursorInput(dpy, root, XFixesDisplayCursorNotifyMask);
192 "Image r 0x%.6lx g 0x%.6lx b 0x%.6lx and depth %i\n",
196 image->bits_per_pixel);
200 switch (image->bits_per_pixel) {
205 if (image->red_mask == 0xf800 &&
206 image->green_mask == 0x07e0 &&
207 image->blue_mask == 0x001f) {
209 }
else if (image->red_mask == 0x7c00 &&
210 image->green_mask == 0x03e0 &&
211 image->blue_mask == 0x001f) {
216 if (image->red_mask == 0xff0000 &&
217 image->green_mask == 0x00ff00 &&
218 image->blue_mask == 0x0000ff) {
220 }
else if (image->red_mask == 0x0000ff &&
221 image->green_mask == 0x00ff00 &&
222 image->blue_mask == 0xff0000) {
227 if (image->red_mask == 0xff0000 &&
228 image->green_mask == 0x00ff00 &&
229 image->blue_mask == 0x0000ff ) {
236 "XImages with RGB mask 0x%.6lx 0x%.6lx 0x%.6lx and depth %i "
237 "are currently not supported.\n",
241 image->bits_per_pixel);
265 int x_off = 0, y_off = 0,
ret = 0,
screen, use_shm = 0;
275 offset = strchr(dpyname,
'+');
277 sscanf(offset,
"%d,%d", &x_off, &y_off);
278 if (strstr(offset,
"nomouse")) {
280 "'nomouse' specification in argument is deprecated: "
281 "use 'draw_mouse' option with value 0 instead\n");
288 "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
291 dpy = XOpenDisplay(dpyname);
306 screen = DefaultScreen(dpy);
309 int screen_w, screen_h;
312 screen_w = DisplayWidth(dpy,
screen);
313 screen_h = DisplayHeight(dpy,
screen);
314 XQueryPointer(dpy, RootWindow(dpy,
screen), &w, &w, &x_off, &y_off,
316 x_off -= x11grab->
width / 2;
317 y_off -= x11grab->
height / 2;
318 x_off = av_clip(x_off, 0, screen_w - x11grab->
width);
319 y_off = av_clip(y_off, 0, screen_h - x11grab->
height);
321 "followmouse is enabled, resetting grabbing region to x: %d y: %d\n",
326 use_shm = XShmQueryExtension(dpy);
328 "shared memory extension %sfound\n", use_shm ?
"" :
"not ");
331 if (use_shm &&
setup_shm(s1, dpy, &image) < 0) {
337 image = XGetImage(dpy, RootWindow(dpy,
screen),
345 "XFixes not available, cannot draw the mouse cursor\n");
353 x11grab->
x_off = x_off;
354 x11grab->
y_off = y_off;
355 x11grab->
image = image;
363 color_map = DefaultColormap(dpy,
screen);
364 for (i = 0; i < 256; ++i)
366 XQueryColors(dpy, color_map, color, 256);
367 for (i = 0; i < 256; ++i)
368 x11grab->
palette[i] = (color[i].red & 0xFF00) << 8 |
369 (color[i].green & 0xFF00) |
370 (color[i].blue & 0xFF00) >> 8;
397 int x_off = s->
x_off;
398 int y_off = s->
y_off;
401 Display *dpy = s->
dpy;
402 XFixesCursorImage *xcim;
405 int to_line, to_column;
406 int pixstride = image->bits_per_pixel >> 3;
413 XSetWindowAttributes attr;
416 if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
420 s->
c = XCreateFontCursor(dpy, XC_left_ptr);
421 root = DefaultRootWindow(dpy);
423 XChangeWindowAttributes(dpy, root, CWCursor, &attr);
425 xcim = XFixesGetCursorImage(dpy);
428 "XFixesGetCursorImage failed\n");
432 x = xcim->x - xcim->xhot;
433 y = xcim->y - xcim->yhot;
435 to_line =
FFMIN((y + xcim->height), (height + y_off));
436 to_column =
FFMIN((x + xcim->width), (width + x_off));
438 for (line =
FFMAX(y, y_off); line < to_line; line++) {
439 for (column =
FFMAX(x, x_off); column < to_column; column++) {
440 int xcim_addr = (line -
y) * xcim->width + column - x;
441 int image_addr = ((line - y_off) * width + column - x_off) * pixstride;
442 int r = (
uint8_t)(xcim->pixels[xcim_addr] >> 0);
443 int g = (
uint8_t)(xcim->pixels[xcim_addr] >> 8);
444 int b = (
uint8_t)(xcim->pixels[xcim_addr] >> 16);
445 int a = (
uint8_t)(xcim->pixels[xcim_addr] >> 24);
448 pix[image_addr + 0] =
r;
449 pix[image_addr + 1] =
g;
450 pix[image_addr + 2] =
b;
453 pix[image_addr + 0] = r + (pix[image_addr + 0] * (255 -
a) + 255 / 2) / 255;
454 pix[image_addr + 1] = g + (pix[image_addr + 1] * (255 -
a) + 255 / 2) / 255;
455 pix[image_addr + 2] = b + (pix[image_addr + 2] * (255 -
a) + 255 / 2) / 255;
474 static int xget_zpixmap(Display *dpy, Drawable d, XImage *image,
int x,
int y)
484 GetReq(GetImage, req);
490 req->width = image->width;
491 req->height = image->height;
492 req->planeMask = (
unsigned int)AllPlanes;
493 req->format = ZPixmap;
495 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) {
501 nbytes = (long)rep.length << 2;
502 _XReadPad(dpy, image->data, nbytes);
519 Display *dpy = s->
dpy;
520 XImage *image = s->
image;
521 int x_off = s->
x_off;
522 int y_off = s->
y_off;
524 int screen, pointer_x, pointer_y,
_, same_screen = 1;
526 int64_t curtime, delay;
541 ts.tv_sec = delay / 1000000;
542 ts.tv_nsec = (delay % 1000000) * 1000;
543 nanosleep(&ts,
NULL);
547 pkt->
data = image->data;
561 screen = DefaultScreen(dpy);
562 root = RootWindow(dpy, screen);
565 same_screen = XQueryPointer(dpy, root, &w, &w,
566 &pointer_x, &pointer_y, &_, &_, &_);
568 if (follow_mouse && same_screen) {
569 int screen_w, screen_h;
571 screen_w = DisplayWidth(dpy, screen);
572 screen_h = DisplayHeight(dpy, screen);
573 if (follow_mouse == -1) {
575 x_off += pointer_x - s->
width / 2 - x_off;
576 y_off += pointer_y - s->
height / 2 - y_off;
580 if (pointer_x > x_off + s->
width - follow_mouse)
581 x_off += pointer_x - (x_off + s->
width - follow_mouse);
582 else if (pointer_x < x_off + follow_mouse)
583 x_off -= (x_off + follow_mouse) - pointer_x;
584 if (pointer_y > y_off + s->
height - follow_mouse)
585 y_off += pointer_y - (y_off + s->
height - follow_mouse);
586 else if (pointer_y < y_off + follow_mouse)
587 y_off -= (y_off + follow_mouse) - pointer_y;
590 s->
x_off = x_off = av_clip(x_off, 0, screen_w - s->
width);
591 s->
y_off = y_off = av_clip(y_off, 0, screen_h - s->
height);
601 XEvent evt = { .type = NoEventMask };
603 while (XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask,
614 if (!XShmGetImage(dpy, root, image, x_off, y_off, AllPlanes))
640 shmdt(x11grab->
shminfo.shmaddr);
645 if (x11grab->
image) {
646 XDestroyImage(x11grab->
image);
654 XCloseDisplay(x11grab->
dpy);
658 #define OFFSET(x) offsetof(X11GrabContext, x)
659 #define DEC AV_OPT_FLAG_DECODING_PARAM
665 {
"follow_mouse",
"move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region",
667 {
"centered",
"keep the mouse pointer at the center of grabbing region when following",
694 .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 AV_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.
common internal API header
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.
#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 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_log(ac->avr, AV_LOG_TRACE,"%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
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