adding support of 16bit per channel data - highly experimental

test16bit
Steffen Pohle 3 years ago
parent a89548deb4
commit d904fead37

@ -6,6 +6,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "simpleskycam.h"
#include "convert.h" #include "convert.h"
#include "gui.h" #include "gui.h"
#include "video.h" #include "video.h"
@ -225,21 +226,11 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
if (dest == NULL || ptrsrc == NULL) if (dest == NULL || ptrsrc == NULL)
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
if (dest->data != NULL && dest->w != srcw && dest->h != srch) {
free (dest->data);
dest->data = NULL;
}
if (dest->data == NULL) {
dest->w = srcw;
dest->h = srch;
dest->size = srcw * srch * 3;
dest->data = (unsigned char*) malloc (dest->size);
}
ptrdst = dest->data;
switch (pixelformat) { switch (pixelformat) {
case (V4L2_PIX_FMT_RGB32): case (V4L2_PIX_FMT_RGB32):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */ /* read the pixel */
@ -267,6 +258,9 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
case (V4L2_PIX_FMT_BGR32): case (V4L2_PIX_FMT_BGR32):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */ /* read the pixel */
@ -293,6 +287,9 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
} }
break; break;
case (V4L2_PIX_FMT_RGB24): case (V4L2_PIX_FMT_RGB24):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */ /* read the pixel */
@ -319,6 +316,10 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
case (V4L2_PIX_FMT_BGR24): case (V4L2_PIX_FMT_BGR24):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */ /* read the pixel */
@ -345,6 +346,10 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
case (V4L2_PIX_FMT_UYVY): case (V4L2_PIX_FMT_UYVY):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
/* read the pixel */ /* read the pixel */
@ -380,6 +385,10 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
case (V4L2_PIX_FMT_YUYV): case (V4L2_PIX_FMT_YUYV):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
for (ys = 0, yd = 0; ys < (signed int)srch; ys++) { for (ys = 0, yd = 0; ys < (signed int)srch; ys++) {
if (yd < dest->h) { if (yd < dest->h) {
for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) { for (xs = 0, xd = 0; xs < (signed int)srcw; xs++) {
@ -416,6 +425,10 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
case (V4L2_PIX_FMT_MJPEG): case (V4L2_PIX_FMT_MJPEG):
dest->SetSize(srcw, srch);
dest->SetPixelSize(3); // 8 bits per pixel
ptrdst = (unsigned char *)dest->GetData();
cdata->cinfo.err = jpeg_std_error(&jerr.pub); cdata->cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpg_error_exit; jerr.pub.error_exit = jpg_error_exit;
if (setjmp(jerr.setjmp_buffer)) { if (setjmp(jerr.setjmp_buffer)) {
@ -437,8 +450,7 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break; break;
default: default:
printf ("%s:%d Error no default possible, need to finish\n", __FILE__, __LINE__); errorexit ((char*)"%s:%d Error no default possible, need to finish\n", __FILE__, __LINE__);
exit (-1);
break; break;
} }

@ -180,8 +180,8 @@ void Detect::InputDetect(int *posx, int *posy) {
image.SetSize (objectW, objectH); image.SetSize (objectW, objectH);
SetInputSize(inFrame.w, inFrame.h); SetInputSize(inFrame.w, inFrame.h);
pxs = inFrame.data; pxs = (unsigned char*)inFrame.GetData();
pxi = image.data; pxi = (unsigned char*)image.GetData();
*posx = 0; *posx = 0;
*posy = 0; *posy = 0;
@ -258,8 +258,8 @@ void Detect::InputDetectCrossC(int *posx, int *posy) {
image.SetSize (objectW, objectH); image.SetSize (objectW, objectH);
SetInputSize(inFrame.w, inFrame.h); SetInputSize(inFrame.w, inFrame.h);
pxi = inFrame.data; pxi = (unsigned char*)inFrame.GetData();
pxo = oldFrame.data; pxo = (unsigned char*)oldFrame.GetData();
mxx = mxy = 0; mxx = mxy = 0;
for (shifty = 0; shifty < DET_MAXSHIFT; shifty++) { for (shifty = 0; shifty < DET_MAXSHIFT; shifty++) {
@ -316,8 +316,8 @@ void Detect::CopyObjectImage(int objx, int objy) {
unsigned char *pxi; // input image unsigned char *pxi; // input image
unsigned char *pxd; // destination image unsigned char *pxd; // destination image
pxi = inFrame.data; pxi = (unsigned char*)inFrame.GetData();
pxd = image.data; pxd = (unsigned char*)image.GetData();
// //
// copy image data to destination // copy image data to destination

@ -99,7 +99,7 @@ void Filter::ComposeOutput() {
image.SetSize(inFrame.w, inFrame.h); image.SetSize(inFrame.w, inFrame.h);
pixd = image.data; pixd = image.data;
pixs = inFrame.data; pixs = (unsigned char*)inFrame.GetData();
if (pixd == NULL || pixs == NULL) return; if (pixd == NULL || pixs == NULL) return;
if (newimage) { if (newimage) {

@ -484,7 +484,7 @@ gboolean cb_thread_video (gpointer data) {
videoctrl_grid_build(); videoctrl_grid_build();
cbdata->running = 2; cbdata->running = 2;
} }
if (vf->w <= 0 || vf->h <= 0 || vf->data == NULL) vf = NULL; if (vf->w <= 0 || vf->h <= 0) vf = NULL;
} }
if (videodev == NULL) return false; if (videodev == NULL) return false;

@ -1,4 +1,5 @@
#include "simpleskycam.h"
#include "convert.h" #include "convert.h"
#include "videodev-v4l2.h" #include "videodev-v4l2.h"
@ -280,15 +281,14 @@ int VideoDev_V4L2::InitMMap() {
if(ioctl(fd, VIDIOC_QUERYBUF, &bufinfo) < 0){ if(ioctl(fd, VIDIOC_QUERYBUF, &bufinfo) < 0){
perror("VIDIOC_QUERYBUF"); perror("VIDIOC_QUERYBUF");
exit(1); errorexit((char*)"%s:%d\n", __FILE__, __LINE__);
} }
inbuffer[i].size = bufinfo.length; inbuffer[i].size = bufinfo.length;
inbuffer[i].data = (unsigned char*)mmap(NULL, bufinfo.length, PROT_READ | PROT_WRITE, inbuffer[i].data = (unsigned char*)mmap(NULL, bufinfo.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, bufinfo.m.offset); MAP_SHARED, fd, bufinfo.m.offset);
if (inbuffer[i].data == MAP_FAILED) { if (inbuffer[i].data == MAP_FAILED) {
printf ( "%s:%d error on mmap %s\n", __FILE__, __LINE__, strerror(errno)); errorexit ((char*)"%s:%d error on mmap %s\n", __FILE__, __LINE__, strerror(errno));
exit (1);
} }
} }
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
@ -327,8 +327,7 @@ int VideoDev_V4L2::UnInit() {
for (inbuffer_idx = 0; inbuffer_idx < VDEV_INBUFFERS; inbuffer_idx++) for (inbuffer_idx = 0; inbuffer_idx < VDEV_INBUFFERS; inbuffer_idx++)
if (inbuffer[inbuffer_idx].data) { if (inbuffer[inbuffer_idx].data) {
if (-1 == munmap(inbuffer[inbuffer_idx].data, inbuffer[inbuffer_idx].size)){ if (-1 == munmap(inbuffer[inbuffer_idx].data, inbuffer[inbuffer_idx].size)){
fprintf(stderr, "Fatal Error @ %s:%d munmap Error:%s\n", __FILE__, __LINE__, strerror(errno)); errorexit((char*)"Fatal Error @ %s:%d munmap Error:%s\n", __FILE__, __LINE__, strerror(errno));
exit(1);
} }
inbuffer[inbuffer_idx].data = NULL; inbuffer[inbuffer_idx].data = NULL;
inbuffer[inbuffer_idx].size = 0; inbuffer[inbuffer_idx].size = 0;

@ -3,14 +3,14 @@
#include "video.h" #include "video.h"
#include "config.h" #include "config.h"
#include "gui.h" #include "gui.h"
#include "simpleskycam.h"
#define VIDEOFRAME_DEPTH_BYTES 3
VideoFrame::VideoFrame() { VideoFrame::VideoFrame() {
data = NULL; data = NULL;
w = 0; w = 0;
h = 0; h = 0;
size = 0; size = 0;
pixelsize = 3;
}; };
@ -28,8 +28,8 @@ VideoFrame::~VideoFrame() {
// //
// we will only allocate a new image if the needed size increases // we will only allocate a new image if the needed size increases
void VideoFrame::SetSize(int nw, int nh) { void VideoFrame::SetMemorySize(int nw, int nh, int nps) {
uint32_t newsize = VIDEOFRAME_DEPTH_BYTES * nh * nw; uint32_t newsize = nps * nh * nw;
if (newsize > size || data == NULL) { if (newsize > size || data == NULL) {
unsigned char *newdata = (unsigned char *) malloc (newsize); unsigned char *newdata = (unsigned char *) malloc (newsize);
@ -39,12 +39,14 @@ void VideoFrame::SetSize(int nw, int nh) {
} }
w = nw; w = nw;
h = nh; h = nh;
pixelsize = nps;
}; };
VideoFrame VideoFrame::operator=(VideoFrame rightside) { VideoFrame VideoFrame::operator=(VideoFrame rightside) {
w = rightside.w; w = rightside.w;
h = rightside.h; h = rightside.h;
pixelsize = rightside.pixelsize;
size = rightside.size; size = rightside.size;
if (size > 0) data = (unsigned char *) malloc (rightside.size); if (size > 0) data = (unsigned char *) malloc (rightside.size);
if (rightside.data != NULL && size > 0) { if (rightside.data != NULL && size > 0) {
@ -55,16 +57,20 @@ VideoFrame VideoFrame::operator=(VideoFrame rightside) {
void VideoFrame::CopyFrom(VideoFrame *source) { void VideoFrame::CopyFrom(VideoFrame *source) {
SetPixelSize(source->pixelsize);
SetSize (source->w, source->h); SetSize (source->w, source->h);
memcpy(data, source->data, VIDEOFRAME_DEPTH_BYTES * w * h); memcpy(data, source->data, pixelsize * w * h);
} }
/*
* will copy the FloatImage to VideoFrame
* with respect of the bits per pixel (3 or 6).
*/
void VideoFrame::CopyFrom(FloatImage *source) { void VideoFrame::CopyFrom(FloatImage *source) {
float min, max, f; float min, max, f;
int x, y, i, idx; int x, y, i, idx;
unsigned char v;
SetSize (source->w, source->h); SetSize (source->w, source->h);
@ -78,30 +84,67 @@ void VideoFrame::CopyFrom(FloatImage *source) {
if (max < source->data[idx+i]) max = source->data[idx+i]; if (max < source->data[idx+i]) max = source->data[idx+i];
} }
//
// 3 bytes per pixel (each channel ^ 1 byte)
if (pixelsize == 3) {
unsigned char v;
for (y = 0; y < h; y++) for (x = 0; x < w; x++) for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x); idx = pixelsize * (y * w + x);
f = (float)(255.0 * (source->data[idx+i]-min) / (max-min)); f = (float)(255.0 * (source->data[idx+i]-min) / (max-min));
if (f < 0.0) v = 0; if (f < 0.0) v = 0;
else if (f > 255.0) v = 255; else if (f > 255.0) v = 255;
else v = f; else v = f;
data[idx+i] = v; data[idx+i] = v;
} }
}
//
// 6 bytes per pixel (each channel ^ 2 byte)
else if (pixelsize == 6) {
uint16_t v;
int max = (2^16)-1;
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = pixelsize * (y * w + x);
f = (float)(double(max) * (source->data[idx+i]-min) / (max-min));
if (f < 0.0) v = 0;
else if (f > double(max)) v = max;
else v = f;
memcpy(data+(idx+2*i), &v, 2);
}
}
else {
errorexit((char*)"Pixelsize not known or implemented. pixelsize should be 3 or 6, current value is:%d\n", pixelsize);
}
} }
void VideoFrame::CopyTo(FloatImage *dest) { void VideoFrame::CopyTo(FloatImage *dest) {
int x, y, i, idx; int x, y, i, idx;
if (dest == NULL) return; if (dest == NULL) return;
dest->SetSize (w, h); dest->SetSize (w, h);
if (pixelsize == 3) {
for (y = 0; y < h; y++) for (x = 0; x < w; x++) for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x); idx = 3 * (y * w + x);
dest->data[idx+i] = data[idx+i]; dest->data[idx+i] = data[idx+i];
} }
}
else if (pixelsize == 6) {
uint16_t *sdata = (uint16_t*)data;
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x);
dest->data[idx+i] = sdata[idx+i];
}
}
else {
errorexit ((char*) "pixelsize not supported.\n");
}
} }
@ -112,6 +155,7 @@ void VideoFrame::ToPixbuf(GdkPixbuf* dest) {
if (dest == NULL) return; if (dest == NULL) return;
if (pixelsize == 3) {
desth = gdk_pixbuf_get_height(dest); desth = gdk_pixbuf_get_height(dest);
destw = gdk_pixbuf_get_width(dest); destw = gdk_pixbuf_get_width(dest);
destpixel = gdk_pixbuf_get_pixels(dest); destpixel = gdk_pixbuf_get_pixels(dest);
@ -122,11 +166,24 @@ void VideoFrame::ToPixbuf(GdkPixbuf* dest) {
} }
memcpy (destpixel, data, 3*destw*desth); memcpy (destpixel, data, 3*destw*desth);
} }
else if (pixelsize == 6) {
desth = gdk_pixbuf_get_height(dest);
destw = gdk_pixbuf_get_width(dest);
destpixel = gdk_pixbuf_get_pixels(dest);
uint16_t *sdata = (uint16_t*)data;
int x, y, idx, i;
for (y = 0; y < desth; y++) for (x = 0; x < destw; x++)
for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x);
destpixel[idx+i] = sdata[idx+i];
}
}
else {
errorexit ((char*) "pixelsize (%d) not supported.\n", pixelsize);
}
}
FloatImage::FloatImage() { FloatImage::FloatImage() {

@ -26,20 +26,25 @@ public:
class VideoFrame { class VideoFrame {
private: private:
void SetMemorySize (int nw, int nh, int nps);
unsigned char *data;
public: public:
int w; int w;
int h; int h;
uint32_t pixelsize;
uint32_t size; uint32_t size;
unsigned char *data;
VideoFrame(); VideoFrame();
~VideoFrame(); ~VideoFrame();
VideoFrame operator=(VideoFrame rightside); VideoFrame operator=(VideoFrame rightside);
void SetSize(int nw, int nh); void SetSize(int nw, int nh) { SetMemorySize (nw, nh, pixelsize); };
void SetW(int nw) { SetSize(nw, h); }; void* GetData() { return data; };
void SetH(int nh) { SetSize(w, nh); }; void SetPixelSize(uint32_t nps) { SetMemorySize (w, h, nps); };
void SetW(int nw) { SetMemorySize(nw, h, pixelsize); };
void SetH(int nh) { SetMemorySize(w, nh, pixelsize); };
void CopyFrom(VideoFrame *source); void CopyFrom(VideoFrame *source);
void CopyFrom(FloatImage *source); void CopyFrom(FloatImage *source);
void CopyTo(FloatImage *dest); void CopyTo(FloatImage *dest);

Loading…
Cancel
Save