WIP scaling

pull/2901/head
hax0kartik 2020-03-27 11:15:15 -07:00
parent 8f5a3c1bf2
commit 23205cd07f
3 changed files with 54 additions and 12 deletions

View File

@ -1,6 +1,11 @@
#include "zm.h"
#include "zm_signal.h"
#include "zm_libvnc_camera.h"
extern "C" {
#include <libavutil/imgutils.h>
#include <libavutil/parseutils.h>
#include <libswscale/swscale.h>
}
#if HAVE_LIBVNC
@ -76,13 +81,11 @@ VncCamera::~VncCamera() {
void VncCamera::Initialise() {
Debug(2, "Initializing Client");
mRfb = rfbGetClient(8, 3, 4);
rfbClientSetClientData(mRfb, &TAG_0, &mVncData);
rfbClientSetClientData(mRfb, &TAG_1, (void *)mPass.c_str());
rfbClientSetClientData(mRfb, &TAG_2, (void *)mUser.c_str());
mVncData.bufferSize = width * height * 4;
mVncData.buffer = (uint8_t *)malloc(mVncData.bufferSize * sizeof(uint8_t));
mRfb->GotFrameBufferUpdate = GotFrameBufferUpdateCallback;
mRfb->GetPassword = GetPasswordCallback;
mRfb->GetCredential = GetCredentialsCallback;
@ -94,13 +97,15 @@ void VncCamera::Initialise() {
}
void VncCamera::Terminate() {
if(mVncData.buffer)
free(mVncData.buffer);
return;
}
int VncCamera::PrimeCapture() {
Info("Priming capture from %s", mHost.c_str());
if(mRfb->si.framebufferWidth != width || mRfb->si.framebufferHeight != height) {
Info("Expected screen resolution does not match with the provided resolution, using scaling");
mScale = true;
}
return 0;
}
@ -112,11 +117,49 @@ int VncCamera::PreCapture() {
int VncCamera::Capture(Image &image) {
Debug(2, "Capturing");
int srcLineSize[4];
int dstLineSize[4];
int dstSize;
if(mScale) {
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;
}
if (av_image_fill_arrays(srcbuf, srcLineSize, mVncData.buffer, AV_PIX_FMT_RGBA,
mRfb->si.framebufferWidth, mRfb->si.framebufferHeight, 16) < 0) {
sws_freeContext(sws);
Error("Could not allocate source image. Scaling failed");
return -1;
}
if ((dstSize = av_image_alloc(dstbuf, dstLineSize, width, height,
AV_PIX_FMT_RGBA, 1)) < 0) {
av_freep(&srcbuf[0]);
sws_freeContext(sws);
Error("Could not allocate dest image. Scaling failed");
return -1;
}
sws_scale(sws, (const uint8_t* const*)srcbuf, srcLineSize, 0, mRfb->si.framebufferHeight,
dstbuf, dstLineSize);
}
else{
dstbuf[0] = mVncData.buffer;
}
image.Assign(width, height, colours, subpixelorder, mVncData.buffer, width * height * 4);
return 1;
}
int VncCamera::PostCapture() {
if(mScale) {
av_freep(&srcbuf[0]);
av_freep(&dstbuf[0]);
sws_freeContext(sws);
}
return 0;
}

View File

@ -13,10 +13,8 @@
struct VncPrivateData
{
uint8_t *buffer;
uint8_t *prevBuffer;
uint32_t bufferSize;
Mutex mutex;
ThreadData<bool> newImage;
uint8_t width;
uint8_t height;
};
class VncCamera : public Camera {
@ -26,12 +24,13 @@ protected:
int mBpp;
int mSpp;
int mBps;
char** mOptArgvs;
bool mScale;
uint8_t *srcbuf[4], *dstbuf[4];
struct SwsContext *sws;
std::string mHost;
std::string mPort;
std::string mUser;
std::string mPass;
time_t secs;
public:
VncCamera(
unsigned int p_monitor_id,

View File

@ -785,7 +785,7 @@ include('_monitor_source_nvsocket.php');
<tr><td><?php echo translate('Host Addr') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>" size="36"/></td></tr>
<tr><td><?php echo translate('Host Port') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" size="6"/></td></tr>
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>" size="12"/></td></tr>
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>" size="12"/></td></tr>
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>" size="12"/></td></tr>
<?php
} else if ( $monitor->Type() == 'Remote' ) {
?>