gpt4 book ai didi

c - Linux 帧缓冲区低效的帧抓取

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:40 25 4
gpt4 key购买 nike

我尝试从 Linux 帧缓冲区中重复抓取一个帧,但每个帧需要大约一秒钟的时间。

虽然我没想到 60FPS,但我希望超过 60FPM。这是正常的吗?我正在使用开源视频驱动程序;我的 GPU 是 AMD 280X,我的 CPU 是 AMD 8320 @ 4.4GHz。

我的代码看起来像这样:

static uint8_t *previous_buffer;
static uint8_t *fbp;

static long int location = 0;
long int screensize = 0;

int sf = open("/dev/fb0",O_RDWR);
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;

ioctl(sf, FBIOGET_FSCREENINFO, &finfo);
ioctl(sf, FBIOGET_VSCREENINFO, &vinfo);

screensize = finfo.smem_len;

fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, sf, (off_t)0);

previous_buffer = malloc(screensize);

bytespp = (vinfo.bits_per_pixel / 8);

for(int x = 0; x < vinfo->xres * bytespp; x+=bytespp)
for(int y = 0; y < vinfo->yres * finfo->line_length; y+=finfo->line_length){
//printf("xoff: %d yoff:%d x:%d y:%d\n", xoff, yoff, x, y);
location = x + y + off;
//printf("Location: %lu\n", location);
if(*((uint32_t*)(fbp+location)) != *((uint32_t*)(previous_buffer+location))){
memcpy((fbp+location), (previous_buffer+location), 4); // sizeof(uint32_t)
d1++;
}
}

我的完整代码可用here ,但我认为循环是重要的部分。

此外,我尝试运行来自 this website 的程序它将每个像素设置为粉红色,循环本身只用了 7 毫秒(即使它在循环的每次运行中执行乘法和除法):

#include <linux/fb.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

inline uint32_t pixel_color(uint8_t r, uint8_t g, uint8_t b, struct fb_var_screeninfo *vinfo)
{
return (r<<vinfo->red.offset) | (g<<vinfo->green.offset) | (b<<vinfo->blue.offset);
}

int main()
{
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;

int fb_fd = open("/dev/fb0",O_RDWR);

//Get variable screen information
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);
vinfo.grayscale=0;
vinfo.bits_per_pixel=32;
ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vinfo);
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);

ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);

long screensize = vinfo.yres_virtual * finfo.line_length;

uint8_t *fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, (off_t)0);

int x,y;

for (x=0;x<vinfo.xres;x++)
for (y=0;y<vinfo.yres;y++)
{
long location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length;
*((uint32_t*)(fbp + location)) = pixel_color(0xFF,0x00,0xFF, &vinfo);
}

return 0;
}

写入帧缓冲区真的比从中读取快得多吗?

最佳答案

我对循环的(未经测试的)建议:

void const *start = (fbp + vinfo->yoffset * finfo->line_length + 
vinfo->xoffset * bytespp);
void *out = previous_buffer;
size_t xres_bytes = vinfo->xres * bytespp;
size_t d_stride = finfo->line_length - xres_bytes;

if (d_stride == 0 && allow_memcpy) {
memcpy(out, start, finfo->line_length * vinfo->yres);
} else {
for (int y = 0; y < vinfo->yres_virtual; ++y) {
start += d_stride;
if (allow_memcpy) {
out = mempcpy(out, start, xres_bytes);
start += xres_bytes;
} else {
/* or do the #include thing below here */
for (int x = 0; x < vinfo->xres_virtual; ++x) {
switch (bytesbpp) {
case 1: out = mempcpy(out, start, 1); break;
case 2: out = mempcpy(out, start, 2); break;
case 3: out = mempcpy(out, start, 3); break;
case 4: out = mempcpy(out, start, 4); break;
default: out = mempcpy(out, start, bytesbpp); break;
}
start += bytesbpp;
}
}
}
}

当你想进一步优化它时,你可以将内部 x 循环放入一个额外的文件(例如 inner-x-loop.inc.h)并包含喜欢

if (bytesbpp == 1) {
#include "inner-x-loop.inc.h"
} else if (bytesbpp == 2) {
#include "inner-x-loop.inc.h"
} else if (bytesbpp == 3) {
#include "inner-x-loop.inc.h"
} else if (bytesbpp == 4) {
#include "inner-x-loop.inc.h"
} else
#include "inner-x-loop.inc.h"
}

枚举bytesbpp允许编译器内联mempcpy()

关于c - Linux 帧缓冲区低效的帧抓取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36360139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com