FFmpeg
xcbgrab.c
Go to the documentation of this file.
1 /*
2  * XCB input grabber
3  * Copyright (C) 2014 Luca Barbato <lu_zero@gentoo.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 
24 #include <stdlib.h>
25 #include <xcb/xcb.h>
26 
27 #if CONFIG_LIBXCB_XFIXES
28 #include <xcb/xfixes.h>
29 #endif
30 
31 #if CONFIG_LIBXCB_SHM
32 #include <sys/shm.h>
33 #include <xcb/shm.h>
34 #endif
35 
36 #if CONFIG_LIBXCB_SHAPE
37 #include <xcb/shape.h>
38 #endif
39 
40 #include "libavutil/internal.h"
41 #include "libavutil/mathematics.h"
42 #include "libavutil/opt.h"
43 #include "libavutil/parseutils.h"
44 #include "libavutil/time.h"
45 
46 #include "libavformat/avformat.h"
47 #include "libavformat/internal.h"
48 
49 typedef struct XCBGrabContext {
50  const AVClass *class;
51 
53 
54  xcb_connection_t *conn;
55  xcb_screen_t *screen;
56  xcb_window_t window;
57 #if CONFIG_LIBXCB_SHM
58  xcb_shm_seg_t segment;
59 #endif
60  int64_t time_frame;
62 
63  int x, y;
64  int width, height;
66  int bpp;
67 
72  int centered;
73 
74  const char *video_size;
75  const char *framerate;
76 
77  int has_shm;
79 
80 #define FOLLOW_CENTER -1
81 
82 #define OFFSET(x) offsetof(XCBGrabContext, x)
83 #define D AV_OPT_FLAG_DECODING_PARAM
84 static const AVOption options[] = {
85  { "x", "Initial x coordinate.", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
86  { "y", "Initial y coordinate.", OFFSET(y), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
87  { "grab_x", "Initial x coordinate.", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
88  { "grab_y", "Initial y coordinate.", OFFSET(y), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
89  { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga" }, 0, 0, D },
90  { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc" }, 0, 0, D },
91  { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D },
92  { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region.",
93  OFFSET(follow_mouse), AV_OPT_TYPE_INT, { .i64 = 0 }, FOLLOW_CENTER, INT_MAX, D, "follow_mouse" },
94  { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, D, "follow_mouse" },
95  { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
96  { "region_border", "Set the region border thickness.", OFFSET(region_border), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 128, D },
97  { NULL },
98 };
99 
100 static const AVClass xcbgrab_class = {
101  .class_name = "xcbgrab indev",
102  .item_name = av_default_item_name,
103  .option = options,
104  .version = LIBAVUTIL_VERSION_INT,
106 };
107 
109  xcb_query_pointer_reply_t *p,
110  xcb_get_geometry_reply_t *geo)
111 {
112  XCBGrabContext *c = s->priv_data;
113  int x = c->x, y = c->y;
114  int w = c->width, h = c->height, f = c->follow_mouse;
115  int p_x, p_y;
116 
117  if (!p || !geo)
118  return AVERROR(EIO);
119 
120  p_x = p->win_x;
121  p_y = p->win_y;
122 
123  if (f == FOLLOW_CENTER) {
124  x = p_x - w / 2;
125  y = p_y - h / 2;
126  } else {
127  int left = x + f;
128  int right = x + w - f;
129  int top = y + f;
130  int bottom = y + h - f;
131  if (p_x > right) {
132  x += p_x - right;
133  } else if (p_x < left) {
134  x -= left - p_x;
135  }
136  if (p_y > bottom) {
137  y += p_y - bottom;
138  } else if (p_y < top) {
139  y -= top - p_y;
140  }
141  }
142 
143  c->x = FFMIN(FFMAX(0, x), geo->width - w);
144  c->y = FFMIN(FFMAX(0, y), geo->height - h);
145 
146  return 0;
147 }
148 
150 {
151  XCBGrabContext *c = s->priv_data;
152  xcb_get_image_cookie_t iq;
153  xcb_get_image_reply_t *img;
154  xcb_drawable_t drawable = c->screen->root;
155  xcb_generic_error_t *e = NULL;
156  uint8_t *data;
157  int length, ret;
158 
159  iq = xcb_get_image(c->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
160  c->x, c->y, c->width, c->height, ~0);
161 
162  img = xcb_get_image_reply(c->conn, iq, &e);
163 
164  if (e) {
165  av_log(s, AV_LOG_ERROR,
166  "Cannot get the image data "
167  "event_error: response_type:%u error_code:%u "
168  "sequence:%u resource_id:%u minor_code:%u major_code:%u.\n",
169  e->response_type, e->error_code,
170  e->sequence, e->resource_id, e->minor_code, e->major_code);
171  return AVERROR(EACCES);
172  }
173 
174  if (!img)
175  return AVERROR(EAGAIN);
176 
177  data = xcb_get_image_data(img);
178  length = xcb_get_image_data_length(img);
179 
180  ret = av_new_packet(pkt, length);
181 
182  if (!ret)
183  memcpy(pkt->data, data, length);
184 
185  free(img);
186 
187  return ret;
188 }
189 
191 {
192  XCBGrabContext *c = s->priv_data;
193  int64_t curtime, delay;
194  int64_t frame_time = av_rescale_q(1, c->time_base, AV_TIME_BASE_Q);
195 
196  c->time_frame += frame_time;
197 
198  for (;;) {
199  curtime = av_gettime();
200  delay = c->time_frame - curtime;
201  if (delay <= 0)
202  break;
203  av_usleep(delay);
204  }
205 
206  pkt->pts = curtime;
207 }
208 
209 #if CONFIG_LIBXCB_SHM
210 static int check_shm(xcb_connection_t *conn)
211 {
212  xcb_shm_query_version_cookie_t cookie = xcb_shm_query_version(conn);
213  xcb_shm_query_version_reply_t *reply;
214 
215  reply = xcb_shm_query_version_reply(conn, cookie, NULL);
216  if (reply) {
217  free(reply);
218  return 1;
219  }
220 
221  return 0;
222 }
223 
224 static int allocate_shm(AVFormatContext *s)
225 {
226  XCBGrabContext *c = s->priv_data;
228  uint8_t *data;
229  int id;
230 
231  if (c->buffer)
232  return 0;
233  id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
234  if (id == -1) {
235  char errbuf[1024];
236  int err = AVERROR(errno);
237  av_strerror(err, errbuf, sizeof(errbuf));
238  av_log(s, AV_LOG_ERROR, "Cannot get %d bytes of shared memory: %s.\n",
239  size, errbuf);
240  return err;
241  }
242  xcb_shm_attach(c->conn, c->segment, id, 0);
243  data = shmat(id, NULL, 0);
244  shmctl(id, IPC_RMID, 0);
245  if ((intptr_t)data == -1 || !data)
246  return AVERROR(errno);
247  c->buffer = data;
248  return 0;
249 }
250 
251 static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt)
252 {
253  XCBGrabContext *c = s->priv_data;
254  xcb_shm_get_image_cookie_t iq;
255  xcb_shm_get_image_reply_t *img;
256  xcb_drawable_t drawable = c->screen->root;
257  xcb_generic_error_t *e = NULL;
258  int ret;
259 
260  ret = allocate_shm(s);
261  if (ret < 0)
262  return ret;
263 
264  iq = xcb_shm_get_image(c->conn, drawable,
265  c->x, c->y, c->width, c->height, ~0,
266  XCB_IMAGE_FORMAT_Z_PIXMAP, c->segment, 0);
267  img = xcb_shm_get_image_reply(c->conn, iq, &e);
268 
269  xcb_flush(c->conn);
270 
271  if (e) {
272  av_log(s, AV_LOG_ERROR,
273  "Cannot get the image data "
274  "event_error: response_type:%u error_code:%u "
275  "sequence:%u resource_id:%u minor_code:%u major_code:%u.\n",
276  e->response_type, e->error_code,
277  e->sequence, e->resource_id, e->minor_code, e->major_code);
278 
279  return AVERROR(EACCES);
280  }
281 
282  free(img);
283 
284  pkt->data = c->buffer;
285  pkt->size = c->frame_size;
286 
287  return 0;
288 }
289 #endif /* CONFIG_LIBXCB_SHM */
290 
291 #if CONFIG_LIBXCB_XFIXES
292 static int check_xfixes(xcb_connection_t *conn)
293 {
294  xcb_xfixes_query_version_cookie_t cookie;
295  xcb_xfixes_query_version_reply_t *reply;
296 
297  cookie = xcb_xfixes_query_version(conn, XCB_XFIXES_MAJOR_VERSION,
298  XCB_XFIXES_MINOR_VERSION);
299  reply = xcb_xfixes_query_version_reply(conn, cookie, NULL);
300 
301  if (reply) {
302  free(reply);
303  return 1;
304  }
305  return 0;
306 }
307 
308 #define BLEND(target, source, alpha) \
309  (target) + ((source) * (255 - (alpha)) + 255 / 2) / 255
310 
311 static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt,
312  xcb_query_pointer_reply_t *p,
313  xcb_get_geometry_reply_t *geo)
314 {
315  XCBGrabContext *gr = s->priv_data;
316  uint32_t *cursor;
317  uint8_t *image = pkt->data;
318  int stride = gr->bpp / 8;
319  xcb_xfixes_get_cursor_image_cookie_t cc;
320  xcb_xfixes_get_cursor_image_reply_t *ci;
321  int cx, cy, x, y, w, h, c_off, i_off;
322 
323  cc = xcb_xfixes_get_cursor_image(gr->conn);
324  ci = xcb_xfixes_get_cursor_image_reply(gr->conn, cc, NULL);
325  if (!ci)
326  return;
327 
328  cursor = xcb_xfixes_get_cursor_image_cursor_image(ci);
329  if (!cursor)
330  return;
331 
332  cx = ci->x - ci->xhot;
333  cy = ci->y - ci->yhot;
334 
335  x = FFMAX(cx, gr->x);
336  y = FFMAX(cy, gr->y);
337 
338  w = FFMIN(cx + ci->width, gr->x + gr->width) - x;
339  h = FFMIN(cy + ci->height, gr->y + gr->height) - y;
340 
341  c_off = x - cx;
342  i_off = x - gr->x;
343 
344  cursor += (y - cy) * ci->width;
345  image += (y - gr->y) * gr->width * stride;
346 
347  for (y = 0; y < h; y++) {
348  cursor += c_off;
349  image += i_off * stride;
350  for (x = 0; x < w; x++, cursor++, image += stride) {
351  int r, g, b, a;
352 
353  r = *cursor & 0xff;
354  g = (*cursor >> 8) & 0xff;
355  b = (*cursor >> 16) & 0xff;
356  a = (*cursor >> 24) & 0xff;
357 
358  if (!a)
359  continue;
360 
361  if (a == 255) {
362  image[0] = r;
363  image[1] = g;
364  image[2] = b;
365  } else {
366  image[0] = BLEND(r, image[0], a);
367  image[1] = BLEND(g, image[1], a);
368  image[2] = BLEND(b, image[2], a);
369  }
370 
371  }
372  cursor += ci->width - w - c_off;
373  image += (gr->width - w - i_off) * stride;
374  }
375 
376  free(ci);
377 }
378 #endif /* CONFIG_LIBXCB_XFIXES */
379 
381 {
382  XCBGrabContext *c = s->priv_data;
383  const uint32_t args[] = { c->x - c->region_border,
384  c->y - c->region_border };
385 
386  xcb_configure_window(c->conn,
387  c->window,
388  XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
389  args);
390 }
391 
393 {
394  XCBGrabContext *c = s->priv_data;
395  xcb_query_pointer_cookie_t pc;
396  xcb_get_geometry_cookie_t gc;
397  xcb_query_pointer_reply_t *p = NULL;
398  xcb_get_geometry_reply_t *geo = NULL;
399  int ret = 0;
400 
401  wait_frame(s, pkt);
402 
403  if (c->follow_mouse || c->draw_mouse) {
404  pc = xcb_query_pointer(c->conn, c->screen->root);
405  gc = xcb_get_geometry(c->conn, c->screen->root);
406  p = xcb_query_pointer_reply(c->conn, pc, NULL);
407  geo = xcb_get_geometry_reply(c->conn, gc, NULL);
408  }
409 
410  if (c->follow_mouse && p->same_screen)
411  xcbgrab_reposition(s, p, geo);
412 
413  if (c->show_region)
415 
416 #if CONFIG_LIBXCB_SHM
417  if (c->has_shm && xcbgrab_frame_shm(s, pkt) < 0)
418  c->has_shm = 0;
419 #endif
420  if (!c->has_shm)
421  ret = xcbgrab_frame(s, pkt);
422 
423 #if CONFIG_LIBXCB_XFIXES
424  if (ret >= 0 && c->draw_mouse && p->same_screen)
425  xcbgrab_draw_mouse(s, pkt, p, geo);
426 #endif
427 
428  free(p);
429  free(geo);
430 
431  return ret;
432 }
433 
435 {
437 
438 #if CONFIG_LIBXCB_SHM
439  if (ctx->buffer) {
440  shmdt(ctx->buffer);
441  }
442 #endif
443 
444  xcb_disconnect(ctx->conn);
445 
446  return 0;
447 }
448 
449 static xcb_screen_t *get_screen(const xcb_setup_t *setup, int screen_num)
450 {
451  xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
452  xcb_screen_t *screen = NULL;
453 
454  for (; it.rem > 0; xcb_screen_next (&it)) {
455  if (!screen_num) {
456  screen = it.data;
457  break;
458  }
459 
460  screen_num--;
461  }
462 
463  return screen;
464 }
465 
467  int *pix_fmt)
468 {
469  XCBGrabContext *c = s->priv_data;
470  const xcb_setup_t *setup = xcb_get_setup(c->conn);
471  const xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
472  int length = xcb_setup_pixmap_formats_length(setup);
473 
474  *pix_fmt = 0;
475 
476  while (length--) {
477  if (fmt->depth == depth) {
478  switch (depth) {
479  case 32:
480  if (fmt->bits_per_pixel == 32)
481  *pix_fmt = AV_PIX_FMT_0RGB;
482  break;
483  case 24:
484  if (fmt->bits_per_pixel == 32)
485  *pix_fmt = AV_PIX_FMT_0RGB32;
486  else if (fmt->bits_per_pixel == 24)
487  *pix_fmt = AV_PIX_FMT_RGB24;
488  break;
489  case 16:
490  if (fmt->bits_per_pixel == 16)
491  *pix_fmt = AV_PIX_FMT_RGB565;
492  break;
493  case 15:
494  if (fmt->bits_per_pixel == 16)
495  *pix_fmt = AV_PIX_FMT_RGB555;
496  break;
497  case 8:
498  if (fmt->bits_per_pixel == 8)
499  *pix_fmt = AV_PIX_FMT_RGB8;
500  break;
501  }
502  }
503 
504  if (*pix_fmt) {
505  c->bpp = fmt->bits_per_pixel;
506  c->frame_size = c->width * c->height * fmt->bits_per_pixel / 8;
507  return 0;
508  }
509 
510  fmt++;
511  }
512  avpriv_report_missing_feature(s, "Mapping this pixmap format");
513 
514  return AVERROR_PATCHWELCOME;
515 }
516 
518 {
519  XCBGrabContext *c = s->priv_data;
521  xcb_get_geometry_cookie_t gc;
522  xcb_get_geometry_reply_t *geo;
523  int ret;
524 
525  if (!st)
526  return AVERROR(ENOMEM);
527 
528  ret = av_parse_video_size(&c->width, &c->height, c->video_size);
529  if (ret < 0)
530  return ret;
531 
533  if (ret < 0)
534  return ret;
535 
536  avpriv_set_pts_info(st, 64, 1, 1000000);
537 
538  gc = xcb_get_geometry(c->conn, c->screen->root);
539  geo = xcb_get_geometry_reply(c->conn, gc, NULL);
540 
541  if (c->x + c->width > geo->width ||
542  c->y + c->height > geo->height) {
543  av_log(s, AV_LOG_ERROR,
544  "Capture area %dx%d at position %d.%d "
545  "outside the screen size %dx%d\n",
546  c->width, c->height,
547  c->x, c->y,
548  geo->width, geo->height);
549  return AVERROR(EINVAL);
550  }
551 
553  st->avg_frame_rate.num };
554  c->time_frame = av_gettime();
555 
558  st->codecpar->width = c->width;
559  st->codecpar->height = c->height;
560 
561  ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codecpar->format);
562 
563  free(geo);
564 
565  return ret;
566 }
567 
569 {
570  XCBGrabContext *c = s->priv_data;
571  xcb_gcontext_t gc = xcb_generate_id(c->conn);
572  uint32_t mask = XCB_GC_FOREGROUND |
573  XCB_GC_BACKGROUND |
574  XCB_GC_LINE_WIDTH |
575  XCB_GC_LINE_STYLE |
576  XCB_GC_FILL_STYLE;
577  uint32_t values[] = { c->screen->black_pixel,
578  c->screen->white_pixel,
579  c->region_border,
580  XCB_LINE_STYLE_DOUBLE_DASH,
581  XCB_FILL_STYLE_SOLID };
582  xcb_rectangle_t r = { 1, 1,
583  c->width + c->region_border * 2 - 3,
584  c->height + c->region_border * 2 - 3 };
585 
586  xcb_create_gc(c->conn, gc, c->window, mask, values);
587 
588  xcb_poly_rectangle(c->conn, c->window, gc, 1, &r);
589 }
590 
592 {
593  XCBGrabContext *c = s->priv_data;
594  uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
595  uint32_t values[] = { 1,
596  XCB_EVENT_MASK_EXPOSURE |
597  XCB_EVENT_MASK_STRUCTURE_NOTIFY };
598  av_unused xcb_rectangle_t rect = { 0, 0, c->width, c->height };
599 
600  c->window = xcb_generate_id(c->conn);
601 
602  xcb_create_window(c->conn, XCB_COPY_FROM_PARENT,
603  c->window,
604  c->screen->root,
605  c->x - c->region_border,
606  c->y - c->region_border,
607  c->width + c->region_border * 2,
608  c->height + c->region_border * 2,
609  0,
610  XCB_WINDOW_CLASS_INPUT_OUTPUT,
611  XCB_COPY_FROM_PARENT,
612  mask, values);
613 
614 #if CONFIG_LIBXCB_SHAPE
615  xcb_shape_rectangles(c->conn, XCB_SHAPE_SO_SUBTRACT,
616  XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
617  c->window,
619  1, &rect);
620 #endif
621 
622  xcb_map_window(c->conn, c->window);
623 
624  draw_rectangle(s);
625 }
626 
628 {
629  XCBGrabContext *c = s->priv_data;
630  int screen_num, ret;
631  const xcb_setup_t *setup;
632  char *display_name = av_strdup(s->url);
633 
634  if (!display_name)
635  return AVERROR(ENOMEM);
636 
637  if (!sscanf(s->url, "%[^+]+%d,%d", display_name, &c->x, &c->y)) {
638  *display_name = 0;
639  sscanf(s->url, "+%d,%d", &c->x, &c->y);
640  }
641 
642  c->conn = xcb_connect(display_name[0] ? display_name : NULL, &screen_num);
643  av_freep(&display_name);
644 
645  if ((ret = xcb_connection_has_error(c->conn))) {
646  av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n",
647  s->url[0] ? s->url : "default", ret);
648  return AVERROR(EIO);
649  }
650 
651  setup = xcb_get_setup(c->conn);
652 
653  c->screen = get_screen(setup, screen_num);
654  if (!c->screen) {
655  av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n",
656  screen_num);
658  return AVERROR(EIO);
659  }
660 
661  ret = create_stream(s);
662 
663  if (ret < 0) {
665  return ret;
666  }
667 
668 #if CONFIG_LIBXCB_SHM
669  if ((c->has_shm = check_shm(c->conn)))
670  c->segment = xcb_generate_id(c->conn);
671 #endif
672 
673 #if CONFIG_LIBXCB_XFIXES
674  if (c->draw_mouse) {
675  if (!(c->draw_mouse = check_xfixes(c->conn))) {
677  "XFixes not available, cannot draw the mouse.\n");
678  }
679  if (c->bpp < 24) {
680  avpriv_report_missing_feature(s, "%d bits per pixel screen",
681  c->bpp);
682  c->draw_mouse = 0;
683  }
684  }
685 #endif
686 
687  if (c->show_region)
688  setup_window(s);
689 
690  return 0;
691 }
692 
694  .name = "x11grab",
695  .long_name = NULL_IF_CONFIG_SMALL("X11 screen capture, using XCB"),
696  .priv_data_size = sizeof(XCBGrabContext),
700  .flags = AVFMT_NOFILE,
701  .priv_class = &xcbgrab_class,
702 };
static xcb_screen_t * get_screen(const xcb_setup_t *setup, int screen_num)
Definition: xcbgrab.c:449
AVInputFormat ff_xcbgrab_demuxer
Definition: xcbgrab.c:693
#define NULL
Definition: coverity.c:32
xcb_connection_t * conn
Definition: xcbgrab.c:54
static enum AVPixelFormat pix_fmt
static av_cold int xcbgrab_read_header(AVFormatContext *s)
Definition: xcbgrab.c:627
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:179
static int create_stream(AVFormatContext *s)
Definition: xcbgrab.c:517
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
Parse str and put in width_ptr and height_ptr the detected values.
Definition: parseutils.c:148
static void xcbgrab_update_region(AVFormatContext *s)
Definition: xcbgrab.c:380
const char * fmt
Definition: avisynth_c.h:861
uint8_t * buffer
Definition: xcbgrab.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4929
const char * g
Definition: vf_curves.c:115
static void draw_rectangle(AVFormatContext *s)
Definition: xcbgrab.c:568
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3968
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1481
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
xcb_window_t window
Definition: xcbgrab.c:56
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
static AVPacket pkt
int centered
Definition: xcbgrab.c:72
Format I/O context.
Definition: avformat.h:1358
#define img
int frame_size
Definition: xcbgrab.c:65
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
uint8_t
#define av_cold
Definition: attributes.h:82
int width
Video only.
Definition: avcodec.h:4034
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4502
static const AVClass xcbgrab_class
Definition: xcbgrab.c:100
xcb_screen_t * screen
Definition: xcbgrab.c:55
uint8_t * data
Definition: avcodec.h:1480
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s it
static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt)
Definition: xcbgrab.c:149
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
ptrdiff_t size
Definition: opengl_enc.c:100
#define av_log(a,...)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth, int *pix_fmt)
Definition: xcbgrab.c:466
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
AVRational time_base
Definition: xcbgrab.c:61
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static const uint16_t mask[17]
Definition: lzw.c:38
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
char * url
input or output URL.
Definition: avformat.h:1454
const char * r
Definition: vf_curves.c:114
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3964
GLsizei GLsizei * length
Definition: opengl_enc.c:114
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:954
#define FFMAX(a, b)
Definition: common.h:94
Definition: hls.c:68
common internal API header
#define b
Definition: input.c:41
#define FFMIN(a, b)
Definition: common.h:96
static const AVOption options[]
Definition: xcbgrab.c:84
const char * framerate
Definition: xcbgrab.c:75
uint8_t w
Definition: llviddspenc.c:38
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return values
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
static void wait_frame(AVFormatContext *s, AVPacket *pkt)
Definition: xcbgrab.c:190
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
Stream structure.
Definition: avformat.h:881
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
int64_t time_frame
Definition: xcbgrab.c:60
const char * video_size
Definition: xcbgrab.c:74
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:206
int show_region
Definition: xcbgrab.c:70
Describe the class of an AVClass context structure.
Definition: log.h:67
Definition: f_ebur128.c:91
static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: xcbgrab.c:392
Rational number (pair of numerator and denominator).
Definition: rational.h:58
misc parsing utilities
#define OFFSET(x)
Definition: xcbgrab.c:82
static void setup_window(AVFormatContext *s)
Definition: xcbgrab.c:591
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define flags(name, subs,...)
Definition: cbs_av1.c:561
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:105
static int xcbgrab_reposition(AVFormatContext *s, xcb_query_pointer_reply_t *p, xcb_get_geometry_reply_t *geo)
Definition: xcbgrab.c:108
Main libavformat public API header.
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
#define D
Definition: xcbgrab.c:83
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
int region_border
Definition: xcbgrab.c:71
static av_cold int xcbgrab_read_close(AVFormatContext *s)
Definition: xcbgrab.c:434
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
int den
Denominator.
Definition: rational.h:60
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:793
int follow_mouse
Definition: xcbgrab.c:69
void * priv_data
Format private data.
Definition: avformat.h:1386
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:374
int draw_mouse
Definition: xcbgrab.c:68
#define av_freep(p)
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:654
#define FOLLOW_CENTER
Definition: xcbgrab.c:80
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
#define stride
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
enum AVCodecID id
This structure stores compressed data.
Definition: avcodec.h:1457
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1473
#define av_unused
Definition: attributes.h:125
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:364