mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Extract ImageResampler from X11Grabber
Former-commit-id: 63e95fa85fc0ef5a66f6eb8b396cf4b6370cf5dd
This commit is contained in:
parent
93de656985
commit
e608b11caa
@ -57,8 +57,8 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
|
|||||||
# Prefer static linking over dynamic
|
# Prefer static linking over dynamic
|
||||||
#set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
|
#set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
|
||||||
|
|
||||||
#set(CMAKE_BUILD_TYPE "Debug")
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
#set(CMAKE_BUILD_TYPE "Release")
|
||||||
|
|
||||||
# enable C++11
|
# enable C++11
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
|
||||||
|
@ -11,119 +11,119 @@
|
|||||||
// util includes
|
// util includes
|
||||||
#include <utils/Image.h>
|
#include <utils/Image.h>
|
||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
|
#include <utils/PixelFormat.h>
|
||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
// grabber includes
|
// grabber includes
|
||||||
#include <grabber/VideoStandard.h>
|
#include <grabber/VideoStandard.h>
|
||||||
#include <grabber/PixelFormat.h>
|
|
||||||
|
|
||||||
/// Capture class for V4L2 devices
|
/// Capture class for V4L2 devices
|
||||||
///
|
///
|
||||||
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
|
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
|
||||||
class V4L2Grabber : public QObject
|
class V4L2Grabber : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
V4L2Grabber(const std::string & device,
|
V4L2Grabber(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard, PixelFormat pixelFormat,
|
VideoStandard videoStandard, PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
int horizontalPixelDecimation,
|
int horizontalPixelDecimation,
|
||||||
int verticalPixelDecimation);
|
int verticalPixelDecimation);
|
||||||
virtual ~V4L2Grabber();
|
virtual ~V4L2Grabber();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCropping(int cropLeft,
|
void setCropping(int cropLeft,
|
||||||
int cropRight,
|
int cropRight,
|
||||||
int cropTop,
|
int cropTop,
|
||||||
int cropBottom);
|
int cropBottom);
|
||||||
|
|
||||||
void set3D(VideoMode mode);
|
void set3D(VideoMode mode);
|
||||||
|
|
||||||
void setSignalThreshold(double redSignalThreshold,
|
void setSignalThreshold(double redSignalThreshold,
|
||||||
double greenSignalThreshold,
|
double greenSignalThreshold,
|
||||||
double blueSignalThreshold,
|
double blueSignalThreshold,
|
||||||
int noSignalCounterThreshold);
|
int noSignalCounterThreshold);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newFrame(const Image<ColorRgb> & image);
|
void newFrame(const Image<ColorRgb> & image);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
int read_frame();
|
int read_frame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void open_device();
|
void open_device();
|
||||||
|
|
||||||
void close_device();
|
void close_device();
|
||||||
|
|
||||||
void init_read(unsigned int buffer_size);
|
void init_read(unsigned int buffer_size);
|
||||||
|
|
||||||
void init_mmap();
|
void init_mmap();
|
||||||
|
|
||||||
void init_userp(unsigned int buffer_size);
|
void init_userp(unsigned int buffer_size);
|
||||||
|
|
||||||
void init_device(VideoStandard videoStandard, int input);
|
void init_device(VideoStandard videoStandard, int input);
|
||||||
|
|
||||||
void uninit_device();
|
void uninit_device();
|
||||||
|
|
||||||
void start_capturing();
|
void start_capturing();
|
||||||
|
|
||||||
void stop_capturing();
|
void stop_capturing();
|
||||||
|
|
||||||
bool process_image(const void *p, int size);
|
bool process_image(const void *p, int size);
|
||||||
|
|
||||||
void process_image(const uint8_t *p);
|
void process_image(const uint8_t *p);
|
||||||
|
|
||||||
int xioctl(int request, void *arg);
|
int xioctl(int request, void *arg);
|
||||||
|
|
||||||
void throw_exception(const std::string &error);
|
void throw_exception(const std::string &error);
|
||||||
|
|
||||||
void throw_errno_exception(const std::string &error);
|
void throw_errno_exception(const std::string &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum io_method {
|
enum io_method {
|
||||||
IO_METHOD_READ,
|
IO_METHOD_READ,
|
||||||
IO_METHOD_MMAP,
|
IO_METHOD_MMAP,
|
||||||
IO_METHOD_USERPTR
|
IO_METHOD_USERPTR
|
||||||
};
|
};
|
||||||
|
|
||||||
struct buffer {
|
struct buffer {
|
||||||
void *start;
|
void *start;
|
||||||
size_t length;
|
size_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string _deviceName;
|
const std::string _deviceName;
|
||||||
const io_method _ioMethod;
|
const io_method _ioMethod;
|
||||||
int _fileDescriptor;
|
int _fileDescriptor;
|
||||||
std::vector<buffer> _buffers;
|
std::vector<buffer> _buffers;
|
||||||
|
|
||||||
PixelFormat _pixelFormat;
|
PixelFormat _pixelFormat;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
int _frameByteSize;
|
int _frameByteSize;
|
||||||
int _cropLeft;
|
int _cropLeft;
|
||||||
int _cropRight;
|
int _cropRight;
|
||||||
int _cropTop;
|
int _cropTop;
|
||||||
int _cropBottom;
|
int _cropBottom;
|
||||||
int _frameDecimation;
|
int _frameDecimation;
|
||||||
int _horizontalPixelDecimation;
|
int _horizontalPixelDecimation;
|
||||||
int _verticalPixelDecimation;
|
int _verticalPixelDecimation;
|
||||||
int _noSignalCounterThreshold;
|
int _noSignalCounterThreshold;
|
||||||
|
|
||||||
ColorRgb _noSignalThresholdColor;
|
ColorRgb _noSignalThresholdColor;
|
||||||
|
|
||||||
VideoMode _mode3D;
|
VideoMode _mode3D;
|
||||||
|
|
||||||
int _currentFrame;
|
int _currentFrame;
|
||||||
int _noSignalCounter;
|
int _noSignalCounter;
|
||||||
|
|
||||||
QSocketNotifier * _streamNotifier;
|
QSocketNotifier * _streamNotifier;
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Hyperion-utils includes
|
// Hyperion-utils includes
|
||||||
#include <utils/Image.h>
|
#include <utils/Image.h>
|
||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
|
#include <utils/ImageResampler.h>
|
||||||
|
|
||||||
// X11 includes
|
// X11 includes
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
@ -10,7 +11,7 @@ class X11Grabber
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
X11Grabber(const unsigned cropHorizontal, const unsigned cropVertical, const unsigned pixelDecimation);
|
X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
||||||
|
|
||||||
virtual ~X11Grabber();
|
virtual ~X11Grabber();
|
||||||
|
|
||||||
@ -19,11 +20,12 @@ public:
|
|||||||
Image<ColorRgb> & grab();
|
Image<ColorRgb> & grab();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ImageResampler _imageResampler;
|
||||||
|
|
||||||
const unsigned _pixelDecimation;
|
int _cropLeft;
|
||||||
|
int _cropRight;
|
||||||
const unsigned _cropWidth;
|
int _cropTop;
|
||||||
const unsigned _cropHeight;
|
int _cropBottom;
|
||||||
|
|
||||||
/// Reference to the X11 display (nullptr if not opened)
|
/// Reference to the X11 display (nullptr if not opened)
|
||||||
Display * _x11Display;
|
Display * _x11Display;
|
||||||
|
@ -11,207 +11,202 @@ class Image
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Pixel_T pixel_type;
|
typedef Pixel_T pixel_type;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Default constructor for an image
|
/// Default constructor for an image
|
||||||
///
|
///
|
||||||
Image() :
|
Image() :
|
||||||
_width(1),
|
_width(1),
|
||||||
_height(1),
|
_height(1),
|
||||||
_pixels(new Pixel_T[2]),
|
_pixels(new Pixel_T[2]),
|
||||||
_endOfPixels(_pixels + 1)
|
_endOfPixels(_pixels + 1)
|
||||||
{
|
{
|
||||||
memset(_pixels, 0, 2*sizeof(Pixel_T));
|
memset(_pixels, 0, 2*sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructor for an image with specified width and height
|
/// Constructor for an image with specified width and height
|
||||||
///
|
///
|
||||||
/// @param width The width of the image
|
/// @param width The width of the image
|
||||||
/// @param height The height of the image
|
/// @param height The height of the image
|
||||||
///
|
///
|
||||||
Image(const unsigned width, const unsigned height) :
|
Image(const unsigned width, const unsigned height) :
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_pixels(new Pixel_T[width * height + 1]),
|
_pixels(new Pixel_T[width * height + 1]),
|
||||||
_endOfPixels(_pixels + width * height)
|
_endOfPixels(_pixels + width * height)
|
||||||
{
|
{
|
||||||
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
|
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructor for an image with specified width and height
|
/// Constructor for an image with specified width and height
|
||||||
///
|
///
|
||||||
/// @param width The width of the image
|
/// @param width The width of the image
|
||||||
/// @param height The height of the image
|
/// @param height The height of the image
|
||||||
/// @param background The color of the image
|
/// @param background The color of the image
|
||||||
///
|
///
|
||||||
Image(const unsigned width, const unsigned height, const Pixel_T background) :
|
Image(const unsigned width, const unsigned height, const Pixel_T background) :
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_pixels(new Pixel_T[width * height + 1]),
|
_pixels(new Pixel_T[width * height + 1]),
|
||||||
_endOfPixels(_pixels + width * height)
|
_endOfPixels(_pixels + width * height)
|
||||||
{
|
{
|
||||||
std::fill(_pixels, _endOfPixels, background);
|
std::fill(_pixels, _endOfPixels, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copy constructor for an image
|
/// Copy constructor for an image
|
||||||
///
|
///
|
||||||
Image(const Image & other) :
|
Image(const Image & other) :
|
||||||
_width(other._width),
|
_width(other._width),
|
||||||
_height(other._height),
|
_height(other._height),
|
||||||
_pixels(new Pixel_T[other._width * other._height + 1]),
|
_pixels(new Pixel_T[other._width * other._height + 1]),
|
||||||
_endOfPixels(_pixels + other._width * other._height)
|
_endOfPixels(_pixels + other._width * other._height)
|
||||||
{
|
{
|
||||||
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
|
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor
|
/// Destructor
|
||||||
///
|
///
|
||||||
~Image()
|
~Image()
|
||||||
{
|
{
|
||||||
delete[] _pixels;
|
delete[] _pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the width of the image
|
/// Returns the width of the image
|
||||||
///
|
///
|
||||||
/// @return The width of the image
|
/// @return The width of the image
|
||||||
///
|
///
|
||||||
inline unsigned width() const
|
inline unsigned width() const
|
||||||
{
|
{
|
||||||
return _width;
|
return _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the height of the image
|
/// Returns the height of the image
|
||||||
///
|
///
|
||||||
/// @return The height of the image
|
/// @return The height of the image
|
||||||
///
|
///
|
||||||
inline unsigned height() const
|
inline unsigned height() const
|
||||||
{
|
{
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t alpha(const unsigned pixel) const
|
uint8_t red(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->red;
|
return (_pixels + pixel)->red;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t red(const unsigned pixel) const
|
uint8_t green(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->red;
|
return (_pixels + pixel)->green;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t green(const unsigned pixel) const
|
uint8_t blue(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->green;
|
return (_pixels + pixel)->blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t blue(const unsigned pixel) const
|
///
|
||||||
{
|
/// Returns a const reference to a specified pixel in the image
|
||||||
return (_pixels + pixel)->blue;
|
///
|
||||||
}
|
/// @param x The x index
|
||||||
|
/// @param y The y index
|
||||||
|
///
|
||||||
|
/// @return const reference to specified pixel
|
||||||
|
///
|
||||||
|
const Pixel_T& operator()(const unsigned x, const unsigned y) const
|
||||||
|
{
|
||||||
|
return _pixels[toIndex(x,y)];
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a const reference to a specified pixel in the image
|
/// Returns a reference to a specified pixel in the image
|
||||||
///
|
///
|
||||||
/// @param x The x index
|
/// @param x The x index
|
||||||
/// @param y The y index
|
/// @param y The y index
|
||||||
///
|
///
|
||||||
/// @return const reference to specified pixel
|
/// @return reference to specified pixel
|
||||||
///
|
///
|
||||||
const Pixel_T& operator()(const unsigned x, const unsigned y) const
|
Pixel_T& operator()(const unsigned x, const unsigned y)
|
||||||
{
|
{
|
||||||
return _pixels[toIndex(x,y)];
|
return _pixels[toIndex(x,y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
/// Resize the image
|
||||||
/// Returns a reference to a specified pixel in the image
|
/// @param width The width of the image
|
||||||
///
|
/// @param height The height of the image
|
||||||
/// @param x The x index
|
void resize(const unsigned width, const unsigned height)
|
||||||
/// @param y The y index
|
{
|
||||||
///
|
if ((width*height) > (_endOfPixels-_pixels))
|
||||||
/// @return reference to specified pixel
|
{
|
||||||
///
|
delete[] _pixels;
|
||||||
Pixel_T& operator()(const unsigned x, const unsigned y)
|
_pixels = new Pixel_T[width*height + 1];
|
||||||
{
|
_endOfPixels = _pixels + width*height;
|
||||||
return _pixels[toIndex(x,y)];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Resize the image
|
_width = width;
|
||||||
/// @param width The width of the image
|
_height = height;
|
||||||
/// @param height The height of the image
|
}
|
||||||
void resize(const unsigned width, const unsigned height)
|
|
||||||
{
|
|
||||||
if ((width*height) > (_endOfPixels-_pixels))
|
|
||||||
{
|
|
||||||
delete[] _pixels;
|
|
||||||
_pixels = new Pixel_T[width*height + 1];
|
|
||||||
_endOfPixels = _pixels + width*height;
|
|
||||||
}
|
|
||||||
|
|
||||||
_width = width;
|
///
|
||||||
_height = height;
|
/// Copies another image into this image. The images should have exactly the same size.
|
||||||
}
|
///
|
||||||
|
/// @param other The image to copy into this
|
||||||
|
///
|
||||||
|
void copy(const Image<Pixel_T>& other)
|
||||||
|
{
|
||||||
|
assert(other._width == _width);
|
||||||
|
assert(other._height == _height);
|
||||||
|
|
||||||
///
|
memcpy(_pixels, other._pixels, _width*_height*sizeof(Pixel_T));
|
||||||
/// Copies another image into this image. The images should have exactly the same size.
|
}
|
||||||
///
|
|
||||||
/// @param other The image to copy into this
|
|
||||||
///
|
|
||||||
void copy(const Image<Pixel_T>& other)
|
|
||||||
{
|
|
||||||
assert(other._width == _width);
|
|
||||||
assert(other._height == _height);
|
|
||||||
|
|
||||||
memcpy(_pixels, other._pixels, _width*_height*sizeof(Pixel_T));
|
///
|
||||||
}
|
/// Returns a memory pointer to the first pixel in the image
|
||||||
|
/// @return The memory pointer to the first pixel
|
||||||
|
///
|
||||||
|
Pixel_T* memptr()
|
||||||
|
{
|
||||||
|
return _pixels;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a memory pointer to the first pixel in the image
|
/// Returns a const memory pointer to the first pixel in the image
|
||||||
/// @return The memory pointer to the first pixel
|
/// @return The const memory pointer to the first pixel
|
||||||
///
|
///
|
||||||
Pixel_T* memptr()
|
const Pixel_T* memptr() const
|
||||||
{
|
{
|
||||||
return _pixels;
|
return _pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a const memory pointer to the first pixel in the image
|
|
||||||
/// @return The const memory pointer to the first pixel
|
|
||||||
///
|
|
||||||
const Pixel_T* memptr() const
|
|
||||||
{
|
|
||||||
return _pixels;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Translate x and y coordinate to index of the underlying vector
|
/// Translate x and y coordinate to index of the underlying vector
|
||||||
///
|
///
|
||||||
/// @param x The x index
|
/// @param x The x index
|
||||||
/// @param y The y index
|
/// @param y The y index
|
||||||
///
|
///
|
||||||
/// @return The index into the underlying data-vector
|
/// @return The index into the underlying data-vector
|
||||||
///
|
///
|
||||||
inline unsigned toIndex(const unsigned x, const unsigned y) const
|
inline unsigned toIndex(const unsigned x, const unsigned y) const
|
||||||
{
|
{
|
||||||
return y*_width + x;
|
return y*_width + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The width of the image
|
/// The width of the image
|
||||||
unsigned _width;
|
unsigned _width;
|
||||||
/// The height of the image
|
/// The height of the image
|
||||||
unsigned _height;
|
unsigned _height;
|
||||||
|
|
||||||
/// The pixels of the image
|
/// The pixels of the image
|
||||||
Pixel_T* _pixels;
|
Pixel_T* _pixels;
|
||||||
|
|
||||||
/// Pointer to the last(extra) pixel
|
/// Pointer to the last(extra) pixel
|
||||||
Pixel_T* _endOfPixels;
|
Pixel_T* _endOfPixels;
|
||||||
};
|
};
|
||||||
|
40
include/utils/ImageResampler.h
Normal file
40
include/utils/ImageResampler.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/VideoMode.h>
|
||||||
|
#include <utils/PixelFormat.h>
|
||||||
|
#include <utils/Image.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
|
||||||
|
class ImageResampler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageResampler();
|
||||||
|
~ImageResampler();
|
||||||
|
|
||||||
|
void setHorizontalPixelDecimation(int decimator);
|
||||||
|
|
||||||
|
void setVerticalPixelDecimation(int decimator);
|
||||||
|
|
||||||
|
void setCropping(int cropLeft,
|
||||||
|
int cropRight,
|
||||||
|
int cropTop,
|
||||||
|
int cropBottom);
|
||||||
|
|
||||||
|
void set3D(VideoMode mode);
|
||||||
|
|
||||||
|
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat,
|
||||||
|
Image<ColorRgb> & outputImage) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline uint8_t clamp(int x);
|
||||||
|
static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _horizontalDecimation;
|
||||||
|
int _verticalDecimation;
|
||||||
|
int _cropLeft;
|
||||||
|
int _cropRight;
|
||||||
|
int _cropTop;
|
||||||
|
int _cropBottom;
|
||||||
|
VideoMode _videoMode;
|
||||||
|
};
|
@ -9,8 +9,9 @@
|
|||||||
enum PixelFormat {
|
enum PixelFormat {
|
||||||
PIXELFORMAT_YUYV,
|
PIXELFORMAT_YUYV,
|
||||||
PIXELFORMAT_UYVY,
|
PIXELFORMAT_UYVY,
|
||||||
PIXELFORMAT_RGB32,
|
PIXELFORMAT_RGB32,
|
||||||
PIXELFORMAT_NO_CHANGE
|
PIXELFORMAT_BGR32,
|
||||||
|
PIXELFORMAT_NO_CHANGE
|
||||||
};
|
};
|
||||||
|
|
||||||
inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
||||||
@ -26,10 +27,14 @@ inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
|||||||
{
|
{
|
||||||
return PIXELFORMAT_UYVY;
|
return PIXELFORMAT_UYVY;
|
||||||
}
|
}
|
||||||
else if (pixelFormat == "rgb32")
|
else if (pixelFormat == "rgb32")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_RGB32;
|
return PIXELFORMAT_RGB32;
|
||||||
}
|
}
|
||||||
|
else if (pixelFormat == "bgr32")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_BGR32;
|
||||||
|
}
|
||||||
|
|
||||||
// return the default NO_CHANGE
|
// return the default NO_CHANGE
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
@ -9,7 +9,6 @@ SET(V4L2_QT_HEADERS
|
|||||||
|
|
||||||
SET(V4L2_HEADERS
|
SET(V4L2_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/VideoStandard.h
|
${CURRENT_HEADER_DIR}/VideoStandard.h
|
||||||
${CURRENT_HEADER_DIR}/PixelFormat.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(V4L2_SOURCES
|
SET(V4L2_SOURCES
|
||||||
|
@ -20,19 +20,19 @@
|
|||||||
|
|
||||||
static inline uint8_t clamp(int x)
|
static inline uint8_t clamp(int x)
|
||||||
{
|
{
|
||||||
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
|
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b)
|
static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b)
|
||||||
{
|
{
|
||||||
// see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
|
// see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
|
||||||
int c = y - 16;
|
int c = y - 16;
|
||||||
int d = u - 128;
|
int d = u - 128;
|
||||||
int e = v - 128;
|
int e = v - 128;
|
||||||
|
|
||||||
r = clamp((298 * c + 409 * e + 128) >> 8);
|
r = clamp((298 * c + 409 * e + 128) >> 8);
|
||||||
g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
|
g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
|
||||||
b = clamp((298 * c + 516 * d + 128) >> 8);
|
b = clamp((298 * c + 516 * d + 128) >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,16 +8,20 @@
|
|||||||
// X11Grabber includes
|
// X11Grabber includes
|
||||||
#include <grabber/X11Grabber.h>
|
#include <grabber/X11Grabber.h>
|
||||||
|
|
||||||
X11Grabber::X11Grabber(const unsigned cropHorizontal, const unsigned cropVertical, const unsigned pixelDecimation) :
|
X11Grabber::X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
||||||
_pixelDecimation(pixelDecimation),
|
_imageResampler(),
|
||||||
_cropWidth(cropHorizontal),
|
_cropLeft(cropLeft),
|
||||||
_cropHeight(cropVertical),
|
_cropRight(cropRight),
|
||||||
|
_cropTop(cropTop),
|
||||||
|
_cropBottom(cropBottom),
|
||||||
_x11Display(nullptr),
|
_x11Display(nullptr),
|
||||||
_screenWidth(0),
|
_screenWidth(0),
|
||||||
_screenHeight(0),
|
_screenHeight(0),
|
||||||
_image(0,0)
|
_image(0,0)
|
||||||
{
|
{
|
||||||
// empty
|
_imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation);
|
||||||
|
_imageResampler.setVerticalPixelDecimation(verticalPixelDecimation);
|
||||||
|
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XGetImage
|
||||||
}
|
}
|
||||||
|
|
||||||
X11Grabber::~X11Grabber()
|
X11Grabber::~X11Grabber()
|
||||||
@ -51,42 +55,18 @@ Image<ColorRgb> & X11Grabber::grab()
|
|||||||
|
|
||||||
updateScreenDimensions();
|
updateScreenDimensions();
|
||||||
|
|
||||||
const int croppedWidth = _screenWidth - 2*_cropWidth;
|
const unsigned croppedWidth = _screenWidth - _cropLeft - _cropRight;
|
||||||
const int croppedHeight = _screenHeight - 2*_cropHeight;
|
const unsigned croppedHeight = _screenHeight - _cropTop - _cropBottom;
|
||||||
|
|
||||||
// Capture the current screen
|
// Capture the current screen
|
||||||
XImage * xImage = XGetImage(_x11Display, DefaultRootWindow(_x11Display), _cropWidth, _cropHeight, croppedWidth, croppedHeight, AllPlanes, ZPixmap);
|
XImage * xImage = XGetImage(_x11Display, DefaultRootWindow(_x11Display), _cropLeft, _cropTop, croppedWidth, croppedHeight, AllPlanes, ZPixmap);
|
||||||
if (xImage == nullptr)
|
if (xImage == nullptr)
|
||||||
{
|
{
|
||||||
std::cerr << "Grab failed" << std::endl;
|
std::cerr << "Grab failed" << std::endl;
|
||||||
return _image;
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the capture XImage to the local image (and apply required decimation)
|
_imageResampler.processImage(reinterpret_cast<const uint8_t *>(xImage->data), xImage->width, xImage->height, xImage->bytes_per_line, PIXELFORMAT_BGR32, _image);
|
||||||
ColorRgb * outputPtr = _image.memptr();
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
for (int iY=(_pixelDecimation/2); iY<croppedHeight; iY+=_pixelDecimation)
|
|
||||||
{
|
|
||||||
width = 0;
|
|
||||||
for (int iX=(_pixelDecimation/2); iX<croppedWidth; iX+=_pixelDecimation)
|
|
||||||
{
|
|
||||||
// Extract the pixel from the X11-image
|
|
||||||
const uint32_t pixel = uint32_t(XGetPixel(xImage, iX, iY));
|
|
||||||
|
|
||||||
// Assign the color value
|
|
||||||
outputPtr->red = uint8_t((pixel >> 16) & 0xff);
|
|
||||||
outputPtr->green = uint8_t((pixel >> 8) & 0xff);
|
|
||||||
outputPtr->blue = uint8_t((pixel >> 0) & 0xff);
|
|
||||||
|
|
||||||
// Move to the next output pixel
|
|
||||||
++outputPtr;
|
|
||||||
++width;
|
|
||||||
}
|
|
||||||
++height;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "decimated X11 message: " << width << " x " << height << std::endl;
|
|
||||||
|
|
||||||
// Cleanup allocated resources of the X11 grab
|
// Cleanup allocated resources of the X11 grab
|
||||||
XDestroyImage(xImage);
|
XDestroyImage(xImage);
|
||||||
@ -114,11 +94,5 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
_screenHeight = window_attributes_return.height;
|
_screenHeight = window_attributes_return.height;
|
||||||
std::cout << "[" << _screenWidth << "x" << _screenHeight <<"]" << std::endl;
|
std::cout << "[" << _screenWidth << "x" << _screenHeight <<"]" << std::endl;
|
||||||
|
|
||||||
// Update the size of the buffer used to transfer the screenshot
|
|
||||||
int width = (_screenWidth - 2 * _cropWidth - _pixelDecimation/2 - 1) / _pixelDecimation + 1;
|
|
||||||
int height = (_screenHeight - 2 * _cropHeight - _pixelDecimation/2 - 1) / _pixelDecimation + 1;
|
|
||||||
|
|
||||||
_image.resize(width, height);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,12 @@ add_library(hyperion-utils
|
|||||||
${CURRENT_HEADER_DIR}/Image.h
|
${CURRENT_HEADER_DIR}/Image.h
|
||||||
${CURRENT_HEADER_DIR}/Sleep.h
|
${CURRENT_HEADER_DIR}/Sleep.h
|
||||||
|
|
||||||
|
${CURRENT_HEADER_DIR}/PixelFormat.h
|
||||||
|
${CURRENT_HEADER_DIR}/VideoMode.h
|
||||||
|
|
||||||
|
${CURRENT_HEADER_DIR}/ImageResampler.h
|
||||||
|
${CURRENT_SOURCE_DIR}/ImageResampler.cpp
|
||||||
|
|
||||||
${CURRENT_HEADER_DIR}/HsvTransform.h
|
${CURRENT_HEADER_DIR}/HsvTransform.h
|
||||||
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
||||||
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
|
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
|
||||||
|
133
libsrc/utils/ImageResampler.cpp
Normal file
133
libsrc/utils/ImageResampler.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include "utils/ImageResampler.h"
|
||||||
|
|
||||||
|
ImageResampler::ImageResampler() :
|
||||||
|
_horizontalDecimation(1),
|
||||||
|
_verticalDecimation(1),
|
||||||
|
_cropLeft(0),
|
||||||
|
_cropRight(0),
|
||||||
|
_cropTop(0),
|
||||||
|
_cropBottom(0),
|
||||||
|
_videoMode(VIDEO_2D)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageResampler::~ImageResampler()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::setHorizontalPixelDecimation(int decimator)
|
||||||
|
{
|
||||||
|
_horizontalDecimation = decimator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::setVerticalPixelDecimation(int decimator)
|
||||||
|
{
|
||||||
|
_verticalDecimation = decimator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||||
|
{
|
||||||
|
_cropLeft = cropLeft;
|
||||||
|
_cropRight = cropRight;
|
||||||
|
_cropTop = cropTop;
|
||||||
|
_cropBottom = cropBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::set3D(VideoMode mode)
|
||||||
|
{
|
||||||
|
_videoMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> &outputImage) const
|
||||||
|
{
|
||||||
|
int cropLeft = _cropLeft;
|
||||||
|
int cropRight = _cropRight;
|
||||||
|
int cropTop = _cropTop;
|
||||||
|
int cropBottom = _cropBottom;
|
||||||
|
|
||||||
|
// handle 3D mode
|
||||||
|
switch (_videoMode)
|
||||||
|
{
|
||||||
|
case VIDEO_3DSBS:
|
||||||
|
cropRight = width/2;
|
||||||
|
break;
|
||||||
|
case VIDEO_3DTAB:
|
||||||
|
cropBottom = height/2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the output size
|
||||||
|
int outputWidth = (width - cropLeft - cropRight - _horizontalDecimation/2 + _horizontalDecimation - 1) / _horizontalDecimation;
|
||||||
|
int outputHeight = (height - cropTop - cropBottom - _verticalDecimation/2 + _verticalDecimation - 1) / _verticalDecimation;
|
||||||
|
outputImage.resize(outputWidth, outputHeight);
|
||||||
|
|
||||||
|
for (int yDest = 0, ySource = cropTop + _verticalDecimation/2; yDest < outputHeight; ySource += _verticalDecimation, ++yDest)
|
||||||
|
{
|
||||||
|
for (int xDest = 0, xSource = cropLeft + _horizontalDecimation/2; xDest < outputWidth; xSource += _horizontalDecimation, ++xDest)
|
||||||
|
{
|
||||||
|
ColorRgb & rgb = outputImage(xDest, yDest);
|
||||||
|
|
||||||
|
switch (pixelFormat)
|
||||||
|
{
|
||||||
|
case PIXELFORMAT_UYVY:
|
||||||
|
{
|
||||||
|
int index = lineLength * ySource + xSource * 2;
|
||||||
|
uint8_t y = data[index+1];
|
||||||
|
uint8_t u = ((xSource&1) == 0) ? data[index ] : data[index-2];
|
||||||
|
uint8_t v = ((xSource&1) == 0) ? data[index+2] : data[index ];
|
||||||
|
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_YUYV:
|
||||||
|
{
|
||||||
|
int index = lineLength * ySource + xSource * 2;
|
||||||
|
uint8_t y = data[index];
|
||||||
|
uint8_t u = ((xSource&1) == 0) ? data[index+1] : data[index-1];
|
||||||
|
uint8_t v = ((xSource&1) == 0) ? data[index+3] : data[index+1];
|
||||||
|
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_RGB32:
|
||||||
|
{
|
||||||
|
int index = lineLength * ySource + xSource * 4;
|
||||||
|
rgb.red = data[index ];
|
||||||
|
rgb.green = data[index+1];
|
||||||
|
rgb.blue = data[index+2];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_BGR32:
|
||||||
|
{
|
||||||
|
int index = lineLength * ySource + xSource * 4;
|
||||||
|
rgb.blue = data[index ];
|
||||||
|
rgb.green = data[index+1];
|
||||||
|
rgb.red = data[index+2];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_NO_CHANGE:
|
||||||
|
std::cerr << "Invalid pixel format given" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ImageResampler::clamp(int x)
|
||||||
|
{
|
||||||
|
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResampler::yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t &r, uint8_t &g, uint8_t &b)
|
||||||
|
{
|
||||||
|
// see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
|
||||||
|
int c = y - 16;
|
||||||
|
int d = u - 128;
|
||||||
|
int e = v - 128;
|
||||||
|
|
||||||
|
r = clamp((298 * c + 409 * e + 128) >> 8);
|
||||||
|
g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
|
||||||
|
b = clamp((298 * c + 516 * d + 128) >> 8);
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
#include <getoptPlusPlus/getoptpp.h>
|
#include <getoptPlusPlus/getoptpp.h>
|
||||||
|
|
||||||
// grabber includes
|
// grabber includes
|
||||||
#include <grabber/PixelFormat.h>
|
#include <utils/PixelFormat.h>
|
||||||
|
|
||||||
using namespace vlofgren;
|
using namespace vlofgren;
|
||||||
|
|
||||||
@ -10,34 +10,34 @@ using namespace vlofgren;
|
|||||||
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
|
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
|
||||||
|
|
||||||
namespace vlofgren {
|
namespace vlofgren {
|
||||||
/// Translates a string (as passed on the commandline) to a pixel format
|
/// Translates a string (as passed on the commandline) to a pixel format
|
||||||
///
|
///
|
||||||
/// @param[in] s The string (as passed on the commandline)
|
/// @param[in] s The string (as passed on the commandline)
|
||||||
/// @return The pixel format
|
/// @return The pixel format
|
||||||
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
|
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
|
||||||
template<>
|
template<>
|
||||||
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
QString input = QString::fromStdString(s).toLower();
|
QString input = QString::fromStdString(s).toLower();
|
||||||
|
|
||||||
if (input == "yuyv")
|
if (input == "yuyv")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_YUYV;
|
return PIXELFORMAT_YUYV;
|
||||||
}
|
}
|
||||||
else if (input == "uyvy")
|
else if (input == "uyvy")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_UYVY;
|
return PIXELFORMAT_UYVY;
|
||||||
}
|
}
|
||||||
else if (input == "rgb32")
|
else if (input == "rgb32")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_RGB32;
|
return PIXELFORMAT_RGB32;
|
||||||
}
|
}
|
||||||
else if (input == "no-change")
|
else if (input == "no-change")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
|
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ int main(int argc, char** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cropping values if not defined
|
||||||
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
// Hyperion-X11 includes
|
// Hyperion-X11 includes
|
||||||
#include "X11Wrapper.h"
|
#include "X11Wrapper.h"
|
||||||
|
|
||||||
X11Wrapper::X11Wrapper(int grabInterval, const unsigned cropHorizontal, const unsigned cropVertical, const unsigned pixelDecimation) :
|
X11Wrapper::X11Wrapper(int grabInterval, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(cropHorizontal, cropVertical, pixelDecimation)
|
_grabber(cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(grabInterval);
|
_timer.setInterval(grabInterval);
|
||||||
|
@ -9,7 +9,7 @@ class X11Wrapper : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
X11Wrapper(int grabInterval, const unsigned cropHorizontal, const unsigned cropVertical, const unsigned pixelDecimation);
|
X11Wrapper(int grabInterval, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
||||||
|
|
||||||
const Image<ColorRgb> & getScreenshot();
|
const Image<ColorRgb> & getScreenshot();
|
||||||
|
|
||||||
|
@ -30,9 +30,13 @@ int main(int argc, char ** argv)
|
|||||||
ParameterSet & parameters = optionParser.getParameters();
|
ParameterSet & parameters = optionParser.getParameters();
|
||||||
|
|
||||||
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Cpture frame rate [default=10]");
|
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Cpture frame rate [default=10]");
|
||||||
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides in the picture before decimation [default=0]");
|
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default=0]");
|
||||||
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom in the picture before decimation [default=0]");
|
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default=0]");
|
||||||
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=16]");
|
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
|
||||||
|
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
|
||||||
|
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
|
||||||
|
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
|
||||||
|
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=8]");
|
||||||
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
||||||
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
||||||
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
||||||
@ -43,7 +47,7 @@ int main(int argc, char ** argv)
|
|||||||
argFps.setDefault(10);
|
argFps.setDefault(10);
|
||||||
argCropWidth.setDefault(0);
|
argCropWidth.setDefault(0);
|
||||||
argCropHeight.setDefault(0);
|
argCropHeight.setDefault(0);
|
||||||
argSizeDecimation.setDefault(16);
|
argSizeDecimation.setDefault(8);
|
||||||
argAddress.setDefault("127.0.0.1:19445");
|
argAddress.setDefault("127.0.0.1:19445");
|
||||||
argPriority.setDefault(800);
|
argPriority.setDefault(800);
|
||||||
|
|
||||||
@ -57,9 +61,22 @@ int main(int argc, char ** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cropping values if not defined
|
||||||
|
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
||||||
|
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
||||||
|
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
||||||
|
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
|
||||||
|
|
||||||
// Create the X11 grabbing stuff
|
// Create the X11 grabbing stuff
|
||||||
int grabInterval = 1000 / argFps.getValue();
|
int grabInterval = 1000 / argFps.getValue();
|
||||||
X11Wrapper x11Wrapper(grabInterval, argCropWidth.getValue(), argCropHeight.getValue(), argSizeDecimation.getValue());
|
X11Wrapper x11Wrapper(
|
||||||
|
grabInterval,
|
||||||
|
argCropLeft.getValue(),
|
||||||
|
argCropRight.getValue(),
|
||||||
|
argCropTop.getValue(),
|
||||||
|
argCropBottom.getValue(),
|
||||||
|
argSizeDecimation.getValue(), // horizontal decimation
|
||||||
|
argSizeDecimation.getValue()); // vertical decimation
|
||||||
|
|
||||||
if (argScreenshot.isSet())
|
if (argScreenshot.isSet())
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user