私はLinuxフレームバッファーからフレームを繰り返し取得しようとしていますが、フレームごとに約2秒かかります。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利用可能ですが、私はループが重要な部分だと思います:
私のコードは次のようになります。
#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;
}
:(それはそのループの各実行で乗算および除算を実行しても)
さらに、私はピンクに、各画素を設定this websiteからプログラムを実行しようとした、ループ自体のみ7MSを取りましたフレームバッファへの書き込みは、それよりもはるかに速いですか?
各ループ内で高価な操作(乗算)を行っています。ピクセルとラインごとにポインタをインクリメントすることでそれらを避けてください。これのためにxとyのループを入れ替えるべきです。 – ensc
2つの提案:まず、それらの 'uint32_t'ポインタのキャストを取り除くと、コードが読めなくなります。内部ループの 'if'チェックを取り除くと、そのオーバヘッドはおそらくあなたがそれを保存しようとする時よりも大きいでしょう。最後に、 'memcpy()'またはGCCが提供する一式の整列された亜種のうちの一つを使って、行全体をコピーしてください。つまり、あなたのコードはどこで正確に時間を費やしていますか?コードをプロファイルしましたか? –
@UlrichEckhardt 'uint32_t'ポインタのキャストを取り除き、フレームバッファのポインタから' memcpy'を 'uint32_t'のサイズの以前のバッファポインタに置き換えました(与えられた行は全ピクセルではありません) 、性能はほぼ同等(すなわち、990ms)であった。 – Vreality