Modify Convert to scale as well
This commit is contained in:
parent
ba8d9ee768
commit
6886b2b375
|
@ -1,11 +1,7 @@
|
|||
#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>
|
||||
}
|
||||
#include "zm_swscale.h"
|
||||
|
||||
#if HAVE_LIBVNC
|
||||
|
||||
|
@ -25,6 +21,7 @@ static char* GetPasswordCallback(rfbClient* cl){
|
|||
static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
||||
rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential));
|
||||
if ( credentialType != rfbCredentialTypeUser ) {
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -68,6 +65,23 @@ VncCamera::VncCamera(
|
|||
mPass(pass)
|
||||
{
|
||||
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 )
|
||||
Initialise();
|
||||
}
|
||||
|
@ -94,6 +108,7 @@ void VncCamera::Initialise() {
|
|||
mRfb->serverHost = strdup(mHost.c_str());
|
||||
mRfb->serverPort = atoi(mPort.c_str());
|
||||
rfbInitClient(mRfb, 0, nullptr);
|
||||
scale.init();
|
||||
}
|
||||
|
||||
void VncCamera::Terminate() {
|
||||
|
@ -102,65 +117,20 @@ void VncCamera::Terminate() {
|
|||
|
||||
int VncCamera::PrimeCapture() {
|
||||
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;
|
||||
}
|
||||
|
||||
int VncCamera::PreCapture() {
|
||||
Debug(2, "PreCapture");
|
||||
WaitForMessage(mRfb, 500);
|
||||
Debug(2, "After Wait ");
|
||||
rfbBool res = HandleRFBServerMessage(mRfb);
|
||||
Debug(2, "After Handle ");
|
||||
return res == TRUE ? 1 : -1 ;
|
||||
}
|
||||
|
||||
int VncCamera::Capture(Image &image) {
|
||||
Debug(2, "Capturing");
|
||||
int srcLineSize[4];
|
||||
int dstLineSize[4];
|
||||
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);
|
||||
}
|
||||
uint8_t *directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -173,15 +143,6 @@ int VncCamera::CaptureAndRecord(Image &image, timeval recording, char* event_dir
|
|||
}
|
||||
|
||||
int VncCamera::Close() {
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mScale ) {
|
||||
av_freep(&srcbuf[0]);
|
||||
av_freep(&dstbuf[0]);
|
||||
sws_freeContext(sws);
|
||||
sws = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
rfbClientCleanup(mRfb);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,17 @@
|
|||
#include "zm_buffer.h"
|
||||
#include "zm_camera.h"
|
||||
#include "zm_thread.h"
|
||||
#include "zm_swscale.h"
|
||||
|
||||
#if HAVE_LIBVNC
|
||||
#include <rfb/rfbclient.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/parseutils.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
// Used by vnc callbacks
|
||||
struct VncPrivateData
|
||||
{
|
||||
|
@ -22,11 +29,8 @@ protected:
|
|||
rfbClient *mRfb;
|
||||
VncPrivateData mVncData;
|
||||
int mBpp;
|
||||
int mSpp;
|
||||
int mBps;
|
||||
bool mScale;
|
||||
uint8_t *srcbuf[4], *dstbuf[4];
|
||||
struct SwsContext *sws;
|
||||
SWScale scale;
|
||||
AVPixelFormat mImgPixFmt;
|
||||
std::string mHost;
|
||||
std::string mPort;
|
||||
std::string mUser;
|
||||
|
|
|
@ -84,7 +84,7 @@ int SWScale::SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf,
|
|||
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 */
|
||||
if(in_buffer == NULL || out_buffer == NULL) {
|
||||
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");
|
||||
// return -2;
|
||||
// }
|
||||
if (!width || !height) {
|
||||
if (!width || !height || !new_height || !new_width) {
|
||||
Error("Invalid width or height");
|
||||
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 */
|
||||
#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
|
||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||
#endif
|
||||
|
@ -120,9 +120,9 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
return -4;
|
||||
}
|
||||
#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
|
||||
size_t outsize = avpicture_get_size(out_pf, width, height);
|
||||
size_t outsize = avpicture_get_size(out_pf, new_width, new_height);
|
||||
#endif
|
||||
|
||||
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 */
|
||||
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) {
|
||||
Error("Failed getting swscale context");
|
||||
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 (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
|
||||
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, width,
|
||||
height) <= 0) {
|
||||
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, new_width,
|
||||
new_height) <= 0) {
|
||||
#endif
|
||||
Error("Failed filling output frame with output buffer");
|
||||
return -8;
|
||||
|
@ -168,6 +168,10 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
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) {
|
||||
if(img->Width() != width) {
|
||||
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
||||
|
|
|
@ -16,6 +16,7 @@ class SWScale {
|
|||
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 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:
|
||||
bool gotdefaults;
|
||||
|
|
Loading…
Reference in New Issue