/* * video.c: A plugin for the Video Disk Recorder * * See the README file for copyright information and how to reach the author. * * $Id: video-fb.c,v 1.21 2008-02-26 10:53:22 lucke Exp $ * * This is a software output driver. * It scales the image more or less perfect in sw and put it into the framebuffer * This should work with every 16 bit FB (15 bit mode not tested) */ #include #include #include #include #include "video-fb.h" #include "utils.h" #include "setup-softdevice.h" static pthread_mutex_t fb_mutex = PTHREAD_MUTEX_INITIALIZER; // --- cFrameBuffer -------------------------------------------------------- cFBVideoOut::cFBVideoOut(cSetupStore *setupStore, cSetupSoftlog *Softlog) : cVideoOut(setupStore, Softlog) { char *fbName = getFBName(); printf("[video-fb] Initializing Driver\n"); if ((fbdev = open(fbName, O_RDWR)) == -1) { printf("[video-fb] cant open framebuffer %s\n", fbName); free(fbName); exit(1); } free(fbName); if (ioctl(fbdev, FBIOGET_VSCREENINFO, &fb_vinfo)) { printf("[video-fb] Can't get VSCREENINFO\n"); exit(1); } if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fb_finfo)) { printf("[video-fb] Can't get FSCREENINFO\n"); exit(1); } fb_orig_vinfo = fb_vinfo; size = fb_finfo.smem_len; line_len = fb_finfo.line_length; if ((fb = (unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev, 0)) == (unsigned char *) -1) { printf("[video-fb] Can't mmap\n"); exit(1); } // set up picture buffer; privBuf.pixel[0]=fb; privBuf.stride[0]=line_len; if (fb_vinfo.red.length==5 && fb_vinfo.green.length==5 && fb_vinfo.blue.length==5 ) Bpp=15; else Bpp=fb_vinfo.bits_per_pixel; switch (Bpp) { case 32 : privBuf.format=PIX_FMT_RGBA32; break; case 24 : privBuf.format=PIX_FMT_RGB24; break; case 16 : privBuf.format=PIX_FMT_RGB565; break; default: privBuf.format=PIX_FMT_RGB555; }; privBuf.max_width=dwidth=fb_vinfo.xres; privBuf.max_height=dheight=fb_vinfo.yres; SetParValues ((double) fb_vinfo.xres / (double) fb_vinfo.yres, (double) fb_vinfo.xres / (double) fb_vinfo.yres); switch (fb_finfo.visual) { case FB_VISUAL_TRUECOLOR: printf("[video-fb] Truecolor FB found\n"); break; case FB_VISUAL_DIRECTCOLOR: struct fb_cmap cmap; __u16 red[256], green[256], blue[256]; printf("[video-fb] DirectColor FB found\n"); orig_cmaplen = 1<cropTopLines || cutBottom != setupStore->cropBottomLines || cutLeft != setupStore->cropLeftCols || cutRight != setupStore->cropRightCols) { aspect_changed = 0; cutTop = setupStore->cropTopLines; cutBottom = setupStore->cropBottomLines; cutLeft = setupStore->cropLeftCols; cutRight = setupStore->cropRightCols; ClearPicBuffer(&privBuf); } if ( OSDpresent ) { CopyScalePicBufAlphaBlend(&privBuf,buf, sxoff, syoff, swidth, sheight, lxoff, lyoff, lwidth, lheight, OsdPy,OsdPu,OsdPv, OsdPAlphaY,OsdPAlphaUV,OSD_FULL_WIDTH, cutTop,cutBottom,cutLeft,cutRight); } else { CopyScalePicBuf(&privBuf, buf, sxoff, syoff, swidth, sheight, lxoff, lyoff, lwidth, lheight, cutTop,cutBottom,cutLeft,cutRight); }; pthread_mutex_unlock(&fb_mutex); } /* --------------------------------------------------------------------------- */ cFBVideoOut::~cFBVideoOut() { switch (fb_finfo.visual) { case FB_VISUAL_DIRECTCOLOR: { struct fb_cmap cmap; if ( orig_cmap ) { cmap.start = 0; cmap.len = orig_cmaplen; cmap.red = &orig_cmap[0*orig_cmaplen]; cmap.green = &orig_cmap[1*orig_cmaplen]; cmap.blue = &orig_cmap[2*orig_cmaplen]; cmap.transp = NULL; if ( ioctl(fbdev, FBIOPUTCMAP, &cmap)) { printf("cFBVideoOut : Can't put cmap\n"); } free(orig_cmap); orig_cmap = NULL; } break; } } if (fbdev) close(fbdev); } #ifdef USE_SUBPLUGINS /* --------------------------------------------------------------------------- */ extern "C" void * SubPluginCreator(cSetupStore *s, cSetupSoftlog *log) { return new cFBVideoOut(s,log); } #endif