diff --git a/Makefile.am b/Makefile.am index 79961b2..3e0cf4b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,8 @@ prpa_LDADD = \ lib/libfilterSample.a \ lib/libencoder.a -prpa_SOURCES = src/main.cc src/configuration.cc src/pipeline.cc +prpa_SOURCES = src/main.cc src/configuration.cc src/pipeline.cc \ + src/compose.cc prpa_LDFLAGS = \ $(BOOST_LDFLAGS) \ diff --git a/configure.ac b/configure.ac index b1da88e..bef510b 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ AC_CONFIG_MACRO_DIR([m4]) # Look for a C++ compiler.CXXFLAGS_save="$CXXFLAGS" AC_PROG_CXX AC_PROG_RANLIB -CXXFLAGS="$CXXFLAGS_save -std=c++11 -g" +CXXFLAGS="$CXXFLAGS_save -std=c++11 -g -O0" AC_ARG_ENABLE(debug, [ --enable-debug compile with debugging support], diff --git a/src/compose.cc b/src/compose.cc new file mode 100644 index 0000000..67c3fcb --- /dev/null +++ b/src/compose.cc @@ -0,0 +1,16 @@ +#include +#include +#include "compose.hh" + +#include "opencv2/opencv.hpp" + +void* Compose::operator()(void* para) +{ + cv::Mat* mat = (cv::Mat*)para; + std::pair* res = new std::pair(); + + res->first = mat; + res->second = (cv::Mat*)this->vr_(nullptr); + + return res; +} diff --git a/src/compose.hh b/src/compose.hh new file mode 100644 index 0000000..cebb2c3 --- /dev/null +++ b/src/compose.hh @@ -0,0 +1,16 @@ +#ifndef COMPOSE_HH_ +# define COMPOSE_HH_ + +# include "tbb/pipeline.h" +# include "encoder/video_reader.hh" + +class Compose: public tbb::filter +{ + public: + Compose(VideoReader vr): filter(tbb::filter::serial_in_order), vr_(vr) {} + void* operator()(void*); + private: + VideoReader vr_; +}; + +#endif /* COMPOSE_HH_ */ diff --git a/src/encoder/video_reader.cc b/src/encoder/video_reader.cc index 2153943..9afc030 100644 --- a/src/encoder/video_reader.cc +++ b/src/encoder/video_reader.cc @@ -1,36 +1,34 @@ #include "opencv2/opencv.hpp" #include "video_reader.hh" +VideoReader::VideoReader(std::string filename) + : filter(tbb::filter::serial_in_order), capture_(filename) +{ + this->remaining_ = framecount_get(); +} + VideoReader::VideoReader(const VideoReader& vr) : filter(tbb::filter::serial_in_order) { this->capture_ = vr.capture_; - this->maxframe_ = vr.maxframe_; - this->current_ = vr.current_; + this->remaining_ = framecount_get(); } void* VideoReader::operator()(void* ign) { (void)ign; - if (this->capture_.grab() && this->current_ < this->maxframe_) + cv::Mat retrieved; + if (this->remaining_ > 0) { - this->current_++; - cv::Mat retrieved; + this->capture_.read(retrieved); cv::Mat* res = new cv::Mat; - this->capture_.retrieve(retrieved); *res = retrieved.clone(); + this->remaining_--; return res; } else - { return nullptr; - } -} - -void VideoReader::maxframe_set(int limit) -{ - this->maxframe_ = limit; } int VideoReader::framecount_get() diff --git a/src/encoder/video_reader.hh b/src/encoder/video_reader.hh index 490481b..6e31f51 100644 --- a/src/encoder/video_reader.hh +++ b/src/encoder/video_reader.hh @@ -3,23 +3,21 @@ # include # include "tbb/pipeline.h" +# include "opencv2/opencv.hpp" class VideoReader: public tbb::filter { public: VideoReader(const VideoReader& vr); - VideoReader(std::string filename) : filter(tbb::filter::serial_in_order), - capture_(filename), current_(0) {} + VideoReader(std::string filename); int framecount_get(); int fps_get(); int width_get(); int height_get(); - void maxframe_set(int limit); void* operator()(void*); private: cv::VideoCapture capture_; - int maxframe_; - int current_; + int remaining_; }; #endif /* !VIDEO_READER_HH_ */ diff --git a/src/filterSample/Makefile.am b/src/filterSample/Makefile.am index 3d4787d..e2c381d 100644 --- a/src/filterSample/Makefile.am +++ b/src/filterSample/Makefile.am @@ -6,4 +6,4 @@ AM_CXXFLAGS = \ $(BOOST_CPPFLAGS) \ $(DEBUG_CXXFLAGS) -______lib_libfilterSample_a_SOURCES = grey.cc +______lib_libfilterSample_a_SOURCES = grey.cc reverse.cc merge.cc interlace.cc diff --git a/src/filterSample/interlace.cc b/src/filterSample/interlace.cc new file mode 100644 index 0000000..a7cd82b --- /dev/null +++ b/src/filterSample/interlace.cc @@ -0,0 +1,32 @@ +#include +#include +#include "interlace.hh" + +#include "opencv2/opencv.hpp" + +void* Interlace::operator()(void* para) +{ + std::pair* pair = (std::pair*)para; + cv::Mat* mat = pair->first; + + if (mat == nullptr) + return nullptr; + + if (pair->second != nullptr) + { + for (size_t i = 0; i < mat->rows; ++i) + for (size_t j = 0; j < mat->cols; ++j) + if (i < pair->second->rows && j < pair->second->cols + && (i + j) % 2 == 0) + { + mat->at(i, j)[0] = pair->second->at(i, j)[0]; + mat->at(i, j)[1] = pair->second->at(i, j)[1]; + mat->at(i, j)[2] = pair->second->at(i, j)[2]; + } + + delete pair->second; + } + + delete pair; + return mat; +} diff --git a/src/filterSample/interlace.hh b/src/filterSample/interlace.hh new file mode 100644 index 0000000..1e3e45b --- /dev/null +++ b/src/filterSample/interlace.hh @@ -0,0 +1,13 @@ +#ifndef INTERLACE_HH_ +# define INTERLACE_HH_ + +# include "tbb/pipeline.h" + +class Interlace: public tbb::filter +{ + public: + Interlace(): filter(tbb::filter::parallel) {} + void* operator()(void*); +}; + +#endif /* !INTERLACE_HH_ */ diff --git a/src/filterSample/merge.cc b/src/filterSample/merge.cc new file mode 100644 index 0000000..179c176 --- /dev/null +++ b/src/filterSample/merge.cc @@ -0,0 +1,33 @@ +#include +#include +#include "merge.hh" + +#include "opencv2/opencv.hpp" + +void* Merge::operator()(void* para) +{ + std::pair* pair = (std::pair*)para; + cv::Mat* mat = pair->first; + + if (mat == nullptr) + return nullptr; + + if (pair->second != nullptr) + { + for (size_t i = 0; i < mat->rows; ++i) + for (size_t j = 0; j < mat->cols; ++j) + if (i < pair->second->rows && j < pair->second->cols) + { + mat->at(i, j)[0] = (mat->at(i, j)[0] + + pair->second->at(i, j)[0]) / 2; + mat->at(i, j)[1] = (mat->at(i, j)[1] + + pair->second->at(i, j)[1]) / 2; + mat->at(i, j)[2] = (mat->at(i, j)[2] + + pair->second->at(i, j)[2]) / 2; + } + } + + delete pair->second; + delete pair; + return mat; +} diff --git a/src/filterSample/merge.hh b/src/filterSample/merge.hh new file mode 100644 index 0000000..67fb8af --- /dev/null +++ b/src/filterSample/merge.hh @@ -0,0 +1,13 @@ +#ifndef MERGE_HH_ +# define MERGE_HH_ + +# include "tbb/pipeline.h" + +class Merge: public tbb::filter +{ + public: + Merge(): filter(tbb::filter::parallel) {} + void* operator()(void*); +}; + +#endif /* !MERGE_HH_ */ diff --git a/src/filterSample/reverse.cc b/src/filterSample/reverse.cc new file mode 100644 index 0000000..22f2024 --- /dev/null +++ b/src/filterSample/reverse.cc @@ -0,0 +1,20 @@ +#include "reverse.hh" + +#include "opencv2/opencv.hpp" + +void* Reverse::operator()(void* para) +{ + cv::Mat* mat = (cv::Mat*)para; + + if (mat == nullptr) + return nullptr; + + for (auto it = mat->begin(); it != mat->end(); ++it) + { + (*it)[0] = ~(*it)[0]; + (*it)[1] = ~(*it)[1]; + (*it)[2] = ~(*it)[2]; + } + + return mat; +} diff --git a/src/filterSample/reverse.hh b/src/filterSample/reverse.hh new file mode 100644 index 0000000..22eeab9 --- /dev/null +++ b/src/filterSample/reverse.hh @@ -0,0 +1,13 @@ +#ifndef REVERSE_HH_ +# define REVERSE_HH_ + +# include "tbb/pipeline.h" + +class Reverse: public tbb::filter +{ + public: + Reverse(): filter(tbb::filter::parallel) {} + void* operator()(void*); +}; + +#endif /* !REVERSE_HH_ */ diff --git a/src/main.cc b/src/main.cc index b0ebdff..f3491de 100644 --- a/src/main.cc +++ b/src/main.cc @@ -95,12 +95,17 @@ int main (int argc, char** argv) return 1; VideoReader vr(conf.input.front()); + auto it = conf.input.begin(); + it++; VideoWriter vw = VideoWriter(); vw.open(conf.output, conf.codec, vr.fps_get(), vr.width_get(), vr.height_get()); - Pipeline pipe(std::list { vr }, vw); + Pipeline pipe(std::list { vr, VideoReader(*it) }, vw); // add filters here - pipe.add_filter("grey"); + //pipe.add_filter("grey"); + //pipe.add_filter("reverse"); + //pipe.add_filter("interlace"); + //pipe.add_filter("merge"); pipe.run(); return 0; diff --git a/src/pipeline.cc b/src/pipeline.cc index 28c05d1..1313acd 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -1,18 +1,38 @@ #include "tbb/pipeline.h" #include "pipeline.hh" +#include "compose.hh" #include "filterSample/grey.hh" +#include "filterSample/reverse.hh" +#include "filterSample/merge.hh" +#include "filterSample/interlace.hh" Pipeline::Pipeline(std::list input, VideoWriter output) : input_(input), output_(output) { + this->input_it_ = this->input_.begin(); this->pipeline_.add_filter(this->input_.front()); + this->input_it_++; } bool Pipeline::add_filter(std::string filter) { if (filter == "grey" || filter == "gray") this->pipeline_.add_filter(*(new Grey())); + else if (filter == "reverse" || filter == "inverse") + this->pipeline_.add_filter(*(new Reverse())); + else if (filter == "merge" && this->input_it_ != this->input_.end()) + { + this->pipeline_.add_filter(*(new Compose(*this->input_it_))); + this->input_it_++; + this->pipeline_.add_filter(*(new Merge())); + } + else if (filter == "interlace" && this->input_it_ != this->input_.end()) + { + this->pipeline_.add_filter(*(new Compose(*this->input_it_))); + this->input_it_++; + this->pipeline_.add_filter(*(new Interlace())); + } else return false; @@ -21,13 +41,6 @@ bool Pipeline::add_filter(std::string filter) void Pipeline::run() { - int minframe = this->input_.front().framecount_get(); - for (auto it = this->input_.begin(); it != this->input_.end(); ++it) - if (minframe > it->framecount_get()) - minframe = it->framecount_get(); - for (auto it = this->input_.begin(); it != this->input_.end(); ++it) - it->maxframe_set(minframe); - this->pipeline_.add_filter(this->output_); this->pipeline_.run(CHUNK_SIZE); } diff --git a/src/pipeline.hh b/src/pipeline.hh index c4e94da..4e9047c 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -20,6 +20,7 @@ class Pipeline private: std::list> filters_; std::list input_; + std::list::const_iterator input_it_; VideoWriter output_; tbb::pipeline pipeline_; };