You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于X11/Xlib的虚拟显示RGB像素获取及CPU优化问询

优化方案:生成RGB格式像素数据并降低CPU占用

可以实现直接(或高效)生成RGBRGBRGB格式的像素数据,同时通过减少内存拷贝开销、优化循环逻辑、改用更高效的截图方式来降低CPU占用。以下是具体方案:

1. 修正像素顺序(匹配RGB格式需求)

原代码存储的是BGRBGRBGR顺序,若需严格的RGBRGBRGB格式,需调整赋值顺序:

// 原BGR顺序赋值
img_packets[i].arr[j+2] = image->data[w+2];//red
img_packets[i].arr[j+1] = image->data[w+1];//green
img_packets[i].arr[j+0] = image->data[w+0];//blue

// 修改为RGB顺序赋值
img_packets[i].arr[j+0] = image->data[w+2];//red
img_packets[i].arr[j+1] = image->data[w+1];//green
img_packets[i].arr[j+2] = image->data[w+0];//blue

2. 优化循环逻辑:用指针代替数组下标

数组下标访问需要额外偏移计算,改用指针直接操作可显著提升循环效率:

while(1)
{
    XImage *image = XGetImage(Display, root, 0, 0, display_width, display_height, AllPlanes, ZPixmap);
    if (!image) continue; // 新增空指针判断

    int line_size_src = image->bytes_per_line;
    unsigned char *src_base = image->data;

    for(int i = 1; i <= display_height; i++)
    {
        unsigned char *src = src_base + line_size_src * (i-1);
        unsigned char *dst = img_packets[i].arr + header_size;
        int pixel_count = display_width;

        // 逐像素转换,指针直接移动
        for (int k = 0; k < pixel_count; k++) {
            *dst++ = src[2]; // Red
            *dst++ = src[1]; // Green
            *dst++ = src[0]; // Blue
            src += 4; // 跳过Alpha通道
        }
    }
    XDestroyImage(image);
    // 添加帧率控制,避免CPU满载(按60fps设置延迟)
    usleep(16667);
}

3. 改用共享内存截图(XShm):大幅降低数据拷贝开销

XGetImage通过X协议跨进程拷贝数据,开销极大。XShmCreateImage使用共享内存直接映射服务器端图像数据,避免冗余拷贝,能显著降低CPU占用:

#include <X11/extensions/XShm.h>

void func(struct data *img_packets)
{
    Display *display = XOpenDisplay(NULL);
    if(!display)
    {
        fprintf(stderr, "%s\n", strerror(errno));
        return;
    }
    Window root = DefaultRootWindow(display);

    XWindowAttributes attributes;
    XGetWindowAttributes(display, root, &attributes);
    int width = display_width;
    int height = display_height;

    // 创建共享内存图像
    XShmSegmentInfo shminfo;
    XImage *image = XShmCreateImage(display, DefaultVisual(display, 0),
                                    attributes.depth, ZPixmap, NULL, &shminfo,
                                    width, height);
    if (!image) {
        fprintf(stderr, "Failed to create shared memory image\n");
        XCloseDisplay(display);
        return;
    }

    // 分配并挂载共享内存
    shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height, IPC_CREAT|0777);
    shminfo.shmaddr = image->data = (char*)shmat(shminfo.shmid, NULL, 0);
    shminfo.readOnly = False;
    if (!XShmAttach(display, &shminfo)) {
        fprintf(stderr, "Failed to attach shared memory\n");
        shmdt(shminfo.shmaddr);
        shmctl(shminfo.shmid, IPC_RMID, NULL);
        XDestroyImage(image);
        XCloseDisplay(display);
        return;
    }

    while(1)
    {
        // 从共享内存获取图像
        XShmGetImage(display, root, image, 0, 0, AllPlanes);

        unsigned char *src_base = image->data;
        int line_size_src = image->bytes_per_line;

        for(int i = 1; i <= height; i++)
        {
            unsigned char *src = src_base + line_size_src * (i-1);
            unsigned char *dst = img_packets[i].arr + header_size;
            int pixel_count = width;

            // 批量转换为RGB格式
            for (int k = 0; k < pixel_count; k++) {
                *dst++ = src[2]; // Red
                *dst++ = src[1]; // Green
                *dst++ = src[0]; // Blue
                src += 4;
            }
        }

        // 控制帧率,降低CPU占用
        usleep(16667);
    }

    // 资源清理(需添加退出逻辑才能执行到此处)
    XShmDetach(display, &shminfo);
    shmdt(shminfo.shmaddr);
    shmctl(shminfo.shmid, IPC_RMID, NULL);
    XDestroyImage(image);
    XCloseDisplay(display);
}

4. 额外优化细节

  • 帧率控制:原代码无限循环无延迟会导致CPU满载,添加usleep可按需求控制帧率(如60fps对应16ms左右延迟)。
  • 错误处理:新增XGetImage、XShmCreateImage等操作的错误判断,避免空指针访问或资源泄漏。
  • 预计算常量:提前计算display_width、display_height等常量,避免循环内重复计算。

内容的提问来源于stack exchange,提问作者Bpwnz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 05:42:46