我正在使用 xcb-shm 来捕获屏幕。我创建与屏幕分辨率相同的 drm/gbm 缓冲区,然后将其 fd 提供给
xcb_shm_attach_fd()
。有时,我创建的 drm/gbm 缓冲区的步幅大小与 xcb 的 geometry->width * 4
不相等,这使得一切都被破坏。
当我尝试捕获 1920x1080 分辨率时,一切都很好,因为我创建的 drm/gbm 缓冲区与
1920 * 4
具有相同的步幅。但是当我为我的第一个 1366x768 显示器创建 drm/gbm 缓冲区时,drm/gbm 的步幅不是 1366 * 4
。是1408 * 4
。当我将 drm/gbm 缓冲区提供给 xcb 来捕获屏幕时,我得到了损坏的结果。我使用 gbm_bo_create()
并使用 gbm_bo_get_stride()
迈出一大步。
我如何知道 shm/fd 的步幅为
xcb_shm_get_image()
?或者是否有更快/类似的方法来捕获屏幕来处理 shm/fd 步幅?
嗯,好吧。这里尝试解释一下。 我认为以下内容不会为您提供任何新信息。
第一:SHM 使用与普通 X11 相同的像素格式。因此
xcb_shm_get_image()
为您提供与 xcb_get_image()
相同的格式。像素数据的格式取决于深度和视觉效果。有关这些的信息位于 xcb_get_setup()
的结果中,并由 /usr/bin/xdpyinfo
打印。
让我们看一下我的 X11 服务器的示例。
xdpyinfo
介绍了像素图格式:
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
这包含有关如何存储数据的信息。 “现在”,我们只关心深度 24 和深度 32。它们都使用每像素 32 位,即 4 字节。在扫描线的末尾,内容被填充为 32 位的倍数。由于每个像素的大小已经是 32 位,这基本上意味着没有填充。
接下来,我的 X11 服务器的默认视觉效果是什么?为什么是这个?只是因为有太多,我必须以某种方式选择一个。
screen #0:
[...]
default visual id: 0x21
visual:
visual id: 0x21
class: TrueColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 8 bits
该视觉效果使用 24 的深度。正如我们在上面看到的,这意味着每个像素有 4 个字节,并且在扫描线末尾没有额外的填充。
换句话说:尺寸为
w
xh
的图像需要 w*h*4
字节,每行需要 w*4
字节。
请注意https://www.x.org/releases/X11R7.7/doc/xextproto/shm.html#USE_OF_SHARED_MEMORY_PIXMAPS说
与任何图像格式都可用的 X 图像不同,共享内存扩展仅支持共享内存像素图中存储的数据的单一格式(即 XYPixmap 或 ZPixmap)。
但是,我怀疑是否有任何 X11 服务器实际上使用了这一点。
XYPixmap
很奇怪...