diff --git a/src/app/capture_thread.cpp b/src/app/capture_thread.cpp index 25ca3b3b..99e9e56b 100644 --- a/src/app/capture_thread.cpp +++ b/src/app/capture_thread.cpp @@ -32,7 +32,11 @@ CaptureThread::CaptureThread(int cam_id) control->addChild( (VarData*) (c_reset = new VarTrigger("reset bus","Reset"))); control->addChild( (VarData*) (c_auto_refresh= new VarBool("auto refresh params",true))); control->addChild( (VarData*) (c_refresh= new VarTrigger("re-read params","Refresh"))); + control->addChild( (VarData*) (captureModule= new VarStringEnum("Capture Module","DC 1394"))); + captureModule->addItem("DC 1394"); + captureModule->addItem("Read from files"); settings->addChild( (VarData*) (dc1394 = new VarList("DC1394"))); + settings->addChild( (VarData*) (fromfile = new VarList("Read from files"))); settings->addRenderFlags( DT_FLAG_AUTO_EXPAND_TREE ); c_stop->addRenderFlags( DT_FLAG_READONLY ); c_refresh->addRenderFlags( DT_FLAG_READONLY ); @@ -43,8 +47,9 @@ CaptureThread::CaptureThread(int cam_id) stack = 0; counter=new FrameCounter(); - capture = new CaptureDC1394v2(dc1394,cam_id); - + capture = 0; + captureDC1394 = new CaptureDC1394v2(dc1394,camId); + captureFiles = new CaptureFromFile(fromfile); _kill =false; rb=0; } @@ -61,7 +66,8 @@ VarList * CaptureThread::getSettings() { CaptureThread::~CaptureThread() { - delete capture; + delete captureDC1394; + delete captureFiles; delete counter; } @@ -86,6 +92,10 @@ void CaptureThread::kill() { bool CaptureThread::init() { capture_mutex.lock(); + if(captureModule->getString() == "Read from files") + capture = captureFiles; + else + capture = captureDC1394; bool res = capture->startCapture(); if (res==true) { c_start->addRenderFlags( DT_FLAG_READONLY ); @@ -136,7 +146,7 @@ void CaptureThread::run() { stats=(CaptureStats *)d->map.insert("capture_stats",new CaptureStats()); } capture_mutex.lock(); - if (capture->isCapturing()) { + if ((capture != 0) && (capture->isCapturing())) { RawImage pic_raw=capture->getFrame(); capture->copyAndConvertFrame( pic_raw,d->video); capture_mutex.unlock(); @@ -175,10 +185,10 @@ void CaptureThread::run() { usleep(100); } if (_kill) { - capture->stopCapture(); + if(capture != 0) + capture->stopCapture(); return; } } } - } diff --git a/src/app/capture_thread.h b/src/app/capture_thread.h index 5991ef70..11c4f8a3 100644 --- a/src/app/capture_thread.h +++ b/src/app/capture_thread.h @@ -22,6 +22,7 @@ #ifndef CAPTURE_THREAD_H #define CAPTURE_THREAD_H #include "capturedc1394v2.h" +#include "capturefromfile.h" #include #include "ringbuffer.h" #include "framedata.h" @@ -43,17 +44,21 @@ Q_OBJECT VisionStack * stack; FrameCounter * counter; CaptureInterface * capture; + CaptureInterface * captureDC1394; + CaptureInterface * captureFiles; FrameBuffer * rb; bool _kill; int camId; VarList * settings; VarList * dc1394; + VarList * fromfile; VarList * control; VarTrigger * c_start; VarTrigger * c_stop; VarTrigger * c_reset; VarTrigger * c_refresh; VarBool * c_auto_refresh; + VarStringEnum * captureModule; Timer timer; public slots: diff --git a/src/shared/capture/capturefromfile.cpp b/src/shared/capture/capturefromfile.cpp new file mode 100644 index 00000000..77f3e47b --- /dev/null +++ b/src/shared/capture/capturefromfile.cpp @@ -0,0 +1,275 @@ +//======================================================================== +// This software is free: you can redistribute it and/or modify +// it under the terms of the GNU General Public License Version 3, +// as published by the Free Software Foundation. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// Version 3 in the file COPYING that came with this distribution. +// If not, see . +//======================================================================== +/*! + \file capturefromfile.cpp + \brief C++ Implementation: CaptureFromFile + \author OB, (C) 2008 + \author TL, (C) 2009 +*/ +//======================================================================== + +#include +#include +#include "capturefromfile.h" +#include "image_io.h" +#include "conversions.h" + + +#ifndef VDATA_NO_QT +CaptureFromFile::CaptureFromFile(VarList * _settings, QObject * parent) : QObject(parent), CaptureInterface(_settings) +#else +CaptureFromFile::CaptureFromFile(VarList * _settings) : CaptureInterface(_settings) +#endif +{ + currentImageIndex = 0; + is_capturing=false; + + settings->addChild(conversion_settings = new VarList("Conversion Settings")); + settings->addChild(capture_settings = new VarList("Capture Settings")); + + //=======================CONVERSION SETTINGS======================= + conversion_settings->addChild(v_colorout=new VarStringEnum("convert to mode",Colors::colorFormatToString(COLOR_YUV422_UYVY))); + v_colorout->addItem(Colors::colorFormatToString(COLOR_RGB8)); + v_colorout->addItem(Colors::colorFormatToString(COLOR_YUV422_UYVY)); + + //=======================CAPTURE SETTINGS========================== + capture_settings->addChild(v_cap_dir = new VarString("directory", "")); + + // Valid file endings + validImageFileEndings.push_back("PNG"); + validImageFileEndings.push_back("BMP"); + validImageFileEndings.push_back("JPG"); + validImageFileEndings.push_back("JPEG"); +} + +CaptureFromFile::~CaptureFromFile() +{ + for(unsigned int i=0; igetString() == "") || ((dp = opendir(v_cap_dir->getString().c_str())) == 0)) + { + fprintf(stderr,"Failed to open directory %s \n", v_cap_dir->getString().c_str()); +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + is_capturing=false; + return false; + } + while ((dirp = readdir(dp))) + { + if (strcmp(dirp->d_name,".") != 0 && strcmp(dirp->d_name,"..") != 0) + { + if(isImageFileName(std::string(dirp->d_name))) + imgs_to_load.push_back(v_cap_dir->getString() + std::string(dirp->d_name)); + else + fprintf(stderr,"Not a valid image file: %s \n", dirp->d_name); + } + } + closedir(dp); + if(imgs_to_load.size() == 0) + { +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + is_capturing=false; + return false; + } + + // Read images to buffer in memory: + imgs_to_load.sort(); + imgs_it = imgs_to_load.begin(); + std::list::iterator currentImage = imgs_it; + while(currentImage != imgs_to_load.end()) + { + int width(-1); + int height(-1); + rgba* rgba_img = ImageIO::readRGBA(width, height, currentImage->c_str()); + fprintf (stderr, "Loaded %s \n", currentImage->c_str()); + images.push_back(rgba_img); + heights.push_back(height); + widths.push_back(width); + ++currentImage; + } + currentImageIndex = 0; + } + is_capturing=true; + +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + return true; +} + +bool CaptureFromFile::isImageFileName(const std::string& fileName) +{ + // Get ending and turn it to uppercase: + string::size_type pointPos = fileName.find_last_of("."); + if(pointPos == string::npos) + return false; + string ending = fileName.substr(pointPos+1); + for(unsigned int i=0; igetSelection().c_str()); + ColorFormat src_fmt=src.getColorFormat(); + + if (target.getData()==0) + target.allocate(output_fmt, src.getWidth(), src.getHeight()); + else + target.ensure_allocation(output_fmt, src.getWidth(), src.getHeight()); + + target.setTime(src.getTime()); + + if (output_fmt == src_fmt) + { + if (src.getData() != 0) + memcpy(target.getData(),src.getData(),src.getNumBytes()); + } + else if (src_fmt == COLOR_RGB8 && output_fmt == COLOR_YUV422_UYVY) + { + if (src.getData() != 0) + dc1394_convert_to_YUV422(src.getData(), target.getData(), src.getWidth(), src.getHeight(), + DC1394_BYTE_ORDER_UYVY, DC1394_COLOR_CODING_RGB8, 8); + } + else if (src_fmt == COLOR_YUV422_UYVY && output_fmt == COLOR_RGB8) + { + if (src.getData() != 0) + dc1394_convert_to_RGB8(src.getData(),target.getData(), src.getWidth(), src.getHeight(), + DC1394_BYTE_ORDER_UYVY, DC1394_COLOR_CODING_YUV422, 8); + } + else + { + fprintf(stderr,"Cannot copy and convert frame...unknown conversion selected from: %s to %s\n", + Colors::colorFormatToString(src_fmt).c_str(), + Colors::colorFormatToString(output_fmt).c_str()); +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + return false; + } +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + return true; +} + +RawImage CaptureFromFile::getFrame() +{ +#ifndef VDATA_NO_QT + mutex.lock(); +#endif + + RawImage result; + result.setColorFormat(COLOR_RGB8); + result.setTime(0.0); + rgba* rgba_img = 0; + int width; + int height; + if(images.size()) + { + rgba_img = images[currentImageIndex]; + width = widths[currentImageIndex]; + height = heights[currentImageIndex]; + currentImageIndex = (currentImageIndex + 1) % images.size(); + } + if (rgba_img == 0) + { + fprintf (stderr, "CaptureFromFile Error, no images available"); + is_capturing=false; + result.setData(0); + result.setWidth(640); + result.setHeight(480); + frame = 0; + } + else + { + frame = new unsigned char[width*height*3]; + unsigned char* p = &frame[0]; + for (int i=0; i < width * height; i++) + { + *p = rgba_img[i].r; + p++; + *p = rgba_img[i].g; + p++; + *p = rgba_img[i].b; + p++; + } + result.setWidth(width); + result.setHeight(height); + result.setData(frame); + timeval tv; + gettimeofday(&tv,0); + result.setTime((double)tv.tv_sec + tv.tv_usec*(1.0E-6)); + } +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif + return result; +} + +void CaptureFromFile::releaseFrame() +{ +#ifndef VDATA_NO_QT + mutex.lock(); +#endif + delete[] frame; +#ifndef VDATA_NO_QT + mutex.unlock(); +#endif +} + +string CaptureFromFile::getCaptureMethodName() const +{ + return "FromFile"; +} diff --git a/src/shared/capture/capturefromfile.h b/src/shared/capture/capturefromfile.h new file mode 100644 index 00000000..a02002ee --- /dev/null +++ b/src/shared/capture/capturefromfile.h @@ -0,0 +1,101 @@ +//======================================================================== +// This software is free: you can redistribute it and/or modify +// it under the terms of the GNU General Public License Version 3, +// as published by the Free Software Foundation. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// Version 3 in the file COPYING that came with this distribution. +// If not, see . +//======================================================================== +/*! + \file capturefromfile.h + \brief C++ Interface: CaptureFromFile + \author OB, (C) 2009 + \author TL, (C) 2009 +*/ +//======================================================================== + +#ifndef CAPTUREFROMFILE_H +#define CAPTUREFROMFILE_H + +#include "captureinterface.h" +#include +#include +#include +#include +#include "VarTypes.h" + +#ifndef VDATA_NO_QT + #include +#else + #include +#endif + + +#ifndef VDATA_NO_QT + #include + //if using QT, inherit QObject as a base +class CaptureFromFile : public QObject, public CaptureInterface +#else +class CaptureFromFile : public CaptureInterface +#endif +{ +#ifndef VDATA_NO_QT + Q_OBJECT +/* public slots: */ +/* void changed(VarData * group); */ + protected: + QMutex mutex; + public: +#endif + +protected: + bool is_capturing; + + //processing variables: + VarStringEnum * v_colorout; + + //capture variables: + VarString * v_cap_dir; + VarList * capture_settings; + VarList * conversion_settings; + + unsigned char* frame; + std::list imgs_to_load; + std::list::iterator imgs_it; + std::vector images; + std::vector heights; + std::vector widths; + unsigned int currentImageIndex; + + bool isImageFileName(const std::string& fileName); + std::vector validImageFileEndings; + +public: +#ifndef VDATA_NO_QT + CaptureFromFile(VarList * _settings, QObject * parent=0); + void mvc_connect(VarList * group); +#else + CaptureFromFile(VarList * _settings); +#endif + ~CaptureFromFile(); + + virtual bool startCapture(); + virtual bool stopCapture(); + virtual bool isCapturing() { return is_capturing; }; + + virtual RawImage getFrame(); + virtual void releaseFrame(); + + void cleanup(); + + virtual bool copyAndConvertFrame(const RawImage & src, RawImage & target); + virtual string getCaptureMethodName() const; +}; + +#endif diff --git a/src/shared/capture/sources.pro.inc b/src/shared/capture/sources.pro.inc index 999bfbb7..f68936be 100644 --- a/src/shared/capture/sources.pro.inc +++ b/src/shared/capture/sources.pro.inc @@ -10,3 +10,6 @@ HEADERS += $${PREFIX}/capturedc1394v2.h SOURCES += $${PREFIX}/captureinterface.cpp HEADERS += $${PREFIX}/captureinterface.h +SOURCES += $${PREFIX}/capturefromfile.cpp +HEADERS += $${PREFIX}/capturefromfile.h + diff --git a/test-data/ssl-field-2008.jpg b/test-data/ssl-field-2008.jpg new file mode 100644 index 00000000..fe9c5ff3 Binary files /dev/null and b/test-data/ssl-field-2008.jpg differ