#include #include #include #include #include #include #include #include #include #include #include volatile sig_atomic_t flag = 0; void Error(const char * format, ...) { fprintf(stderr, "Error: "); va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); } // fast and only approximate void DownsampleFrameBufferBGRA2RGB(uint8_t *in, int xin, int yin, uint8_t* out, int xout, int yout){ int sx = xin/xout; int sy = yin/yout; int size = sx*sy; for(int y = 0; y != yout; y++){ for(int x = 0; x != xout; x++){ int xmin = x*xin/xout; int ymin = y*yin/yout; int xmax = xmin+sx; int ymax = ymin+sy; int r = 0, g = 0, b = 0; int idx = xmin+ymin*xin; uint8_t *mem = in+4*idx; for (int yp = ymin; yp != ymax; yp++ ){ for (int xp =xmin; xp != xmax; xp++ ){ b += *mem++; g += *mem++; r += *mem++; mem++; } mem += 4*(xin-sx); } *out++ = r/size; *out++ = g/size; *out++ = b/size; } } } void SignalHandler(int sig){ flag = 1; } int main(int argc, char **argv) { //DISPMANX_RESOURCE_HANDLE_T screen_resource; uint32_t image_prt; //VC_RECT_T rect1; int ret; int fbfd = 0; char *framebuffer_gbra = 0; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; int serial; int x = atoi(argv[2]); int y = atoi(argv[3]); uint8_t * out_rgb = malloc(x*y*3+1); signal(SIGINT, SignalHandler); if (argc < 4){ fprintf(stderr, "Wrong number of parameters, should be:\n\n"); fprintf(stderr, " fbcp \n\n"); fprintf(stderr, "i.e. fbcp /dev/fb0\n"); goto exit; } fbfd = open(argv[1], O_RDWR); if (fbfd == -1) { Error("Unable to open display %s", argv[2]); goto clean1_1; } if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { Error("Unable to get display information"); goto clean2; } if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { Error("Unable to get display information"); goto clean2; } fprintf(stderr, "Display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); if (vinfo.bits_per_pixel != 32){ Error("Display has %i bits per pixel. This program only works for 32.", vinfo.bits_per_pixel); } framebuffer_gbra = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if (framebuffer_gbra <= 0) { Error("Unable to create framebuffer memory mapping"); goto clean3; } FILE *logfile = fopen("out.log", "w"); int frame = 0; while(!flag) { // vc_dispmanx_resource_read_data(screen_resource, &rect1, framebuffer_gbra, vinfo.xres * vinfo.bits_per_pixel / 8); fflush(logfile); uint8_t* out = out_rgb; *out++ = 1; // Begin of frame marker DownsampleFrameBufferBGRA2RGB(framebuffer_gbra, vinfo.xres, vinfo.yres, out, x, y); write(1, out_rgb+1, x*y*3); frame++; } clean4: munmap(framebuffer_gbra, finfo.smem_len); clean3: clean2: close(fbfd); clean1_1: clean1: exit: return 0; }