📄 xlibvid.cxx
字号:
XMapWindow(display, win[xIndex()]);
XRaiseWindow(display,win[xIndex()]);
gc = XCreateGC(display, win[xIndex()], 0, NULL);
OpenRender();
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); //Handles user selecting cross.
(void) XSetWMProtocols(display,win[xIndex()], &wm_delete_window, 1);
PTRACE(3,"XDisplay\t OpenWindow all done, internal size is "<<width<<"x"<<height);
PTRACE(3,"XDisplay\t OpenWindow. Display size is "<<displayWidth[xIndex()]<<"x"<<displayHeight[xIndex()]);
PTRACE(3,"XDisplay\t OpenWindow of "<<DirectionStr()<<" window DONE....");
return TRUE;
}
BOOL GenericXlibVideoDevice::DetermineVisualInformation(void)
{
// get visual information
XVisualInfo visualTemplate;
XVisualInfo *visualInfo;
int count;
int index;
int visualIndex;
BOOL foundVisual;
visualTemplate.screen = screen;
visualInfo = XGetVisualInfo(display, VisualScreenMask, &visualTemplate, &count);
if(!visualInfo) { //No memory available to hold result.
cerr<<" Failed to obtain information on the available visual formats."<<endl;
cerr<<" No video display window constructed. Sorry."<<endl;
PTRACE(3,"XDisplay\t Failed to open buffer to hold intermediate memory result");
XFree(visualInfo);
return FALSE;
}
foundVisual=FALSE;
visualIndex=0;
byteDepth =1;
//Look for 24||32 bit visual that supports direct or true colour.
for(index=0; (index<count) && (!foundVisual);index++)
if( ((forceDepth == 0) || (forceDepth == 24) || (forceDepth == 32)) &&
(visualInfo[index].depth >= 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; (index<count) && (!foundVisual);index++)
if( ((forceDepth == 0) || (forceDepth == 16) ) &&
(visualInfo[index].depth == 16) && (!foundVisual) &&
( visualInfo[index].c_class == DirectColor ||
visualInfo[index].c_class == TrueColor) ) {
visualIndex = index;
foundVisual = TRUE;
byteDepth = 2;
}
#if 0
//Look for 8 bit visual that supports static colour.
for(index=0; (index<count) && (!foundVisual);index++)
if( ((forceDepth == 0) || (forceDepth == 8) ) &&
(visualInfo[index].depth == 8) && (!foundVisual) &&
( visualInfo[index].c_class == StaticColor) ) {
visualIndex = index;
foundVisual = TRUE;
byteDepth = 1;
}
#endif
//Look for 8 bit visual that supports psuedo colour.
for(index=0; (index<count) && (!foundVisual);index++)
if( ((forceDepth == 0) || (forceDepth == 8) ) &&
(visualInfo[index].depth == 8) && (!foundVisual) &&
( visualInfo[index].c_class == PseudoColor) ) {
visualIndex = index;
foundVisual = TRUE;
byteDepth = 1;
}
if(!foundVisual) {
if (forceDepth == 0) {
PTRACE(0,"XDisplay\t Default screen does not support 24 or 16 bit TrueColor,");
PTRACE(0,"XDisplay\t or DirectColor visuals," );
PTRACE(0,"XDisplay\t or 8 bit StaticColor visuals" );
PTRACE(0,"XDisplay\t or 8 bit PseudoColor visuals" );
} else
PTRACE(0,"XDisplay\t Default screen does not support " << forceDepth << " bit visuals" );
PTRACE(0,"XDisplay\t No window created, as could not decide on a suitable bit depth.");
XFree(visualInfo);
return FALSE;
}
visual = visualInfo[visualIndex].visual;
pixelDepth = visualInfo[visualIndex].depth;
XFree(visualInfo);
// if we ended up with a PseudoColor visual, then use 64 level gray scale
if (visual->c_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 "<<redLoose <<" at "<<redPos);
PTRACE(3,"XDisplay\t Display bitmap:GREEN loose "<<greenLoose<<" at "<<greenPos);
PTRACE(3,"XDisplay\t Display bitmap:BLUE loose "<<blueLoose <<" at "<<bluePos);
colormap = XCreateColormap(display, RootWindow(display, screen), visual, AllocNone);
} else {
useGrayScale = TRUE;
colormap=DefaultColormap(display,screen);
PTRACE(3,"XDisplay\t Finished finding gray colormap.");
AllocGrays(64);
if(nGrayColors<4) {
PTRACE(0,"XDisplay\t No window created, as could not create 8 bit gray scale window.");
return FALSE;
}
pixelDepth = 8;
byteDepth = 1;
}
return TRUE;
}
void GenericXlibVideoDevice::MaskCalc(int & startPos, int & looseNBits, int visualMask)
{
/*The source data (from the YUV 420P image) is three bytes, one each for RGB.
These three bytes have to be transformed into the N bit per pixel display.
Some part of each of the three bytes will have to be lost.
EG (abcd efgh) (klmn opqr) (stuv wxyz) are the three source RGB bytes.
Want to display on a 15 bit display (15 makes the description easy)
Thus, each of the three bytes will have to have three bits deleted.
the bytes will need to be shifted, one 10 bits, one 5 bits, one not.
The source data will transformed into::
abcde klmno stuvw
From this Mask calc routine, we need to know how many bits to truncate,
how many bits to shift to display.
*/
// look for starting position
int pos=0,wid;
if(visualMask==0)
return;
while ((visualMask & (1 << pos)) == 0)
pos++;
startPos=pos;
//look for ending position.
while ((visualMask & (1 << pos)) != 0)
pos++;
wid=pos-startPos;
looseNBits= 8-wid;
}
void GenericXlibVideoDevice::CloseWindowOfType(BOOL closeEncoder)
{
int isEncodingOld;
isEncodingOld= isEncoding;
isEncoding = closeEncoder;
usleep(1000);
CloseRender();
XFlush(display);
XDestroyWindow(display,win[xIndex()]);
XFlush(display);
win[xIndex()]= (Window)NULL;
nWindowsOpen--;
isEncoding= isEncodingOld;
}
void GenericXlibVideoDevice::CloseWindow()
{
PTRACE(3,"XDisplay\t Close the "<<DirectionStr()<<" window.");
if(!(width||height)) {
PTRACE(3,"XDisplay\tAttempting to close 0x0 sized window. So do nothing");
return;
}
//Do the special case first. The act of closing the
//receive window (if PIP is on) should first close the
//local window.
if((nWindowsOpen==2)&& videoPIP&&(!isEncoding)) {
PTRACE(3,"XDisplay\t Close the local video window in a PIP setup.");
CloseWindowOfType(TRUE); //close local window here.
}
if(nWindowsOpen==1) {
PTRACE(3,"XDisplay\t close the last remaining window");
FreeColormapInformation();
XFreeGC(display, gc);
CloseWindowOfType(isEncoding);
XCloseDisplay(display);
display=NULL;
}
if(nWindowsOpen==2) {
PTRACE(3,"XDisplay\t Close the 2nd window - no display change");
CloseWindowOfType(isEncoding);
}
width=0;
height=0;
}
void GenericXlibVideoDevice::FreeColormapInformation(void)
{
XFreeColormap(display, colormap);
}
void GenericXlibVideoDevice::AllocGrays(int num)
{
XColor xcol;
int i;
if (num < 4) {
nGrayColors=0;
PTRACE(0,"XDisplay\t Error allocating grayscale colormap.");
return;
}
if (num > 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 "<<nGrayColors<<" for 8 bit display");
}
#define LIMIT(x) (BYTE)(((x>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;y<height;y+=2) { \
for(x=0;x<width;x+=2) { \
CALCULATE ; \
if(sw==1) \
RGBPIXEL(yplane,dtype,d1) \
else \
GRAYPIXEL(yplane,dtype,d1) \
*(d1+1)=*d1; \
*(d2++)=*d1; \
*(d2++)=*d1; \
d1+=2; \
if(sw==1) \
RGBPIXEL(yplane,dtype,d1) \
else \
GRAYPIXEL(yplane,dtype,d1) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -