Modify Convert to scale as well
This commit is contained in:
parent
ba8d9ee768
commit
6886b2b375
|
@ -1,11 +1,7 @@
|
||||||
#include "zm.h"
|
#include "zm.h"
|
||||||
#include "zm_signal.h"
|
#include "zm_signal.h"
|
||||||
#include "zm_libvnc_camera.h"
|
#include "zm_libvnc_camera.h"
|
||||||
extern "C" {
|
#include "zm_swscale.h"
|
||||||
#include <libavutil/imgutils.h>
|
|
||||||
#include <libavutil/parseutils.h>
|
|
||||||
#include <libswscale/swscale.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_LIBVNC
|
#if HAVE_LIBVNC
|
||||||
|
|
||||||
|
@ -25,6 +21,7 @@ static char* GetPasswordCallback(rfbClient* cl){
|
||||||
static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
||||||
rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential));
|
rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential));
|
||||||
if ( credentialType != rfbCredentialTypeUser ) {
|
if ( credentialType != rfbCredentialTypeUser ) {
|
||||||
|
free(c);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +65,23 @@ VncCamera::VncCamera(
|
||||||
mPass(pass)
|
mPass(pass)
|
||||||
{
|
{
|
||||||
Debug(2, "Host:%s Port: %s User: %s Pass:%s", mHost.c_str(), mPort.c_str(), mUser.c_str(), mPass.c_str());
|
Debug(2, "Host:%s Port: %s User: %s Pass:%s", mHost.c_str(), mPort.c_str(), mUser.c_str(), mPass.c_str());
|
||||||
|
|
||||||
|
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||||
|
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
|
||||||
|
mImgPixFmt = AV_PIX_FMT_RGBA;
|
||||||
|
mBpp = 4;
|
||||||
|
} else if ( colours == ZM_COLOUR_RGB24 ) {
|
||||||
|
subpixelorder = ZM_SUBPIX_ORDER_RGB;
|
||||||
|
mImgPixFmt = AV_PIX_FMT_RGB24;
|
||||||
|
mBpp = 3;
|
||||||
|
} else if ( colours == ZM_COLOUR_GRAY8 ) {
|
||||||
|
subpixelorder = ZM_SUBPIX_ORDER_NONE;
|
||||||
|
mImgPixFmt = AV_PIX_FMT_GRAY8;
|
||||||
|
mBpp = 1;
|
||||||
|
} else {
|
||||||
|
Panic("Unexpected colours: %d", colours);
|
||||||
|
}
|
||||||
|
|
||||||
if ( capture )
|
if ( capture )
|
||||||
Initialise();
|
Initialise();
|
||||||
}
|
}
|
||||||
|
@ -94,6 +108,7 @@ void VncCamera::Initialise() {
|
||||||
mRfb->serverHost = strdup(mHost.c_str());
|
mRfb->serverHost = strdup(mHost.c_str());
|
||||||
mRfb->serverPort = atoi(mPort.c_str());
|
mRfb->serverPort = atoi(mPort.c_str());
|
||||||
rfbInitClient(mRfb, 0, nullptr);
|
rfbInitClient(mRfb, 0, nullptr);
|
||||||
|
scale.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VncCamera::Terminate() {
|
void VncCamera::Terminate() {
|
||||||
|
@ -102,65 +117,20 @@ void VncCamera::Terminate() {
|
||||||
|
|
||||||
int VncCamera::PrimeCapture() {
|
int VncCamera::PrimeCapture() {
|
||||||
Info("Priming capture from %s", mHost.c_str());
|
Info("Priming capture from %s", mHost.c_str());
|
||||||
if ( mRfb->si.framebufferWidth != width || mRfb->si.framebufferHeight != height ) {
|
|
||||||
Info("Expected screen resolution (%dx%d) does not match the provided resolution (%dx%d), using scaling",
|
|
||||||
width, height, mRfb->si.framebufferWidth, mRfb->si.framebufferHeight);
|
|
||||||
mScale = true;
|
|
||||||
sws = sws_getContext(
|
|
||||||
mRfb->si.framebufferWidth, mRfb->si.framebufferHeight, AV_PIX_FMT_RGBA,
|
|
||||||
width, height, AV_PIX_FMT_RGBA, SWS_BICUBIC,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
if ( !sws ) {
|
|
||||||
Error("Could not scale image");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VncCamera::PreCapture() {
|
int VncCamera::PreCapture() {
|
||||||
Debug(2, "PreCapture");
|
Debug(2, "PreCapture");
|
||||||
WaitForMessage(mRfb, 500);
|
WaitForMessage(mRfb, 500);
|
||||||
Debug(2, "After Wait ");
|
|
||||||
rfbBool res = HandleRFBServerMessage(mRfb);
|
rfbBool res = HandleRFBServerMessage(mRfb);
|
||||||
Debug(2, "After Handle ");
|
|
||||||
return res == TRUE ? 1 : -1 ;
|
return res == TRUE ? 1 : -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VncCamera::Capture(Image &image) {
|
int VncCamera::Capture(Image &image) {
|
||||||
Debug(2, "Capturing");
|
Debug(2, "Capturing");
|
||||||
int srcLineSize[4];
|
uint8_t *directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||||
int dstLineSize[4];
|
scale.Convert(mVncData.buffer, mRfb->si.framebufferHeight * mRfb->si.framebufferWidth * 4, directbuffer, width * height * mBpp, AV_PIX_FMT_RGBA, mImgPixFmt, mRfb->si.framebufferWidth, mRfb->si.framebufferHeight, width, height);
|
||||||
int dstSize;
|
|
||||||
|
|
||||||
if ( mScale ) {
|
|
||||||
uint8_t* directbuffer;
|
|
||||||
|
|
||||||
/* Request a writeable buffer of the target image */
|
|
||||||
directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
|
||||||
if ( directbuffer == NULL ) {
|
|
||||||
Error("Failed requesting writeable buffer for the captured image.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( av_image_fill_arrays(dstbuf, dstLineSize, directbuffer, AV_PIX_FMT_RGBA,
|
|
||||||
width, height, 16) < 0) {
|
|
||||||
Error("Could not allocate dst image. Scaling failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( av_image_fill_arrays(srcbuf, srcLineSize, mVncData.buffer, AV_PIX_FMT_RGBA,
|
|
||||||
mRfb->si.framebufferWidth, mRfb->si.framebufferHeight, 16) < 0) {
|
|
||||||
Error("Could not allocate source image. Scaling failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sws_scale(sws, (const uint8_t* const*)srcbuf, srcLineSize, 0, mRfb->si.framebufferHeight,
|
|
||||||
dstbuf, dstLineSize);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
image.Assign(width, height, colours, subpixelorder, mVncData.buffer, width * height * 4);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,15 +143,6 @@ int VncCamera::CaptureAndRecord(Image &image, timeval recording, char* event_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
int VncCamera::Close() {
|
int VncCamera::Close() {
|
||||||
#if HAVE_LIBSWSCALE
|
|
||||||
if ( mScale ) {
|
|
||||||
av_freep(&srcbuf[0]);
|
|
||||||
av_freep(&dstbuf[0]);
|
|
||||||
sws_freeContext(sws);
|
|
||||||
sws = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rfbClientCleanup(mRfb);
|
rfbClientCleanup(mRfb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,17 @@
|
||||||
#include "zm_buffer.h"
|
#include "zm_buffer.h"
|
||||||
#include "zm_camera.h"
|
#include "zm_camera.h"
|
||||||
#include "zm_thread.h"
|
#include "zm_thread.h"
|
||||||
|
#include "zm_swscale.h"
|
||||||
|
|
||||||
#if HAVE_LIBVNC
|
#if HAVE_LIBVNC
|
||||||
#include <rfb/rfbclient.h>
|
#include <rfb/rfbclient.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libavutil/imgutils.h>
|
||||||
|
#include <libavutil/parseutils.h>
|
||||||
|
#include <libswscale/swscale.h>
|
||||||
|
}
|
||||||
|
|
||||||
// Used by vnc callbacks
|
// Used by vnc callbacks
|
||||||
struct VncPrivateData
|
struct VncPrivateData
|
||||||
{
|
{
|
||||||
|
@ -22,11 +29,8 @@ protected:
|
||||||
rfbClient *mRfb;
|
rfbClient *mRfb;
|
||||||
VncPrivateData mVncData;
|
VncPrivateData mVncData;
|
||||||
int mBpp;
|
int mBpp;
|
||||||
int mSpp;
|
SWScale scale;
|
||||||
int mBps;
|
AVPixelFormat mImgPixFmt;
|
||||||
bool mScale;
|
|
||||||
uint8_t *srcbuf[4], *dstbuf[4];
|
|
||||||
struct SwsContext *sws;
|
|
||||||
std::string mHost;
|
std::string mHost;
|
||||||
std::string mPort;
|
std::string mPort;
|
||||||
std::string mUser;
|
std::string mUser;
|
||||||
|
|
|
@ -84,7 +84,7 @@ int SWScale::SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height, unsigned int new_width, unsigned int new_height) {
|
||||||
/* Parameter checking */
|
/* Parameter checking */
|
||||||
if(in_buffer == NULL || out_buffer == NULL) {
|
if(in_buffer == NULL || out_buffer == NULL) {
|
||||||
Error("NULL Input or output buffer");
|
Error("NULL Input or output buffer");
|
||||||
|
@ -94,7 +94,7 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
// Error("Invalid input or output pixel formats");
|
// Error("Invalid input or output pixel formats");
|
||||||
// return -2;
|
// return -2;
|
||||||
// }
|
// }
|
||||||
if (!width || !height) {
|
if (!width || !height || !new_height || !new_width) {
|
||||||
Error("Invalid width or height");
|
Error("Invalid width or height");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
|
|
||||||
/* Check the buffer sizes */
|
/* Check the buffer sizes */
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
size_t insize = av_image_get_buffer_size(in_pf, width, height,1);
|
size_t insize = av_image_get_buffer_size(in_pf, width, height, 1);
|
||||||
#else
|
#else
|
||||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
@ -120,9 +120,9 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
size_t outsize = av_image_get_buffer_size(out_pf, width, height,1);
|
size_t outsize = av_image_get_buffer_size(out_pf, new_width, new_height, 1);
|
||||||
#else
|
#else
|
||||||
size_t outsize = avpicture_get_size(out_pf, width, height);
|
size_t outsize = avpicture_get_size(out_pf, new_width, new_height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(outsize < out_buffer_size) {
|
if(outsize < out_buffer_size) {
|
||||||
|
@ -131,7 +131,7 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the context */
|
/* Get the context */
|
||||||
swscale_ctx = sws_getCachedContext( swscale_ctx, width, height, in_pf, width, height, out_pf, SWS_FAST_BILINEAR, NULL, NULL, NULL );
|
swscale_ctx = sws_getCachedContext( swscale_ctx, width, height, in_pf, new_width, new_height, out_pf, SWS_FAST_BILINEAR, NULL, NULL, NULL );
|
||||||
if(swscale_ctx == NULL) {
|
if(swscale_ctx == NULL) {
|
||||||
Error("Failed getting swscale context");
|
Error("Failed getting swscale context");
|
||||||
return -6;
|
return -6;
|
||||||
|
@ -150,10 +150,10 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
}
|
}
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
if (av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
if (av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
||||||
out_buffer, out_pf, width, height, 1) <= 0) {
|
out_buffer, out_pf, new_width, new_height, 1) <= 0) {
|
||||||
#else
|
#else
|
||||||
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, width,
|
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, new_width,
|
||||||
height) <= 0) {
|
new_height) <= 0) {
|
||||||
#endif
|
#endif
|
||||||
Error("Failed filling output frame with output buffer");
|
Error("Failed filling output frame with output buffer");
|
||||||
return -8;
|
return -8;
|
||||||
|
@ -168,6 +168,10 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
||||||
|
return Convert(in_buffer, in_buffer_size, out_buffer, out_buffer_size, in_pf, out_pf, width, height, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
||||||
if(img->Width() != width) {
|
if(img->Width() != width) {
|
||||||
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
||||||
|
|
|
@ -10,12 +10,13 @@ class SWScale {
|
||||||
public:
|
public:
|
||||||
SWScale();
|
SWScale();
|
||||||
~SWScale();
|
~SWScale();
|
||||||
bool init();
|
bool init();
|
||||||
int SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
int SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
||||||
int ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size);
|
int ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size);
|
||||||
int ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size);
|
int ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size);
|
||||||
int Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
int Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
||||||
int Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
int Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height);
|
||||||
|
int Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height, unsigned int new_width, unsigned int new_height);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool gotdefaults;
|
bool gotdefaults;
|
||||||
|
|
Loading…
Reference in New Issue