From: Pierre Ossman Date: Thu, 5 Mar 2009 11:57:11 +0000 (+0000) Subject: Remove the "video" feature and its associated custom JPEG handling. X-Git-Tag: v0.0.90~152 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=02e43d78bf13276ef18fd542167e1ca26830a2f4;p=tigervnc.git Remove the "video" feature and its associated custom JPEG handling. Having the client specifiy the video region is conceptually wrong and a problem like this should be handled by better encoding selection. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3635 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx index 671e6ee8..40f5142e 100644 --- a/common/rfb/ComparingUpdateTracker.cxx +++ b/common/rfb/ComparingUpdateTracker.cxx @@ -39,14 +39,6 @@ ComparingUpdateTracker::~ComparingUpdateTracker() void ComparingUpdateTracker::compare() { - // First of all, exclude video area from both changed and copied regions. - // We handle video area separately and do not compare it -- we know it's - // being changed continuously. - if (!video_area.is_empty()) { - changed.assign_subtract(video_area); - copied.assign_subtract(video_area); - } - std::vector rects; std::vector::iterator i; diff --git a/common/rfb/IrixCLJpegCompressor.cxx b/common/rfb/IrixCLJpegCompressor.cxx deleted file mode 100644 index 5fef1660..00000000 --- a/common/rfb/IrixCLJpegCompressor.cxx +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -using namespace rfb; - -static LogWriter vlog("IrixCLJpeg"); - -const int IrixCLJpegCompressor::DEFAULT_QUALITY = 75; - -// -// Constructor and destructor. -// - -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; - } - -#ifdef DEBUG_FORCE_CL - vlog.debug("DEBUG: Trying Irix software JPEG compressor"); - r = clOpenCompressor(CL_JPEG_SOFTWARE, &m_clHandle); - if (r == SUCCESS) { - vlog.debug("DEBUG: Using Irix software JPEG compressor"); - m_clHandleValid = true; - return; - } -#endif - - 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; -} - -// -// Set JPEG quality level (1..99) -// - -void -IrixCLJpegCompressor::setQuality(int level) -{ - if (level < 1) { - level = 1; - } else if (level > 99) { - level = 99; - } - if (level != m_quality) { - m_quality = level; - } -} - -// -// Perform JPEG compression. -// -// FIXME: This function assumes that pixel format is 32-bit XBGR -// (depth 24), compatible with IRIX Compression Library. -// - -void -IrixCLJpegCompressor::compress(const rdr::U32 *buf, - const PixelFormat *fmt, - int w, int h, int stride) -{ - // Discard previous compression results. - m_compressedLength = 0; - - // 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); - - // (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 deleted file mode 100644 index 39ebd4a7..00000000 --- a/common/rfb/IrixCLJpegCompressor.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __IRIXCLJPEGCOMPRESSOR_H__ -#define __IRIXCLJPEGCOMPRESSOR_H__ - -#include -#include - -#include -#include - -#include - -namespace rfb { - - // - // A C++ class for performing JPEG compression. - // This implementation uses IRIX Compression Library (CL). - // - - class IrixCLJpegCompressor : public JpegCompressor - { - public: - IrixCLJpegCompressor(); - virtual ~IrixCLJpegCompressor(); - - // Check if the object has been created successfully. - bool isValid() const { return m_clHandleValid; } - - // Set JPEG quality level (0..100). - virtual void setQuality(int level); - - // Actually compress the image. - virtual void compress(const rdr::U32 *buf, const PixelFormat *fmt, - int w, int h, int stride); - - // Access results of the compression. - virtual size_t getDataLength() { return m_compressedLength; } - virtual const char *getDataPtr() { return m_compressedData; } - - protected: - 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; - }; - -} - -#endif // __IRIXCLJPEGCOMPRESSOR_H__ - diff --git a/common/rfb/IrixDMIC_RawToJpeg.cxx b/common/rfb/IrixDMIC_RawToJpeg.cxx deleted file mode 100644 index 4cdb1ba0..00000000 --- a/common/rfb/IrixDMIC_RawToJpeg.cxx +++ /dev/null @@ -1,499 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -using namespace rfb; - -static LogWriter vlog("IrixDMIC"); - -// -// Constructor. Find a converter and create a context. Also, create -// DMparams structures for using with dmICSetSrcParams, -// dmICSetDstParams and dmICSetConvParams. -// - -IrixDMIC_RawToJpeg::IrixDMIC_RawToJpeg(bool needRealtime) - : m_valid_ic(false), - m_srcParams(0), - m_dstParams(0), - m_convParams(0) -{ - if ( dmParamsCreate(&m_srcParams) != DM_SUCCESS || - dmParamsCreate(&m_dstParams) != DM_SUCCESS || - dmParamsCreate(&m_convParams) != DM_SUCCESS ) { - reportError("dmParamsCreate"); - return; - } - - DMparams *p; - const int JPEG_ID = 0x6A706567; // same as 'jpeg' - int id, direction, speed; - - int n = dmICGetNum(); - while (n--) { - if (dmParamsCreate(&p) != DM_SUCCESS) { - reportError("dmParamsCreate"); - return; - } - if (dmICGetDescription(n, p) != DM_SUCCESS) - continue; - id = dmParamsGetInt(p, DM_IC_ID); - direction = dmParamsGetEnum(p, DM_IC_CODE_DIRECTION); - speed = dmParamsGetEnum(p, DM_IC_SPEED); - if ( id == JPEG_ID && direction == DM_IC_CODE_DIRECTION_ENCODE && - (!needRealtime || speed == DM_IC_SPEED_REALTIME) ) { - - const char *engine = dmParamsGetString(p, DM_IC_ENGINE); - vlog.info("Found JPEG encoder: \"%s\" (%d)", engine, n); - - dmParamsDestroy(p); - break; - } - dmParamsDestroy(p); - } - if (n < 0) { - vlog.error("Error: No matching JPEG encoder found"); - debugListConverters(); - return; - } - if (dmICCreate(n, &m_ic) != DM_SUCCESS) { - reportError("dmICCreate"); - return; - } - - m_valid_ic = true; -} - -// -// Destructor. -// - -IrixDMIC_RawToJpeg::~IrixDMIC_RawToJpeg() -{ - if (m_valid_ic) - dmICDestroy(m_ic); - - if (m_convParams) - dmParamsDestroy(m_convParams); - if (m_dstParams) - dmParamsDestroy(m_dstParams); - if (m_srcParams) - dmParamsDestroy(m_srcParams); -} - -void -IrixDMIC_RawToJpeg::debugListConverters() -{ - int n = dmICGetNum(); - vlog.debug("IRIX DMIC converters available (%d):", n); - for (int i = 0; i < n; i++) { - DMparams *p; - if (dmParamsCreate(&p) != DM_SUCCESS) { - return; - } - if (dmICGetDescription(i, p) != DM_SUCCESS) { - vlog.debug(" continue"); - continue; - } - union { - int id; - char label[5]; - } id; - id.id = dmParamsGetInt(p, DM_IC_ID); - id.label[4] = '\0'; - int direction = dmParamsGetEnum(p, DM_IC_CODE_DIRECTION); - const char *directionLabel = "converter"; - if (direction == DM_IC_CODE_DIRECTION_ENCODE) { - directionLabel = "encoder"; - } else if (direction == DM_IC_CODE_DIRECTION_DECODE) { - directionLabel = "decoder"; - } - int speed = dmParamsGetEnum(p, DM_IC_SPEED); - const char *speedLabel = ""; - if (speed == DM_IC_SPEED_REALTIME) { - speedLabel = "realtime "; - } - const char *engine = dmParamsGetString(p, DM_IC_ENGINE); - vlog.debug(" converter %d: '%s' %s%s (%s)", - i, id.label, speedLabel, directionLabel, engine); - dmParamsDestroy(p); - } -} - -// -// Configure the source and destination formats. -// -// FIXME: Remember image size that was previously set, do not set the -// same size again. -// - -bool -IrixDMIC_RawToJpeg::setImageParams(int w, int h) -{ - if (!m_valid_ic) { - reportErrorNotInited(); - return false; - } - - // Set source image parameters. - DMpacking packing = DM_IMAGE_PACKING_XBGR; - int orient = DM_IMAGE_TOP_TO_BOTTOM; - if (dmSetImageDefaults(m_srcParams, w, h, packing) != DM_SUCCESS) { - reportError("dmSetImageDefaults"); - return false; - } - DMstatus err = dmParamsSetEnum(m_srcParams, DM_IMAGE_ORIENTATION, orient); - if (err != DM_SUCCESS) { - reportError("dmParamsSetEnum"); - return false; - } - if (dmICSetSrcParams(m_ic, m_srcParams) != DM_SUCCESS) { - reportError("dmICSetSrcParams"); - return false; - } - - // Set destination image parameters. - packing = DM_IMAGE_PACKING_CbYCrY; - const char *compression = DM_IMAGE_JPEG; - if (dmSetImageDefaults(m_dstParams, w, h, packing) != DM_SUCCESS) { - reportError("dmSetImageDefaults"); - return false; - } - err = dmParamsSetEnum(m_dstParams, DM_IMAGE_ORIENTATION, orient); - if (err != DM_SUCCESS) { - reportError("dmParamsSetEnum"); - return false; - } - err = dmParamsSetString(m_dstParams, DM_IMAGE_COMPRESSION, compression); - if (err != DM_SUCCESS) { - reportError("dmParamsSetString"); - return false; - } - if (dmICSetDstParams(m_ic, m_dstParams) != DM_SUCCESS) { - reportError("dmICSetDstParams"); - return false; - } - - return true; -} - -// -// Set JPEG image quality level (an integer in the range 0..99). -// -// FIXME: Remember image quality that was previously set, do not set -// the same quality again. -// - -bool -IrixDMIC_RawToJpeg::setImageQuality(int quality) -{ - if (!m_valid_ic) { - reportErrorNotInited(); - return false; - } - - double qf = (double)quality / 100.0; - - DMstatus err = dmParamsSetFloat(m_convParams, DM_IMAGE_QUALITY_SPATIAL, qf); - if (err != DM_SUCCESS) { - reportError("dmParamsSetFloat"); - return false; - } - - // For some reason, dmICSetConvParams() does not have effect without - // calling dmICSetDstParams() as well. So we call it here. - if (m_dstParams && dmParamsGetNumElems(m_dstParams) && - dmICSetDstParams(m_ic, m_dstParams) != DM_SUCCESS) { - reportError("dmICSetDstParams"); - return false; - } - - if (dmICSetConvParams(m_ic, m_convParams) != DM_SUCCESS) { - reportError("dmICSetConvParams"); - return false; - } - - return true; -} - -// -// Set up source buffer pool. -// -// NOTE: Both setImageParams() and setImageQuality() functions should -// be called prior to creating and registering buffer pools. -// - -bool -IrixDMIC_RawToJpeg::createSrcBufferPool(DMbufferpool *pool, - int bufCount, int bufSize) -{ - if (!m_valid_ic) { - reportErrorNotInited(); - return false; - } - - DMparams *p; - if (dmParamsCreate(&p) != DM_SUCCESS) { - reportError("dmParamsCreate"); - return false; - } - - if (dmBufferSetPoolDefaults(p, bufCount, bufSize, DM_FALSE, DM_TRUE) != - DM_SUCCESS) { - reportError("dmBufferSetPoolDefaults"); - dmParamsDestroy(p); - return false; - } - if (dmICGetSrcPoolParams(m_ic, p) != DM_SUCCESS) { - reportError("dmICGetSrcPoolParams"); - dmParamsDestroy(p); - return false; - } - if (dmBufferCreatePool(p, pool) != DM_SUCCESS) { - reportError("dmBufferCreatePool"); - dmParamsDestroy(p); - return false; - } - - dmParamsDestroy(p); - return true; -} - -// -// Set up and register destination buffer pool. -// -// NOTE: Both setImageParams() and setImageQuality() functions should -// be called prior to creating and registering buffer pools. -// - -bool -IrixDMIC_RawToJpeg::registerDstBufferPool(DMbufferpool *pool, - int bufCount, int bufSize) -{ - if (!m_valid_ic) { - reportErrorNotInited(); - return false; - } - - DMparams *p; - if (dmParamsCreate(&p) != DM_SUCCESS) { - reportError("dmParamsCreate"); - return false; - } - - if (dmBufferSetPoolDefaults(p, bufCount, bufSize, DM_FALSE, DM_TRUE) != - DM_SUCCESS) { - reportError("dmBufferSetPoolDefaults"); - dmParamsDestroy(p); - return false; - } - if (dmICGetDstPoolParams(m_ic, p) != DM_SUCCESS) { - reportError("dmICGetDstPoolParams"); - dmParamsDestroy(p); - return false; - } - if (dmBufferCreatePool(p, pool) != DM_SUCCESS) { - reportError("dmBufferCreatePool"); - dmParamsDestroy(p); - return false; - } - - dmParamsDestroy(p); - - if (dmICSetDstPool(m_ic, *pool) != DM_SUCCESS) { - reportError("dmICSetDstPool"); - destroyBufferPool(*pool); - return false; - } - - return true; -} - -// -// Destroy buffer pool created with either createSrcBufferPool() or -// registerDstBufferPool(). -// - -void -IrixDMIC_RawToJpeg::destroyBufferPool(DMbufferpool pool) -{ - if (dmBufferDestroyPool(pool) != DM_SUCCESS) - reportError("dmBufferDestroyPool"); -} - -// -// Allocate a buffer from the specified pool. -// - -bool -IrixDMIC_RawToJpeg::allocBuffer(DMbuffer *pbuf, DMbufferpool pool) -{ - if (dmBufferAllocate(pool, pbuf) != DM_SUCCESS) { - reportError("dmBufferAllocate"); - return false; - } - - return true; -} - -// -// Fill in a DMbuffer with data. -// -// NOTE: The caller must make sure that the buffer size is no less -// than dataSize. -// - -bool -IrixDMIC_RawToJpeg::copyToBuffer(DMbuffer buf, const void *data, int dataSize) -{ - void *bufPtr = dmBufferMapData(buf); - memcpy(bufPtr, data, dataSize); - - if (dmBufferSetSize(buf, dataSize) != DM_SUCCESS) { - reportError("dmBufferSetSize"); - return false; - } - - return true; -} - -// -// Fill in a DMbuffer with data. -// -// NOTE: The caller must make sure that the buffer size is no less -// than (nRows * rowSize). -// - -bool -IrixDMIC_RawToJpeg::copyToBuffer(DMbuffer buf, const void *data, - int rowSize, int nRows, int stride) -{ - char *dataBytes = (char *)data; - char *bufPtr = (char *)dmBufferMapData(buf); - for (int i = 0; i < nRows; i++) { - memcpy(bufPtr, &dataBytes[i * stride], rowSize); - bufPtr += rowSize; - } - - if (dmBufferSetSize(buf, nRows * rowSize) != DM_SUCCESS) { - reportError("dmBufferSetSize"); - return false; - } - - return true; -} - -// -// Map DMbuffer to physical memory. -// - -void * -IrixDMIC_RawToJpeg::mapBufferData(DMbuffer buf) -{ - return dmBufferMapData(buf); -} - -// -// Get the number of valid bytes in DMbuffer. -// - -int -IrixDMIC_RawToJpeg::getBufferSize(DMbuffer buf) -{ - return dmBufferGetSize(buf); -} - -// -// Free DMbuffer. -// - -void -IrixDMIC_RawToJpeg::freeBuffer(DMbuffer buf) -{ - if (dmBufferFree(buf) != DM_SUCCESS) - reportError("dmBufferFree"); -} - -// -// Send input data (raw pixels) to the converter. -// - -bool -IrixDMIC_RawToJpeg::sendData(DMbuffer buf) -{ - if (dmICSend(m_ic, buf, 0, NULL) != DM_SUCCESS) { - reportError("dmICSend"); - return false; - } - - return true; -} - -// -// Wait until compression is finished (infinite timeout!). -// This function should be called after sendData() and before receiveData(). -// -// FIXME: Report errors. -// - -bool -IrixDMIC_RawToJpeg::waitConversion() -{ - struct pollfd ps; - ps.fd = dmICGetDstQueueFD(m_ic); - ps.events = POLLIN; - - int result = poll(&ps, 1, -1); - if (result != 1) - return false; - - if ((ps.revents & POLLIN) != 0) { - return true; - } else { - return false; - } -} - -// -// Receive output (JPEG data) from the converter. -// Call waitConversion() function first. -// - -bool -IrixDMIC_RawToJpeg::receiveData(DMbuffer *pbuf) -{ - if (dmICReceive(m_ic, pbuf) != DM_SUCCESS) { - reportError("dmICReceive"); - return false; - } - - return true; -} - -// -// Report an error when a function returns DM_FAILURE. -// - -void -IrixDMIC_RawToJpeg::reportError(const char *funcName) -{ - char errorDetail[DM_MAX_ERROR_DETAIL]; - const char *errorCategory = dmGetError(NULL, errorDetail); - vlog.error("%s() failed: %s: %s", - funcName, errorCategory, errorDetail); -} - -// -// Report an error when (m_valid_ic == false). -// - -void -IrixDMIC_RawToJpeg::reportErrorNotInited() -{ - vlog.error("Internal error: Image converter not initialized"); -} - diff --git a/common/rfb/IrixDMIC_RawToJpeg.h b/common/rfb/IrixDMIC_RawToJpeg.h deleted file mode 100644 index 704682b9..00000000 --- a/common/rfb/IrixDMIC_RawToJpeg.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __IRIXDMIC_RAWTOJPEG_H__ -#define __IRIXDMIC_RAWTOJPEG_H__ - -#include -#include - -namespace rfb { - - // - // A C++ wrapper for IRIX-specific Digital Media Image Conversion - // library used for JPEG compression. - // - - class IrixDMIC_RawToJpeg - { - public: - IrixDMIC_RawToJpeg(bool needRealtime = true); - virtual ~IrixDMIC_RawToJpeg(); - - void debugListConverters(); - - bool isValid() const { return m_valid_ic; } - - bool setImageParams(int w, int h); - bool setImageQuality(int quality); - - bool createSrcBufferPool(DMbufferpool *pool, int bufCount, int bufSize); - bool registerDstBufferPool(DMbufferpool *pool, int bufCount, int bufSize); - static void destroyBufferPool(DMbufferpool pool); - - static bool allocBuffer(DMbuffer *pbuf, DMbufferpool pool); - static bool copyToBuffer(DMbuffer buf, const void *data, int dataSize); - static bool copyToBuffer(DMbuffer buf, const void *data, - int rowSize, int nRows, int stride); - static int getBufferSize(DMbuffer buf); - static void * mapBufferData(DMbuffer buf); - static void freeBuffer(DMbuffer buf); - - bool sendData(DMbuffer buf); - bool waitConversion(); - bool receiveData(DMbuffer *pbuf); - - static void reportError(const char *funcName); - static void reportErrorNotInited(); - - protected: - DMimageconverter m_ic; - bool m_valid_ic; - - DMparams *m_srcParams; - DMparams *m_dstParams; - DMparams *m_convParams; - }; - -} - -#endif // __IRIXDMIC_RAWTOJPEG_H__ - diff --git a/common/rfb/IrixDMJpegCompressor.cxx b/common/rfb/IrixDMJpegCompressor.cxx deleted file mode 100644 index 33397f63..00000000 --- a/common/rfb/IrixDMJpegCompressor.cxx +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include -#include -#include - -#include - -using namespace rfb; - -const int IrixDMJpegCompressor::DEFAULT_QUALITY = 75; - -// -// Constructor and destructor. -// - -IrixDMJpegCompressor::IrixDMJpegCompressor() - : m_quality(DEFAULT_QUALITY), - m_width(0), - m_height(0), - m_bufferSize(0), - m_compressedData(0), - m_compressedLength(0) -{ -} - -IrixDMJpegCompressor::~IrixDMJpegCompressor() -{ - if (m_bufferSize > 0) { - m_ic.destroyBufferPool(m_srcPool); - m_ic.destroyBufferPool(m_dstPool); - } - - if (m_compressedData) - delete[] m_compressedData; -} - -// -// Set JPEG quality level (1..99) -// - -void -IrixDMJpegCompressor::setQuality(int level) -{ - if (level < 1) { - level = 1; - } else if (level > 99) { - level = 99; - } - if (level != m_quality) { - m_quality = level; - m_ic.setImageQuality(level); - } -} - -// -// Perform JPEG compression. -// -// FIXME: This function assumes that pixel format is 32-bit XBGR -// (depth 24), compatible with IRIX Digital Media libraries. -// - -void -IrixDMJpegCompressor::compress(const rdr::U32 *buf, - const PixelFormat *fmt, - int w, int h, int stride) -{ - // Discard previous compression results. - if (m_compressedData) { - delete[] m_compressedData; - m_compressedData = 0; - } - m_compressedLength = 0; - - // Setup the compressor. - if (!updateImageSize(w, h)) - return; - - // Prepare source image data. - DMbuffer srcBuf; - if (!m_ic.allocBuffer(&srcBuf, m_srcPool)) { - return; - } - int widthInBytes = w * (fmt->bpp / 8); - int strideInBytes = stride * (fmt->bpp / 8); - if (!m_ic.copyToBuffer(srcBuf, buf, widthInBytes, h, strideInBytes)) { - m_ic.freeBuffer(srcBuf); - return; - } - - // Initiate compression. - if (!m_ic.sendData(srcBuf)) { - m_ic.freeBuffer(srcBuf); - return; - } - m_ic.freeBuffer(srcBuf); - - // Wait for results. - if (!m_ic.waitConversion()) { - perror("poll"); // FIXME: Unify error handling. - return; - } - - // Save the results. - DMbuffer dstBuf; - if (!m_ic.receiveData(&dstBuf)) { - return; - } - m_compressedLength = m_ic.getBufferSize(dstBuf); - m_compressedData = new char[m_compressedLength]; - void *bufPtr = m_ic.mapBufferData(dstBuf); - memcpy(m_compressedData, bufPtr, m_compressedLength); - - m_ic.freeBuffer(dstBuf); -} - -// -// Update image size and make sure that our buffer pools will allocate -// properly-sized buffers. -// -// FIXME: Handle image quality separately. -// - -bool -IrixDMJpegCompressor::updateImageSize(int w, int h) -{ - // Configure image formats and parameters, set JPEG image quality level. - if (w != m_width || h != m_height) { - if (!m_ic.setImageParams(w, h) || !m_ic.setImageQuality(m_quality)) { - return false; - } - m_width = w; - m_height = h; - } - - // Set up source and destination buffer pools. - int dataLen = w * h * 4; - if (dataLen > m_bufferSize) { - if (m_bufferSize > 0) { - m_ic.destroyBufferPool(m_srcPool); - m_ic.destroyBufferPool(m_dstPool); - m_bufferSize = 0; - } - if (!m_ic.createSrcBufferPool(&m_srcPool, 1, dataLen)) { - return false; - } - if (!m_ic.registerDstBufferPool(&m_dstPool, 1, dataLen)) { - m_ic.destroyBufferPool(m_srcPool); - return false; - } - m_bufferSize = dataLen; - } - - return true; -} - diff --git a/common/rfb/IrixDMJpegCompressor.h b/common/rfb/IrixDMJpegCompressor.h deleted file mode 100644 index db242003..00000000 --- a/common/rfb/IrixDMJpegCompressor.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __IRIXDMJPEGCOMPRESSOR_H__ -#define __IRIXDMJPEGCOMPRESSOR_H__ - -#include - -#include -#include - -#include -#include - -namespace rfb { - - // - // A C++ class for performing JPEG compression. - // This implementation uses IRIX Digital Media libraries. - // - - class IrixDMJpegCompressor : public JpegCompressor - { - public: - IrixDMJpegCompressor(); - virtual ~IrixDMJpegCompressor(); - - // Check if the object has been created successfully. - bool isValid() const { return m_ic.isValid(); } - - // Set JPEG quality level (0..100). - virtual void setQuality(int level); - - // Actually compress the image. - virtual void compress(const rdr::U32 *buf, const PixelFormat *fmt, - int w, int h, int stride); - - // Access results of the compression. - virtual size_t getDataLength() { return m_compressedLength; } - virtual const char *getDataPtr() { return m_compressedData; } - - protected: - // Update image size and make sure that our buffer pools will - // allocate properly-sized buffers. - bool updateImageSize(int w, int h); - - protected: - static const int DEFAULT_QUALITY; - int m_quality; - - IrixDMIC_RawToJpeg m_ic; - int m_width; - int m_height; - DMbufferpool m_srcPool; - DMbufferpool m_dstPool; - int m_bufferSize; - - char *m_compressedData; - size_t m_compressedLength; - }; - -} - -#endif // __IRIXDMJPEGCOMPRESSOR_H__ - diff --git a/common/rfb/JpegCompressor.cxx b/common/rfb/JpegCompressor.cxx deleted file mode 100644 index 0de87b4c..00000000 --- a/common/rfb/JpegCompressor.cxx +++ /dev/null @@ -1,193 +0,0 @@ -#include - -#include - -using namespace rfb; - -const int StandardJpegCompressor::ALLOC_CHUNK_SIZE = 65536; -const int StandardJpegCompressor::DEFAULT_QUALITY = 75; - -// -// Extend jpeg_destination_mgr struct with a pointer to our object. -// - -typedef struct { - struct jpeg_destination_mgr pub; - StandardJpegCompressor *_this; -} my_destination_mgr; - -// -// C-compatible interface to our destination manager. It just obtains -// a pointer to the right object and calls a corresponding C++ member -// function on that object. -// - -static void -init_destination(j_compress_ptr cinfo) -{ - my_destination_mgr *dest_ptr = (my_destination_mgr *)cinfo->dest; - dest_ptr->_this->initDestination(); -} - -static boolean -empty_output_buffer (j_compress_ptr cinfo) -{ - my_destination_mgr *dest_ptr = (my_destination_mgr *)cinfo->dest; - return (boolean)dest_ptr->_this->emptyOutputBuffer(); -} - -static void -term_destination (j_compress_ptr cinfo) -{ - my_destination_mgr *dest_ptr = (my_destination_mgr *)cinfo->dest; - dest_ptr->_this->termDestination(); -} - -// -// Constructor and destructor. -// - -StandardJpegCompressor::StandardJpegCompressor() - : m_cdata(0), - m_cdata_allocated(0), - m_cdata_ready(0) -{ - // Initialize JPEG compression structure. - m_cinfo.err = jpeg_std_error(&m_jerr); - jpeg_create_compress(&m_cinfo); - - // Set up a destination manager. - my_destination_mgr *dest = new my_destination_mgr; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->_this = this; - m_cinfo.dest = (jpeg_destination_mgr *)dest; - - // Set up a destination manager. - m_cinfo.input_components = 3; - m_cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&m_cinfo); - jpeg_set_quality(&m_cinfo, DEFAULT_QUALITY, true); - - // We prefer speed over quality. - m_cinfo.dct_method = JDCT_FASTEST; -} - -StandardJpegCompressor::~StandardJpegCompressor() -{ - // Free compressed data buffer. - if (m_cdata) - free(m_cdata); - - // Clean up the destination manager. - delete m_cinfo.dest; - m_cinfo.dest = NULL; - - // Release the JPEG compression structure. - jpeg_destroy_compress(&m_cinfo); -} - -// -// Our implementation of destination manager. -// - -void -StandardJpegCompressor::initDestination() -{ - if (!m_cdata) { - size_t new_size = ALLOC_CHUNK_SIZE; - m_cdata = (unsigned char *)malloc(new_size); - m_cdata_allocated = new_size; - } - - m_cdata_ready = 0; - m_cinfo.dest->next_output_byte = m_cdata; - m_cinfo.dest->free_in_buffer = m_cdata_allocated; -} - -bool -StandardJpegCompressor::emptyOutputBuffer() -{ - size_t old_size = m_cdata_allocated; - size_t new_size = old_size + ALLOC_CHUNK_SIZE; - - m_cdata = (unsigned char *)realloc(m_cdata, new_size); - m_cdata_allocated = new_size; - - m_cinfo.dest->next_output_byte = &m_cdata[old_size]; - m_cinfo.dest->free_in_buffer = new_size - old_size; - - return true; -} - -void -StandardJpegCompressor::termDestination() -{ - m_cdata_ready = m_cdata_allocated - m_cinfo.dest->free_in_buffer; -} - -// -// Set JPEG quality level (0..100) -// - -void -StandardJpegCompressor::setQuality(int level) -{ - if (level < 0) { - level = 0; - } else if (level > 100) { - level = 100; - } - jpeg_set_quality(&m_cinfo, level, true); -} - -// -// Perform JPEG compression. -// -// FIXME: This function assumes that (fmt->bpp == 32 && -// fmt->depth == 24 && fmt->redMax == 255 && -// fmt->greenMax == 255 && fmt->blueMax == 255). -// - -void -StandardJpegCompressor::compress(const rdr::U32 *buf, - const PixelFormat *fmt, - int w, int h, int stride) -{ - m_cinfo.image_width = w; - m_cinfo.image_height = h; - - jpeg_start_compress(&m_cinfo, TRUE); - - const rdr::U32 *src = buf; - - // We'll pass up to 8 rows to jpeg_write_scanlines(). - JSAMPLE *rgb = new JSAMPLE[w * 3 * 8]; - JSAMPROW row_pointer[8]; - for (int i = 0; i < 8; i++) - row_pointer[i] = &rgb[w * 3 * i]; - - // Feed the pixels to the JPEG library. - while (m_cinfo.next_scanline < m_cinfo.image_height) { - int max_rows = m_cinfo.image_height - m_cinfo.next_scanline; - if (max_rows > 8) { - max_rows = 8; - } - for (int dy = 0; dy < max_rows; dy++) { - JSAMPLE *dst = row_pointer[dy]; - for (int x = 0; x < w; x++) { - dst[x*3] = (JSAMPLE)(src[x] >> fmt->redShift); - dst[x*3+1] = (JSAMPLE)(src[x] >> fmt->greenShift); - dst[x*3+2] = (JSAMPLE)(src[x] >> fmt->blueShift); - } - src += stride; - } - jpeg_write_scanlines(&m_cinfo, row_pointer, max_rows); - } - - delete[] rgb; - - jpeg_finish_compress(&m_cinfo); -} - diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h deleted file mode 100644 index 93f6decf..00000000 --- a/common/rfb/JpegCompressor.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __JPEGCOMPRESSOR_H__ -#define __JPEGCOMPRESSOR_H__ - -#include -#include -extern "C" { -#include -} - -#include -#include - -namespace rfb { - - // - // An abstract interface for performing JPEG compression. - // - - class JpegCompressor - { - public: - virtual ~JpegCompressor() {} - - // Set JPEG quality level (0..100) - virtual void setQuality(int level) = 0; - - // Actually compress an image. - virtual void compress(const rdr::U32 *buf, const PixelFormat *fmt, - int w, int h, int stride) = 0; - - // Access results of the compression. - virtual size_t getDataLength() = 0; - virtual const char *getDataPtr() = 0; - }; - - // - // A C++ class for performing JPEG compression via the - // Independent JPEG Group's software (free JPEG library). - // - - class StandardJpegCompressor : public JpegCompressor - { - public: - StandardJpegCompressor(); - virtual ~StandardJpegCompressor(); - - // Set JPEG quality level (0..100) - virtual void setQuality(int level); - - // Actually compress the image. - virtual void compress(const rdr::U32 *buf, const PixelFormat *fmt, - int w, int h, int stride); - - // Access results of the compression. - virtual size_t getDataLength() { return m_cdata_ready; } - virtual const char *getDataPtr() { return (const char *)m_cdata; } - - public: - // Our implementation of JPEG destination manager. These three - // functions should never be called directly. They are made public - // because they should be accessible from C-compatible functions - // called by the JPEG library. - void initDestination(); - bool emptyOutputBuffer(); - void termDestination(); - - protected: - static const int ALLOC_CHUNK_SIZE; - static const int DEFAULT_QUALITY; - - struct jpeg_compress_struct m_cinfo; - struct jpeg_error_mgr m_jerr; - - unsigned char *m_cdata; - size_t m_cdata_allocated; - size_t m_cdata_ready; - }; - -} - -#endif // __JPEGCOMPRESSOR_H__ - diff --git a/common/rfb/JpegEncoder.cxx b/common/rfb/JpegEncoder.cxx deleted file mode 100644 index 2c47a604..00000000 --- a/common/rfb/JpegEncoder.cxx +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright (C) 2007 Constantin Kaplinsky. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_COMMON_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_CL -#include -#endif -#ifdef HAVE_DMEDIA -#include -#endif - -using namespace rfb; - -static LogWriter vlog("JpegEncoder"); - -BoolParameter JpegEncoder::useHardwareJPEG -("UseHardwareJPEG", - "Use hardware-accelerated JPEG compressor for video if available", - true); - -const int JpegEncoder::qualityMap[10] = { - 2, 10, 15, 25, 37, 50, 60, 70, 80, 90 -}; - -JpegEncoder::JpegEncoder(SMsgWriter* writer_) : writer(writer_), jcomp(0) -{ -#ifdef HAVE_DMEDIA -#ifdef DEBUG_FORCE_CL - vlog.debug("DEBUG: skipping IRIX DM JPEG compressor"); -#else - if (!jcomp && useHardwareJPEG) { - vlog.debug("trying IRIX DM JPEG compressor"); - IrixDMJpegCompressor *dmComp = new IrixDMJpegCompressor; - if (dmComp->isValid()) { - vlog.debug("initialized IRIX DM JPEG compressor successfully"); - jcomp = dmComp; - } else { - vlog.error("warning: could not create IRIX DM JPEG compressor"); - delete dmComp; - } - } -#endif -#endif - -#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 - - if (!jcomp) { - if (useHardwareJPEG) { - vlog.info("no hardware JPEG compressor available"); - } - vlog.debug("using software JPEG compressor"); - jcomp = new StandardJpegCompressor; - } - jcomp->setQuality(qualityMap[6]); -} - -JpegEncoder::~JpegEncoder() -{ - delete jcomp; -} - -void JpegEncoder::setQualityLevel(int level) -{ - if (level < 0) { - level = 0; - } else if (level > 9) { - level = 9; - } - jcomp->setQuality(qualityMap[level]); -} - -bool JpegEncoder::isPixelFormatSupported(PixelBuffer* pb) const -{ - 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); - rdr::OutStream* os = writer->getOutStream(); - - // Get access to pixel data - int stride; - const rdr::U32* pixels = (const rdr::U32 *)pb->getPixelsR(r, &stride); - const PixelFormat& fmt = pb->getPF(); - - // Try to encode data - jcomp->compress(pixels, &fmt, r.width(), r.height(), stride); - - // If not successful, switch to StandardJpegCompressor - if (jcomp->getDataLength() == 0) { - vlog.info("switching to standard software JPEG compressor"); - delete jcomp; - jcomp = new StandardJpegCompressor; - jcomp->setQuality(qualityMap[6]); - jcomp->compress(pixels, &fmt, r.width(), r.height(), stride); - } - - // Write Tight-encoded header and JPEG data. - os->writeU8(0x09 << 4); - os->writeCompactLength(jcomp->getDataLength()); - os->writeBytes(jcomp->getDataPtr(), jcomp->getDataLength()); - - writer->endRect(); -} - diff --git a/common/rfb/JpegEncoder.h b/common/rfb/JpegEncoder.h deleted file mode 100644 index f2f077dd..00000000 --- a/common/rfb/JpegEncoder.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007 Constantin Kaplinsky. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef __RFB_JPEGENCODER_H__ -#define __RFB_JPEGENCODER_H__ - -#include -#include -#include -#include - -// -// JPEG Encoder. -// NOTE: JpegEncoder class is NOT derived from Encoder, because we need -// access to the original server's framebuffer, without extra pixel -// copying and with no pixel format translation. -// - -namespace rfb { - - class JpegEncoder { - public: - JpegEncoder(SMsgWriter* writer); - virtual ~JpegEncoder(); - - virtual void setQualityLevel(int level); - virtual bool isPixelFormatSupported(PixelBuffer* pb) const; - virtual void writeRect(PixelBuffer* pb, const Rect& r); - - static BoolParameter useHardwareJPEG; - - private: - SMsgWriter* writer; - JpegCompressor* jcomp; - - static const int qualityMap[10]; - }; - -} - -#endif diff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am index 25df0007..d20752b1 100644 --- a/common/rfb/Makefile.am +++ b/common/rfb/Makefile.am @@ -9,8 +9,7 @@ HDRS = Blacklist.h CapsContainer.h CapsList.h CConnection.h CFTMsgReader.h \ FileWriter.h fttypes.h hextileConstants.h hextileDecode.h \ HextileDecoder.h hextileEncodeBetter.h hextileEncode.h \ HextileEncoder.h Hostname.h HTTPServer.h ImageGetter.h InputHandler.h \ - IrixCLJpegCompressor.h IrixDMIC_RawToJpeg.h IrixDMJpegCompressor.h \ - JpegCompressor.h JpegEncoder.h KeyRemapper.h keysymdef.h \ + KeyRemapper.h keysymdef.h \ ListConnInfo.h Logger_file.h Logger.h Logger_stdio.h LogWriter.h \ msgTypes.h Password.h PixelBuffer.h PixelFormat.h Pixel.h \ RawDecoder.h RawEncoder.h Rect.h Region.h rreDecode.h RREDecoder.h \ @@ -31,8 +30,8 @@ librfb_la_SOURCES = $(HDRS) Blacklist.cxx CConnection.cxx CFTMsgReader.cxx CFTMs CSecurityVncAuth.cxx CapsContainer.cxx CapsList.cxx \ ComparingUpdateTracker.cxx Configuration.cxx ConnParams.cxx \ Cursor.cxx Decoder.cxx d3des.c Encoder.cxx FileInfo.cxx \ - FileManager.cxx FileReader.cxx FileWriter.cxx JpegCompressor.cxx \ - JpegEncoder.cxx HTTPServer.cxx HextileDecoder.cxx HextileEncoder.cxx \ + FileManager.cxx FileReader.cxx FileWriter.cxx \ + HTTPServer.cxx HextileDecoder.cxx HextileEncoder.cxx \ KeyRemapper.cxx LogWriter.cxx Logger.cxx Logger_file.cxx \ Logger_stdio.cxx Password.cxx PixelBuffer.cxx PixelFormat.cxx \ RREEncoder.cxx RREDecoder.cxx RawDecoder.cxx RawEncoder.cxx \ @@ -49,15 +48,6 @@ librfb_la_SOURCES = $(HDRS) Blacklist.cxx CConnection.cxx CFTMsgReader.cxx CFTMs librfb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/../win librfb_la_LIBADD = -if IRIX_COMPRESS -librfb_la_SOURCES += IrixCLJpegCompressor.cxx -librfb_la_LIBADD += -lcl -endif -if IRIX_MEDIA -librfb_la_SOURCES += IrixDMJpegCompressor.cxx IrixDMIC_RawToJpeg.cxx -librfb_la_LIBADD += -ldmedia -endif - if INCLUDED_JPEG librfb_la_CPPFLAGS += -I$(top_srcdir)/jpeg librfb_la_LIBADD += $(top_srcdir)/jpeg/libjpeg.la diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx index a61627ca..9c6ffe31 100644 --- a/common/rfb/SConnection.cxx +++ b/common/rfb/SConnection.cxx @@ -46,8 +46,7 @@ SConnection::SConnection(SSecurityFactory* secFact, bool reverseConnection_) : readyForSetColourMapEntries(false), is(0), os(0), reader_(0), writer_(0), security(0), securityFactory(secFact), state_(RFBSTATE_UNINITIALISED), - reverseConnection(reverseConnection_), - m_videoSelectionEnabled(false) + reverseConnection(reverseConnection_) { defaultMajorVersion = 3; defaultMinorVersion = 8; @@ -77,11 +76,6 @@ void SConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_) os = os_; } -void SConnection::setProtocolOptions(bool enableVideoSelection) -{ - m_videoSelectionEnabled = enableVideoSelection; -} - void SConnection::initialiseProtocol() { cp.writeVersion(os); @@ -465,10 +459,6 @@ void SConnection::sendInteractionCaps() ccaps.addTightExt(msgTypeFileDeleteRequest, "FTC_RMRQ"); */ - if (m_videoSelectionEnabled) { - ccaps.addTightExt(msgTypeVideoRectangleSelection, "VRECTSEL"); - } - // // Advertise all supported encoding types (except raw encoding). // diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h index 2540ed78..e41ef5fb 100644 --- a/common/rfb/SConnection.h +++ b/common/rfb/SConnection.h @@ -50,11 +50,6 @@ namespace rfb { // (i.e. SConnection will not delete them). void setStreams(rdr::InStream* is, rdr::OutStream* os); - // setProtocolOptions() configures TightVNC-specific protocol options. - // It can be optionally called before calling initialiseProtocol(). - // See also: VNCServerST::enableVideoSelection(); - void setProtocolOptions(bool enableVideoSelection); - // initialiseProtocol() should be called once the streams and security // types are set. Subsequently, processMsg() should be called whenever // there is data to read on the InStream. @@ -203,9 +198,6 @@ namespace rfb { SSecurityFactory* securityFactory; stateEnum state_; bool reverseConnection; - - // TightVNC-specific protocol options. - bool m_videoSelectionEnabled; }; } #endif diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx index a4ae46d2..c55a8b72 100644 --- a/common/rfb/SMsgHandler.cxx +++ b/common/rfb/SMsgHandler.cxx @@ -51,6 +51,3 @@ void SMsgHandler::supportsLocalCursor() { } -void SMsgHandler::setVideoRectangle(const Rect& r) -{ -} diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h index 16b3c900..cf3377d5 100644 --- a/common/rfb/SMsgHandler.h +++ b/common/rfb/SMsgHandler.h @@ -47,8 +47,6 @@ namespace rfb { virtual void setEncodings(int nEncodings, rdr::U32* encodings); virtual void framebufferUpdateRequest(const Rect& r, bool incremental); - virtual void setVideoRectangle(const Rect& r); - // InputHandler interface // The InputHandler methods will be called for the corresponding messages. diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx index d2270640..447e0a41 100644 --- a/common/rfb/SMsgReader.cxx +++ b/common/rfb/SMsgReader.cxx @@ -99,25 +99,3 @@ void SMsgReader::readClientCutText() handler->clientCutText(ca.buf, len); } -void SMsgReader::readVideoRectangleSelection() -{ - (void)is->readU8(); - int x = is->readU16(); - int y = is->readU16(); - int w = is->readU16(); - int h = is->readU16(); - Rect rect(x, y, x+w, y+h); - - if (!rect.is_empty()) { - vlog.debug("Video area selected by client: %dx%d at (%d,%d)", - w, h, x, y); - } else if (x != 0 || y != 0 || w != 0 || h != 0) { - vlog.debug("Empty video area selected by client: %dx%d at (%d,%d)", - w, h, x, y); - rect.clear(); - } else { - vlog.debug("Video area discarded by client"); - } - handler->setVideoRectangle(rect); -} - diff --git a/common/rfb/SMsgReader.h b/common/rfb/SMsgReader.h index 145c747a..e6e40448 100644 --- a/common/rfb/SMsgReader.h +++ b/common/rfb/SMsgReader.h @@ -47,9 +47,6 @@ namespace rfb { virtual void readPointerEvent(); virtual void readClientCutText(); - // Read TightVNC-specific protocol messages. - virtual void readVideoRectangleSelection(); - SMsgReader(SMsgHandler* handler, rdr::InStream* is); SMsgHandler* handler; diff --git a/common/rfb/SMsgReaderV3.cxx b/common/rfb/SMsgReaderV3.cxx index da012c6c..165b23e9 100644 --- a/common/rfb/SMsgReaderV3.cxx +++ b/common/rfb/SMsgReaderV3.cxx @@ -63,8 +63,6 @@ void SMsgReaderV3::readMsg() case msgTypeFileRenameRequest: case msgTypeFileDeleteRequest: handler->processFTMsg(msgType); break; - case msgTypeVideoRectangleSelection: readVideoRectangleSelection(); break; - default: fprintf(stderr, "unknown message type %d\n", msgType); throw Exception("unknown message type"); diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index a8b9c29e..f3079eed 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -24,7 +24,6 @@ #include #include #include -#include using namespace rfb; @@ -40,7 +39,6 @@ SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_) bytesSent[i] = 0; rectsSent[i] = 0; } - jpegEncoder = new JpegEncoder(this); } SMsgWriter::~SMsgWriter() @@ -58,7 +56,6 @@ SMsgWriter::~SMsgWriter() vlog.info(" raw bytes equivalent %d, compression ratio %f", rawBytesEquivalent, (double)rawBytesEquivalent / bytes); delete [] imageBuf; - delete jpegEncoder; } void SMsgWriter::writeSetColourMapEntries(int firstColour, int nColours, @@ -105,8 +102,6 @@ void SMsgWriter::setupCurrentEncoder() encoders[encoding]->setCompressLevel(cp->compressLevel); encoders[encoding]->setQualityLevel(cp->qualityLevel); - if (cp->qualityLevel != -1) - jpegEncoder->setQualityLevel(cp->qualityLevel); } int SMsgWriter::getNumRects(const Rect &r) @@ -174,16 +169,6 @@ bool SMsgWriter::writeRect(const Rect& r, unsigned int encoding, return encoders[encoding]->writeRect(r, ig, actual); } -bool SMsgWriter::canUseJpegEncoder(PixelBuffer *pb) const -{ - return (cp->qualityLevel != -1 && jpegEncoder->isPixelFormatSupported(pb)); -} - -void SMsgWriter::writeJpegRect(PixelBuffer *pb, const Rect& r) -{ - jpegEncoder->writeRect(pb, r); -} - void SMsgWriter::writeCopyRect(const Rect& r, int srcX, int srcY) { startRect(r,encodingCopyRect); diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index 959f865d..bab9a1a2 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -37,7 +37,6 @@ namespace rfb { class ColourMap; class Region; class UpdateInfo; - class JpegEncoder; class WriteSetCursorCallback { public: @@ -133,9 +132,6 @@ namespace rfb { virtual void writeCopyRect(const Rect& r, int srcX, int srcY); - 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; @@ -161,14 +157,12 @@ namespace rfb { rdr::OutStream* os; Encoder* encoders[encodingMax+1]; - JpegEncoder* jpegEncoder; int lenBeforeRect; unsigned int currentEncoding; int updatesSent; int bytesSent[encodingMax+1]; int rectsSent[encodingMax+1]; int rawBytesEquivalent; - // FIXME: Gather statistics for JpegEncoder as well. rdr::U8* imageBuf; int imageBufSize; diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx index 43586171..4294b782 100644 --- a/common/rfb/ServerCore.cxx +++ b/common/rfb/ServerCore.cxx @@ -93,8 +93,3 @@ rfb::BoolParameter rfb::Server::queryConnect "Prompt the local user to accept or reject incoming connections.", false); -// TightVNC-specific parameters -rfb::IntParameter rfb::Server::videoPriority -("VideoPriority", - "Priority of sending video updates (0..8)", - 2, 0, 8); diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h index 85d4e902..68d7b74b 100644 --- a/common/rfb/ServerCore.h +++ b/common/rfb/ServerCore.h @@ -48,9 +48,6 @@ namespace rfb { static BoolParameter sendCutText; static BoolParameter queryConnect; - // TightVNC-specific parameters - static IntParameter videoPriority; - }; }; diff --git a/common/rfb/UpdateTracker.cxx b/common/rfb/UpdateTracker.cxx index 79f43f60..14ac49d7 100644 --- a/common/rfb/UpdateTracker.cxx +++ b/common/rfb/UpdateTracker.cxx @@ -60,10 +60,6 @@ void ClippingUpdateTracker::add_copied(const Region &dest, const Point &delta) { ut->add_changed(tmp); } -void ClippingUpdateTracker::set_video_area(const Rect &rect) { - ut->set_video_area(rect.intersect(clipRect)); -} - // SimpleUpdateTracker SimpleUpdateTracker::SimpleUpdateTracker(bool use_copyrect) { @@ -139,18 +135,6 @@ void SimpleUpdateTracker::add_copied(const Region &dest, const Point &delta) { return; } -void SimpleUpdateTracker::set_video_area(const Rect &rect) -{ - video_area = rect; -} - -// -// subtract() is called to mark some region as unchanged. We just remove that -// region from both `copied' and `changed' regions. Note that `video_area' is -// not affected intentionally; we assume that video is continuously changing, -// so it should always be treated as "changed". -// - void SimpleUpdateTracker::subtract(const Region& region) { copied.assign_subtract(region); changed.assign_subtract(region); @@ -158,15 +142,10 @@ void SimpleUpdateTracker::subtract(const Region& region) { void SimpleUpdateTracker::getUpdateInfo(UpdateInfo* info, const Region& clip) { - changed.assign_subtract(video_area); - copied.assign_subtract(changed.union_(video_area)); + copied.assign_subtract(changed); info->changed = changed.intersect(clip); info->copied = copied.intersect(clip); info->copy_delta = copy_delta; - // FIXME: Using get_bounding_rect() is not what should actually be done! - // We should use the biggest inner rectangle of the `clip' instead. - // From the other side, `clip' is usually just a sole rectangle. - info->video_area = video_area.intersect(clip.get_bounding_rect()); } void SimpleUpdateTracker::copyTo(UpdateTracker* to) const { @@ -174,5 +153,4 @@ void SimpleUpdateTracker::copyTo(UpdateTracker* to) const { to->add_copied(copied, copy_delta); if (!changed.is_empty()) to->add_changed(changed); - to->set_video_area(video_area); } diff --git a/common/rfb/UpdateTracker.h b/common/rfb/UpdateTracker.h index 9cd99ab1..8e96d55e 100644 --- a/common/rfb/UpdateTracker.h +++ b/common/rfb/UpdateTracker.h @@ -30,15 +30,14 @@ namespace rfb { Region changed; Region copied; Point copy_delta; - Rect video_area; bool is_empty() const { - return copied.is_empty() && changed.is_empty() && video_area.is_empty(); + return copied.is_empty() && changed.is_empty(); } // NOTE: We do not ever use UpdateInfo::numRects(), because Tight encoding // complicates computing the number of rectangles. /* int numRects() const { - return copied.numRects() + changed.numRects() + !video_area.is_empty(); + return copied.numRects() + changed.numRects(); } */ }; @@ -50,7 +49,6 @@ namespace rfb { virtual void add_changed(const Region ®ion) = 0; virtual void add_copied(const Region &dest, const Point &delta) = 0; - virtual void set_video_area(const Rect &rect) = 0; }; class ClippingUpdateTracker : public UpdateTracker { @@ -63,7 +61,6 @@ namespace rfb { virtual void add_changed(const Region ®ion); virtual void add_copied(const Region &dest, const Point &delta); - virtual void set_video_area(const Rect &rect); protected: UpdateTracker* ut; Rect clipRect; @@ -78,49 +75,26 @@ namespace rfb { virtual void add_changed(const Region ®ion); virtual void add_copied(const Region &dest, const Point &delta); - virtual void set_video_area(const Rect &rect); virtual void subtract(const Region& region); // Fill the supplied UpdateInfo structure with update information // FIXME: Provide getUpdateInfo() with no clipping, for better efficiency. virtual void getUpdateInfo(UpdateInfo* info, const Region& cliprgn); - // Get coordinates of the video rectangle - virtual const Rect& getVideoArea() const { - return video_area; - } - // Copy the contained updates to another tracker virtual void copyTo(UpdateTracker* to) const; // Move the entire update region by an offset - void translate(const Point& p) { - changed.translate(p); - copied.translate(p); - video_area.translate(p); - } + void translate(const Point& p) {changed.translate(p); copied.translate(p);} - virtual bool is_empty() const { - return changed.is_empty() && copied.is_empty() && video_area.is_empty(); - } - - // NOTE: We do not clear video_area intentionally. - virtual void clear() { - changed.clear(); - copied.clear(); - } + virtual bool is_empty() const {return changed.is_empty() && copied.is_empty();} + virtual void clear() {changed.clear(); copied.clear();}; protected: Region changed; Region copied; Point copy_delta; bool copy_enabled; - - // We can track one rectangle on the screen as a "video area". We assume - // it is changing continuously, in whole. Thus, we don't need to detect - // and track individual changes in the video area -- we can assume it's - // always in the changed state. - Rect video_area; }; } diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 9fe644cc..8e234743 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -86,7 +86,6 @@ VNCSConnectionST::~VNCSConnectionST() bool VNCSConnectionST::init() { try { - setProtocolOptions(server->isVideoSelectionEnabled()); initialiseProtocol(); } catch (rdr::Exception& e) { close(e.str()); @@ -128,12 +127,9 @@ void VNCSConnectionST::processMessages() } // If there were update requests, try to send a framebuffer update. - // We don't send updates immediately on requests for two reasons: - // (1) If a video area is set, we don't want to send it on every - // update request. We should gobble all the pending update - // requests and send just one update. - // (2) This way, we give higher priority to user actions such as - // keyboard and pointer events. + // We don't send updates immediately on requests as this way, we + // give higher priority to user actions such as keyboard and + // pointer events. if (!requested.is_empty()) { writeFramebufferUpdate(); } @@ -508,11 +504,6 @@ void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental) } } -void VNCSConnectionST::setVideoRectangle(const Rect& r) -{ - server->setVideoRectangle(r); -} - void VNCSConnectionST::setInitialColourMap() { setColourMapEntries(0, 0); @@ -573,26 +564,11 @@ void VNCSConnectionST::writeFramebufferUpdate() updates.enable_copyrect(cp.useCopyRect); - static int counter = 1; - if (--counter > 0) { - server->checkVideoUpdate(); - } else { - counter = rfb::Server::videoPriority; - server->checkUpdate(); - } - - // If VideoPriority is 0, convert video updates to normal updates. - - if (rfb::Server::videoPriority == 0) { - Region videoRegion(updates.getVideoArea()); - updates.add_changed(videoRegion); - Rect nullRect(0, 0, 0, 0); - updates.set_video_area(nullRect); - } + server->checkUpdate(); // Get the lists of updates. Prior to exporting the data to the `ui' object, // getUpdateInfo() will normalize the `updates' object such way that its - // `changed', `copied' and `video_area' regions would not intersect. + // `changed' and `copied' regions would not intersect. UpdateInfo ui; updates.getUpdateInfo(&ui, requested); @@ -665,13 +641,6 @@ void VNCSConnectionST::writeFramebufferUpdate() writer()->setupCurrentEncoder(); int nRects = (ui.copied.numRects() + (drawRenderedCursor ? 1 : 0)); - if (!ui.video_area.is_empty()) { - if (writer()->canUseJpegEncoder(server->getPixelBuffer())) { - nRects++; - } else { - nRects += writer()->getNumRects(ui.video_area); - } - } std::vector rects; std::vector::const_iterator i; @@ -682,14 +651,6 @@ void VNCSConnectionST::writeFramebufferUpdate() } writer()->writeFramebufferUpdateStart(nRects); - 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); diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index d1c08573..d17bf6b9 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -94,7 +94,6 @@ namespace rfb { void add_copied(const Region& dest, const Point& delta) { updates.add_copied(dest, delta); } - void set_video_area(const Rect &rect) { updates.set_video_area(rect); } const char* getPeerEndpoint() const {return peerEndpoint.buf;} @@ -131,8 +130,6 @@ namespace rfb { virtual void setInitialColourMap(); virtual void supportsLocalCursor(); - virtual void setVideoRectangle(const Rect& r); - // setAccessRights() allows a security package to limit the access rights // of a VNCSConnectioST to the server. These access rights are applied // such that the actual rights granted are the minimum of the server's diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index d36354c8..8f160e88 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -77,8 +77,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_, securityFactory(sf ? sf : &defaultSecurityFactory), queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance), useEconomicTranslate(false), - lastConnectionTime(0), disableclients(false), - m_videoSelectionEnabled(false) + lastConnectionTime(0), disableclients(false) { lastUserInputTime = lastDisconnectTime = time(0); slog.debug("creating single-threaded server %s", name.buf); @@ -147,7 +146,6 @@ void VNCServerST::removeSocket(network::Socket* sock) { slog.debug("no authenticated clients - stopping desktop"); desktopStarted = false; desktop->stop(); - setVideoRectangle(Rect(0, 0, 0, 0)); } return; } @@ -260,7 +258,6 @@ void VNCServerST::setPixelBuffer(PixelBuffer* pb_) if (pb) { comparer = new ComparingUpdateTracker(pb); - applyVideoRectangle(); cursor.setPF(pb->getPF()); renderedCursor.setPF(pb->getPF()); @@ -326,13 +323,6 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta) } } -void VNCServerST::set_video_area(const Rect &rect) -{ - if (comparer != 0) { - comparer->set_video_area(rect); - } -} - bool VNCServerST::clientsReadyForUpdate() { std::list::iterator ci; @@ -478,7 +468,7 @@ void VNCServerST::checkUpdate() if (ui.is_empty() && !(renderCursor && renderedCursorInvalid)) return; - Region toCheck = ui.changed.union_(ui.copied).union_(ui.video_area); + Region toCheck = ui.changed.union_(ui.copied); if (renderCursor) { Rect clippedCursorRect @@ -516,28 +506,11 @@ void VNCServerST::checkUpdate() ci_next = ci; ci_next++; (*ci)->add_copied(ui.copied, ui.copy_delta); (*ci)->add_changed(ui.changed); - (*ci)->set_video_area(ui.video_area); } comparer->clear(); } -void VNCServerST::checkVideoUpdate() -{ - const Rect &videoRect = comparer->getVideoArea(); - Region videoRegion(videoRect); - - if (!videoRegion.is_empty()) { - pb->grabRegion(videoRegion); - - std::list::iterator ci, ci_next; - for (ci = clients.begin(); ci != clients.end(); ci = ci_next) { - ci_next = ci; ci_next++; - (*ci)->set_video_area(videoRect); - } - } -} - void VNCServerST::getConnInfo(ListConnInfo * listConn) { listConn->Clear(); @@ -571,43 +544,3 @@ void VNCServerST::setConnStatus(ListConnInfo* listConn) } } -void VNCServerST::enableVideoSelection(bool enable) -{ - slog.debug("Enabling video selection"); - m_videoSelectionEnabled = enable; - applyVideoRectangle(); -} - -bool VNCServerST::isVideoSelectionEnabled() const -{ - return m_videoSelectionEnabled; -} - -void VNCServerST::setVideoRectangle(const Rect& r) -{ - m_videoRect = r; - applyVideoRectangle(); -} - -void VNCServerST::setDefaultVideoRectangle(const Rect& r) -{ - m_defaultVideoRect = r; - applyVideoRectangle(); -} - -void VNCServerST::applyVideoRectangle() -{ - if (pb != 0) { - if (isVideoSelectionEnabled() && !m_videoRect.is_empty()) { - slog.debug("Applying video selection"); - set_video_area(m_videoRect); - } else { - if (!m_defaultVideoRect.is_empty()) { - slog.debug("Applying default video area"); - } else { - slog.debug("Applying empty video area"); - } - set_video_area(m_defaultVideoRect); - } - } -} diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index ddd73c92..7503bd39 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -84,7 +84,6 @@ namespace rfb { virtual void serverCutText(const char* str, int len); virtual void add_changed(const Region ®ion); virtual void add_copied(const Region &dest, const Point &delta); - virtual void set_video_area(const Rect &rect); virtual bool clientsReadyForUpdate(); virtual void tryUpdate(); virtual void setCursor(int width, int height, const Point& hotspot, @@ -192,19 +191,6 @@ namespace rfb { void setFTManager(rfb::SFileTransferManager *pFTManager) { m_pFTManager = pFTManager; }; - // Enable/disable support for TightVNC-specific VideoRectangleSelection - // client message. This is a protocol option that lets a client select a - // rectangle to be treated by the server as video data. Once selected, this - // part of the framebuffer will be sent using JpegEncoder, on each update - // request, as we expect that video data is changing continuously. By - // default, this option is disabled, as it's rather a specialized feature - // and video selection GUI can confuse users of the TigerVNC client. - void enableVideoSelection(bool enable); - bool isVideoSelectionEnabled() const; - - void setVideoRectangle(const Rect& r); - void setDefaultVideoRectangle(const Rect& r); - protected: friend class VNCSConnectionST; @@ -241,7 +227,6 @@ namespace rfb { bool needRenderedCursor(); void checkUpdate(); - void checkVideoUpdate(); SSecurityFactory* securityFactory; QueryConnectionHandler* queryConnectionHandler; @@ -253,12 +238,6 @@ namespace rfb { time_t lastConnectionTime; bool disableclients; - - bool m_videoSelectionEnabled; - Rect m_videoRect; - Rect m_defaultVideoRect; - - void applyVideoRectangle(); }; }; diff --git a/common/rfb/msgTypes.h b/common/rfb/msgTypes.h index 32b1395f..ec26adc7 100644 --- a/common/rfb/msgTypes.h +++ b/common/rfb/msgTypes.h @@ -57,6 +57,5 @@ namespace rfb { const int msgTypeFileDeleteRequest = 139; const int msgTypeEnableContinuousUpdates = 150; - const int msgTypeVideoRectangleSelection = 151; } #endif diff --git a/common/rfb/rfb.dsp b/common/rfb/rfb.dsp index 1c3b3644..cbec8521 100644 --- a/common/rfb/rfb.dsp +++ b/common/rfb/rfb.dsp @@ -219,14 +219,6 @@ SOURCE=.\HTTPServer.cxx # End Source File # Begin Source File -SOURCE=.\JpegCompressor.cxx -# End Source File -# Begin Source File - -SOURCE=.\JpegEncoder.cxx -# End Source File -# Begin Source File - SOURCE=.\KeyRemapper.cxx # End Source File # Begin Source File @@ -553,14 +545,6 @@ SOURCE=.\InputHandler.h # End Source File # Begin Source File -SOURCE=.\JpegCompressor.h -# End Source File -# Begin Source File - -SOURCE=.\JpegEncoder.h -# End Source File -# Begin Source File - SOURCE=.\KeyRemapper.h # End Source File # Begin Source File diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx index f6bd26e5..ec2fd764 100644 --- a/unix/x0vncserver/x0vncserver.cxx +++ b/unix/x0vncserver/x0vncserver.cxx @@ -188,7 +188,6 @@ public: server = (VNCServerST *)vs; server->setPixelBuffer(pb); - server->setDefaultVideoRectangle(geometry->getVideoRect()); running = true; } @@ -447,7 +446,6 @@ int main(int argc, char** argv) VNCServerST server("x0vncserver", &desktop); QueryConnHandler qcHandler(dpy, &server); server.setQueryConnectionHandler(&qcHandler); - server.enableVideoSelection(true); TcpListener listener((int)rfbport); vlog.info("Listening on port %d", (int)rfbport);