/* * xlibvid.cxx * *This file contains the class heirachy for 1)creating windows under xlib. * 2)displaying data on those windows * 3)converting image formats. * * Copyright (c) 1999-2000 Indranet Technologies ltd * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Open H323 * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): Author Derek J Smithies (derek@indranet.co.nz) * * Note the license of this file was changed to the above with the full * permission of the authors. * * $Log: xlibvid.cxx,v $ * Revision 1.20 2003/03/18 07:11:34 robertj * Removed openh323 versions of videoio.h classes as PVideoOutputDevice * descendants for NULL and PPM files added to PWLib. * * Revision 1.19 2002/10/08 08:19:19 dereks * Fix so compiles with gcc 3.2 (Redhat 8.0) * * Revision 1.18 2002/06/27 02:17:40 robertj * Renamed video format 411 to the correct 420P, thanks Mark Cooke * * Revision 1.17 2001/05/25 01:14:44 dereks * Alter SetFrameSize & OpenWindo to use unsigned variables. Change type of * other variables to eliminate compiler warnings. * * Revision 1.16 2001/05/03 02:28:35 robertj * Fixed problem with KDE events, thanks Tom Dolsky * * Revision 1.15 2000/12/19 22:35:53 dereks * Install revised video handling code, so that a video channel is used. * Code now better handles the situation where the video grabber could not be opened. * * Revision 1.14 2000/09/27 03:06:13 dereks * Added lots of PTRACE statements to xlib code. * Removed X videoMutex from main.cxx & main.h * Removed some weird display issues from X code. * * Revision 1.13 2000/09/15 03:36:29 dereks * remove debug message * * Revision 1.12 2000/09/13 23:58:12 dereks * Corrected bug in video display. Now correctly handles 8, 16, 32 bit colour * Correctly handles 8 bit grayscale. * * Revision 1.11 2000/09/08 06:49:14 craigs * Removed extensive comment at end of file * * Revision 1.10 2000/09/08 03:43:00 dereks * Fix 8 and 16 bit display options. * * Revision 1.9 2000/08/21 04:41:58 dereks * Add parameter to set a)transmitted video quality and b)number of unchanged * blocks that are sent with every frame. * Fix some problems introduced with --videopip option. * * Revision 1.8 2000/08/07 03:47:42 dereks * Add picture in picture option (only for X window display), better handling * of X windows. Handles situation where user selects cross on a X window. * * Revision 1.6 2000/07/03 06:35:20 craigs * Added ability for video to work on 24, 16 and 8 bit visuals * * Revision 1.5 2000/05/02 04:32:25 robertj * Fixed copyright notice comment. * */ #ifdef HAS_X11 #include #include #include #include #include #include "xlibvid.h" int GenericXlibVideoDevice::nWindowsOpen=0; Window GenericXlibVideoDevice::win[2]; Display *GenericXlibVideoDevice::display; GC GenericXlibVideoDevice::gc; Visual *GenericXlibVideoDevice::visual; PMutex GenericXlibVideoDevice::videoMutex; Colormap GenericXlibVideoDevice::colormap; int GenericXlibVideoDevice::pixelDepth; int GenericXlibVideoDevice::byteDepth; BOOL GenericXlibVideoDevice::useGrayScale; int GenericXlibVideoDevice::nGrayColors; unsigned long GenericXlibVideoDevice::grayColors[64 ]; float GenericXlibVideoDevice::grayScaleFactor ; int GenericXlibVideoDevice::redLoose; int GenericXlibVideoDevice::greenLoose; int GenericXlibVideoDevice::blueLoose; int GenericXlibVideoDevice::redPos; int GenericXlibVideoDevice::greenPos; int GenericXlibVideoDevice::bluePos; XImage *GenericXlibVideoDevice::images[4]; BYTE *GenericXlibVideoDevice::pixels[4]; int GenericXlibVideoDevice::displayWidth[2]; int GenericXlibVideoDevice::displayHeight[2]; XShmSegmentInfo ShmXlibVideoDevice::shminfo[4]; //Error handler for messages from X. cannot be included in a class. int XLibErrorHandler(Display *dpy,XErrorEvent *ee) { #if 0 cerr<< "Error handler called in "<error_code<<" " << (int)ee->request_code<<" "<<(int)ee->minor_code<<::dec<error_code==BadDrawable) cerr <<"Internal error. Code attempted to manipulate non existant window"<= 24) && (!foundVisual) && ( visualInfo[index].c_class == DirectColor || visualInfo[index].c_class == TrueColor) ) { visualIndex = index; foundVisual = TRUE; byteDepth = 4; } //Look for 16 bit visual that supports direct or true colour. for(index=0; (indexc_class != PseudoColor) { useGrayScale = FALSE; MaskCalc(redPos, redLoose, visual->red_mask); MaskCalc(greenPos, greenLoose, visual->green_mask); MaskCalc(bluePos, blueLoose, visual->blue_mask); PTRACE(3,"XDisplay\t Display bitmap:RED loose "< 128) num = 128; for (i = 0; i < num; ++i) { xcol.red = xcol.green = xcol.blue = 65535*i/(num-1); xcol.flags = DoRed | DoGreen | DoBlue; if (!XAllocColor(display, colormap, &xcol)) { if (i) XFreeColors(display, colormap, grayColors, i, 0); AllocGrays(num/2); return; } grayColors[i] = xcol.pixel; } nGrayColors= num; grayScaleFactor= nGrayColors/((float)255.0); PTRACE(3,"XDisplay\t Allocated "<0xffffff)?0xff0000:((x<=0xffff)?0:x&0xff0000))>>16) void GenericXlibVideoDevice::Translate420PInput(BYTE *d, const void *frame) { const BYTE * yplane = (const BYTE *) frame; const BYTE * yplane2 = yplane + width; const BYTE * uplane = yplane + n_bytes; const BYTE * vplane = yplane + n_bytes + (n_bytes >> 2); long Y,Cr,Cb; long l,lr2,lg2,lb2; long lr,lb,lg; unsigned x, y,gray; unsigned r,g,b; #ifdef REPORT_TIMES struct timeval t1,t2; gettimeofday(&t1,NULL); #endif //In the YUV frame, there are four Y pixels for every UV pair. //Thus, calculate the Cr and Cb values for a UV pair, and then //determine the RGB values for each of the four Y Pixels. #define CALCULATE Cr = *(uplane++) - 128; /* First, get Cb and Cr.*/\ Cb = *(vplane++) - 128; \ lr2 = 104635 * Cb; \ lg2 = -25690 * Cr + -53294 * Cb; \ lb2 = 132278 * Cr #define GETRGB(yp) Y= *(yp++) -16; \ if(Y<0) Y=0; l = 76310 * Y; \ lr = l + lr2; \ lg = l + lg2; \ lb = l + lb2; \ r = LIMIT(lr); \ g = LIMIT(lg); \ b = LIMIT(lb); #define GRAYPIXEL(yp,dtype,d) { GETRGB(yp); \ gray = (int)((r * 0.299) + (g * 0.587) + (b * 0.114)); \ if (gray > 255) \ gray = 255; \ else if (gray < 0) \ gray = 0; \ *((dtype *)(d)) = grayColors[((int)(gray * grayScaleFactor))]; } #define RGBPIXEL(yp,dtype,d) { GETRGB(yp); \ *((dtype *)(d))=((r >> redLoose) << redPos) |\ ((g >> greenLoose)<< greenPos) |\ ((b >> blueLoose) << bluePos); } #define YUVCONVERT(sw,dtype,d1,d2,d3,d4) \ { /*Handle the case for LARGE IMAGE */ \ if(videoPIP&&(!isEncoding)){ \ d1= ((dtype *)d); \ d2= ((dtype *)d) + (width*2); \ d3= ((dtype *)d) + (width*4); \ d4= ((dtype *)d) + (width*6); \ for(y=0;y100){ cerr<100){ cerr< 0 ; } ////////////////////////////////////////////////////////////////////////// // // Shared memory Xlib functions // void ShmXlibVideoDevice::OpenRender(void) { PTRACE(3,"XDisplayShm\t Open Render, label "<shmid = shmget(IPC_PRIVATE, w1 * h1 * byteDepth, IPC_CREAT | 0777 ); if(xsi->shmid<0) { PTRACE(0,"XDisplayShm\t Failed to create shared memory area" ); return; } xsi->shmaddr = (*image)->data = (char *)shmat(xsi->shmid,0 ,0); if (xsi->shmaddr == (char *) -1) { PTRACE(0,"XDisplayShm\t Failed to assign shared memory area to image->data"); return; } xsi->readOnly = False; if(!XShmAttach(display, xsi)) { PTRACE(0,"XDisplayShm\t Failed to attach shared memory area to X server"); return; } } void ShmXlibVideoDevice::DestroyShmXImage(XImage **image, XShmSegmentInfo *xsi) { struct shmid_ds shared_ds; if ((*image) != NULL) { XShmDetach(display,xsi); XDestroyImage(*image); shmdt(xsi->shmaddr); shmctl(xsi->shmid,IPC_RMID,&shared_ds); *image=NULL; } } void ShmXlibVideoDevice::DisplayImage(XImage *xi) { XShmPutImage(display,win[xIndex()],gc,xi,0,0,0,0, xi->width,xi->height,False); } ////////////////////////////////////////////////////////////////////////// // // Non-shared memory Xlib functions // void XlibVideoDevice::OpenRender(void) { PTRACE(3,"XDisplayNonShm\t Open Render, label "<width,xi->height); } #endif // HAS_X11