]> source.dussan.org Git - tigervnc.git/commitdiff
Functional version of IrixCLJpegCompressor. This commit includes modifications used...
authorConstantin Kaplinsky <const@tightvnc.com>
Wed, 19 Dec 2007 06:25:06 +0000 (06:25 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Wed, 19 Dec 2007 06:25:06 +0000 (06:25 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2376 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/IrixCLJpegCompressor.cxx
common/rfb/IrixCLJpegCompressor.h
common/rfb/JpegEncoder.cxx

index 636c3337fc39a6651007c41620d5f44c28c5a3b5..3e33a0c1ec480ed642170fcf178aa584ad1994e6 100644 (file)
@@ -4,9 +4,12 @@
 #include <sys/poll.h>
 
 #include <rfb/IrixCLJpegCompressor.h>
+#include <rfb/LogWriter.h>
 
 using namespace rfb;
 
+static LogWriter vlog("IrixCLJpeg");
+
 const int IrixCLJpegCompressor::DEFAULT_QUALITY = 75;
 
 //
@@ -15,13 +18,54 @@ const int IrixCLJpegCompressor::DEFAULT_QUALITY = 75;
 
 IrixCLJpegCompressor::IrixCLJpegCompressor()
   : m_quality(DEFAULT_QUALITY),
+    m_clHandleValid(false),
+    m_srcBufferSize(0),
+    m_dstBufferSize(0),
+    m_sourceData(0),
     m_compressedData(0),
     m_compressedLength(0)
 {
+  int impactScheme = clQuerySchemeFromName(CL_ALG_VIDEO, "impact");
+  if (impactScheme < 0) {
+    vlog.error("Warning: No compression scheme named \"impact\"");
+  }
+
+  vlog.debug("Trying \"impact\" compression scheme (Octane Compression)");
+  int r = clOpenCompressor(impactScheme, &m_clHandle);
+  if (r == SUCCESS) {
+    vlog.debug("Using \"impact\" compression scheme");
+    m_clHandleValid = true;
+    return;
+  }
+  vlog.debug("Trying Cosmo Compress");
+  r = clOpenCompressor(CL_JPEG_COSMO, &m_clHandle);
+  if (r == SUCCESS) {
+    vlog.debug("Using Cosmo Compress");
+    m_clHandleValid = true;
+    return;
+  }
+
+  // DEBUG: Uncomment to test without hardware compressor.
+  /*
+  vlog.debug("Trying Irix software JPEG compressor (debug mode!)");
+  r = clOpenCompressor(CL_JPEG_SOFTWARE, &m_clHandle);
+  if (r == SUCCESS) {
+    vlog.debug("Using Irix software JPEG compressor (debug mode!)");
+    m_clHandleValid = true;
+    return;
+  }
+  */
+
+  vlog.error("Ho hardware JPEG available via Irix CL library");
 }
 
 IrixCLJpegCompressor::~IrixCLJpegCompressor()
 {
+  if (m_clHandleValid)
+    clCloseCompressor(m_clHandle);
+
+  if (m_sourceData)
+    delete[] m_sourceData;
   if (m_compressedData)
     delete[] m_compressedData;
 }
@@ -47,7 +91,7 @@ IrixCLJpegCompressor::setQuality(int level)
 // Perform JPEG compression.
 //
 // FIXME: This function assumes that pixel format is 32-bit XBGR
-//        (depth 24), compatible with IRIX Digital Media libraries.
+//        (depth 24), compatible with IRIX Compression Library.
 //
 
 void
@@ -56,12 +100,59 @@ IrixCLJpegCompressor::compress(const rdr::U32 *buf,
                                int w, int h, int stride)
 {
   // Discard previous compression results.
-  if (m_compressedData) {
-    delete[] m_compressedData;
-    m_compressedData = 0;
-  }
   m_compressedLength = 0;
 
-  // FIXME: Do something.
+  // A sanity check.
+  if (!m_clHandleValid)
+    return;
+
+  // (Re)allocate the source buffer if necessary.
+  if (w * h > m_srcBufferSize) {
+    if (m_sourceData)
+      delete[] m_sourceData;
+    m_srcBufferSize = w * h;
+    m_sourceData = new rdr::U32[m_srcBufferSize];
+  }
+
+  // Copy source pixels
+  for (int y = 0; y < h; y++) {
+    memcpy(&m_sourceData[y * w], &buf[y * stride], w * sizeof(rdr::U32));
+  }
+
+  // Set image attributes and JPEG quality factor.
+  clSetParam(m_clHandle, CL_FORMAT, CL_FORMAT_XBGR);
+  clSetParam(m_clHandle, CL_IMAGE_WIDTH, w);
+  clSetParam(m_clHandle, CL_IMAGE_HEIGHT, h);
+  clSetParam(m_clHandle, CL_FRAME_BUFFER_SIZE, w * h * 4);
+  clSetParam(m_clHandle, CL_JPEG_QUALITY_FACTOR, m_quality);
+
+  // Determine buffer size required.
+  int newBufferSize = clGetParam(m_clHandle, CL_COMPRESSED_BUFFER_SIZE);
+
+  /* DEBUG:
+  int arr[200];
+  int nn = clQueryParams(m_clHandle, arr, 200);
+  vlog.debug("Params:");
+  for (int ii = 0; ii < nn; ii += 2) {
+    int id = clGetParamID(m_clHandle, (char *)arr[ii]);
+    vlog.debug("  %s = %d", (char*)arr[ii], clGetParam(m_clHandle, id));
+  }
+  */
+
+  // (Re)allocate destination buffer if necessary.
+  if (newBufferSize > m_dstBufferSize) {
+    if (m_compressedData)
+      delete[] m_compressedData;
+    m_dstBufferSize = newBufferSize;
+    m_compressedData = new char[m_dstBufferSize];
+  }
+
+  int newCompressedSize = newBufferSize;
+  int n = clCompress(m_clHandle, 1, m_sourceData,
+                     &newCompressedSize, m_compressedData);
+  if (n != 1)
+    return;
+
+  m_compressedLength = (size_t)newCompressedSize;
 }
 
index e32659a2204bd77d8093ed99fb57a8d14a597ec7..39ebd4a759aa1f2645d86af4f7b994654a988280 100644 (file)
@@ -2,6 +2,7 @@
 #define __IRIXCLJPEGCOMPRESSOR_H__
 
 #include <sys/types.h>
+#include <dmedia/cl.h>
 
 #include <rdr/types.h>
 #include <rfb/PixelFormat.h>
@@ -22,7 +23,7 @@ namespace rfb {
     virtual ~IrixCLJpegCompressor();
 
     // Check if the object has been created successfully.
-    bool isValid() const { return false; }
+    bool isValid() const { return m_clHandleValid; }
 
     // Set JPEG quality level (0..100).
     virtual void setQuality(int level);
@@ -39,7 +40,15 @@ namespace rfb {
     static const int DEFAULT_QUALITY;
     int m_quality;
 
+    CLhandle m_clHandle;
+    bool m_clHandleValid;
+
+    int m_srcBufferSize;
+    int m_dstBufferSize;
+
+    rdr::U32 *m_sourceData;
     char *m_compressedData;
+
     size_t m_compressedLength;
   };
 
index 054a5ef32138a5ab3eb5a5d09944dd554dc7bf86..1d9b3c79f0337c649693fcabd25023a8f2bf41eb 100644 (file)
@@ -23,6 +23,9 @@
 #include <rfb/ConnParams.h>
 #include <rfb/LogWriter.h>
 
+#ifdef HAVE_CL
+#include <rfb/IrixCLJpegCompressor.h>
+#endif
 #ifdef HAVE_DMEDIA
 #include <rfb/IrixDMJpegCompressor.h>
 #endif
@@ -42,24 +45,37 @@ const int JpegEncoder::qualityMap[10] = {
 
 JpegEncoder::JpegEncoder(SMsgWriter* writer_) : writer(writer_), jcomp(0)
 {
+  // FIXME: DM should be preferred over CL.
+#ifdef HAVE_CL
+  if (!jcomp && useHardwareJPEG) {
+    vlog.debug("trying IRIX CL JPEG compressor");
+    IrixCLJpegCompressor *clComp = new IrixCLJpegCompressor;
+    if (clComp->isValid()) {
+      vlog.debug("initialized IRIX CL JPEG compressor successfully");
+      jcomp = clComp;
+    } else {
+      vlog.error("warning: could not create IRIX CL JPEG compressor");
+      delete clComp;
+    }
+  }
+#endif
 #ifdef HAVE_DMEDIA
-  if (useHardwareJPEG) {
+  if (!jcomp && useHardwareJPEG) {
     vlog.debug("trying IRIX DM JPEG compressor");
-    IrixDMJpegCompressor *irixComp = new IrixDMJpegCompressor;
-    if (irixComp->isValid()) {
+    IrixDMJpegCompressor *dmComp = new IrixDMJpegCompressor;
+    if (dmComp->isValid()) {
       vlog.debug("initialized IRIX DM JPEG compressor successfully");
-      jcomp = irixComp;
+      jcomp = dmComp;
     } else {
       vlog.error("warning: could not create IRIX DM JPEG compressor");
-      delete irixComp;
+      delete dmComp;
     }
   }
-#else
-  if (useHardwareJPEG) {
-    vlog.info("no hardware JPEG compressor available");
-  }
 #endif
   if (!jcomp) {
+    if (useHardwareJPEG) {
+      vlog.info("no hardware JPEG compressor available");
+    }
     vlog.debug("using software JPEG compressor");
     jcomp = new StandardJpegCompressor;
   }