]> source.dussan.org Git - tigervnc.git/commitdiff
Using JpegEncoder for video only with proper pixel formats.
authorConstantin Kaplinsky <const@tightvnc.com>
Wed, 17 Oct 2007 17:40:23 +0000 (17:40 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Wed, 17 Oct 2007 17:40:23 +0000 (17:40 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2361 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/JpegEncoder.cxx
common/rfb/JpegEncoder.h
common/rfb/SMsgWriter.cxx
common/rfb/SMsgWriter.h
common/rfb/VNCSConnectionST.cxx

index 6903c2cc919fd8567cd05fc4da06b5dae9ded570..054a5ef32138a5ab3eb5a5d09944dd554dc7bf86 100644 (file)
@@ -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;
 }
 
index 78e08facd73e30436dc1becd3463ee921b5881fc..f2f077dd70202f42f9f53fd81dc4ed10b429f1f2 100644 (file)
@@ -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;
 
index 8d09f8810e9908472862fa7587b6e0dc7bf6b68c..1a02ce34b309601aa0b2d4e11311333819cef778 100644 (file)
@@ -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);
 }
index 490d556c7128ec4029fbaac697e3b8a5c0bf637d..6f7feeb5fa48c6e0cb0dffbe303ee6f5271d6cfe 100644 (file)
@@ -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;
index d6541f9738ea5597f375fc267fc97448f6e8138b..3929b1fbc2467042ab63f17438352fd32c4b4e30 100644 (file)
@@ -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);