aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2007-12-19 06:25:06 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2007-12-19 06:25:06 +0000
commit51e66524409678240d39a61fd79f05f3263f3e1e (patch)
treebe694f3d52d170513bc1194b77279a060c692625 /common
parent39e31a1ceb90bdc8db4344035a7a191ed23e18ae (diff)
downloadtigervnc-51e66524409678240d39a61fd79f05f3263f3e1e.tar.gz
tigervnc-51e66524409678240d39a61fd79f05f3263f3e1e.zip
Functional version of IrixCLJpegCompressor. This commit includes modifications used to test this class without hardware compressors available via Irix CL.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2376 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common')
-rw-r--r--common/rfb/IrixCLJpegCompressor.cxx103
-rw-r--r--common/rfb/IrixCLJpegCompressor.h11
-rw-r--r--common/rfb/JpegEncoder.cxx34
3 files changed, 132 insertions, 16 deletions
diff --git a/common/rfb/IrixCLJpegCompressor.cxx b/common/rfb/IrixCLJpegCompressor.cxx
index 636c3337..3e33a0c1 100644
--- a/common/rfb/IrixCLJpegCompressor.cxx
+++ b/common/rfb/IrixCLJpegCompressor.cxx
@@ -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;
}
diff --git a/common/rfb/IrixCLJpegCompressor.h b/common/rfb/IrixCLJpegCompressor.h
index e32659a2..39ebd4a7 100644
--- a/common/rfb/IrixCLJpegCompressor.h
+++ b/common/rfb/IrixCLJpegCompressor.h
@@ -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;
};
diff --git a/common/rfb/JpegEncoder.cxx b/common/rfb/JpegEncoder.cxx
index 054a5ef3..1d9b3c79 100644
--- a/common/rfb/JpegEncoder.cxx
+++ b/common/rfb/JpegEncoder.cxx
@@ -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;
}