Commit 3aebbe560b83207db00c9237852a72de6eca33b9

Authored by Charles Otto
1 parent e095c645

Preliminary refactor of video support in stream

Shift support for reading video formats into Gallery subclasses, rather
than using TemplateProcessor subclasses.

This allows a more uniform interface (rather than having separate gallery/
video modes, everything goes through galleries), and gallery subclasses
can also be used in other contexts.
openbr/core/qtutils.cpp
@@ -484,5 +484,22 @@ float overlap(const QRectF &r, const QRectF &s) { @@ -484,5 +484,22 @@ float overlap(const QRectF &r, const QRectF &s) {
484 return (intersection.width()*intersection.height())/(r.width()*r.height()); 484 return (intersection.width()*intersection.height())/(r.width()*r.height());
485 } 485 }
486 486
  487 +
  488 +QString getAbsolutePath(const QString &filename)
  489 +{
  490 + // Try adding the global path, if present
  491 + QString withPath = (Globals->path.isEmpty() ? "" : Globals->path + "/") + filename;
  492 +
  493 + // we weren't necessarily using it to begin with, so see if that file
  494 + // exists
  495 + QFileInfo wpInfo(withPath);
  496 + if (wpInfo.exists() )
  497 + return wpInfo.absoluteFilePath();
  498 +
  499 + // If no, just use the nominal filename
  500 + return QFileInfo(filename).absoluteFilePath();
  501 +}
  502 +
  503 +
487 } // namespace QtUtils 504 } // namespace QtUtils
488 505
openbr/core/qtutils.h
@@ -50,6 +50,7 @@ namespace QtUtils @@ -50,6 +50,7 @@ namespace QtUtils
50 void emptyDir(QDir &dir); 50 void emptyDir(QDir &dir);
51 void deleteDir(QDir &dir); 51 void deleteDir(QDir &dir);
52 QString find(const QString &file, const QString &alt); 52 QString find(const QString &file, const QString &alt);
  53 + QString getAbsolutePath(const QString &filename);
53 54
54 /**** String Utilities ****/ 55 /**** String Utilities ****/
55 bool toBool(const QString &string); 56 bool toBool(const QString &string);
openbr/plugins/gallery.cpp
@@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@
34 #include "openbr/core/opencvutils.h" 34 #include "openbr/core/opencvutils.h"
35 #include "openbr/core/qtutils.h" 35 #include "openbr/core/qtutils.h"
36 36
  37 +#include <fstream>
  38 +
37 #ifdef CVMATIO 39 #ifdef CVMATIO
38 #include "MatlabIO.hpp" 40 #include "MatlabIO.hpp"
39 #include "MatlabIOContainer.hpp" 41 #include "MatlabIOContainer.hpp"
@@ -1671,6 +1673,330 @@ BR_REGISTER(Gallery, vbbGallery) @@ -1671,6 +1673,330 @@ BR_REGISTER(Gallery, vbbGallery)
1671 1673
1672 #endif 1674 #endif
1673 1675
  1676 +
  1677 +// Read a video frame by frame using cv::VideoCapture
  1678 +class videoGallery : public Gallery
  1679 +{
  1680 + Q_OBJECT
  1681 +public:
  1682 + qint64 idx;
  1683 + ~videoGallery()
  1684 + {
  1685 + video.release();
  1686 + }
  1687 +
  1688 + static QMutex openLock;
  1689 +
  1690 + virtual void deferredInit()
  1691 + {
  1692 + bool status = video.open(QtUtils::getAbsolutePath(file.name).toStdString());
  1693 +
  1694 + if (!status)
  1695 + qFatal("Failed to open file %s with path %s", qPrintable(file.name), qPrintable(QtUtils::getAbsolutePath(file.name)));
  1696 + }
  1697 +
  1698 + TemplateList readBlock(bool *done)
  1699 + {
  1700 + if (!video.isOpened()) {
  1701 + // opening videos appears to not be thread safe on windows
  1702 + QMutexLocker lock(&openLock);
  1703 +
  1704 + deferredInit();
  1705 + idx = 0;
  1706 + }
  1707 +
  1708 + Template output;
  1709 + output.file = file;
  1710 + output.m() = cv::Mat();
  1711 +
  1712 + cv::Mat temp;
  1713 + bool res = video.read(temp);
  1714 +
  1715 + if (!res) {
  1716 + // The video capture broke, return an empty list.
  1717 + output.m() = cv::Mat();
  1718 + video.release();
  1719 + *done = true;
  1720 + return TemplateList();
  1721 + }
  1722 +
  1723 + // This clone is critical, if we don't do it then the output matrix will
  1724 + // be an alias of an internal buffer of the video source, leading to various
  1725 + // problems later.
  1726 + output.m() = temp.clone();
  1727 +
  1728 + output.file.set("progress", idx);
  1729 + idx++;
  1730 +
  1731 + TemplateList rVal;
  1732 + rVal.append(temp);
  1733 + *done = false;
  1734 + return rVal;
  1735 + }
  1736 +
  1737 + void write(const Template &t)
  1738 + {
  1739 + (void)t; qFatal("Not implemented");
  1740 + }
  1741 +
  1742 +protected:
  1743 + cv::VideoCapture video;
  1744 +};
  1745 +BR_REGISTER(Gallery,videoGallery)
  1746 +
  1747 +QMutex videoGallery::openLock;
  1748 +
  1749 +class aviGallery : public videoGallery
  1750 +{
  1751 + Q_OBJECT
  1752 +};
  1753 +BR_REGISTER(Gallery, aviGallery)
  1754 +
  1755 +class wmvGallery : public videoGallery
  1756 +{
  1757 + Q_OBJECT
  1758 +};
  1759 +BR_REGISTER(Gallery, wmvGallery)
  1760 +
  1761 +// Mostly the same as videoGallery, but we open the VideoCapture with an integer index
  1762 +// rather than file name/web address
  1763 +class webcamGallery : public videoGallery
  1764 +{
  1765 +public:
  1766 + Q_OBJECT
  1767 +
  1768 + void deferredInit()
  1769 + {
  1770 + bool intOK = false;
  1771 + int anInt = file.baseName().toInt(&intOK);
  1772 +
  1773 + if (!intOK)
  1774 + qFatal("Expected integer basename, got %s", qPrintable(file.baseName()));
  1775 +
  1776 + bool rc = video.open(anInt);
  1777 +
  1778 + if (!rc)
  1779 + qFatal("Failed to open webcam with index: %s", qPrintable(file.baseName()));
  1780 + }
  1781 +
  1782 +};
  1783 +BR_REGISTER(Gallery,webcamGallery)
  1784 +
  1785 +class seqGallery : public Gallery
  1786 +{
  1787 +public:
  1788 + Q_OBJECT
  1789 +
  1790 + bool open()
  1791 + {
  1792 + seqFile.open(QtUtils::getAbsolutePath(file.name).toStdString().c_str(), std::ios::in | std::ios::binary | std::ios::ate);
  1793 + if (!isOpen()) {
  1794 + qDebug("Failed to open file %s for reading", qPrintable(file.name));
  1795 + return false;
  1796 + }
  1797 +
  1798 + int headSize = 1024;
  1799 + // start at end of file to get full size
  1800 + int fileSize = seqFile.tellg();
  1801 + if (fileSize < headSize) {
  1802 + qDebug("No header in seq file");
  1803 + return false;
  1804 + }
  1805 +
  1806 + // first 4 bytes store 0xEDFE, next 24 store 'Norpix seq '
  1807 + char firstFour[4];
  1808 + seqFile.seekg(0, std::ios::beg);
  1809 + seqFile.read(firstFour, 4);
  1810 + char nextTwentyFour[24];
  1811 + readText(24, nextTwentyFour);
  1812 + if (firstFour[0] != (char)0xED || firstFour[1] != (char)0xFE || strncmp(nextTwentyFour, "Norpix seq", 10) != 0) {
  1813 + qDebug("Invalid header in seq file");
  1814 + return false;
  1815 + }
  1816 +
  1817 + // next 8 bytes for version (skipped below) and header size (1024), then 512 for descr
  1818 + seqFile.seekg(4, std::ios::cur);
  1819 + int hSize = readInt();
  1820 + if (hSize != headSize) {
  1821 + qDebug("Invalid header size");
  1822 + return false;
  1823 + }
  1824 + char desc[512];
  1825 + readText(512, desc);
  1826 + file.set("Description", QString(desc));
  1827 +
  1828 + width = readInt();
  1829 + height = readInt();
  1830 + // get # channels from bit depth
  1831 + numChan = readInt()/8;
  1832 + int imageBitDepthReal = readInt();
  1833 + if (imageBitDepthReal != 8) {
  1834 + qDebug("Invalid bit depth");
  1835 + return false;
  1836 + }
  1837 + // the size of just the image part of a raw img
  1838 + imgSizeBytes = readInt();
  1839 +
  1840 + int imgFormatInt = readInt();
  1841 + if (imgFormatInt == 100 || imgFormatInt == 200 || imgFormatInt == 101) {
  1842 + imgFormat = "raw";
  1843 + } else if (imgFormatInt == 102 || imgFormatInt == 201 || imgFormatInt == 103 ||
  1844 + imgFormatInt == 1 || imgFormatInt == 2) {
  1845 + imgFormat = "compressed";
  1846 + } else {
  1847 + qFatal("unsupported image format");
  1848 + }
  1849 +
  1850 + numFrames = readInt();
  1851 + // skip empty int
  1852 + seqFile.seekg(4, std::ios::cur);
  1853 + // the size of a full raw file, with extra crap after img data
  1854 + trueImgSizeBytes = readInt();
  1855 +
  1856 + // gather all the frame positions in an array
  1857 + seekPos.reserve(numFrames);
  1858 + // start at end of header
  1859 + seekPos.append(headSize);
  1860 + // extra 8 bytes at end of img
  1861 + int extra = 8;
  1862 + for (int i=1; i<numFrames; i++) {
  1863 + int s;
  1864 + // compressed images have different sizes
  1865 + // the first byte at the beginning of the file
  1866 + // says how big the current img is
  1867 + if (imgFormat == "compressed") {
  1868 + int lastPos = seekPos[i-1];
  1869 + seqFile.seekg(lastPos, std::ios::beg);
  1870 + int currSize = readInt();
  1871 + s = lastPos + currSize + extra;
  1872 +
  1873 + // but there might be 16 extra bytes instead of 8...
  1874 + if (i == 1) {
  1875 + seqFile.seekg(s, std::ios::beg);
  1876 + char zero;
  1877 + seqFile.read(&zero, 1);
  1878 + if (zero == 0) {
  1879 + s += 8;
  1880 + extra += 8;
  1881 + }
  1882 + }
  1883 + }
  1884 + // raw images are all the same size
  1885 + else {
  1886 + s = headSize + (i*trueImgSizeBytes);
  1887 + }
  1888 +
  1889 + seekPos.enqueue(s);
  1890 + }
  1891 +
  1892 +#ifdef CVMATIO
  1893 + if (basis.file.contains("vbb")) {
  1894 + QString vbb = basis.file.get<QString>("vbb");
  1895 + annotations = TemplateList::fromGallery(File(vbb));
  1896 + }
  1897 +#else
  1898 + qWarning("cvmatio not installed, bounding boxes will not be available. Add -DBR_WITH_CVMATIO cmake flag to install.");
  1899 +#endif
  1900 +
  1901 + return true;
  1902 + }
  1903 +
  1904 + bool isOpen()
  1905 + {
  1906 + return seqFile.is_open();
  1907 + }
  1908 +
  1909 + void close()
  1910 + {
  1911 + seqFile.close();
  1912 + }
  1913 +
  1914 + TemplateList readBlock(bool *done)
  1915 + {
  1916 + if (!isOpen()) {
  1917 + if (!open())
  1918 + qFatal("Failed to open file %s for reading", qPrintable(file.name));
  1919 + else
  1920 + idx = 0;
  1921 + }
  1922 +
  1923 + // if we've reached the last frame, we're done
  1924 + if (seekPos.size() == 0) {
  1925 + *done = true;
  1926 + return TemplateList();
  1927 + }
  1928 +
  1929 + seqFile.seekg(seekPos.dequeue(), std::ios::beg);
  1930 +
  1931 + cv::Mat temp;
  1932 + // let imdecode do all the work to decode the compressed img
  1933 + if (imgFormat == "compressed") {
  1934 + int imgSize = readInt() - 4;
  1935 + std::vector<char> imgBuf(imgSize);
  1936 + seqFile.read(&imgBuf[0], imgSize);
  1937 + // flags < 0 means load image as-is (keep color info if available)
  1938 + cv::imdecode(imgBuf, -1, &temp);
  1939 + }
  1940 + // raw images can be loaded straight into a Mat
  1941 + else {
  1942 + char *imgBuf = new char[imgSizeBytes];
  1943 + seqFile.read(imgBuf, imgSizeBytes);
  1944 + int type = (numChan == 1 ? CV_8UC1 : CV_8UC3);
  1945 + temp = cv::Mat(height, width, type, imgBuf);
  1946 + }
  1947 + Template output;
  1948 + output.file = file;
  1949 + if (!annotations.empty()) {
  1950 + output.file.setRects(annotations.first().file.rects());
  1951 + annotations.removeFirst();
  1952 + }
  1953 + output.m() = temp;
  1954 + output.file.set("position",idx);
  1955 + idx++;
  1956 +
  1957 + *done = false;
  1958 + TemplateList rVal;
  1959 + rVal.append(output);
  1960 +
  1961 + return rVal;
  1962 + }
  1963 +
  1964 + void write(const Template &t)
  1965 + {
  1966 + (void) t;
  1967 + qFatal("Not implemented.");
  1968 + }
  1969 +
  1970 +private:
  1971 + qint64 idx;
  1972 + int readInt()
  1973 + {
  1974 + int num;
  1975 + seqFile.read((char*)&num, 4);
  1976 + return num;
  1977 + }
  1978 +
  1979 + // apparently the text in seq files is 16 bit characters (UTF-16?)
  1980 + // since we don't really need the last byte, snad since it gets interpreted as
  1981 + // a terminating char, let's just grab the first byte for storage
  1982 + void readText(int bytes, char *buffer)
  1983 + {
  1984 + seqFile.read(buffer, bytes);
  1985 + for (int i=0; i<bytes; i+=2) {
  1986 + buffer[i/2] = buffer[i];
  1987 + }
  1988 + buffer[bytes/2] = '\0';
  1989 + }
  1990 +
  1991 +protected:
  1992 + std::ifstream seqFile;
  1993 + QQueue<int> seekPos;
  1994 + int width, height, numChan, imgSizeBytes, trueImgSizeBytes, numFrames;
  1995 + QString imgFormat;
  1996 + TemplateList annotations;
  1997 +};
  1998 +BR_REGISTER(Gallery, seqGallery)
  1999 +
1674 void FileGallery::init() 2000 void FileGallery::init()
1675 { 2001 {
1676 f.setFileName(file); 2002 f.setFileName(file);
openbr/plugins/stream.cpp
@@ -23,10 +23,9 @@ class Idiocy : public QObject @@ -23,10 +23,9 @@ class Idiocy : public QObject
23 { 23 {
24 Q_OBJECT 24 Q_OBJECT
25 public: 25 public:
26 - enum StreamModes { StreamVideo,  
27 - DistributeFrames,  
28 - StreamGallery,  
29 - Auto}; 26 + enum StreamModes { DistributeFrames,
  27 + StreamGallery
  28 + };
30 29
31 Q_ENUMS(StreamModes) 30 Q_ENUMS(StreamModes)
32 }; 31 };
@@ -207,88 +206,8 @@ public: @@ -207,88 +206,8 @@ public:
207 virtual bool getNextTemplate(Template &output)=0; 206 virtual bool getNextTemplate(Template &output)=0;
208 protected: 207 protected:
209 Template basis; 208 Template basis;
210 - string getAbsolutePath(QString filename)  
211 - {  
212 - // Yes, we should specify absolute path:  
213 - // http://stackoverflow.com/questions/9396459/loading-a-video-in-opencv-in-python  
214 - QString fileName = (Globals->path.isEmpty() ? "" : Globals->path + "/") + filename;  
215 - return QFileInfo(fileName).absoluteFilePath().toStdString();  
216 - }  
217 }; 209 };
218 210
219 -static QMutex openLock;  
220 -  
221 -// Read a video frame by frame using cv::VideoCapture  
222 -class VideoReader : public TemplateProcessor  
223 -{  
224 -public:  
225 - VideoReader() {}  
226 -  
227 - bool open(Template &input)  
228 - {  
229 - basis = input;  
230 -  
231 - // We can open either files (well actually this includes addresses of ip cameras  
232 - // through ffmpeg), or webcams. Webcam VideoCaptures are created through a separate  
233 - // overload of open that takes an integer, not a string.  
234 - // So, does this look like an integer?  
235 - bool is_int = false;  
236 - int anInt = input.file.name.toInt(&is_int);  
237 - if (is_int)  
238 - {  
239 - bool rc = video.open(anInt);  
240 -  
241 - if (!rc)  
242 - {  
243 - qDebug("open failed!");  
244 - }  
245 - if (!video.isOpened())  
246 - {  
247 - qDebug("Video not open!");  
248 - }  
249 - } else {  
250 - // On windows, this appears to not be thread-safe  
251 - QMutexLocker lock(&openLock);  
252 - video.open(getAbsolutePath(input.file.name));  
253 - }  
254 -  
255 - return video.isOpened();  
256 - }  
257 -  
258 - bool isOpen() { return video.isOpened(); }  
259 -  
260 - void close() { video.release(); }  
261 -  
262 - bool getNextTemplate(Template &output)  
263 - {  
264 - if (!isOpen()) {  
265 - qDebug("video source is not open");  
266 - return false;  
267 - }  
268 - output.file = basis.file;  
269 - output.m() = cv::Mat();  
270 -  
271 - cv::Mat temp;  
272 - bool res = video.read(temp);  
273 -  
274 - if (!res) {  
275 - // The video capture broke, return false.  
276 - output.m() = cv::Mat();  
277 - close();  
278 - return false;  
279 - }  
280 -  
281 - // This clone is critical, if we don't do it then the matrix will  
282 - // be an alias of an internal buffer of the video source, leading  
283 - // to various problems later.  
284 - output.m() = temp.clone();  
285 - return true;  
286 - }  
287 -protected:  
288 - cv::VideoCapture video;  
289 -};  
290 -  
291 -  
292 struct StreamGallery : public TemplateProcessor 211 struct StreamGallery : public TemplateProcessor
293 { 212 {
294 bool open(Template &input) 213 bool open(Template &input)
@@ -387,199 +306,6 @@ protected: @@ -387,199 +306,6 @@ protected:
387 bool data_ok; 306 bool data_ok;
388 }; 307 };
389 308
390 -class SeqReader : public TemplateProcessor  
391 -{  
392 -public:  
393 - SeqReader() {}  
394 -  
395 - bool open(Template &input)  
396 - {  
397 - basis = input;  
398 -  
399 - seqFile.open(getAbsolutePath(input.file.name).c_str(), ios::in | ios::binary | ios::ate);  
400 - if (!isOpen()) return false;  
401 -  
402 - int headSize = 1024;  
403 - // start at end of file to get full size  
404 - int fileSize = seqFile.tellg();  
405 - if (fileSize < headSize) {  
406 - qDebug("No header in seq file");  
407 - return false;  
408 - }  
409 -  
410 - // first 4 bytes store 0xEDFE, next 24 store 'Norpix seq '  
411 - char firstFour[4];  
412 - seqFile.seekg(0, ios::beg);  
413 - seqFile.read(firstFour, 4);  
414 - char nextTwentyFour[24];  
415 - readText(24, nextTwentyFour);  
416 - if (firstFour[0] != (char)0xED || firstFour[1] != (char)0xFE || strncmp(nextTwentyFour, "Norpix seq", 10) != 0) {  
417 - qDebug("Invalid header in seq file");  
418 - return false;  
419 - }  
420 -  
421 - // next 8 bytes for version (skipped below) and header size (1024), then 512 for descr  
422 - seqFile.seekg(4, ios::cur);  
423 - int hSize = readInt();  
424 - if (hSize != headSize) {  
425 - qDebug("Invalid header size");  
426 - return false;  
427 - }  
428 - char desc[512];  
429 - readText(512, desc);  
430 - basis.file.set("Description", QString(desc));  
431 -  
432 - width = readInt();  
433 - height = readInt();  
434 - // get # channels from bit depth  
435 - numChan = readInt()/8;  
436 - int imageBitDepthReal = readInt();  
437 - if (imageBitDepthReal != 8) {  
438 - qDebug("Invalid bit depth");  
439 - return false;  
440 - }  
441 - // the size of just the image part of a raw img  
442 - imgSizeBytes = readInt();  
443 -  
444 - int imgFormatInt = readInt();  
445 - if (imgFormatInt == 100 || imgFormatInt == 200 || imgFormatInt == 101) {  
446 - imgFormat = "raw";  
447 - } else if (imgFormatInt == 102 || imgFormatInt == 201 || imgFormatInt == 103 ||  
448 - imgFormatInt == 1 || imgFormatInt == 2) {  
449 - imgFormat = "compressed";  
450 - } else {  
451 - qFatal("unsupported image format");  
452 - }  
453 -  
454 - numFrames = readInt();  
455 - // skip empty int  
456 - seqFile.seekg(4, ios::cur);  
457 - // the size of a full raw file, with extra crap after img data  
458 - trueImgSizeBytes = readInt();  
459 -  
460 - // gather all the frame positions in an array  
461 - seekPos.reserve(numFrames);  
462 - // start at end of header  
463 - seekPos.append(headSize);  
464 - // extra 8 bytes at end of img  
465 - int extra = 8;  
466 - for (int i=1; i<numFrames; i++) {  
467 - int s;  
468 - // compressed images have different sizes  
469 - // the first byte at the beginning of the file  
470 - // says how big the current img is  
471 - if (imgFormat == "compressed") {  
472 - int lastPos = seekPos[i-1];  
473 - seqFile.seekg(lastPos, ios::beg);  
474 - int currSize = readInt();  
475 - s = lastPos + currSize + extra;  
476 -  
477 - // but there might be 16 extra bytes instead of 8...  
478 - if (i == 1) {  
479 - seqFile.seekg(s, ios::beg);  
480 - char zero;  
481 - seqFile.read(&zero, 1);  
482 - if (zero == 0) {  
483 - s += 8;  
484 - extra += 8;  
485 - }  
486 - }  
487 - }  
488 - // raw images are all the same size  
489 - else {  
490 - s = headSize + (i*trueImgSizeBytes);  
491 - }  
492 -  
493 - seekPos.enqueue(s);  
494 - }  
495 -  
496 -#ifdef CVMATIO  
497 - if (basis.file.contains("vbb")) {  
498 - QString vbb = basis.file.get<QString>("vbb");  
499 - annotations = TemplateList::fromGallery(File(vbb));  
500 - }  
501 -#else  
502 - qWarning("cvmatio not installed, bounding boxes will not be available. Add -DBR_WITH_CVMATIO cmake flag to install.");  
503 -#endif  
504 -  
505 - return true;  
506 - }  
507 -  
508 - bool isOpen()  
509 - {  
510 - return seqFile.is_open();  
511 - }  
512 -  
513 - void close()  
514 - {  
515 - seqFile.close();  
516 - }  
517 -  
518 - bool getNextTemplate(Template &output)  
519 - {  
520 - if (!isOpen()) {  
521 - qDebug("Seq not open");  
522 - return false;  
523 - }  
524 - // if we've reached the last frame, we're done  
525 - if (seekPos.size() == 0) return false;  
526 -  
527 - seqFile.seekg(seekPos.dequeue(), ios::beg);  
528 -  
529 - Mat temp;  
530 - // let imdecode do all the work to decode the compressed img  
531 - if (imgFormat == "compressed") {  
532 - int imgSize = readInt() - 4;  
533 - vector<char> imgBuf(imgSize);  
534 - seqFile.read(&imgBuf[0], imgSize);  
535 - // flags < 0 means load image as-is (keep color info if available)  
536 - imdecode(imgBuf, -1, &temp);  
537 - }  
538 - // raw images can be loaded straight into a Mat  
539 - else {  
540 - char *imgBuf = new char[imgSizeBytes];  
541 - seqFile.read(imgBuf, imgSizeBytes);  
542 - int type = (numChan == 1 ? CV_8UC1 : CV_8UC3);  
543 - temp = Mat(height, width, type, imgBuf);  
544 - }  
545 -  
546 - output.file = basis.file;  
547 - if (!annotations.empty()) {  
548 - output.file.setRects(annotations.first().file.rects());  
549 - annotations.removeFirst();  
550 - }  
551 - output.m() = temp;  
552 -  
553 - return true;  
554 - }  
555 -private:  
556 - int readInt()  
557 - {  
558 - int num;  
559 - seqFile.read((char*)&num, 4);  
560 - return num;  
561 - }  
562 -  
563 - // apparently the text in seq files is 16 bit characters (UTF-16?)  
564 - // since we don't really need the last byte, snad since it gets interpreted as  
565 - // a terminating char, let's just grab the first byte for storage  
566 - void readText(int bytes, char *buffer)  
567 - {  
568 - seqFile.read(buffer, bytes);  
569 - for (int i=0; i<bytes; i+=2) {  
570 - buffer[i/2] = buffer[i];  
571 - }  
572 - buffer[bytes/2] = '\0';  
573 - }  
574 -  
575 -protected:  
576 - ifstream seqFile;  
577 - QQueue<int> seekPos;  
578 - int width, height, numChan, imgSizeBytes, trueImgSizeBytes, numFrames;  
579 - QString imgFormat;  
580 - TemplateList annotations;  
581 -};  
582 -  
583 // Interface for sequentially getting data from some data source. 309 // Interface for sequentially getting data from some data source.
584 // Given a TemplateList, return single template frames sequentially by applying a TemplateProcessor 310 // Given a TemplateList, return single template frames sequentially by applying a TemplateProcessor
585 // to each individual template. 311 // to each individual template.
@@ -650,7 +376,6 @@ public: @@ -650,7 +376,6 @@ public:
650 return true; 376 return true;
651 } 377 }
652 378
653 -  
654 // non-blocking version of getFrame 379 // non-blocking version of getFrame
655 // Returns a NULL FrameData if too many frames are out, or the 380 // Returns a NULL FrameData if too many frames are out, or the
656 // data source is broken. Sets last_frame to true iff the FrameData 381 // data source is broken. Sets last_frame to true iff the FrameData
@@ -744,19 +469,7 @@ protected: @@ -744,19 +469,7 @@ protected:
744 frameSource->close(); 469 frameSource->close();
745 470
746 Template curr = this->templates[current_template_idx]; 471 Template curr = this->templates[current_template_idx];
747 - if (mode == br::Idiocy::Auto)  
748 - {  
749 - delete frameSource;  
750 - if (curr.empty()) {  
751 - if (curr.file.name.right(3) == "seq")  
752 - frameSource = new SeqReader();  
753 - else  
754 - frameSource = new VideoReader();  
755 - }  
756 - else  
757 - frameSource = new DirectReturn();  
758 - }  
759 - else if (mode == br::Idiocy::DistributeFrames) 472 + if (mode == br::Idiocy::DistributeFrames)
760 { 473 {
761 if (!frameSource) 474 if (!frameSource)
762 frameSource = new DirectReturn(); 475 frameSource = new DirectReturn();
@@ -766,15 +479,6 @@ protected: @@ -766,15 +479,6 @@ protected:
766 if (!frameSource) 479 if (!frameSource)
767 frameSource = new StreamGallery(); 480 frameSource = new StreamGallery();
768 } 481 }
769 - else if (mode == br::Idiocy::StreamVideo)  
770 - {  
771 - if (!frameSource) {  
772 - if (curr.file.name.right(3) == "seq")  
773 - frameSource = new SeqReader();  
774 - else  
775 - frameSource = new VideoReader();  
776 - }  
777 - }  
778 open_res = frameSource->open(curr); 482 open_res = frameSource->open(curr);
779 if (!open_res) 483 if (!open_res)
780 { 484 {
@@ -1271,7 +975,7 @@ public: @@ -1271,7 +975,7 @@ public:
1271 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) 975 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode)
1272 Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true) 976 Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true)
1273 BR_PROPERTY(int, activeFrames, 100) 977 BR_PROPERTY(int, activeFrames, 100)
1274 - BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) 978 + BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::StreamGallery)
1275 BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) 979 BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput"))
1276 980
1277 friend class StreamTransfrom; 981 friend class StreamTransfrom;
@@ -1589,7 +1293,7 @@ public: @@ -1589,7 +1293,7 @@ public:
1589 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) 1293 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode)
1590 1294
1591 BR_PROPERTY(int, activeFrames, 100) 1295 BR_PROPERTY(int, activeFrames, 100)
1592 - BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) 1296 + BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::StreamGallery)
1593 BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) 1297 BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput"))
1594 1298
1595 bool timeVarying() const { return true; } 1299 bool timeVarying() const { return true; }