📄 vdisplay.cxx
字号:
//// 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 CPhone, a cross platform voip gui.//// The Initial Developer of the Original Code is Derek Smithies.//// Copyright (C) 2002 Indranet Technologies Ltd, // http://www.indranet-technologies.com// All Rights Reserved.//// Contributor(s): _______________/* * * $Log: vdisplay.cxx,v $ * Revision 1.3 2003/05/09 03:08:24 dereksmithies * Fix Microtelco handling, and message display * * Revision 1.2 2003/04/04 04:37:49 dereksmithies * Major upgrade. * Ixj & microtelco support added. Fix threading issues. * * Revision 1.1.1.1 2002/05/12 22:55:05 dereksmithies * Initial release. * * * * */#include <ptlib.h>#include <qdatetime.h>#include "vdisplay.h"#include <sys/types.h>#include <unistd.h>#include <qpainter.h>#include <qevent.h>#include <qapplication.h>#include <qmessagebox.h>LabelDisplay::LabelDisplay( QWidget *parent, const char *name, WFlags f) : QLabel( parent, name, f){ displayText = "";}void LabelDisplay::prepareDisplayText(QString s){ PWaitAndSignal m(displayMutex); displayText = s;}void LabelDisplay::customEvent(QCustomEvent *e){ PWaitAndSignal m(displayMutex); setText(displayText);}////////////////////////////////////////////////////////////////////////VideoDisplay::VideoDisplay( QWidget *parent, const char *name, WFlags f) : QFrame(parent, name, f ){ blankImage = NULL; incomingImage = NULL; displayImage = NULL; bufferImage = NULL; scaledImage = NULL; displayFlipped = FALSE; newImageData = FALSE; width = 0; height = 0; converter = NULL;};VideoDisplay::~VideoDisplay(){ PWaitAndSignal m(bufferMutex); if (bufferImage != NULL) delete bufferImage; bufferImage = NULL; if (displayImage != NULL) delete displayImage; displayImage = NULL; if (incomingImage != NULL) delete incomingImage; incomingImage = NULL; if (scaledImage != NULL) delete scaledImage; scaledImage = NULL; if (converter!=NULL) delete converter; converter = NULL;}void VideoDisplay::RemoveVideoImage(){ SwapImages( SWAP_BLANK ); InitiateRepaint( TRUE );}void VideoDisplay::InitiateRepaint(BOOL doErase){ QRect r = contentsRect(); QThread::postEvent(this, new QPaintEvent(r, doErase) );}void VideoDisplay::CreateColourConverter(){ if (converter != NULL) { delete converter; converter = NULL; } if (converter == NULL) converter = PColourConverter::Create("YUV420P", "RGB32F", width, height);}//SetDisplayBuffer is only called by one thread. Thus, we do not need to//protect incomingImage with a mutex.void VideoDisplay::SetDisplayBuffer(const void *videoFrame, unsigned _width, unsigned _height, BOOL doFlip){ width = _width; height = _height; if (incomingImage == NULL) incomingImage = new QImage(width, height, 32); if ((incomingImage->width() != width) || (incomingImage->height() != height) ) { delete incomingImage; incomingImage = new QImage(width, height, 32); if (incomingImage == NULL) return; delete converter; //There has been a size change. The colour converter converter = NULL; //must be changed to the new size. } CreateColourConverter(); if (converter == NULL) return; converter->SetVFlipState(doFlip); PINDEX bytesReturned; converter->Convert( (const BYTE *)videoFrame, incomingImage->bits(), &bytesReturned); SwapImages(SWAP_INCOMING ); InitiateRepaint(FALSE );}void VideoDisplay::drawContents (QPainter *p){ SwapImages ( SWAP_BUFFER ); if (displayImage == NULL) return; QRect r = contentsRect();#if 1 if (scaledImage != NULL) { if ((scaledImage->width() != r.width()) || (scaledImage->height() != r.height())) { delete scaledImage; scaledImage = NULL; } } if (scaledImage == NULL) scaledImage = new QImage(r.width(), r.height(), 32); ResizeImage(scaledImage->bits(), r.width(), r.height(), displayImage->bits(), displayImage->width(), displayImage->height()); bitBlt(this, 0, 0, scaledImage);#else QPixmap sourcePixmap; sourcePixmap.convertFromImage(*displayImage); QWMatrix m; // transformation matrix double sx,sy; sx = (double)r.width()/displayImage->width(); //get scale factors. sy = (double)r.height()/displayImage->height(); m.scale(sx,sy); // scale coordinate system QPixmap sp = sourcePixmap.xForm( m ); // sp is the sourcepixmap after resizing. bitBlt(this, 0, 0, &sp);#endif}void VideoDisplay::SwapImages(int actionToTake ){ PWaitAndSignal m(bufferMutex); if ((actionToTake == SWAP_BUFFER) && (newImageData == FALSE)) { return; } if (actionToTake == SWAP_BUFFER) newImageData = FALSE; else newImageData = TRUE; QImage *temp; switch(actionToTake) { case SWAP_BUFFER: temp = displayImage; displayImage = bufferImage; bufferImage = temp; break; case SWAP_INCOMING: temp = incomingImage; incomingImage = bufferImage; bufferImage = temp; break; case SWAP_BLANK: temp = blankImage; blankImage = bufferImage; bufferImage = temp; delete blankImage; blankImage = NULL; break; default: return; }} void VideoDisplay::ResizeImage(uchar *dest_data, unsigned dest_width, unsigned dest_height, uchar *source_data, unsigned source_width, unsigned source_height){ // declare local variables unsigned source_x,source_y, dest_x,dest_y; unsigned source_yWidth,dest_yWidth; unsigned *dest_bitmap = (unsigned *)dest_data; unsigned *source_bitmap = (unsigned *)source_data; for(dest_y=0;dest_y<dest_height;dest_y++) { source_y = dest_y * source_height/dest_height; source_yWidth = source_y * source_width; dest_yWidth = dest_y * dest_width; for(dest_x=0;dest_x<dest_width; dest_x++) { source_x= dest_x*source_width/dest_width; dest_bitmap[dest_yWidth + dest_x] = source_bitmap[source_yWidth + source_x]; } }} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Rgb32Image::Rgb32Image(int x, int y, QString newMessage){ image = NULL; image = new QImage(x,y,32); QPainter p; image->fill( 0xffeeeeee ); frameWidth = x; frameHeight = y; textMessage = newMessage; QCustomEvent *ce = new QCustomEvent(QEvent::User); QApplication::postEvent(this, ce); //Qt will delete "ce" when done.}Rgb32Image::~Rgb32Image(){ access.lock(); if (image != NULL) delete image; access.unlock();}void Rgb32Image::CopyData(u_char *dest){ access.lock(); if (image == NULL) memset(dest, 64, frameWidth * frameHeight * 3); else memcpy(dest, image->bits(), frameWidth * frameHeight * 3); access.unlock(); return ;}void Rgb32Image::MakeImage(){ access.lock(); if (image != NULL) delete image; image = new QImage(frameWidth, frameHeight, 32); QPainter p; // our painter image->fill(0xffe0e0e0 ); //alpha r g b // initialize pixmap QPixmap pm; pm.convertFromImage(*image); p.begin(&pm ); // start painting pixmap QFont f( "Charter", 48 ); // use Charter 24pt font p.setFont(f ); // text rectangle p.setPen(QColor(10, 10, 210)); QRect br; QFontMetrics fm(p.fontMetrics() ); // get widget font metrics br = fm.boundingRect(textMessage ); // rectangle covering text QPoint posn = (QPoint(frameWidth,frameHeight) - br.topRight()-br.bottomLeft() )/2; p.drawText(posn, textMessage); p.end(); // painting done *image = pm.convertToImage(); access.unlock();}BYTE *Rgb32Image::GetDataPointer() const{ return (BYTE *)image->bits();}bool Rgb32Image::event(QEvent *e){ if (e->type() == QEvent::User) { MakeImage(); return TRUE; } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -