From 651606d27852f0158da7243f5db94ebbd3c6b813 Mon Sep 17 00:00:00 2001 From: Constantin Kaplinsky Date: Wed, 17 Oct 2007 17:40:23 +0000 Subject: [PATCH] Using JpegEncoder for video only with proper pixel formats. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2361 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- common/rfb/JpegEncoder.cxx | 33 ++++++++++++++++++++++----------- common/rfb/JpegEncoder.h | 3 ++- common/rfb/SMsgWriter.cxx | 7 ++++++- common/rfb/SMsgWriter.h | 3 ++- common/rfb/VNCSConnectionST.cxx | 19 ++++++++++++++++--- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/common/rfb/JpegEncoder.cxx b/common/rfb/JpegEncoder.cxx index 6903c2cc..054a5ef3 100644 --- a/common/rfb/JpegEncoder.cxx +++ b/common/rfb/JpegEncoder.cxx @@ -18,7 +18,9 @@ #include #include +#include #include +#include #include #ifdef HAVE_DMEDIA @@ -79,16 +81,27 @@ void JpegEncoder::setQualityLevel(int level) jcomp->setQuality(qualityMap[level]); } -bool JpegEncoder::writeRect(PixelBuffer* pb, const Rect& r) +bool JpegEncoder::isPixelFormatSupported(PixelBuffer* pb) const { - int serverBitsPerPixel = pb->getPF().bpp; - int clientBitsPerPixel = writer->bpp(); - - // FIXME: Implement JPEG compression for (serverBitsPerPixel == 16). - // FIXME: Check that all color components are actually 8 bits wide. - if (serverBitsPerPixel != 32 || clientBitsPerPixel < 16) { - // FIXME: Make sure this return value is checked properly. - return false; + const PixelFormat &serverPF = pb->getPF(); + const PixelFormat &clientPF = writer->getConnParams()->pf(); + + // FIXME: Ask encoders if they support given pixel formats. + + if ( serverPF.bpp == 32 && clientPF.bpp >= 16 && + serverPF.depth == 24 && serverPF.redMax == 255 && + serverPF.greenMax == 255 && serverPF.blueMax == 255 ) { + return true; + } + + return false; +} + +void JpegEncoder::writeRect(PixelBuffer* pb, const Rect& r) +{ + if (!isPixelFormatSupported(pb)) { + vlog.error("pixel format unsupported by JPEG encoder"); + throw rdr::Exception("internal error in JpegEncoder"); } writer->startRect(r, encodingTight); @@ -108,7 +121,5 @@ bool JpegEncoder::writeRect(PixelBuffer* pb, const Rect& r) os->writeBytes(jcomp->getDataPtr(), jcomp->getDataLength()); writer->endRect(); - - return true; } diff --git a/common/rfb/JpegEncoder.h b/common/rfb/JpegEncoder.h index 78e08fac..f2f077dd 100644 --- a/common/rfb/JpegEncoder.h +++ b/common/rfb/JpegEncoder.h @@ -38,7 +38,8 @@ namespace rfb { virtual ~JpegEncoder(); virtual void setQualityLevel(int level); - virtual bool writeRect(PixelBuffer* pb, const Rect& r); + virtual bool isPixelFormatSupported(PixelBuffer* pb) const; + virtual void writeRect(PixelBuffer* pb, const Rect& r); static BoolParameter useHardwareJPEG; diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index 8d09f881..1a02ce34 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -173,7 +173,12 @@ bool SMsgWriter::writeRect(const Rect& r, unsigned int encoding, return encoders[encoding]->writeRect(r, ig, actual); } -void SMsgWriter::writeVideoRect(PixelBuffer *pb, const Rect& r) +bool SMsgWriter::canUseJpegEncoder(PixelBuffer *pb) const +{ + return jpegEncoder->isPixelFormatSupported(pb); +} + +void SMsgWriter::writeJpegRect(PixelBuffer *pb, const Rect& r) { jpegEncoder->writeRect(pb, r); } diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index 490d556c..6f7feeb5 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -131,7 +131,8 @@ namespace rfb { virtual void writeCopyRect(const Rect& r, int srcX, int srcY); - virtual void writeVideoRect(PixelBuffer *pb, const Rect& r); + virtual bool canUseJpegEncoder(PixelBuffer *pb) const; + virtual void writeJpegRect(PixelBuffer *pb, const Rect& r); virtual void startRect(const Rect& r, unsigned int enc)=0; virtual void endRect()=0; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index d6541f97..3929b1fb 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -646,8 +646,15 @@ void VNCSConnectionST::writeFramebufferUpdate() // complicated as compared to the original VNC4. writer()->setupCurrentEncoder(); int nRects = (ui.copied.numRects() + - (ui.video_area.is_empty() ? 0 : 1) + (drawRenderedCursor ? 1 : 0)); + if (!ui.video_area.is_empty()) { + if (writer()->canUseJpegEncoder(server->getPixelBuffer())) { + nRects++; + } else { + nRects += writer()->getNumRects(ui.video_area); + } + } + std::vector rects; std::vector::const_iterator i; ui.changed.get_rects(&rects); @@ -657,8 +664,14 @@ void VNCSConnectionST::writeFramebufferUpdate() } writer()->writeFramebufferUpdateStart(nRects); - if (!ui.video_area.is_empty()) - writer()->writeVideoRect(server->getPixelBuffer(), ui.video_area); + if (!ui.video_area.is_empty()) { + if (writer()->canUseJpegEncoder(server->getPixelBuffer())) { + writer()->writeJpegRect(server->getPixelBuffer(), ui.video_area); + } else { + Rect actual; + writer()->writeRect(ui.video_area, &image_getter, &actual); + } + } Region updatedRegion; writer()->writeRects(ui, &image_getter, &updatedRegion); updates.subtract(updatedRegion); -- 2.39.5