diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2007-12-19 06:25:06 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2007-12-19 06:25:06 +0000 |
commit | 51e66524409678240d39a61fd79f05f3263f3e1e (patch) | |
tree | be694f3d52d170513bc1194b77279a060c692625 /common | |
parent | 39e31a1ceb90bdc8db4344035a7a191ed23e18ae (diff) | |
download | tigervnc-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.cxx | 103 | ||||
-rw-r--r-- | common/rfb/IrixCLJpegCompressor.h | 11 | ||||
-rw-r--r-- | common/rfb/JpegEncoder.cxx | 34 |
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; } |