diff --git a/Makefile.am b/Makefile.am index 31f486b..79961b2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ prpa_LDADD = \ lib/libfilterSample.a \ lib/libencoder.a -prpa_SOURCES = src/main.cc src/configuration.cc +prpa_SOURCES = src/main.cc src/configuration.cc src/pipeline.cc prpa_LDFLAGS = \ $(BOOST_LDFLAGS) \ diff --git a/src/encoder/video_reader.cc b/src/encoder/video_reader.cc index c7840bf..80f3616 100644 --- a/src/encoder/video_reader.cc +++ b/src/encoder/video_reader.cc @@ -1,19 +1,43 @@ #include "video_reader.hh" -VideoReader::VideoReader(std::string filename) - : capture_(filename) +VideoReader::VideoReader(const VideoReader& vr) + : filter(tbb::filter::serial_in_order) +{ + this->capture_ = vr.capture_; + this->maxframe_ = vr.maxframe_; + this->current_ = vr.current_; +} + +void* VideoReader::operator()(void* ign) +{ + (void)ign; + + if (this->capture_.grab() && this->current_ < this->maxframe_) + { + this->current_++; + cv::Mat retrieved; + cv::Mat* res = new cv::Mat; + this->capture_.retrieve(retrieved); + *res = retrieved.clone(); + return res; + } + else + { + return nullptr; + } +} + +void VideoReader::maxframe_set(int limit) +{ + this->maxframe_ = limit; +} + +int VideoReader::framecount_get() { if (this->capture_.isOpened()) - { - while (this->capture_.grab()) - { - cv::Mat retrieved; - cv::Mat* mat = new cv::Mat(); - this->capture_.retrieve(retrieved); - *mat = retrieved.clone(); - this->images_.push_back(mat); - } - } + return (int)this->capture_.get(CV_CAP_PROP_FRAME_COUNT); + else + return -1; } int VideoReader::fps_get() diff --git a/src/encoder/video_reader.hh b/src/encoder/video_reader.hh index 6513c25..9899643 100644 --- a/src/encoder/video_reader.hh +++ b/src/encoder/video_reader.hh @@ -2,17 +2,25 @@ # define VIDEO_READER_HH_ # include +# include "tbb/pipeline.h" # include "video.hh" -class VideoReader: public Video +class VideoReader: public tbb::filter { public: - VideoReader(std::string filename); + VideoReader(const VideoReader& vr); + VideoReader(std::string filename) : filter(tbb::filter::serial_in_order), + capture_(filename), current_(0) {} + 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_; }; #endif /* !VIDEO_READER_HH_ */ diff --git a/src/encoder/video_writer.cc b/src/encoder/video_writer.cc index 4f82e08..1e62853 100644 --- a/src/encoder/video_writer.cc +++ b/src/encoder/video_writer.cc @@ -1,5 +1,11 @@ #include "video_writer.hh" +VideoWriter::VideoWriter(const VideoWriter& vw) + : filter(tbb::filter::serial_in_order) +{ + this->writer_ = vw.writer_; +} + bool VideoWriter::open(std::string filename, std::string enc, int fps, int width, int height) { @@ -10,11 +16,12 @@ bool VideoWriter::open(std::string filename, std::string enc, CV_FOURCC(enc[0], enc[1], enc[2], enc[3]), fps, { width, height } ); } -void VideoWriter::write() +void* VideoWriter::operator()(void* para) { + cv::Mat* mat = (cv::Mat*)para; if (this->writer_.isOpened()) - { - for (auto it = this->images_.begin(); it != this->images_.end(); ++it) - this->writer_.write(**it); - } + this->writer_.write(*mat); + + delete mat; + return nullptr; } diff --git a/src/encoder/video_writer.hh b/src/encoder/video_writer.hh index 0692d6f..dc9cf2d 100644 --- a/src/encoder/video_writer.hh +++ b/src/encoder/video_writer.hh @@ -2,12 +2,15 @@ # define VIDEO_WRITER_HH_ # include +# include "tbb/pipeline.h" # include "video.hh" -class VideoWriter: public Video +class VideoWriter: public tbb::filter { public: - void write(); + VideoWriter() : filter(tbb::filter::serial_in_order) {} + VideoWriter(const VideoWriter&); + void* operator()(void* mat); bool open(std::string filename, std::string enc, int fps, int width, int height); private: diff --git a/src/main.cc b/src/main.cc index 5b2f3d6..df87518 100644 --- a/src/main.cc +++ b/src/main.cc @@ -2,8 +2,10 @@ #include #include #include +#include "tbb/task_scheduler_init.h" #include "configuration.hh" +#include "pipeline.hh" #include "encoder/video.hh" #include "encoder/video_reader.hh" @@ -87,6 +89,7 @@ bool parse_cli(Configuration& conf, int argc, char** argv) int main (int argc, char** argv) { + tbb::task_scheduler_init init; Configuration conf = Configuration(); if (!parse_cli(conf, argc, argv)) @@ -95,8 +98,10 @@ int main (int argc, char** argv) VideoReader vr(conf.input.front()); VideoWriter vw = VideoWriter(); vw.open(conf.output, conf.codec, vr.fps_get(), vr.width_get(), vr.height_get()); - vw.copy(vr); - vw.write(); + + Pipeline pipe(std::list { vr }, vw); + // add filters + pipe.run(); return 0; } diff --git a/src/pipeline.cc b/src/pipeline.cc new file mode 100644 index 0000000..ec6e943 --- /dev/null +++ b/src/pipeline.cc @@ -0,0 +1,23 @@ +#include "tbb/pipeline.h" + +#include "pipeline.hh" + +bool Pipeline::add_filter(std::string filter) +{ + return true; +} + +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->input_.front()); + this->pipeline_.add_filter(this->output_); + + this->pipeline_.run(CHUNK_SIZE); +} diff --git a/src/pipeline.hh b/src/pipeline.hh new file mode 100644 index 0000000..9f11ba7 --- /dev/null +++ b/src/pipeline.hh @@ -0,0 +1,28 @@ +#ifndef PIPELINE_HH_ +# define PIPELINE_HH_ + +# include +# include "opencv2/opencv.hpp" +# include "tbb/pipeline.h" + +# include "encoder/video.hh" +# include "encoder/video_reader.hh" +# include "encoder/video_writer.hh" + +# define CHUNK_SIZE 16 + +class Pipeline +{ + public: + Pipeline(std::list input, VideoWriter output) + : input_(input), output_(output) {} + bool add_filter(std::string filter); + void run(); + private: + std::list> filters_; + std::list input_; + VideoWriter output_; + tbb::pipeline pipeline_; +}; + +#endif /* !PIPELINE_HH_ */