📄 xlibvid.cxx
字号:
/*
* 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 <X11/Xatom.h>
#include <sys/time.h>
#include <unistd.h>
#include <ptlib.h>
#include <string.h>
#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 "<<getpid()<<endl
<< " Error is "<<::hex<<(int)ee->error_code<<" "
<< (int)ee->request_code<<" "<<(int)ee->minor_code<<::dec<<endl;
if(ee->error_code==BadDrawable)
cerr <<"Internal error. Code attempted to manipulate non existant window"<<endl;
#endif
return(00);
}
void segvhandler(int signo)
{
cerr<<"##########################################"<<endl;
cerr<<"##########################################"<<endl;
cerr<<"SEGV error ("<<signo<<") in pid "<<getpid()<<endl;
PTRACE(0,"XDisplay\t segvhandler called");
usleep(1000);
exit(0);
}
//////////////////////////////////////////////////////////////////////////
//
// Generic Xlib functions
//
GenericXlibVideoDevice::GenericXlibVideoDevice(const PString & _remoteName,BOOL _isEncoding,
BOOL _videoPIP)
{
videoMutex.Wait();
PTRACE(3,"Generic\t constructor start.");
remoteName = _remoteName; n_bytes=0; forceDepth = 0;
isEncoding= _isEncoding;
videoPIP = _videoPIP;
width=0;
height=0;
pixels[xIndex(0)]=NULL; pixels[ xIndex(1) ]=NULL;
images[xIndex(0)]=NULL; images[ xIndex(1) ]=NULL;
// XSetErrorHandler(XLibErrorHandler);
// signal(SIGSEGV,segvhandler);
videoMutex.Signal();
}
GenericXlibVideoDevice::~GenericXlibVideoDevice()
{
Close();
}
BOOL GenericXlibVideoDevice::Open(const PString &, BOOL)
{
return TRUE;
}
BOOL GenericXlibVideoDevice::Close()
{
videoMutex.Wait();
PTRACE(3,"Xdisplay\t Close Start");
CloseWindow();
PTRACE(3,"Xdisplay\tClose DONE");
videoMutex.Signal();
return TRUE;
}
PStringList GenericXlibVideoDevice::GetDeviceNames() const
{
return PStringList();
}
PINDEX GenericXlibVideoDevice::GetMaxFrameBytes()
{
return 0;
}
BOOL GenericXlibVideoDevice::SetFrameSize (unsigned _width, unsigned _height)
{
videoMutex.Wait();
PTRACE(3,"XDisplay\t SetFrameSize Start for the "<<DirectionStr()<<" window" );
if ((width != _width) || (height != _height)) {
PTRACE(3,"XDisplay\t Requested internal size of "<<_width<<"x"<<_height);
PTRACE(3,"XDisplay\t did not match internal size of "<<width<<"x"<<height);
CloseWindow(); //Close memory for images
OpenWindow(_width,_height); //Allocate memory for images.
}
PTRACE(3,"XDisplay\tSetSize DONE for the "<<DirectionStr()<<" window" );
videoMutex.Signal();
return TRUE;
}
BOOL GenericXlibVideoDevice::OpenWindow(unsigned _width, unsigned _height)
{
PTRACE(3,"XDisplay\tOpenWindow of size "<<_width<<"x"<<_height<<
" "<<DirectionStr()<<" window");
if ((_width == 0) || (_height == 0))
return FALSE; //refuse to open a window containg 0 pixels.
// save parameters
width = _width;
height = _height;
n_bytes = width*height;
useImage0 = 0;
if(videoPIP && isEncoding) {
//Need to do picture in picture. Check first if parent exists.
if(nWindowsOpen==0)
return FALSE; //parent does not exist
}
// open display and screen
if (nWindowsOpen==0) {
display = XOpenDisplay(NULL);
if (display == NULL) {
cerr << "Failed to open display in GenericXlibVideoDevice::OpenWindow"<<endl;
PTRACE(0,"OpenWindow\t Failed to open display for XWindows");
return FALSE;
}
}
screen = DefaultScreen(display);
if(( nWindowsOpen==0 ) && (!DetermineVisualInformation())) {
XCloseDisplay(display);
display=NULL;
return FALSE;
}
XSetWindowAttributes attributes;
int attributeMask = 0;
attributeMask |= CWColormap;
attributes.colormap = colormap;
attributeMask |= CWBorderPixel;
attributes.border_pixel = 0;
Window rootWindow;
if(videoPIP&&isEncoding) {
rootWindow= win[xReceiveIndex()];
attributeMask |= CWOverrideRedirect;
attributes.override_redirect= FALSE; //Remove border for the inset picture.
} else
rootWindow=RootWindow(display,screen);
unsigned int xpos,ypos,border_width;
displayWidth[xIndex()] =width;
displayHeight[xIndex()]=height;
xpos=ypos= 10;
border_width=5;
if(videoPIP) {
if(isEncoding) {
displayWidth[xIndex()] =width/2;
displayHeight[xIndex()]=height/2;
border_width=0;
xpos= displayWidth[xReceiveIndex()] -(width/2);
ypos= displayHeight[xReceiveIndex()]-(height/2);;
} else {
displayWidth[xIndex()] =width*2;
displayHeight[xIndex()]=height*2;
}
}
win[xIndex()] = XCreateWindow(display,
rootWindow,
xpos,ypos,
displayWidth[xIndex()],
displayHeight[xIndex()],
border_width,
pixelDepth,
InputOutput,
visual,
attributeMask, &attributes);
if (win[xIndex()] == 0) {
PTRACE(0,"XDisplay\t Failed to open "<<DirectionStr()<< "window. ");
cerr << "Allocation of X window failed" << endl;
if(nWindowsOpen)
return FALSE;
FreeColormapInformation();
n_bytes=0;
return FALSE;
}
nWindowsOpen++;
XSizeHints size_hints;
size_hints.flags = PSize | PMinSize | PMaxSize; //Prevent resizing.
size_hints.min_width = displayWidth[xIndex()];
size_hints.max_width = displayWidth[xIndex()];
size_hints.min_height = displayHeight[xIndex()];
size_hints.max_height = displayHeight[xIndex()];
// Set name of window, used to display receive or send images.
PString str1;
if (remoteName *= "Local")
str1= remoteName;
else
str1= PString("From ") & remoteName;
XSetStandardProperties(display,
win[xIndex()],
(const char *)str1,
(const char *)str1, /*remoteName,*/
None,0,0,&size_hints);
XSelectInput(display, win[xIndex()], 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -