diff --git a/image.h b/image.h index 05a8612..df02955 100644 --- a/image.h +++ b/image.h @@ -6,16 +6,39 @@ class Image { +private: + + ssize_t bufferSize = -1; + public: + + enum { + FORMAT_RGB, + FORMAT_JPEG, + FORMAT_YUYV + } typedef format_t; + std::shared_ptr data = nullptr; uint32_t width; uint32_t height; uint8_t channels; - const uint32_t size() + format_t format = FORMAT_RGB; + + const size_t size() const { - return width*height*channels; + return bufferSize < 0 ? width*height*channels : bufferSize; } - void save(const char* filename) + void setSize(size_t size) + { + bufferSize = size; + } + void setBuffer(std::shared_ptr buffer, size_t size, format_t inFormat = FORMAT_RGB) + { + data = buffer; + bufferSize = size; + format = inFormat; + } + void save(const char* filename) const { std::ofstream outfile(filename); outfile.write((char *) data.get(), size()); diff --git a/jpeg_img.cpp b/jpeg_img.cpp index 26ae2fd..0615343 100644 --- a/jpeg_img.cpp +++ b/jpeg_img.cpp @@ -25,7 +25,7 @@ Image decompressJpegImage(const unsigned char* buffer, size_t size) image.channels = info.num_components; // 3 = RGB, 4 = RGBA // read RGB(A) scanlines one at a time into jdata[] - image.data = std::shared_ptr(new unsigned char[image.size()]); + image.data = std::shared_ptr(new unsigned char[image.size()], std::default_delete()); unsigned char* rowptr; while(info.output_scanline < image.height) { @@ -58,7 +58,7 @@ Image decompressJpegImage(FILE *file) image.channels = info.num_components; // 3 = RGB, 4 = RGBA // read RGB(A) scanlines one at a time into jdata[] - image.data = std::shared_ptr(new unsigned char[image.size()]); + image.data = std::shared_ptr(new unsigned char[image.size()], std::default_delete()); unsigned char* rowptr; while ( info.output_scanline < image.height ) { diff --git a/main.cpp b/main.cpp index 0d7bc1c..897c6c6 100644 --- a/main.cpp +++ b/main.cpp @@ -41,9 +41,11 @@ int main(int argc, char* argv[]) Config config; argp_parse(&argp, argc, argv, 0, 0, &config); + bool passthough = config.mjpeg && config.overlay.empty(); + std::cout<<"UVOS webcam sender v0.1\n"; - Webcam webcam(config.device, config.Xres, config.Yres, config.mjpeg); + Webcam webcam(config.device, config.Xres, config.Yres, config.mjpeg, passthough); std::stringstream ss; ss<<"nc "<(new unsigned char[rgb_frame.size()]); + rgb_frame.data = std::shared_ptr(new unsigned char[rgb_frame.size()], std::default_delete()); start_capturing(); } @@ -138,21 +139,42 @@ const Image& Webcam::frame(int timeout) } int idx = read_frame(); if (idx != -1) { - if (format == V4L2_PIX_FMT_YUYV) + if(!passthrough_format) { - v4lconvert_yuyv_to_rgb24((unsigned char *) buffers[idx].data, - rgb_frame.data.get(), - xres, - yres, - stride); - } - else if(format == V4L2_PIX_FMT_MJPEG) - { - rgb_frame = decompressJpegImage((unsigned char *) buffers[idx].data, buffers[idx].size); + if (format == V4L2_PIX_FMT_YUYV) + { + v4lconvert_yuyv_to_rgb24((unsigned char *) buffers[idx].data, + rgb_frame.data.get(), + xres, + yres, + stride); + } + else if(format == V4L2_PIX_FMT_MJPEG) + { + rgb_frame = decompressJpegImage((unsigned char *) buffers[idx].data, buffers[idx].size); + } + else + { + assert(false); + } } else { - assert(false); + if(format == V4L2_PIX_FMT_YUYV) + { + rgb_frame.setBuffer(std::shared_ptr(new unsigned char[buffers[idx].size], std::default_delete()), + buffers[idx].size, Image::FORMAT_YUYV); + } + else if(format == V4L2_PIX_FMT_MJPEG) + { + rgb_frame.setBuffer(std::shared_ptr(new unsigned char[buffers[idx].size], std::default_delete()), + buffers[idx].size, Image::FORMAT_RGB); + } + else + { + assert(false); + } + memcpy(rgb_frame.data.get(), buffers[idx].data, buffers[idx].size); } return rgb_frame; } diff --git a/webcam.h b/webcam.h index 09f2fdb..bc8c0ef 100644 --- a/webcam.h +++ b/webcam.h @@ -18,7 +18,7 @@ class Webcam { public: Webcam(const std::string& device = "/dev/video0", int width = 640, - int height = 480, bool mjpeg = false); + int height = 480, bool mjpeg = false, bool passthrough = false); ~Webcam(); @@ -60,6 +60,7 @@ private: size_t stride; bool force_format = true; + bool passthrough_format; uint32_t format; };