summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2007-10-17 17:40:23 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2007-10-17 17:40:23 +0000
commit651606d27852f0158da7243f5db94ebbd3c6b813 (patch)
treeecb57c595d8e3beac123c8ff8ece0b5164919549
parentc257370bef6c70176eef01e47edc3e59080fcef4 (diff)
downloadtigervnc-651606d27852f0158da7243f5db94ebbd3c6b813.tar.gz
tigervnc-651606d27852f0158da7243f5db94ebbd3c6b813.zip
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
-rw-r--r--common/rfb/JpegEncoder.cxx33
-rw-r--r--common/rfb/JpegEncoder.h3
-rw-r--r--common/rfb/SMsgWriter.cxx7
-rw-r--r--common/rfb/SMsgWriter.h3
-rw-r--r--common/rfb/VNCSConnectionST.cxx19
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 <rfb/JpegEncoder.h>
#include <rdr/OutStream.h>
+#include <rdr/Exception.h>
#include <rfb/encodings.h>
+#include <rfb/ConnParams.h>
#include <rfb/LogWriter.h>
#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<Rect> rects;
std::vector<Rect>::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);