diff --git a/Makefile b/Makefile index 69a6812..9627533 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ LDFLAGS= -lUDPTCPNetwork -L/usr/local/lib -ljpeg OBJFILES= webserver.o configuration.o main.o video.o convert.o debayer.o inmemoryfile.o videoframe.o all: dep miniwebcam -miniwebcam: dep $(OBJFILES) +miniwebcam: $(OBJFILES) $(CXX) $(OBJFILES) -o $@ -L./ -I./ $(LDFLAGS) install: miniwebcam diff --git a/convert.cc b/convert.cc index 4575bac..da779e2 100644 --- a/convert.cc +++ b/convert.cc @@ -16,7 +16,7 @@ #include "configuration.h" #include "debayer.h" -int debayer_mode = 0; // testing 0 or 1 +int debayer_mode = 1; // testing 0 or 1 uint32_t convert_pixelformats [] = { V4L2_PIX_FMT_MJPEG, @@ -28,7 +28,7 @@ uint32_t convert_pixelformats [] = { V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_SGRBG16, V4L2_PIX_FMT_SRGGB10P, - V4L2_PIX_FMT_SBGGR10, + V4L2_PIX_FMT_SRGGB10, V4L2_PIX_FMT_SRGGB8, V4L2_PIX_FMT_SGRBG8, 0 @@ -104,6 +104,8 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr unsigned char cb, cr, y1; unsigned char *ptrdst = NULL; + debug ("srcsize:%d pixfmt:%s size: %dx%d", srcsize, convert_from_pixelformat(pixelformat).c_str(), srcw, srch); + struct jpg_error_mgr jerr; if (cdata == NULL) return 0; @@ -221,20 +223,28 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr } break; - case (V4L2_PIX_FMT_SRGGB10P): + case (V4L2_PIX_FMT_SGRBG16): if (debayer_mode == 0) - debayer_rggb10packet_simple ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + debayer_grbg16_simple ((uint16_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); else - debayer_rggb10packet_bilinear ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + debayer_grbg16_bilinear ((uint16_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); break; - case (V4L2_PIX_FMT_SGRBG16): + case (V4L2_PIX_FMT_SRGGB10P): if (debayer_mode == 0) - debayer_grbg16_simple ((uint16_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + debayer_rggb10packet_simple ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); else - debayer_grbg16_bilinear ((uint16_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + debayer_rggb10packet_bilinear ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); break; + case (V4L2_PIX_FMT_SRGGB10): + if (debayer_mode == 0) + debayer_rggb10_simple ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + else + debayer_rggb10_bilinear ((uint8_t *)ptrsrc, srcw, srch, ptrdst, srcw, srch); + break; + + case (V4L2_PIX_FMT_SRGGB8): case (V4L2_PIX_FMT_SGRBG8): if (debayer_mode == 0) diff --git a/debayer.cc b/debayer.cc index dab4cb3..e874bb2 100644 --- a/debayer.cc +++ b/debayer.cc @@ -1,5 +1,10 @@ #include #include +#include +#include +#include + +std::string toBits(unsigned int i, int maxbits); /* The function converts a 16bit GRBG 2x2 CFA coded image into an 8bit @@ -365,14 +370,121 @@ void debayer_grbg8_bilinear (uint8_t * src, int src_w, int src_h, STORE8; } + +#define P_U (*(psrc-src_w*(10/8))) +#define P_D (*(psrc+src_w*(10/8))) +#define P_L (*(psrc-1)) +#define P_R (*(psrc+1)) +#define P_UL (*(psrc-1-src_w*(10/8))) +#define P_UR (*(psrc+1-src_w*(10/8))) +#define P_DL (*(psrc-1+src_w*(10/8))) +#define P_DR (*(psrc+1+src_w*(10/8))) void debayer_rggb10packet_simple (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 RR + // GG BB GG BB GG + // RR GG RR GG RR + // GG BB GG BB 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 = (P_L + P_R + P_U + P_D)/4; + r = (P_UL + P_DL + P_UR + P_UL)/4; + } + else { + b = (P_L + P_R)/2; + g = *psrc; + r = (P_U + P_D)/2; + } + } + else { + if (xs&1) { + b = (P_U + P_D)/2; + g = *psrc; + r = (P_L + P_R)/2; + } + else { + g = (P_L + P_R + P_U + P_D)/4; + b = (P_UL + P_DL + P_UR + P_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] = r; + pdst[1] = g; + pdst[2] = b; + pdst += 3; + psrc++; + // if (xs >= src_w -1) psrc += src_w / 4; + if (xs && (xs % 4 == 0)) psrc++; + } + } }; +std::string toBits(unsigned int i, int maxbits) { + int b; + std::string out = ""; + for (b = 0; b < maxbits; b++) { + if (b % 8 == 0 && b) out = ":" + out; + if (i % 2) out = "1" + out; + else out = "0" + out; + i = i >> 1; + } + return out; +} + void debayer_rggb10packet_bilinear (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) { + debayer_rggb10packet_simple (src, src_w, src_h, dst, dst_w, dst_h); + +}; + + +void debayer_rggb10_simple (uint8_t * src, int src_w, int src_h, + uint8_t * dst, int dst_w, int dst_h) { + int s, d; + for (s = 0, d = 0; d < dst_w * dst_h * 3; d++) { + dst[d] = src[s]; + if (++s >= src_h * src_h) s = 0; + } + +}; + + +void debayer_rggb10_bilinear (uint8_t * src, int src_w, int src_h, + uint8_t * dst, int dst_w, int dst_h) { + int s, d; + for (s = 0, d = 0; d < dst_w * dst_h * 3; d++) { + dst[d] = src[s]; + if (++s >= src_h * src_h) s = 0; + } + + }; diff --git a/debayer.h b/debayer.h index 3950f9d..4b0c98c 100644 --- a/debayer.h +++ b/debayer.h @@ -18,4 +18,9 @@ void debayer_rggb10packet_simple (uint8_t * src, int src_w, int src_h, void debayer_rggb10packet_bilinear (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h); +void debayer_rggb10_simple (uint8_t * src, int src_w, int src_h, + uint8_t * dst, int dst_w, int dst_h); +void debayer_rggb10_bilinear (uint8_t * src, int src_w, int src_h, + uint8_t * dst, int dst_w, int dst_h); + #endif diff --git a/webserver.cc b/webserver.cc index df87991..ad9b21d 100644 --- a/webserver.cc +++ b/webserver.cc @@ -48,7 +48,7 @@ std::string GenerateHtmlFile() { res += " src = src + '?' + new Date().getTime();\n"; res += " img.src = src;\n"; res += "}\n\n"; - res += "setInterval(reloadImage, 1000);\n"; + res += "setInterval(reloadImage, 5000);\n"; res += "\n\n"; res += "\n"; res += "";