VideoFrameFloat seem to work

main
Steffen Pohle 2 months ago
parent 72b847a691
commit 13448b19c0

@ -91,6 +91,7 @@ int ConvertStart(ConvertData *cdata, uint32_t pixelformat) {
return 1;
};
int ConvertStop(ConvertData *cdata, uint32_t pixelformat) {
dumpframe_close();
@ -104,14 +105,15 @@ int ConvertStop(ConvertData *cdata, uint32_t pixelformat) {
/*
* converts the video from input type to RGB24 type - 24Bit
*/
int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int srcsize, uint32_t pixelformat, int srcw, int srch) {
int Convert (ConvertData *cdata, VideoFrame *dest, VideoFrameFloat *destf, unsigned char *ptrsrc, int srcsize, uint32_t pixelformat, int srcw, int srch) {
int xs, ys;
int xd, yd;
unsigned char r,g,b;
unsigned char cb, cr, y1;
unsigned char *ptrdst = NULL;
float *ptrdstf = NULL; // for float data scaled to 0...1.0
debug ("srcsize:%d pixfmt:%s size: %dx%d", srcsize, convert_from_pixelformat(pixelformat).c_str(), srcw, srch);
// debug ("srcsize:%d pixfmt:%s size: %dx%d", srcsize, convert_from_pixelformat(pixelformat).c_str(), srcw, srch);
if (config.vdev_dumppath.length() > 0) dumpframe(ptrsrc, srcsize, pixelformat, srcw, srch);
struct jpg_error_mgr jerr;
@ -119,11 +121,18 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
// check if there is a destination and that the destination is large to keep
// the full image
if (dest == NULL || ptrsrc == NULL)
if ((dest == NULL && destf == NULL) || ptrsrc == NULL)
return 0;
dest->SetSize(srcw, srch);
ptrdst = dest->GetPixBuf();
if (dest) {
dest->SetSize(srcw, srch);
ptrdst = dest->GetPixBuf();
}
if (destf) {
destf->SetSize(srcw, srch);
ptrdstf = destf->GetPixBuf();
}
switch (pixelformat) {
case (V4L2_PIX_FMT_RGB32):
@ -139,16 +148,25 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
break;
@ -165,17 +183,25 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
break;
@ -190,17 +216,25 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
break;
@ -216,43 +250,51 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
break;
case (V4L2_PIX_FMT_SGRBG16):
debayer_grbg16 ((uint16_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_grbg16 ((uint16_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_SRGGB10P):
debayer_rggb10packet ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_rggb10packet ((uint8_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_SGBRG10):
debayer_gbrg10 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_gbrg10 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_SRGGB10):
debayer_rggb10 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_rggb10 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_SRGGB8):
debayer_rggb8 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_rggb8 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_SGRBG8):
debayer_grbg8 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch);
debayer_grbg8 ((uint8_t *)ptrsrc, srcw, srch, ptrdst, ptrdstf, srcw, srch);
break;
case (V4L2_PIX_FMT_UYVY):
@ -275,17 +317,25 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
break;
@ -308,19 +358,27 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
convert2rgb (y1, cr, cb, &r, &g, &b);
ptrsrc += 2;
/* only paint the image if the source is within the destination */
if (xd < srcw) {
/* set the pixel */
/* only paint the image if the source is within the destination */
if (xd < srcw) {
if (ptrdst) {
*(ptrdst++) = r;
*(ptrdst++) = g;
*(ptrdst++) = b;
xd++;
}
else {
*(ptrdstf++) = (float)r/255.0;
*(ptrdstf++) = (float)g/255.0;
*(ptrdstf++) = (float)b/255.0;
}
xd++;
}
}
/* if the source image is too small ignore the other places.. */
if (xd < srcw)
ptrdst += 3 * (srcw - xd);
if (xd < srcw) {
if (ptrdst) ptrdst += 3 * (srcw - xd);
if (ptrdstf) ptrdstf += 3 *(srcw - xd);
}
yd++;
}
}

@ -18,7 +18,7 @@ struct {
} typedef ConvertData;
int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int srcsize, uint32_t pixelformat, int srcw, int srch);
int Convert (ConvertData *cdata, VideoFrame *dest, VideoFrameFloat *destf, unsigned char *ptrsrc, int srcsize, uint32_t pixelformat, int srcw, int srch);
int ConvertStart(ConvertData *cdata, uint32_t pixelformat);
int ConvertStop(ConvertData *cdata, uint32_t pixelformat);

@ -22,8 +22,10 @@ std::string toBits(unsigned int i, int maxbits);
#define DNRI (*(src+src_w+1))
#define BITCONV(d) ((d>>8) & 0xff)
#define STORE *(dst++) = BITCONV(r); *(dst++) = BITCONV(g); *(dst++) = BITCONV(b); src++;
#define STORE8 *(dst++) = (r & 0xff); *(dst++) = (g & 0xff); *(dst++) = (b & 0xff); src++;
#define STORE if (dst) { *(dst++) = BITCONV(r); *(dst++) = BITCONV(g); *(dst++) = BITCONV(b); src++; }
#define STORE8 if (dst) { *(dst++) = (r & 0xff); *(dst++) = (g & 0xff); *(dst++) = (b & 0xff); src++; }
#define STOREF16 if (dstf) { *(dstf++) = ((float)r/65535.0); *(dstf++) = ((float)g/65535.0); *(dstf++) = ((float)b/65535.0); }
#define STOREF8 if (dstf) { *(dstf++) = ((float)r/255.0); *(dstf++) = ((float)g/255.0); *(dstf++) = ((float)b/255.0); }
/*
@ -31,7 +33,7 @@ std::string toBits(unsigned int i, int maxbits);
RGB image by bilinear interpolation.
*/
void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h) {
uint8_t * dst, float * dstf, int dst_w, int dst_h) {
// GG RR GG RR
// BB GG BB GG
@ -45,6 +47,7 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = CE;
b = DN;
STORE;
STOREF16;
// upper first line, starts with RR GG RR ...
for (xs = 1; xs < src_w - 1; xs+=2) {
@ -53,11 +56,13 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = (LE + RI + DN) / 3;
b = (DNLE + DNRI) / 2;
STORE;
STOREF16;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = DN;
STORE;
STOREF16;
}
// upper right pixel (red)
@ -65,6 +70,7 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = (DN + LE) / 2;
b = DNLE;
STORE;
STOREF16;
// go through the "body" of the image
for (ys = 1; ys < src_h - 1; ys+=2) {
@ -76,23 +82,27 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = (UP + DN + RI) / 3;
b = CE;
STORE;
STOREF16;
for (xs = 1; xs < src_w - 1; xs+=2) {
// green pixel
r = (UP + DN) / 2;
g = CE;
b = (LE + RI) / 2;
STORE;
STOREF16;
// blue pixel
r = (UPLE + UPRI + DNLE + DNRI) / 4;
g = (LE + RI + UP + DN) / 4;
b = CE;
STORE;
STOREF16;
}
// last pixel in line (green)
r = (UP + DN) / 2;
g = CE;
b = LE;
STORE;
STOREF16;
// every second line with GG RR GG RR ... (start at 3rd line)
@ -101,23 +111,27 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = CE;
b = (UP + DN) / 2;
STORE;
STOREF16;
for (xs = 1; xs < src_w - 1; xs+=2) {
// red pixel
r = CE;
g = (LE + RI + UP + DN) / 4;
b = (UPLE + UPRI + DNLE + DNRI) / 4;
STORE;
STOREF16;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = (UP + DN) / 2;
STORE;
STOREF16;
}
// last pixel in line (red)
r = CE;
g = (UP + DN + LE) / 3;
b = (UPLE + DNLE) / 2;
STORE;
STOREF16;
}
// bottom left pixel
@ -125,6 +139,7 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = (UP + RI) / 2;
b = CE;
STORE;
STOREF16;
// last line starting with GG BB GG ...
for (xs = 1; xs < src_w - 1; xs+=2) {
@ -133,11 +148,13 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = CE;
b = (LE + RI) / 2;
STORE;
STOREF16;
// blue pixel
r = (UPLE + UPRI) / 2;
g = (LE + UP + RI) / 2;
b = CE;
STORE;
STOREF16;
}
// bottom right pixel (green)
@ -145,21 +162,22 @@ void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
g = CE;
b = LE;
STORE;
STOREF16;
}
/*
The function converts a 8bit GRBG 2x2 CFA coded image into an 8bit
RGB image by bilinear interpolation.
*/
void debayer_gbrg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
debayer_grbg8 (src, src_w, src_h, dst, dst_w, dst_h);
void debayer_gbrg8 (uint8_t * src, int src_w, int src_h, uint8_t *dst, float *dstf, int dst_w, int dst_h) {
debayer_grbg8 (src, src_w, src_h, dst, dstf, dst_w, dst_h);
};
void debayer_rggb8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
debayer_grbg8 (src, src_w, src_h, dst, dst_w, dst_h);
void debayer_rggb8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, float *dstf, int dst_w, int dst_h) {
debayer_grbg8 (src, src_w, src_h, dst, dstf, dst_w, dst_h);
};
void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, float *dstf, int dst_w, int dst_h) {
// GG RR GG RR
// BB GG BB GG
@ -173,6 +191,7 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = CE;
b = DN;
STORE8;
STOREF8;
// upper first line, starts with RR GG RR ...
for (xs = 1; xs < src_w - 1; xs+=2) {
@ -181,11 +200,13 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = (LE + RI + DN) / 3;
b = (DNLE + DNRI) / 2;
STORE8;
STOREF8;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = DN;
STORE8;
STOREF8;
}
// upper right pixel (red)
@ -193,6 +214,7 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = (DN + LE) / 2;
b = DNLE;
STORE8;
STOREF8;
// go through the "body" of the image
for (ys = 1; ys < src_h - 1; ys+=2) {
@ -204,23 +226,27 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = (UP + DN + RI) / 3;
b = CE;
STORE8;
STOREF8;
for (xs = 1; xs < src_w - 1; xs+=2) {
// green pixel
r = (UP + DN) / 2;
g = CE;
b = (LE + RI) / 2;
STORE8;
STOREF8;
// blue pixel
r = (UPLE + UPRI + DNLE + DNRI) / 4;
g = (LE + RI + UP + DN) / 4;
b = CE;
STORE8;
STOREF8;
}
// last pixel in line (green)
r = (UP + DN) / 2;
g = CE;
b = LE;
STORE8;
STOREF8;
// every second line with GG RR GG RR ... (start at 3rd line)
@ -229,23 +255,27 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = CE;
b = (UP + DN) / 2;
STORE8;
STOREF8;
for (xs = 1; xs < src_w - 1; xs+=2) {
// red pixel
r = CE;
g = (LE + RI + UP + DN) / 4;
b = (UPLE + UPRI + DNLE + DNRI) / 4;
STORE8;
STOREF8;
// green pixel
r = (LE + RI) / 2;
g = CE;
b = (UP + DN) / 2;
STORE8;
STOREF8;
}
// last pixel in line (red)
r = CE;
g = (UP + DN + LE) / 3;
b = (UPLE + DNLE) / 2;
STORE8;
STOREF8;
}
// bottom left pixel
@ -253,6 +283,7 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = (UP + RI) / 2;
b = CE;
STORE8;
STOREF8;
// last line starting with GG BB GG ...
for (xs = 1; xs < src_w - 1; xs+=2) {
@ -261,11 +292,13 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = CE;
b = (LE + RI) / 2;
STORE8;
STOREF8;
// blue pixel
r = (UPLE + UPRI) / 2;
g = (LE + UP + RI) / 2;
b = CE;
STORE8;
STOREF8;
}
// bottom right pixel (green)
@ -273,9 +306,10 @@ void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_
g = CE;
b = LE;
STORE8;
STOREF8;
}
int MAX(int a, int m) { if (a > m) return m; else return a; };
#define MAX(_a_,_m_) ( _a_ > _m_ ? _m_ : _a_)
#define PRGGB10P_U ((uint16_t)(*(psrc-src_w*2*10/8)))
#define PRGGB10P_D ((uint16_t)(*(psrc+src_w*2*10/8)))
#define PRGGB10P_L ((uint16_t)(*(psrc-2)*10/8))
@ -284,75 +318,11 @@ int MAX(int a, int m) { if (a > m) return m; else return a; };
#define PRGGB10P_UR ((uint16_t)(*(psrc+2-src_w*2*10/8)))
#define PRGGB10P_DL ((uint16_t)(*(psrc-2-src_w*2*10/8)))
#define PRGGB10P_DR ((uint16_t)(*(psrc+2+src_w*2*10/8)))
void debayer_rggb10packet (uint8_t * src, int src_w, int src_h,
uint8_t * dst, int dst_w, int dst_h) {
int s, d;
int xs, ys, xd, yd;
unsigned char r, g, b;
int max = dst_w * dst_h * 3;
unsigned char *pdst;
unsigned char *psrc;
int shift;
printf ("%s:%d src size:%dx%d dst size:%dx%d\n", __FILE__, __LINE__, src_w, src_h, dst_w, dst_h);
// RR GG RR GG HH RR
// GG BB GG BB HH GG
// RR GG RR GG HH RR
// GG BB GG BB HH GG
for (ys = 0, yd = 0, psrc = src, pdst = dst; ys < dst_h; ys++, yd++) {
r = 0;
g = 0;
b = 0;
for (xs = 0, xd = 0; xd < dst_w; xs++, xd++) {
r = 0; b = 0; g = 0;
if (ys > 0 && ys < src_h-1 && xs > 0 && xs < src_w-1) {
if (ys&1) {
if (xs&1) {
b = *psrc;
g = (PRGGB10P_L + PRGGB10P_R + PRGGB10P_U + PRGGB10P_D)/4;
r = (PRGGB10P_UL + PRGGB10P_DL + PRGGB10P_UR + PRGGB10P_UL)/4;
}
else {
b = (PRGGB10P_L + PRGGB10P_R)/2;
g = *psrc;
r = (PRGGB10P_U + PRGGB10P_D)/2;
}
}
else {
if (xs&1) {
b = (PRGGB10P_U + PRGGB10P_D)/2;
g = *psrc;
r = (PRGGB10P_L + PRGGB10P_R)/2;
}
else {
g = (PRGGB10P_L + PRGGB10P_R + PRGGB10P_U + PRGGB10P_D)/4;
b = (PRGGB10P_UL + PRGGB10P_DL + PRGGB10P_UR + PRGGB10P_UL)/4;
r = *psrc;
}
}
}
if (pdst - dst > max) {
printf ("debayer error. dpst out of bounds size:%dx%d pos:%dx%d \n", dst_w, dst_h, xd, yd);
}
if ((ys == 10 || ys == 11) && xs < 10) printf ("%dx%d - %d, %d, %d\n", xs, ys, r, g, b);
pdst[0] = MAX(r, 0xff);
pdst[1] = MAX(g, 0xff);
pdst[2] = MAX(b, 0xff);
if (yd < 100 && xd < 300) {
pdst[0] = 0; if (xd < 100) pdst[0] = 255;
pdst[1] = 0; if (xd > 100 && xd < 200) pdst[1] = 255;
pdst[2] = 0; if (xd > 200 && xd < 300) pdst[2] = 255;
}
void debayer_rggb10packet (uint8_t *src, int src_w, int src_h,
uint8_t *dst, float *dstf, int dst_w, int dst_h) {
pdst += 3;
psrc++;
if (xs && (xs % 4 == 0)) psrc++;
}
}
debug ("not yep implemented");
debug ("src size:%dx%d dst size:%dx%d", src_w, src_h, dst_w, dst_h);
};
@ -385,7 +355,7 @@ inline int swap16(uint16_t i) {
#define PRGGB10_UR (unsigned int)(*(psrc+1-src_w))
#define PRGGB10_DL (unsigned int)(*(psrc-1+src_w))
#define PRGGB10_DR (unsigned int)(*(psrc+1+src_w))
void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, float * dstf, int dst_w, int dst_h) {
// GG BB GG BB
// RR GG RR GG
// GG BB GG BB
@ -393,13 +363,16 @@ void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int ds
int xs, ys, xd, yd;
uint32_t r, g, b, data;
int max = dst_w * dst_h * 3;
uint8_t *pdst;
uint16_t *psrc;
uint8_t *pdst = NULL;
float *pdstf = NULL;
uint16_t *psrc = NULL;
int max_r = 0;
int max_g = 0;
int max_b = 0;
for (ys = 0, yd = 0, psrc = (uint16_t*)src, pdst = dst; ys < dst_h; ys++, yd++) {
pdst = dst;
pdstf = dstf;
for (ys = 0, yd = 0, psrc = (uint16_t*)src; ys < dst_h; ys++, yd++) {
r = 0;
g = 0;
b = 0;
@ -431,21 +404,28 @@ void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int ds
}
}
}
pdst[0] = (r >> 2);
pdst[1] = (g >> 2);
pdst[2] = (b >> 2);
// if (yd < 100 && xd < 300) {
// pdst[0] = 0; if (xd < 100) pdst[0] = 255;
// pdst[1] = 0; if (xd > 100 && xd < 200) pdst[1] = 255;
// pdst[2] = 0; if (xd > 200 && xd < 300) pdst[2] = 255;
// }
pdst += 3;
// copy pixel to destination 24RGB
if (pdst) {
pdst[0] = (r >> 2);
pdst[1] = (g >> 2);
pdst[2] = (b >> 2);
pdst += 3;
}
// copy pixel to destination float
if (pdstf) {
pdstf[0] = ((float)r / 1023.0);
pdstf[1] = ((float)g / 1023.0);
pdstf[2] = ((float)b / 1023.0);
pdstf += 3;
}
psrc += 1;
}
}
};
void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float *dstf, int dst_w, int dst_h) {
// RR GG RR GG
// GG BB GG BB
// RR GG RR GG
@ -453,13 +433,16 @@ void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t * dst, int dst_
int xs, ys, xd, yd;
uint32_t r, g, b, data;
int max = dst_w * dst_h * 3;
uint8_t *pdst;
uint8_t *pdst = NULL;
float *pdstf = NULL;
uint16_t *psrc;
int max_r = 0;
int max_g = 0;
int max_b = 0;
for (ys = 0, yd = 0, psrc = (uint16_t*)src, pdst = dst; ys < dst_h; ys++, yd++) {
pdst = dst;
pdstf = dstf;
for (ys = 0, yd = 0, psrc = (uint16_t*)src; ys < dst_h; ys++, yd++) {
r = 0;
g = 0;
b = 0;
@ -491,15 +474,21 @@ void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t * dst, int dst_
}
}
}
pdst[0] = (r >> 2);
pdst[1] = (g >> 2);
pdst[2] = (b >> 2);
// if (yd < 100 && xd < 300) {
// pdst[0] = 0; if (xd < 100) pdst[0] = 255;
// pdst[1] = 0; if (xd > 100 && xd < 200) pdst[1] = 255;
// pdst[2] = 0; if (xd > 200 && xd < 300) pdst[2] = 255;
// }
pdst += 3;
// copy pixel to destination 24RGB
if (pdst) {
pdst[0] = (r >> 2);
pdst[1] = (g >> 2);
pdst[2] = (b >> 2);
pdst += 3;
}
// copy pixel to destination float
if (pdstf) {
pdstf[0] = ((float)r / 1023.0);
pdstf[1] = ((float)g / 1023.0);
pdstf[2] = ((float)b / 1023.0);
pdstf += 3;
}
psrc += 1;
}
}

@ -3,14 +3,14 @@
#include <stdint.h>
void debayer_grbg16 (uint16_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_grbg16 (uint16_t *src, int src_w, int src_h, uint8_t *dst, float*dstf, int dst_w, int dst_h);
void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_gbrg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_rggb8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_grbg8 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float*dstf, int dst_w, int dst_h);
void debayer_gbrg8 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float*dstf, int dst_w, int dst_h);
void debayer_rggb8 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float*dstf, int dst_w, int dst_h);
void debayer_rggb10packet (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_rggb10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h);
void debayer_rggb10packet (uint8_t *src, int src_w, int src_h, uint8_t *dst, float *dstf, int dst_w, int dst_h);
void debayer_gbrg10 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float *dstf, int dst_w, int dst_h);
void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t *dst, float *dstf, int dst_w, int dst_h);
#endif

@ -17,7 +17,10 @@ int SetupSignals();
std::string GetDefaultConfig(std::string name);
VideoFrame inputimage;
VideoFrameFloat inputfloat;
VideoFrameFloat inputfloatfilter;
VideoFrame currentimage;
VideoFrame currentimagefloat;
static void *thread_webserver(void *ignored_argument) {
@ -65,12 +68,15 @@ static void *thread_video(void *ignored_argument) {
currentimage.SetSize (config.web_width, config.web_height);
while (running) {
if (vdev->GetFrame(&inputimage) == 0) {
if (vdev->GetFrame(&inputimage, &inputfloat) == 0) {
vdev->Stop();
vdev->Start();
}
Lock();
inputimage.CopyTo(&currentimage, config.web_width, config.web_height);
if (inputfloatfilter.AddScaledImage(&inputfloat, 0.5, 0.5) == 0)
inputfloat.CopyTo(&inputfloatfilter);
inputfloatfilter.CopyTo(&currentimagefloat);
UnLock();
}

@ -26,9 +26,11 @@ void ErrorExit(std::string text, int errorcode);
int Lock();
int UnLock();
extern VideoFrame currentimage;
extern VideoFrame inputimage;
extern VideoFrame currentimage;
extern VideoFrameFloat inputfloat;
extern VideoFrame currentimagefloat;
extern int running;
#endif

@ -81,7 +81,7 @@ class VideoDevice {
virtual int SetIOMode(int newiomode) { debug (""); return 0; };
virtual int Start() { debug (""); return 0; };
virtual int Stop() { debug (""); return 0; };
virtual int GetFrame (VideoFrame *destframe) { debug (""); return 0; };
virtual int GetFrame (VideoFrame *destframe, VideoFrameFloat *destfloat) { debug (""); return 0; };
virtual int SetDevCtrl(unsigned int id, int value) { debug (""); return 0; };
virtual int GetDevCtrl(unsigned int id, int *value) { debug (""); return 0; };
};

@ -247,7 +247,7 @@ int VideoDevice_Dump::Stop() {
//
#define SIZE_FRAMEHEADER 8
#define SIZE_DUMPHEADER 12
int VideoDevice_Dump::GetFrame(VideoFrame *destframe) {
int VideoDevice_Dump::GetFrame(VideoFrame *destframe, VideoFrameFloat *destfloat) {
struct timeval curtv;
unsigned int diff = 0;
std::list<VideoDevCtrl>::iterator ctrl;
@ -266,7 +266,7 @@ int VideoDevice_Dump::GetFrame(VideoFrame *destframe) {
} while (diff < inframe_nexttime);
ReadFrame();
Convert(&cdata, destframe, inframe, inframe_size,
Convert(&cdata, destframe, destfloat, inframe, inframe_size,
conf_videofmt, w, h);
ctrl = vidctrls.begin();

@ -34,7 +34,7 @@ class VideoDevice_Dump : public VideoDevice {
int SetIOMode(int newiomode) { return 1; };
int Start();
int Stop();
int GetFrame (VideoFrame *destframe);
int GetFrame (VideoFrame *destframe, VideoFrameFloat *destfloat);
int SetDevCtrl(unsigned int id, int value);
int GetDevCtrl(unsigned int id, int *value);
};

@ -380,11 +380,11 @@ int VideoDevice_V4L2::Stop() {
};
int VideoDevice_V4L2::GetFrame(VideoFrame *destframe) {
int VideoDevice_V4L2::GetFrame(VideoFrame *destframe, VideoFrameFloat *destfloat) {
struct v4l2_buffer buf;
int len;
if (destframe == NULL) return 0;
if (destframe == NULL && destfloat == NULL) return 0;
switch (conf_iomode) {
case IOMODE_READ:
@ -399,7 +399,7 @@ int VideoDevice_V4L2::GetFrame(VideoFrame *destframe) {
}
}
else {
Convert(&cdata, destframe, inbuffer[0].data, len,
Convert(&cdata, destframe, destfloat, inbuffer[0].data, len,
fmt.fmt.pix.pixelformat, fmt.fmt.pix.width, fmt.fmt.pix.height);
}
break;
@ -426,7 +426,7 @@ int VideoDevice_V4L2::GetFrame(VideoFrame *destframe) {
}
if (buf.index >= 0 && buf.index < VDEV_INBUFFERS) {
Convert(&cdata, destframe, inbuffer[buf.index].data, buf.bytesused,
Convert(&cdata, destframe, destfloat, inbuffer[buf.index].data, buf.bytesused,
fmt.fmt.pix.pixelformat, fmt.fmt.pix.width, fmt.fmt.pix.height);
}
@ -471,7 +471,7 @@ int VideoDevice_V4L2::SetDevCtrl(unsigned int id, int value) {
CLEAR(ctrl);
ctrl.id = id;
ctrl.value = value;
if (-1 == xioctl (fd, VIDIOC_S_CTRL, &ctrl)) {
if (-1 == xioctl (cfd != -1 ? cfd : fd, VIDIOC_S_CTRL, &ctrl)) {
return 0;
}
@ -484,7 +484,7 @@ int VideoDevice_V4L2::GetDevCtrl(unsigned int id, int *value) {
CLEAR(ctrl);
ctrl.id = id;
if (-1 == xioctl (fd, VIDIOC_G_CTRL, &ctrl)) {
if (-1 == xioctl (cfd != -1 ? cfd : fd, VIDIOC_G_CTRL, &ctrl)) {
return 0;
}
*value = ctrl.value;

@ -30,7 +30,7 @@ class VideoDevice_V4L2 : public VideoDevice {
int SetIOMode(int newiomode);
int Start();
int Stop();
int GetFrame (VideoFrame *destframe);
int GetFrame (VideoFrame *destframe, VideoFrameFloat *destfloat);
int SetDevCtrl(unsigned int id, int value);
int GetDevCtrl(unsigned int id, int *value);

@ -3,6 +3,7 @@
#include <stdio.h>
#include <jpeglib.h>
#include <UDPTCPNetwork.h>
#include <math.h>
#include "videoframe.h"
#include "inmemoryfile.h"
@ -57,6 +58,10 @@ int VideoFrame::SetSize(int w, int h) {
};
/// @brief converts image to jpeg.
/// @param imf ptr to in memory file
/// @param quality
/// @return 0 on error, 1 on success
int VideoFrame::ConvertToJpeg(InMemoryFile *imf, int quality) {
unsigned char *outbuffer = NULL;
unsigned long int outbuffersize;
@ -80,7 +85,7 @@ int VideoFrame::ConvertToJpeg(InMemoryFile *imf, int quality) {
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = width * 3; /* JSAMPLEs per row in image_buffer */
row_stride = width * 3; /* JSAMPLEs per row in image_buffer (24bit image)*/
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & mem[cinfo.next_scanline * row_stride];
@ -161,18 +166,37 @@ int VideoFrame::CopyTo(VideoFrame *dest, int destw, int desth) {
/*********************************************************************/
VideoFrameFloat::VideoFrameFloat() {
memf = NULL;
memf_allocated = 0;
width = 0;
height = 0;
};
VideoFrameFloat::~VideoFrameFloat() {
FreeFrame();
};
void VideoFrameFloat::FreeFrame() {
if (memf != NULL) free(memf);
memf = NULL;
memf_allocated = 0;
};
void VideoFrameFloat::AllocateFrame() {
printf ("VideoFrameFloat::AllocateFrame()\n");
int memnewsize = width * height * 3 * sizeof(float);
if (memnewsize >= mem_allocated) return;
else if (memnewsize == 0) FreeFrame();
mem = (unsigned char *) realloc (mem, memnewsize);
mem_allocated = memnewsize;
if (memnewsize < memf_allocated) return;
else if (memnewsize == 0) {
FreeFrame();
return;
}
if (mem == NULL) {
memf = (float *) realloc (memf, memnewsize);
memf_allocated = memnewsize;
if (memf == NULL) {
debug ("Error on allocation new frame\n");
exit (1);
}
@ -180,3 +204,92 @@ void VideoFrameFloat::AllocateFrame() {
int VideoFrameFloat::TestScreen(int w, int h) {
int x, y;
float r, g, b;
SetSize (w, h);
r = g = b = 0.0;
for (x = 0; x < w; x++) {
for (g = 0, y = 0; y < h; y++) {
if (g )
b = 0.5*(r + g);
memf[3*(x + y * width) + 0] = r;
memf[3*(x + y * width) + 1] = g;
memf[3*(x + y * width) + 2] = b;
g += 0.01;
}
r += 0.01;
}
return 1;
}
int VideoFrameFloat::SetSize(int w, int h) {
if (w < 0 || h < 0) return 0;
width = w;
height = h;
AllocateFrame();
return 1;
};
int VideoFrameFloat::ConvertToJpeg(InMemoryFile *imf, int quality) {
VideoFrame vf;
if (CopyTo (&vf) == 0) return 0;
return vf.ConvertToJpeg(imf, quality);
};
int VideoFrameFloat::CopyTo(VideoFrame *dest) {
int x, y;
unsigned char *dptr;
float *sptr;
if (dest == NULL || memf == NULL || width == 0 || height == 0) return 0;
dest->SetSize(width, height);
for (sptr = memf, dptr = dest->GetPixBuf(), y = 0; y < height; y++)
for (x = 0; x < width*3; x++) {
*dptr = (unsigned char) (sqrtf(*sptr) * 255.0);
dptr++;
sptr++;
}
return 1;
};
int VideoFrameFloat::CopyTo(VideoFrameFloat *dest) {
if (memf == NULL || height == 0 || width == 0) return 0;
if (dest->SetSize(width, height) == 0) return 0;
memcpy (dest->memf, memf, 3 * height * width * sizeof(float));
return 1;
};
int VideoFrameFloat::AddScaledImage(VideoFrameFloat *vf, float f1, float f2) {
float *sptr, *dptr;
int x, y;
if (vf->height != height || vf->width != width || memf == NULL || vf->memf == NULL) return 0;
for (dptr = memf, sptr = vf->GetPixBuf(), y = 0; y < height; y++)
for (x = 0; x < width*3; x++) {
*dptr = f1 * (*dptr) + f2 * (*sptr);
dptr++;
sptr++;
}
return 1;
};

@ -3,11 +3,11 @@
#include "inmemoryfile.h"
//
// only contain 24bit each color 8Bit
// only contain 48bits each color with 16Bit
class VideoFrame {
private:
virtual void AllocateFrame();
protected:
void AllocateFrame();
void FreeFrame();
int mem_allocated;
unsigned char *mem;
@ -29,11 +29,27 @@ class VideoFrame {
};
class VideoFrameFloat : public VideoFrame {
class VideoFrameFloat {
private:
void AllocateFrame();
protected:
void AllocateFrame();
void FreeFrame();
int height;
int width;
int memf_allocated;
float *memf;
public:
VideoFrameFloat();
~VideoFrameFloat();
int SetSize(int w, int h);
int TestScreen(int w, int h);
float *GetPixBuf() { return memf; };
int ConvertToJpeg(InMemoryFile *imf, int quality);
int CopyTo(VideoFrame *dest);
int CopyTo(VideoFrameFloat *dest);
int AddScaledImage(VideoFrameFloat *vf, float f1, float f2);
};

@ -30,6 +30,15 @@ int WebCamServer::HandleRequest (WebRequestBuffer *requestbuffer, WebServerClien
(void*) jpgfile.mem,
jpgfile.memsize) != 1) return 0;
}
else if (request.find("/snapshot-float.jpg") != std::string::npos) {
InMemoryFile jpgfile;
Lock();
currentimagefloat.ConvertToJpeg(&jpgfile, 99);
UnLock();
if (webclient->SendResponseFileFromMemory(requestbuffer, request, "",
(void*) jpgfile.mem,
jpgfile.memsize) != 1) return 0;
}
else {
return 0;
}
@ -42,13 +51,18 @@ int WebCamServer::HandleRequest (WebRequestBuffer *requestbuffer, WebServerClien
std::string GenerateHtmlFile() {
std::string res;
res = "<html><head><title>MiniWebCam</title></head><body>";
res += "<img id=\"myimage\" src=\"snapshot.jpg\"></img>";
res += "<img id=\"myimage1\" src=\"snapshot.jpg\"></img><br>";
res += "<img id=\"myimage2\" src=\"snapshot-float.jpg\"></img>";
res += "<script>\n";
res += " function reloadImage() {\n";
res += " const img = document.getElementById('myimage');\n";
res += " let src = img.src.split('?')[0];\n";
res += " src = src + '?' + new Date().getTime();\n";
res += " img.src = src;\n";
res += " const img1 = document.getElementById('myimage1');\n";
res += " let src1 = img1.src.split('?')[0];\n";
res += " src1 = src1 + '?' + new Date().getTime();\n";
res += " img1.src = src1;\n";
res += " const img2 = document.getElementById('myimage2');\n";
res += " let src2 = img2.src.split('?')[0];\n";
res += " src2 = src2 + '?' + new Date().getTime();\n";
res += " img2.src = src2;\n";
res += "}\n\n";
res += "setInterval(reloadImage, "+to_string(config.web_imagerefresh)+");\n";
res += "\n\n";

Loading…
Cancel
Save