diff --git a/bmf/c_modules/include/fraction.hpp b/bmf/c_modules/include/fraction.hpp index 9f93653f..59d7e0b5 100644 --- a/bmf/c_modules/include/fraction.hpp +++ b/bmf/c_modules/include/fraction.hpp @@ -21,345 +21,340 @@ namespace Fraction { - class Fraction { - public: - Fraction() { - neg_ = false; - den_ = 0; - base_ = 1; +class Fraction { + public: + Fraction() { + neg_ = false; + den_ = 0; + base_ = 1; + } + + Fraction(std::string const &frac) { + neg_ = false; + den_ = 0; + base_ = 1; + if (frac.empty()) { + return; } + int64_t a = -1, b = 1; + size_t i = 0; + std::string tmp = ""; - Fraction(std::string const &frac) { - neg_ = false; - den_ = 0; - base_ = 1; - if (frac.empty()) { - return; - } - int64_t a = -1, b = 1; - size_t i = 0; - std::string tmp = ""; - - if (frac[0] == '-') { - neg_ = true; - ++i; - } - - while (i < frac.length()) { - if (frac[i] == '/') { - if (a >= 0) - throw std::logic_error("Wrong fraction provided."); - a = std::stol(tmp); - tmp = ""; - } else { - tmp += frac[i]; - } - ++i; - } - if (!tmp.empty()) - b = std::stol(tmp); - if (a < 0 || b <= 0) - throw std::logic_error("Wrong fraction provided."); - - den_ = a, base_ = b; - - simplify(); + if (frac[0] == '-') { + neg_ = true; + ++i; } - Fraction(int32_t den, int32_t base) { - neg_ = false; - den_ = den, base_ = base; - if (den < 0) { - den_ = -den_; - neg_ = !neg_; - } - if (base < 0) { - base = -base_; - neg_ = !neg_; + while (i < frac.length()) { + if (frac[i] == '/') { + if (a >= 0) + throw std::logic_error("Wrong fraction provided."); + a = std::stol(tmp); + tmp = ""; + } else { + tmp += frac[i]; } - if (base == 0) - throw std::logic_error("Wrong fraction provided."); + ++i; + } + if (!tmp.empty()) + b = std::stol(tmp); + if (a < 0 || b <= 0) + throw std::logic_error("Wrong fraction provided."); + + den_ = a, base_ = b; + + simplify(); + } + + Fraction(int32_t den, int32_t base) { + neg_ = false; + den_ = den, base_ = base; + if (den < 0) { + den_ = -den_; + neg_ = !neg_; + } + if (base < 0) { + base = -base_; + neg_ = !neg_; + } + if (base == 0) + throw std::logic_error("Wrong fraction provided."); + + simplify(); + } + + void simplify() { + auto gcd_ = gcd(den_, base_); + den_ /= gcd_, base_ /= gcd_; + neg_ = den_ == 0 ? false : neg_; + return; + } + + bool operator==(Fraction const &rhs) { + return neg_ == rhs.neg_ && den_ == rhs.den_ && base_ == rhs.base_; + } + + bool operator>(Fraction const &rhs) { + if (neg_ != rhs.neg_) + return rhs.neg_; + return !(*this - rhs).neg(); + } + + bool operator<(Fraction const &rhs) { + if (neg_ != rhs.neg_) + return neg_; + return (*this - rhs).neg(); + } - simplify(); - } + Fraction &operator*=(Fraction const &rhs) { + neg_ = (neg_ != rhs.neg_); + /* + * a1/b1 * a2/b2 + * a1 gcd b1 == 1 && a2 gcd b2 == 1 + * (a1*a2) gcd (b1*b2) == (a1 gcd b2)*(a2 gcd b1) + */ + auto den_gcd = gcd(rhs.den_, base_); + auto base_gcd = gcd(rhs.base_, den_); + den_ = (den_ / base_gcd) * (rhs.den_ / den_gcd); + base_ = (base_ / den_gcd) * (rhs.base_ / base_gcd); + + return *this; + } + + Fraction &operator*=(int32_t rhs) { + if (rhs < 0) { + rhs = -rhs; + neg_ = !neg_; + } + auto gcd_ = gcd(base_, rhs); + base_ /= gcd_; + den_ *= (rhs / gcd_); + + return *this; + } + + Fraction operator*(Fraction const &rhs) { + Fraction res = *this; + return res *= rhs; + } + + Fraction operator*(int32_t rhs) { + Fraction res = *this; + return res *= rhs; + } + + Fraction &operator/=(Fraction const &rhs) { + neg_ = (neg_ != rhs.neg_); + /* + * (a1/b1) / (a2/b2) == (a1/b1) * (b2/a2); + */ + auto den_gcd = gcd(rhs.den_, den_); + auto base_gcd = gcd(rhs.base_, base_); + den_ = (den_ / den_gcd) * (rhs.base_ / base_gcd); + base_ = (base_ / base_gcd) * (rhs.den_ / den_gcd); - void simplify() { - auto gcd_ = gcd(den_, base_); - den_ /= gcd_, base_ /= gcd_; - neg_ = den_ == 0 ? false : neg_; - return; - } + return *this; + } - bool operator==(Fraction const &rhs) { - return neg_ == rhs.neg_ && den_ == rhs.den_ && base_ == rhs.base_; + Fraction &operator/=(int32_t rhs) { + if (rhs < 0) { + rhs = -rhs; + neg_ = !neg_; } + auto gcd_ = gcd(den_, rhs); + den_ /= gcd_; + base_ *= (rhs / gcd_); - bool operator>(Fraction const &rhs) { - if (neg_ != rhs.neg_) - return rhs.neg_; - return !(*this - rhs).neg(); - } + return *this; + } - bool operator<(Fraction const &rhs) { - if (neg_ != rhs.neg_) - return neg_; - return (*this - rhs).neg(); - } + Fraction operator/(Fraction const &rhs) { + Fraction res = *this; + return res /= rhs; + } - Fraction &operator*=(Fraction const &rhs) { - neg_ = (neg_ != rhs.neg_); - /* - * a1/b1 * a2/b2 - * a1 gcd b1 == 1 && a2 gcd b2 == 1 - * (a1*a2) gcd (b1*b2) == (a1 gcd b2)*(a2 gcd b1) - */ - auto den_gcd = gcd(rhs.den_, base_); - auto base_gcd = gcd(rhs.base_, den_); - den_ = (den_ / base_gcd) * (rhs.den_ / den_gcd); - base_ = (base_ / den_gcd) * (rhs.base_ / base_gcd); - - return *this; - } + Fraction operator/(int32_t rhs) { + Fraction res = *this; + return res /= rhs; + } - Fraction &operator*=(int32_t rhs) { - if (rhs < 0) { - rhs = -rhs; + Fraction &operator+=(Fraction const &rhs) { + /* + * (a1/b1) + (a2/b2) == (a1*b2 + a2*b1)/(b1*b2) + * Cannot be simplified by preprocess. + */ + if (neg_ != rhs.neg_) { + auto a = den_ * rhs.base_, b = rhs.den_ * base_; + den_ = a > b ? a - b : b - a; + if (a < b) neg_ = !neg_; - } - auto gcd_ = gcd(base_, rhs); - base_ /= gcd_; - den_ *= (rhs / gcd_); - - return *this; + } else { + den_ = den_ * rhs.base_ + rhs.den_ * base_; } - Fraction operator*(Fraction const &rhs) { - Fraction res = *this; - return res *= rhs; - } + base_ *= rhs.base_; - Fraction operator*(int32_t rhs) { - Fraction res = *this; - return res *= rhs; - } + simplify(); + return *this; + } - Fraction &operator/=(Fraction const &rhs) { - neg_ = (neg_ != rhs.neg_); - /* - * (a1/b1) / (a2/b2) == (a1/b1) * (b2/a2); - */ - auto den_gcd = gcd(rhs.den_, den_); - auto base_gcd = gcd(rhs.base_, base_); - den_ = (den_ / den_gcd) * (rhs.base_ / base_gcd); - base_ = (base_ / base_gcd) * (rhs.den_ / den_gcd); - - return *this; + Fraction &operator+=(int32_t rhs) { + /* + * Cannot be simpler. + */ + bool neg = rhs < 0; + rhs = rhs < 0 ? -rhs : rhs; + auto den = rhs * base_; + if (neg_ != neg) { + // Equal to {neg_ = den_ > den ? neg_ : !neg_;} + neg_ = den_ > den == neg_; + den_ = den_ > den ? den_ - den : den - den_; + } else { + den_ += den; + } + if (den_ == 0) { + neg_ = false; + base_ = 1; } - - Fraction &operator/=(int32_t rhs) { - if (rhs < 0) { - rhs = -rhs; + return *this; + } + + Fraction operator+(Fraction const &rhs) { + Fraction res = *this; + return res += rhs; + } + + Fraction operator+(int32_t rhs) { + Fraction res = *this; + return res += rhs; + } + + /* + * +(a/b) = a/b + * +(- a/b) = a/b + */ + Fraction operator+() { + Fraction res = *this; + res.neg_ = false; + return res; + } + + Fraction &operator-=(Fraction const &rhs) { + /* + * a - b == a + (-b) + */ + if (neg_ == rhs.neg_) { + auto a = den_ * rhs.base_, b = rhs.den_ * base_; + den_ = a > b ? a - b : b - a; + if (a < b) neg_ = !neg_; - } - auto gcd_ = gcd(den_, rhs); - den_ /= gcd_; - base_ *= (rhs / gcd_); - - return *this; - } - - Fraction operator/(Fraction const &rhs) { - Fraction res = *this; - return res /= rhs; - } - - Fraction operator/(int32_t rhs) { - Fraction res = *this; - return res /= rhs; - } - - Fraction &operator+=(Fraction const &rhs) { - /* - * (a1/b1) + (a2/b2) == (a1*b2 + a2*b1)/(b1*b2) - * Cannot be simplified by preprocess. - */ - if (neg_ != rhs.neg_) { - auto a = den_ * rhs.base_, b = rhs.den_ * base_; - den_ = a > b ? a - b : b - a; - if (a < b) - neg_ = !neg_; - } else { - den_ = den_ * rhs.base_ + rhs.den_ * base_; - } - - base_ *= rhs.base_; - - simplify(); - return *this; + } else { + den_ = den_ * rhs.base_ + rhs.den_ * base_; } - Fraction &operator+=(int32_t rhs) { - /* - * Cannot be simpler. - */ - bool neg = rhs < 0; - rhs = rhs < 0 ? -rhs : rhs; - auto den = rhs * base_; - if (neg_ != neg) { - // Equal to {neg_ = den_ > den ? neg_ : !neg_;} - neg_ = den_ > den == neg_; - den_ = den_ > den ? den_ - den : den - den_; - } else { - den_ += den; - } - if (den_ == 0) { - neg_ = false; - base_ = 1; - } - return *this; - } + base_ *= rhs.base_; - Fraction operator+(Fraction const &rhs) { - Fraction res = *this; - return res += rhs; - } - - Fraction operator+(int32_t rhs) { - Fraction res = *this; - return res += rhs; - } + simplify(); + return *this; + } + Fraction &operator-=(int32_t rhs) { /* - * +(a/b) = a/b - * +(- a/b) = a/b + * a - b == a + (-b) + * Cannot be simpler. */ - Fraction operator+() { - Fraction res = *this; - res.neg_ = false; - return res; + bool neg = rhs < 0; + rhs = rhs < 0 ? -rhs : rhs; + auto den = rhs * base_; + if (neg_ == neg) { + // Equal to {neg_ = den_ > den ? neg_ : !neg_;} + neg_ = den_ > den == neg_; + den_ = den_ > den ? den_ - den : den - den_; + } else { + den_ += den; + } + if (den_ == 0) { + neg_ = false; + base_ = 1; } + return *this; + } - Fraction &operator-=(Fraction const &rhs) { - /* - * a - b == a + (-b) - */ - if (neg_ == rhs.neg_) { - auto a = den_ * rhs.base_, b = rhs.den_ * base_; - den_ = a > b ? a - b : b - a; - if (a < b) - neg_ = !neg_; - } else { - den_ = den_ * rhs.base_ + rhs.den_ * base_; - } + Fraction operator-(Fraction const &rhs) { + Fraction res = *this; + return res -= rhs; + } - base_ *= rhs.base_; + Fraction operator-(int32_t rhs) { + Fraction res = *this; + return res -= rhs; + } - simplify(); - return *this; - } + /* + * -(a/b) = (- a/b) + * -(- a/b) = a/b + */ + Fraction operator-() { + Fraction res = *this; + res.neg_ = !neg_; + return res; + } - Fraction &operator-=(int32_t rhs) { - /* - * a - b == a + (-b) - * Cannot be simpler. - */ - bool neg = rhs < 0; - rhs = rhs < 0 ? -rhs : rhs; - auto den = rhs * base_; - if (neg_ == neg) { - // Equal to {neg_ = den_ > den ? neg_ : !neg_;} - neg_ = den_ > den == neg_; - den_ = den_ > den ? den_ - den : den - den_; - } else { - den_ += den; - } - if (den_ == 0) { - neg_ = false; - base_ = 1; - } - return *this; - } + uint64_t &den() { return den_; } - Fraction operator-(Fraction const &rhs) { - Fraction res = *this; - return res -= rhs; - } + uint64_t &base() { return base_; } - Fraction operator-(int32_t rhs) { - Fraction res = *this; - return res -= rhs; - } + bool &neg() { return neg_; } + Fraction to_based(Fraction const &base) { /* - * -(a/b) = (- a/b) - * -(- a/b) = a/b + * Equal to (this/base). */ - Fraction operator-() { - Fraction res = *this; - res.neg_ = !neg_; - return res; - } - - uint64_t &den() { - return den_; - } - - uint64_t &base() { - return base_; - } - - bool &neg() { - return neg_; - } - - Fraction to_based(Fraction const &base) { - /* - * Equal to (this/base). - */ - auto res = *this; - res /= base; - return res; - } - - int64_t to_int() { - return neg_ ? -int64_t(den_ / base_) : int64_t(den_ / base_); - } + auto res = *this; + res /= base; + return res; + } - int64_t to_int_based(Fraction const &base) { - /* - * Equal to uint64_t(this/base). - */ - auto res = *this; - res /= base; - return res.to_int(); - } + int64_t to_int() { + return neg_ ? -int64_t(den_ / base_) : int64_t(den_ / base_); + } - double_t to_double() { - return neg_ ? -(double_t(den_) / double_t(base_)) : double_t(den_) / double_t(base_); - } + int64_t to_int_based(Fraction const &base) { + /* + * Equal to uint64_t(this/base). + */ + auto res = *this; + res /= base; + return res.to_int(); + } - double_t to_double_based(Fraction const &base) { - /* - * Equal to double_t(this/base). - */ - auto res = *this; - res /= base; - return res.to_double(); - } + double_t to_double() { + return neg_ ? -(double_t(den_) / double_t(base_)) + : double_t(den_) / double_t(base_); + } - uint64_t den_, base_; - bool neg_; - - private: - uint64_t gcd(uint64_t x, uint64_t y) { - if (x < y) - x ^= y, y ^= x, x ^= y; - uint64_t t; - while (y) - t = y, y = x % y, x = t; - return x; - } - }; + double_t to_double_based(Fraction const &base) { + /* + * Equal to double_t(this/base). + */ + auto res = *this; + res /= base; + return res.to_double(); + } + + uint64_t den_, base_; + bool neg_; + + private: + uint64_t gcd(uint64_t x, uint64_t y) { + if (x < y) + x ^= y, y ^= x, x ^= y; + uint64_t t; + while (y) + t = y, y = x % y, x = t; + return x; + } +}; } -#endif //CLOCK_MODULE_FRACTION_HPP +#endif // CLOCK_MODULE_FRACTION_HPP diff --git a/bmf/c_modules/src/audio_fifo.cpp b/bmf/c_modules/src/audio_fifo.cpp index 708471df..e66083b9 100644 --- a/bmf/c_modules/src/audio_fifo.cpp +++ b/bmf/c_modules/src/audio_fifo.cpp @@ -14,10 +14,11 @@ #include "audio_fifo.h" -AudioFifo::AudioFifo(int format, int channels, uint64_t channel_layout, AVRational time_base, int sample_rate) { +AudioFifo::AudioFifo(int format, int channels, uint64_t channel_layout, + AVRational time_base, int sample_rate) { format_ = format; channels_ = channels; - audio_fifo_ = av_audio_fifo_alloc((AVSampleFormat) format, channels, 2048); + audio_fifo_ = av_audio_fifo_alloc((AVSampleFormat)format, channels, 2048); time_base_ = time_base; channel_layout_ = channel_layout; sample_rate_ = sample_rate; @@ -26,7 +27,8 @@ AudioFifo::AudioFifo(int format, int channels, uint64_t channel_layout, AVRation BMFLOG(BMF_ERROR) << "Could not allocate audio_fifo_"; } -int AudioFifo::read(int samples, bool partial, bool &got_frame, AVFrame *&frame) { +int AudioFifo::read(int samples, bool partial, bool &got_frame, + AVFrame *&frame) { int ret; got_frame = false; int buffered_samples = av_audio_fifo_size(audio_fifo_); @@ -49,7 +51,8 @@ int AudioFifo::read(int samples, bool partial, bool &got_frame, AVFrame *&frame) BMFLOG(BMF_ERROR) << "Error allocating an audio buffer"; return ret; } - int read_samples = av_audio_fifo_read(audio_fifo_, (void **) (frame->extended_data), samples); + int read_samples = av_audio_fifo_read( + audio_fifo_, (void **)(frame->extended_data), samples); if (read_samples < 0) { BMFLOG(BMF_ERROR) << "av_audio_fifo_read " << read_samples; return read_samples; @@ -57,7 +60,7 @@ int AudioFifo::read(int samples, bool partial, bool &got_frame, AVFrame *&frame) got_frame = true; frame->nb_samples = read_samples; if (first_pts_ != AV_NOPTS_VALUE) { - frame->pts = (int64_t) (pts_per_sample_ * samples_read_) + first_pts_; + frame->pts = (int64_t)(pts_per_sample_ * samples_read_) + first_pts_; } else { frame->pts = AV_NOPTS_VALUE; } @@ -65,7 +68,8 @@ int AudioFifo::read(int samples, bool partial, bool &got_frame, AVFrame *&frame) return 0; } -int AudioFifo::read_many(int samples, bool partial, std::vector &frame_list) { +int AudioFifo::read_many(int samples, bool partial, + std::vector &frame_list) { while (1) { AVFrame *frame = NULL; frame = av_frame_alloc(); @@ -93,7 +97,8 @@ int AudioFifo::write(AVFrame *frame) { first_pts_ = frame->pts; first_frame_ = false; } - ret = av_audio_fifo_write(audio_fifo_, (void **) (frame->extended_data), frame->nb_samples); + ret = av_audio_fifo_write(audio_fifo_, (void **)(frame->extended_data), + frame->nb_samples); return ret; } diff --git a/bmf/c_modules/src/audio_resampler.cpp b/bmf/c_modules/src/audio_resampler.cpp index 8b21239f..6f0ab294 100644 --- a/bmf/c_modules/src/audio_resampler.cpp +++ b/bmf/c_modules/src/audio_resampler.cpp @@ -13,8 +13,11 @@ */ #include "audio_resampler.h" -AudioResampler::AudioResampler(int input_format, int output_format, int input_channel_layout, int output_channel_layout, - int input_sample_rate, int output_sample_rate, AVRational input_time_base, +AudioResampler::AudioResampler(int input_format, int output_format, + int input_channel_layout, + int output_channel_layout, int input_sample_rate, + int output_sample_rate, + AVRational input_time_base, AVRational output_time_base) { int ret; input_format_ = input_format; @@ -36,7 +39,7 @@ AudioResampler::AudioResampler(int input_format, int output_format, int input_ch av_opt_set_int(swr_ctx_, "in_sample_rate", input_sample_rate, 0); av_opt_set_int(swr_ctx_, "out_sample_rate", output_sample_rate, 0); ret = swr_init(swr_ctx_); - ratio_ = (double) output_sample_rate / input_sample_rate; + ratio_ = (double)output_sample_rate / input_sample_rate; if (ret < 0) BMFLOG(BMF_ERROR) << "init swr failed:" << ret; return; @@ -72,35 +75,41 @@ int AudioResampler::resample(AVFrame *insamples, AVFrame *&outsamples) { return 0; } - // get output samples pts if (insamples) { if (insamples->pts != AV_NOPTS_VALUE && input_time_base_.num != -1) { - //translate pts to timestamps which is in 1/(in_sample_rate * out_sample_rate) units. - int64_t inpts = av_rescale(insamples->pts, input_time_base_.num * - output_sample_rate_ * insamples->sample_rate, - input_time_base_.den); - // get outpts whose timestamps is 1/(in_sample_rate * out_sample_rate) + // translate pts to timestamps which is in 1/(in_sample_rate * + // out_sample_rate) units. + int64_t inpts = av_rescale( + insamples->pts, input_time_base_.num * output_sample_rate_ * + insamples->sample_rate, + input_time_base_.den); + // get outpts whose timestamps is 1/(in_sample_rate * + // out_sample_rate) int64_t outpts = swr_next_pts(swr_ctx_, inpts); // translate pts to timestamps is output_time_base; - outsamples->pts = av_rescale(outpts, output_time_base_.den, - output_time_base_.num * output_sample_rate_ * insamples->sample_rate); + outsamples->pts = + av_rescale(outpts, output_time_base_.den, + output_time_base_.num * output_sample_rate_ * + insamples->sample_rate); } else { outsamples->pts = AV_NOPTS_VALUE; } } else { int64_t outpts = swr_next_pts(swr_ctx_, INT64_MIN); - outsamples->pts = av_rescale(outpts, output_time_base_.den, - output_time_base_.num * output_sample_rate_ * input_sample_rate_); + outsamples->pts = av_rescale( + outpts, output_time_base_.den, + output_time_base_.num * output_sample_rate_ * input_sample_rate_); } uint8_t **input_data = NULL; if (insamples != NULL) { - input_data = (uint8_t **) insamples->extended_data; + input_data = (uint8_t **)insamples->extended_data; } - n_out = swr_convert(swr_ctx_, outsamples->extended_data, n_out, (const uint8_t**)input_data, n_in); + n_out = swr_convert(swr_ctx_, outsamples->extended_data, n_out, + (const uint8_t **)input_data, n_in); if (n_out <= 0) { return n_out; } diff --git a/bmf/c_modules/src/clock_module.cpp b/bmf/c_modules/src/clock_module.cpp index c3f16dac..3dd812c5 100644 --- a/bmf/c_modules/src/clock_module.cpp +++ b/bmf/c_modules/src/clock_module.cpp @@ -1,6 +1,5 @@ #include "../include/clock_module.h" - #include #include @@ -32,7 +31,8 @@ ClockModule::ClockModule(int node_id, JsonParam option) { int ClockModule::process(Task &task) { auto now = std::chrono::high_resolution_clock::now(); - if (lst_ts_.time_since_epoch() == std::chrono::high_resolution_clock::duration::zero()) { + if (lst_ts_.time_since_epoch() == + std::chrono::high_resolution_clock::duration::zero()) { lst_ts_ = now; } else if (now - lst_ts_ < tick_) { // Can be 10us quicker, in order to decrease delay. @@ -43,14 +43,13 @@ int ClockModule::process(Task &task) { lst_ts_ += tick_; Packet pkt(0); - pkt.set_timestamp((fps_tick_ * frm_cnt_++).to_int_based(time_base_) * 1000000); - //pkt.set_timestamp((fps_tick_ * frm_cnt_++).to_int_based(time_base_)); + pkt.set_timestamp((fps_tick_ * frm_cnt_++).to_int_based(time_base_) * + 1000000); + // pkt.set_timestamp((fps_tick_ * frm_cnt_++).to_int_based(time_base_)); task.fill_output_packet(0, pkt); return 0; } -bool ClockModule::is_hungry(int input_stream_id) { - return true; -} +bool ClockModule::is_hungry(int input_stream_id) { return true; } REGISTER_MODULE_CLASS(ClockModule) diff --git a/bmf/c_modules/src/ffmpeg_decoder.cpp b/bmf/c_modules/src/ffmpeg_decoder.cpp index c8afae0e..8e60e6a8 100644 --- a/bmf/c_modules/src/ffmpeg_decoder.cpp +++ b/bmf/c_modules/src/ffmpeg_decoder.cpp @@ -28,7 +28,7 @@ #include using json = nlohmann::json; -#define BMF_CONV_FP(x) ((double) (x)) / (1 << 16) +#define BMF_CONV_FP(x) ((double)(x)) / (1 << 16) USE_BMF_SDK_NS @@ -49,7 +49,7 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { video_frame_count_ = 0; audio_frame_count_ = 0; refcount_ = 1; - + encrypted_ = false; audio_end_ = false; video_end_ = false; @@ -58,20 +58,21 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { last_pts_ = AV_NOPTS_VALUE; curr_pts_ = 0; last_ts_ = AV_NOPTS_VALUE; - //duration_ = 0; + // duration_ = 0; idx_dur_ = -1; dur_end_[0] = false; dur_end_[1] = false; end_audio_time_ = LLONG_MAX; end_video_time_ = LLONG_MAX; - fps_ = 25;//default when there's no correct framerate + fps_ = 25; // default when there's no correct framerate ist_[0] = ist_[1] = {0}; ist_[0].max_pts = ist_[1].max_pts = INT64_MIN; ist_[0].min_pts = ist_[1].min_pts = INT64_MAX; ist_[0].max_frames = ist_[1].max_frames = INT64_MAX; ist_[0].decoding_needed = ist_[1].decoding_needed = true; - ist_[0].filter_in_rescale_delta_last = ist_[1].filter_in_rescale_delta_last = AV_NOPTS_VALUE; + ist_[0].filter_in_rescale_delta_last = + ist_[1].filter_in_rescale_delta_last = AV_NOPTS_VALUE; stream_copy_av_stream_flag_[0] = false; stream_copy_av_stream_flag_[1] = false; @@ -83,34 +84,39 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { /** @addtogroup DecM * @{ * @arg loglevel: to set the loglevel of ffmpeg library - * it can be "quiet","panic","fatal","error","warning","info","verbose","debug","trace" + * it can be + * "quiet","panic","fatal","error","warning","info","verbose","debug","trace" * @} */ if (option.has_key("loglevel")) { std::string log_level = ""; option.get_string("loglevel", log_level); if (!LogBuffer::avlog_cb_set()) { av_log_set_level(LogBuffer::infer_level(log_level)); - BMFLOG_NODE(BMF_INFO, node_id_) << "decode setting log level to: " << log_level; + BMFLOG_NODE(BMF_INFO, node_id_) << "decode setting log level to: " + << log_level; } } /** @addtogroup DecM * @{ - * @arg map_v: video stream index for decoder, exp. 0, which mean choose No.0 stream as video stream to be decode. + * @arg map_v: video stream index for decoder, exp. 0, which mean choose + * No.0 stream as video stream to be decode. * @} */ if (option.has_key("map_v")) option.get_int("map_v", video_stream_index_); /** @addtogroup DecM * @{ - * @arg map_a: audio stream index for decoder, exp. 1, which mean choose No.1 stream as audio stream to be decode. + * @arg map_a: audio stream index for decoder, exp. 1, which mean choose + * No.1 stream as audio stream to be decode. * @} */ if (option.has_key("map_a")) option.get_int("map_a", audio_stream_index_); /** @addtogroup DecM * @{ - * @arg start_time: decode start time in seconds, exp. 1, which mean just decode the frame after 1 second, similar as -ss in ffmpeg command. + * @arg start_time: decode start time in seconds, exp. 1, which mean just + * decode the frame after 1 second, similar as -ss in ffmpeg command. * @} */ if (option.has_key("start_time")) { double opt; @@ -119,28 +125,32 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { } /** @addtogroup DecM * @{ - * @arg end_time: decode end time, exp. 1, which mean just decode the frame before 1 second, just as -to in ffmpeg command. + * @arg end_time: decode end time, exp. 1, which mean just decode the frame + * before 1 second, just as -to in ffmpeg command. * @} */ if (option.has_key("end_time")) { double opt; option.get_double("end_time", opt); end_time_ = (int64_t)(opt * AV_TIME_BASE); if (!option.has_key("copyts") && option.has_key("start_time")) - end_time_ -= start_time_; //the pts will be offset by the start time + end_time_ -= start_time_; // the pts will be offset by the start + // time } - + /** @addtogroup DecM * @{ - * @arg durations: decode multiple group of duration frames/samples, such as [1.1, 4, 6.5, 9, 12.3, 15]. + * @arg durations: decode multiple group of duration frames/samples, such as + * [1.1, 4, 6.5, 9, 12.3, 15]. * @} */ if (option.has_key("durations")) { option.get_double_list("durations", durations_); if (durations_.size() > 0 && durations_.size() % 2 == 0) { auto min = durations_[0]; bool is_valid = true; - for(auto it:durations_) { + for (auto it : durations_) { if (it < min) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "The durations are incorrect"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "The durations are incorrect"; is_valid = false; break; } @@ -148,14 +158,16 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { } if (is_valid) { idx_dur_ = 0; - //to prepare the first start time which overwrite start_time param + // to prepare the first start time which overwrite start_time + // param start_time_ = (int64_t)(durations_[0] * AV_TIME_BASE); end_time_ = 0; } } else - BMFLOG_NODE(BMF_ERROR, node_id_) << "The durations timestamp number should be even"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "The durations timestamp number should be even"; - for(auto it:durations_) { + for (auto it : durations_) { BMFLOG_NODE(BMF_DEBUG, node_id_) << "durations " << it; } } @@ -166,33 +178,37 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { * @} */ if (option.has_key("fps")) option.get_int("fps", fps_); - + /** @addtogroup DecM * @{ - * @arg video_time_base: video stream time base, exp. 1/1000, set the video stream timebase as 1/1000. + * @arg video_time_base: video stream time base, exp. 1/1000, set the video + * stream timebase as 1/1000. * @} */ if (option.has_key("video_time_base")) option.get_string("video_time_base", video_time_base_string_); - + /** @addtogroup DecM * @{ - * @arg skip_frame: skip frame, exp. 32, make decoder discard processing depending on the option value, just as -skip_frame in ffmpeg commnad. - * AVDISCARD_NONE = -16, ///< discard nothing - * AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi - * AVDISCARD_NONREF = 8, ///< discard all non reference - * AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames - * AVDISCARD_NONINTRA= 24, ///< discard all non intra frames - * AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + * @arg skip_frame: skip frame, exp. 32, make decoder discard processing + * depending on the option value, just as -skip_frame in ffmpeg commnad. + * AVDISCARD_NONE = -16, ///< discard nothing + * AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets + * in avi + * AVDISCARD_NONREF = 8, ///< discard all non reference + * AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + * AVDISCARD_NONINTRA= 24, ///< discard all non intra frames + * AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes * AVDISCARD_ALL = 48, ///< discard all * @} */ if (option.has_key("skip_frame")) { int tmp; option.get_int("skip_frame", tmp); - skip_frame_ = (enum AVDiscard) tmp; + skip_frame_ = (enum AVDiscard)tmp; } /** @addtogroup DecM * @{ - * @arg video_codec: video codec name, exp. libx264, set the specific codec for video stream. + * @arg video_codec: video codec name, exp. libx264, set the specific codec + * for video stream. * it will be stream copy when it set to be "copy" * @} */ if (option.has_key("video_codec")) { @@ -203,12 +219,14 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { else video_codec_name_ = tmp; } - + /** @addtogroup DecM * @{ - * @arg overlap_time, which is used in decode live stream, if the live stream cut off, - * if the next packet pts is overlap smaller than overlap time, we will remove the overlap packet. - * default value is 10 + * @arg overlap_time, which is used in decode live stream, if the live + * stream cut off, + * if the next packet pts is overlap smaller than overlap time, we will + * remove the overlap packet. + * default value is 10 * @} */ if (option.has_key("overlap_time")) { double tmp; @@ -217,12 +235,14 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { } else { overlap_time_ = AV_TIME_BASE * 10; } - + /** @addtogroup DecM * @{ - * @arg cut_off_time, which is used in decode live stream ,if the live stream cut off, - * when the next packet pts is larger than last pts + cut_off_time, we will adjust pts to avoid large cut off. - * else we use the packet pts. + * @arg cut_off_time, which is used in decode live stream ,if the live + * stream cut off, + * when the next packet pts is larger than last pts + cut_off_time, we will + * adjust pts to avoid large cut off. + * else we use the packet pts. * @} */ if (option.has_key("cut_off_time")) { double tmp; @@ -234,9 +254,11 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { /** @addtogroup DecM * @{ - * @arg cut_off_interval.which is used in decode live stream ,if the live stream cut off, - * when the next packet pts is larger than last pts + cut_off_time, we will adjust pts to avoid large cut off. - * else we use the packet pts. + * @arg cut_off_interval.which is used in decode live stream ,if the live + * stream cut off, + * when the next packet pts is larger than last pts + cut_off_time, we will + * adjust pts to avoid large cut off. + * else we use the packet pts. * @} */ if (option.has_key("cut_off_interval")) { double tmp; @@ -269,14 +291,17 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { /** @addtogroup DecM * @{ - * @arg max_width_height: set the max width or height limitation of input frame. Once it's - * enabled, frame will be dropped by default or it will throw exp according to "limit_hits" + * @arg max_width_height: set the max width or height limitation of input + * frame. Once it's + * enabled, frame will be dropped by default or it will throw exp according + * to "limit_hits" * @} */ if (option.has_key("max_width_height")) option.get_int("max_width_height", max_wh_); /** @addtogroup DecM * @{ - * @arg max_limit_hits: set the max number of limit hits, once exceeded the exp will be threw + * @arg max_limit_hits: set the max number of limit hits, once exceeded the + * exp will be threw * @} */ if (option.has_key("max_limit_hits")) option.get_int("max_limit_hits", max_limit_hits_); @@ -302,14 +327,16 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { extract_frames_params.get_double("fps", extract_frames_fps_); } if (extract_frames_params.has_key("device")) { - extract_frames_params.get_string("device",extract_frames_device_); + extract_frames_params.get_string("device", + extract_frames_device_); } } } /** @addtogroup DecM * @{ - * @arg audio_codec: audio codec name, exp. aac, set the specific codec for audio stream. + * @arg audio_codec: audio codec name, exp. aac, set the specific codec for + * audio stream. * @} */ if (option.has_key("audio_codec")) { std::string tmp; @@ -330,7 +357,8 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { std::vector> params; dec_params_.get_iterated(params); for (int i = 0; i < params.size(); i++) { - av_dict_set(&opts, params[i].first.c_str(), params[i].second.c_str(), 0); + av_dict_set(&opts, params[i].first.c_str(), + params[i].second.c_str(), 0); } } if (option.has_key("decryption_key")) { @@ -343,7 +371,8 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { /** @addtogroup DecM * @{ - * @arg autorotate: to enable/disable autorotate for the input video if needed, it's enabled by default + * @arg autorotate: to enable/disable autorotate for the input video if + * needed, it's enabled by default * @} */ if (option.has_key("autorotate")) { int autorotate = 1; @@ -400,12 +429,19 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { if (option.has_key("push_raw_stream")) { option.get_int("push_raw_stream", push_raw_stream_); if (push_raw_stream_) { - if (!option.has_key("video_codec") && !option.has_key("audio_codec")) - throw std::runtime_error("Push raw stream requires either 'video_codec' or 'video_codec' in option"); - if (option.has_key("video_codec") && !option.has_key("video_time_base")) - throw std::runtime_error("Missing 'video_time_base' in decoder option"); - if (option.has_key("audio_codec") && (!option.has_key("channels") || !option.has_key("sample_rate"))) - throw std::runtime_error("Missing 'channels' or 'sample_rate' in decoder option"); + if (!option.has_key("video_codec") && + !option.has_key("audio_codec")) + throw std::runtime_error("Push raw stream requires either " + "'video_codec' or 'video_codec' in " + "option"); + if (option.has_key("video_codec") && + !option.has_key("video_time_base")) + throw std::runtime_error( + "Missing 'video_time_base' in decoder option"); + if (option.has_key("audio_codec") && + (!option.has_key("channels") || !option.has_key("sample_rate"))) + throw std::runtime_error( + "Missing 'channels' or 'sample_rate' in decoder option"); } } else { push_raw_stream_ = 0; @@ -427,14 +463,16 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { /** @addtogroup DecM * @{ - * @arg sample_fmt: audio sample format (used for audio push mode - optional) + * @arg sample_fmt: audio sample format (used for audio push mode - + * optional) * @} */ if (option.has_key("sample_fmt")) option.get_int("sample_fmt", push_audio_sample_fmt_); /** @addtogroup DecM * @{ - * @arg orig_pts_time: keep the original pts time of inputstream in the frame + * @arg orig_pts_time: keep the original pts time of inputstream in the + * frame * @} */ if (option.has_key("orig_pts_time")) option.get_int("orig_pts_time", orig_pts_time_); @@ -445,14 +483,15 @@ CFFDecoder::CFFDecoder(int node_id, JsonParam option) { CFFDecoder::~CFFDecoder() { std::lock_guard lock(mutex_); clean(); - BMFLOG_NODE(BMF_INFO, node_id_) << "video frame decoded:" << ist_[0].frame_decoded; - BMFLOG_NODE(BMF_INFO, node_id_) << "audio frame decoded:" << ist_[1].frame_decoded - << ", sample decoded:" << ist_[1].sample_decoded; + BMFLOG_NODE(BMF_INFO, node_id_) << "video frame decoded:" + << ist_[0].frame_decoded; + BMFLOG_NODE(BMF_INFO, node_id_) + << "audio frame decoded:" << ist_[1].frame_decoded + << ", sample decoded:" << ist_[1].sample_decoded; } +int copy_simple_frame(AVFrame *frame) { -int copy_simple_frame(AVFrame* frame) { - AVFrame tmp; int ret; @@ -460,12 +499,12 @@ int copy_simple_frame(AVFrame* frame) { return AVERROR(EINVAL); memset(&tmp, 0, sizeof(tmp)); - tmp.format = frame->format; - tmp.width = frame->width; - tmp.height = frame->height; - tmp.channels = frame->channels; + tmp.format = frame->format; + tmp.width = frame->width; + tmp.height = frame->height; + tmp.channels = frame->channels; tmp.channel_layout = frame->channel_layout; - tmp.nb_samples = frame->nb_samples; + tmp.nb_samples = frame->nb_samples; if (frame->hw_frames_ctx) ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); @@ -473,13 +512,14 @@ int copy_simple_frame(AVFrame* frame) { ret = av_frame_get_buffer(&tmp, 0); if (ret < 0) return ret; - //need to reset frame info for which the av_hwframe_get_buffer may change the width or height according to the hw_frames_ctx. - tmp.format = frame->format; - tmp.width = frame->width; - tmp.height = frame->height; - tmp.channels = frame->channels; + // need to reset frame info for which the av_hwframe_get_buffer may change + // the width or height according to the hw_frames_ctx. + tmp.format = frame->format; + tmp.width = frame->width; + tmp.height = frame->height; + tmp.channels = frame->channels; tmp.channel_layout = frame->channel_layout; - tmp.nb_samples = frame->nb_samples; + tmp.nb_samples = frame->nb_samples; ret = av_frame_copy(&tmp, frame); if (ret < 0) { @@ -502,17 +542,19 @@ int copy_simple_frame(AVFrame* frame) { } #ifdef BMF_USE_MEDIACODEC -int CFFDecoder::init_android_vm(){ +int CFFDecoder::init_android_vm() { static JavaVM *vm = NULL; static JNIEnv *env = NULL; BMFLOG_NODE(BMF_INFO, node_id_) << "vm = " << vm << "env = " << env; if (vm) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Java VM has been inited ever before!"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Java VM has been inited ever before!"; return 0; } int status = init_jvm(&vm, &env); if (status != 0) { - BMFLOG_NODE(BMF_WARNING, node_id_) << "Initialization failure (" << status << ":" << dlerror(); + BMFLOG_NODE(BMF_WARNING, node_id_) << "Initialization failure (" + << status << ":" << dlerror(); return -1; } av_jni_set_java_vm(vm, 0); @@ -521,8 +563,8 @@ int CFFDecoder::init_android_vm(){ #endif -int CFFDecoder::codec_context(int *stream_idx, - AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type) { +int CFFDecoder::codec_context(int *stream_idx, AVCodecContext **dec_ctx, + AVFormatContext *fmt_ctx, enum AVMediaType type) { int ret, stream_index; AVStream *st; AVCodec *dec = NULL; @@ -532,8 +574,8 @@ int CFFDecoder::codec_context(int *stream_idx, ret = av_find_best_stream(fmt_ctx, type, *stream_idx, -1, NULL, 0); if (ret < 0) { BMFLOG_NODE(BMF_ERROR, node_id_) - << "Could not find " << av_get_media_type_string(type) - << " stream in input file '" << input_path_.c_str() << "'"; + << "Could not find " << av_get_media_type_string(type) + << " stream in input file '" << input_path_.c_str() << "'"; return ret; } else { stream_index = ret; @@ -555,23 +597,25 @@ int CFFDecoder::codec_context(int *stream_idx, } } if (!dec) { - BMFLOG_NODE(BMF_ERROR, node_id_) - << "Failed to find " << av_get_media_type_string(type) << " codec"; + BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to find " + << av_get_media_type_string(type) + << " codec"; return AVERROR(EINVAL); } *dec_ctx = avcodec_alloc_context3(dec); if (!*dec_ctx) { - BMFLOG_NODE(BMF_ERROR, node_id_) - << "Failed to allocate the " << av_get_media_type_string(type) << " codec context"; + BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to allocate the " + << av_get_media_type_string(type) + << " codec context"; return AVERROR(ENOMEM); } // Copy codec parameters from input stream to output codec context if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) { BMFLOG_NODE(BMF_ERROR, node_id_) - << "Failed to copy " << av_get_media_type_string(type) - << " codec parameters to decoder context"; + << "Failed to copy " << av_get_media_type_string(type) + << " codec parameters to decoder context"; return ret; } (*dec_ctx)->pkt_timebase = st->time_base; @@ -586,20 +630,26 @@ int CFFDecoder::codec_context(int *stream_idx, if (hwaccel_str_ == "cuda" && type == AVMEDIA_TYPE_VIDEO) { if (hwaccel_check_ == 0) { - av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 1); + av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), + AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 1); } else { if ((*dec_ctx)->has_b_frames < 2) - av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 1); + av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), + AV_HWDEVICE_TYPE_CUDA, NULL, NULL, + 1); } - } - #ifdef BMF_USE_MEDIACODEC + } +#ifdef BMF_USE_MEDIACODEC if (hwaccel_str_ == "mediacodec" && type == AVMEDIA_TYPE_VIDEO) { init_android_vm(); - av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), AV_HWDEVICE_TYPE_MEDIACODEC, NULL, NULL, 1); + av_hwdevice_ctx_create(&((*dec_ctx)->hw_device_ctx), + AV_HWDEVICE_TYPE_MEDIACODEC, NULL, NULL, 1); } - #endif +#endif if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to open " << av_get_media_type_string(type) << " codec"; + BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to open " + << av_get_media_type_string(type) + << " codec"; return ret; } *stream_idx = stream_index; @@ -616,20 +666,22 @@ int CFFDecoder::init_filtergraph(int index, AVFrame *frame) { double current_duration = 0; if (copy_ts_) { - //tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time; //input file start time not supported - //if (!start_at_zero && + // tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time; + // //input file start time not supported + // if (!start_at_zero && if (input_fmt_ctx_->start_time != AV_NOPTS_VALUE) ts_offset += input_fmt_ctx_->start_time; } if (durations_.size() > 0) { current_duration = (durations_[idx_dur_ + 1] - durations_[idx_dur_]); if (idx_dur_ > 0) { - ts_offset = durations_[idx_dur_] + (double)(ts_offset_) / AV_TIME_BASE; + ts_offset = + durations_[idx_dur_] + (double)(ts_offset_) / AV_TIME_BASE; printf("ts offset for trim: %f\n", ts_offset); } } - if (start_time_ != AV_NOPTS_VALUE) {//accurate seek by default + if (start_time_ != AV_NOPTS_VALUE) { // accurate seek by default if (index == 0) graph_descr += "trim=starti=" + std::to_string(ts_offset); else if (index == 1) @@ -665,9 +717,11 @@ int CFFDecoder::init_filtergraph(int index, AVFrame *frame) { fg_config.format = frame->format; fg_config.sample_aspect_ratio = frame->sample_aspect_ratio; fg_config.tb = video_stream_->time_base; - AVRational frame_rate = av_guess_frame_rate(input_fmt_ctx_, video_stream_, NULL); + AVRational frame_rate = + av_guess_frame_rate(input_fmt_ctx_, video_stream_, NULL); if (frame->hw_frames_ctx) { - filter_graph_[index]->hw_frames_ctx_map_[0] = av_buffer_ref(frame->hw_frames_ctx); + filter_graph_[index]->hw_frames_ctx_map_[0] = + av_buffer_ref(frame->hw_frames_ctx); } if (frame_rate.num > 0 && frame_rate.den > 0) fg_config.frame_rate = frame_rate; @@ -687,19 +741,20 @@ int CFFDecoder::get_rotate_desc(std::string &filter_desc) { if (video_stream_ == NULL) { return 0; } - uint8_t *displaymatrix = av_stream_get_side_data(video_stream_, - AV_PKT_DATA_DISPLAYMATRIX, NULL); + uint8_t *displaymatrix = + av_stream_get_side_data(video_stream_, AV_PKT_DATA_DISPLAYMATRIX, NULL); double theta = 0; if (displaymatrix) { double rotation, scale[2]; - int32_t *matrix = (int32_t *) displaymatrix; + int32_t *matrix = (int32_t *)displaymatrix; scale[0] = hypot(BMF_CONV_FP(matrix[0]), BMF_CONV_FP(matrix[3])); scale[1] = hypot(BMF_CONV_FP(matrix[1]), BMF_CONV_FP(matrix[4])); if (scale[0] == 0.0 || scale[1] == 0.0) { theta = 0; } else { theta = atan2(BMF_CONV_FP(matrix[1]) / scale[1], - BMF_CONV_FP(matrix[0]) / scale[0]) * 180 / M_PI; + BMF_CONV_FP(matrix[0]) / scale[0]) * + 180 / M_PI; } } @@ -730,7 +785,8 @@ int CFFDecoder::init_input(AVDictionary *options) { BMF_Error(BMF_TranscodeError, msg.c_str()); } } else { - ret = avformat_open_input(&input_fmt_ctx_, input_path_.c_str(), NULL, &options); + ret = avformat_open_input(&input_fmt_ctx_, input_path_.c_str(), NULL, + &options); if (ret < 0) { std::string msg = "avformat_open_input failed: " + error_msg(ret); BMF_Error(BMF_TranscodeError, msg.c_str()); @@ -738,7 +794,8 @@ int CFFDecoder::init_input(AVDictionary *options) { } if ((ret = avformat_find_stream_info(input_fmt_ctx_, NULL)) < 0) { if (ret < 0) { - std::string msg = "avformat_find_stream_info failed: " + error_msg(ret); + std::string msg = + "avformat_find_stream_info failed: " + error_msg(ret); BMF_Error(BMF_TranscodeError, msg.c_str()); } } @@ -751,7 +808,8 @@ int CFFDecoder::init_input(AVDictionary *options) { if (!(input_fmt_ctx_->iformat->flags & AVFMT_SEEK_TO_PTS)) { int dts_heuristic = 0; for (int i = 0; i < input_fmt_ctx_->nb_streams; i++) { - const AVCodecParameters *par = input_fmt_ctx_->streams[i]->codecpar; + const AVCodecParameters *par = + input_fmt_ctx_->streams[i]->codecpar; if (par->video_delay) { dts_heuristic = 1; break; @@ -764,16 +822,19 @@ int CFFDecoder::init_input(AVDictionary *options) { ret = avformat_seek_file(input_fmt_ctx_, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0); if (ret < 0) { - av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n", + av_log(NULL, AV_LOG_WARNING, + "%s: could not seek to position %0.3f\n", input_path_.c_str(), (double)timestamp / AV_TIME_BASE); } } ts_offset_ = copy_ts_ ? 0 : -timestamp; - if (codec_context(&video_stream_index_, &video_decode_ctx_, input_fmt_ctx_, AVMEDIA_TYPE_VIDEO) >= 0) { + if (codec_context(&video_stream_index_, &video_decode_ctx_, input_fmt_ctx_, + AVMEDIA_TYPE_VIDEO) >= 0) { video_stream_ = input_fmt_ctx_->streams[video_stream_index_]; if (end_time_ > 0 && !encrypted_) { - end_video_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, video_stream_->time_base); + end_video_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, + video_stream_->time_base); } video_decode_ctx_->skip_frame = skip_frame_; if (max_wh_) { @@ -787,10 +848,12 @@ int CFFDecoder::init_input(AVDictionary *options) { ist_[0].next_dts = AV_NOPTS_VALUE; ist_[0].next_pts = AV_NOPTS_VALUE; - if (codec_context(&audio_stream_index_, &audio_decode_ctx_, input_fmt_ctx_, AVMEDIA_TYPE_AUDIO) >= 0) { + if (codec_context(&audio_stream_index_, &audio_decode_ctx_, input_fmt_ctx_, + AVMEDIA_TYPE_AUDIO) >= 0) { audio_stream_ = input_fmt_ctx_->streams[audio_stream_index_]; if (end_time_ > 0 && !encrypted_) { - end_audio_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, audio_stream_->time_base); + end_audio_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, + audio_stream_->time_base); } } ist_[1].next_dts = AV_NOPTS_VALUE; @@ -799,28 +862,30 @@ int CFFDecoder::init_input(AVDictionary *options) { if (!LogBuffer::avlog_cb_set()) av_dump_format(input_fmt_ctx_, 0, input_path_.c_str(), 0); if (!audio_stream_ && !video_stream_) { - BMF_Error(BMF_TranscodeError, "Could not find audio or video stream in the input"); + BMF_Error(BMF_TranscodeError, + "Could not find audio or video stream in the input"); } return 0; } -Packet CFFDecoder::generate_video_packet(AVFrame *frame) -{ +Packet CFFDecoder::generate_video_packet(AVFrame *frame) { AVRational out_tb; AVRational orig_tb; int64_t orig_pts; if (filter_graph_[0]) - out_tb = av_buffersink_get_time_base(filter_graph_[0]->buffer_sink_ctx_[0]); + out_tb = + av_buffersink_get_time_base(filter_graph_[0]->buffer_sink_ctx_[0]); else if (video_stream_) out_tb = video_stream_->time_base; - if (!push_raw_stream_) { - std::string s_tb = std::to_string(out_tb.num) + "," + std::to_string(out_tb.den); + std::string s_tb = + std::to_string(out_tb.num) + "," + std::to_string(out_tb.den); av_dict_set(&frame->metadata, "time_base", s_tb.c_str(), 0); } else - av_dict_set(&frame->metadata, "time_base", video_time_base_string_.c_str(), 0); + av_dict_set(&frame->metadata, "time_base", + video_time_base_string_.c_str(), 0); if (orig_pts_time_) { if (!push_raw_stream_) @@ -834,7 +899,8 @@ Packet CFFDecoder::generate_video_packet(AVFrame *frame) } if (start_time_ != AV_NOPTS_VALUE && !copy_ts_) - orig_pts = frame->pts + av_rescale_q(start_time_, AV_TIME_BASE_Q, video_stream_->time_base); + orig_pts = frame->pts + av_rescale_q(start_time_, AV_TIME_BASE_Q, + video_stream_->time_base); else orig_pts = frame->pts; @@ -846,12 +912,14 @@ Packet CFFDecoder::generate_video_packet(AVFrame *frame) AVRational frame_rate; if (filter_graph_[0]) - frame_rate = av_buffersink_get_frame_rate(filter_graph_[0]->buffer_sink_ctx_[0]); + frame_rate = + av_buffersink_get_frame_rate(filter_graph_[0]->buffer_sink_ctx_[0]); else if (video_stream_) frame_rate = av_guess_frame_rate(input_fmt_ctx_, video_stream_, NULL); std::string s_fr; if (frame_rate.num && frame_rate.den) - s_fr = std::to_string(frame_rate.num) + "," + std::to_string(frame_rate.den); + s_fr = std::to_string(frame_rate.num) + "," + + std::to_string(frame_rate.den); else s_fr = "0,1"; av_dict_set(&frame->metadata, "frame_rate", s_fr.c_str(), 0); @@ -866,27 +934,30 @@ Packet CFFDecoder::generate_video_packet(AVFrame *frame) } std::string stream_node_id_str = std::to_string(node_id_); - av_dict_set(&frame->metadata, "stream_node_id", stream_node_id_str.c_str(), 0); + av_dict_set(&frame->metadata, "stream_node_id", stream_node_id_str.c_str(), + 0); stream_frame_number_++; std::string stream_frame_number_str = std::to_string(stream_frame_number_); - av_dict_set(&frame->metadata, "stream_frame_number", stream_frame_number_str.c_str(), 0); + av_dict_set(&frame->metadata, "stream_frame_number", + stream_frame_number_str.c_str(), 0); auto video_frame = ffmpeg::to_video_frame(frame, true); video_frame.set_pts(frame->pts); - if(!push_raw_stream_){ + if (!push_raw_stream_) { video_frame.set_time_base(Rational(out_tb.num, out_tb.den)); + } else { + video_frame.set_time_base( + Rational(video_time_base_.num, video_time_base_.den)); } - else{ - video_frame.set_time_base(Rational(video_time_base_.num, video_time_base_.den)); - } - + auto packet = Packet(video_frame); if (orig_pts_time_) { packet.set_time(orig_pts * av_q2d(orig_tb)); } if (!push_raw_stream_) - packet.set_timestamp(frame->pts * av_q2d(video_stream_->time_base) * 1000000); + packet.set_timestamp(frame->pts * av_q2d(video_stream_->time_base) * + 1000000); else packet.set_timestamp(frame->pts * av_q2d(video_time_base_) * 1000000); @@ -894,22 +965,25 @@ Packet CFFDecoder::generate_video_packet(AVFrame *frame) return packet; } -Packet CFFDecoder::generate_audio_packet(AVFrame *frame) -{ +Packet CFFDecoder::generate_audio_packet(AVFrame *frame) { AVRational out_tb; if (!push_raw_stream_ && filter_graph_[1]) - out_tb = av_buffersink_get_time_base(filter_graph_[1]->buffer_sink_ctx_[0]); + out_tb = + av_buffersink_get_time_base(filter_graph_[1]->buffer_sink_ctx_[0]); else out_tb = (AVRational){1, audio_decode_ctx_->sample_rate}; - std::string s_tb = std::to_string(out_tb.num) + "," + std::to_string(out_tb.den); + std::string s_tb = + std::to_string(out_tb.num) + "," + std::to_string(out_tb.den); av_dict_set(&frame->metadata, "time_base", s_tb.c_str(), 0); std::string stream_node_id_str = std::to_string(node_id_); - av_dict_set(&frame->metadata, "stream_node_id", stream_node_id_str.c_str(), 0); + av_dict_set(&frame->metadata, "stream_node_id", stream_node_id_str.c_str(), + 0); stream_frame_number_++; std::string stream_frame_number_str = std::to_string(stream_frame_number_); - av_dict_set(&frame->metadata, "stream_frame_number", stream_frame_number_str.c_str(), 0); + av_dict_set(&frame->metadata, "stream_frame_number", + stream_frame_number_str.c_str(), 0); auto audio_frame = ffmpeg::to_audio_frame(frame, true); audio_frame.set_time_base(Rational(out_tb.num, out_tb.den)); @@ -922,8 +996,8 @@ Packet CFFDecoder::generate_audio_packet(AVFrame *frame) return packet; } -static int hwaccel_retrieve_data(AVFrame *input, enum AVPixelFormat output_format) -{ +static int hwaccel_retrieve_data(AVFrame *input, + enum AVPixelFormat output_format) { AVFrame *output = NULL; int err; if (input->format == output_format) { @@ -959,36 +1033,47 @@ static int hwaccel_retrieve_data(AVFrame *input, enum AVPixelFormat output_forma return err; } -int CFFDecoder::extract_frames(AVFrame *frame,std::vector &output_frames) { +int CFFDecoder::extract_frames(AVFrame *frame, + std::vector &output_frames) { AVRational frame_rate; if (filter_graph_[0]) - frame_rate = av_buffersink_get_frame_rate(filter_graph_[0]->buffer_sink_ctx_[0]); + frame_rate = + av_buffersink_get_frame_rate(filter_graph_[0]->buffer_sink_ctx_[0]); else if (video_stream_) frame_rate = av_guess_frame_rate(input_fmt_ctx_, video_stream_, NULL); // std::vector output_frames; if (extract_frames_fps_ != 0) { - std::string extract_frames_fps_str = std::to_string(extract_frames_fps_); + std::string extract_frames_fps_str = + std::to_string(extract_frames_fps_); AVRational video_frame_rate; av_parse_video_rate(&video_frame_rate, extract_frames_fps_str.c_str()); - AVRational temp_time_base = {video_frame_rate.den, video_frame_rate.num}; + AVRational temp_time_base = {video_frame_rate.den, + video_frame_rate.num}; if (video_sync_ == NULL) { - video_sync_ = std::make_shared(video_stream_->time_base, temp_time_base, - frame_rate, video_frame_rate, video_stream_->start_time, video_stream_->first_dts, VSYNC_VFR, 0); + video_sync_ = std::make_shared( + video_stream_->time_base, temp_time_base, frame_rate, + video_frame_rate, video_stream_->start_time, + video_stream_->first_dts, VSYNC_VFR, 0); } - video_sync_->process_video_frame(frame, output_frames, ist_[0].frame_number); + video_sync_->process_video_frame(frame, output_frames, + ist_[0].frame_number); av_frame_free(&frame); - for (int i =0;ipts = av_rescale_q(output_frames[i]->pts,temp_time_base,video_stream_->time_base); + for (int i = 0; i < output_frames.size(); i++) { + output_frames[i]->pts = + av_rescale_q(output_frames[i]->pts, temp_time_base, + video_stream_->time_base); } } else output_frames.push_back(frame); - for (int i =0; ihw_frames_ctx) { enum AVPixelFormat output_pix_fmt; - AVHWFramesContext* hw_frame_ctx = (AVHWFramesContext*)(output_frames[i]->hw_frames_ctx->data); + AVHWFramesContext *hw_frame_ctx = + (AVHWFramesContext *)(output_frames[i] + ->hw_frames_ctx->data); output_pix_fmt = hw_frame_ctx->sw_format; hwaccel_retrieve_data(output_frames[i], output_pix_fmt); } @@ -1006,7 +1091,8 @@ int CFFDecoder::extract_frames(AVFrame *frame,std::vector &output_fram return 0; } -int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eof, bool repeat, int got_output) { +int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, + bool eof, bool repeat, int got_output) { AVFrame *frame; int64_t best_effort_timestamp; int64_t duration_dts = 0; @@ -1018,7 +1104,8 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo index == 0 ? video_end_ = true : audio_end_ = true; Packet packet = Packet::generate_eof_packet(); assert(packet.timestamp() == BMF_EOF); - if (task.get_outputs().find(index) != task.get_outputs().end() && file_list_.size() == 0) + if (task.get_outputs().find(index) != task.get_outputs().end() && + file_list_.size() == 0) task.get_outputs()[index]->push(packet); push_data_flag_ = true; @@ -1031,22 +1118,27 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo best_effort_timestamp = decoded_frm_->best_effort_timestamp; duration_pts = decoded_frm_->pkt_duration; - //if (ist->framerate.num) // force the fps + // if (ist->framerate.num) // force the fps // best_effort_timestamp = ist->cfr_next_pts++; - if (pkt && pkt->size == 0 && best_effort_timestamp == AV_NOPTS_VALUE && ist->nb_dts_buffer > 0) { + if (pkt && pkt->size == 0 && + best_effort_timestamp == AV_NOPTS_VALUE && + ist->nb_dts_buffer > 0) { best_effort_timestamp = ist->dts_buffer[0]; - BMFLOG_NODE(BMF_INFO, node_id_) << "nb_dts_buffer was used when eof of decode for best_effort_timestamp:" - << best_effort_timestamp; + BMFLOG_NODE(BMF_INFO, node_id_) + << "nb_dts_buffer was used when eof of decode for " + "best_effort_timestamp:" + << best_effort_timestamp; for (int i = 0; i < ist->nb_dts_buffer - 1; i++) ist->dts_buffer[i] = ist->dts_buffer[i + 1]; ist->nb_dts_buffer--; } if (stream && best_effort_timestamp != AV_NOPTS_VALUE) { - int64_t ts = av_rescale_q(decoded_frm_->pts = best_effort_timestamp, - stream->time_base, AV_TIME_BASE_Q); + int64_t ts = + av_rescale_q(decoded_frm_->pts = best_effort_timestamp, + stream->time_base, AV_TIME_BASE_Q); if (ts != AV_NOPTS_VALUE) ist->next_pts = ist->pts = ts; @@ -1055,12 +1147,18 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo if (!repeat || !pkt || (pkt && pkt->size == 0) || got_output) { if (stream && pkt && pkt->size != 0 && pkt->duration) { - duration_dts = av_rescale_q(pkt->duration, stream->time_base, AV_TIME_BASE_Q); - } else if (stream && video_decode_ctx_->framerate.num != 0 && video_decode_ctx_->framerate.den != 0) { - int ticks= av_stream_get_parser(stream) ? av_stream_get_parser(stream)->repeat_pict+1 : video_decode_ctx_->ticks_per_frame; + duration_dts = av_rescale_q( + pkt->duration, stream->time_base, AV_TIME_BASE_Q); + } else if (stream && video_decode_ctx_->framerate.num != 0 && + video_decode_ctx_->framerate.den != 0) { + int ticks = + av_stream_get_parser(stream) + ? av_stream_get_parser(stream)->repeat_pict + 1 + : video_decode_ctx_->ticks_per_frame; duration_dts = ((int64_t)AV_TIME_BASE * video_decode_ctx_->framerate.den * ticks) / - video_decode_ctx_->framerate.num / video_decode_ctx_->ticks_per_frame; + video_decode_ctx_->framerate.num / + video_decode_ctx_->ticks_per_frame; } if (ist->dts != AV_NOPTS_VALUE && duration_dts) { @@ -1071,7 +1169,8 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo if (got_output) { if (duration_pts > 0) { - ist->next_pts += av_rescale_q(duration_pts, stream->time_base, AV_TIME_BASE_Q); + ist->next_pts += av_rescale_q( + duration_pts, stream->time_base, AV_TIME_BASE_Q); } else { ist->next_pts += duration_dts; } @@ -1080,26 +1179,29 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo } else { AVRational decoded_frame_tb; if (got_output) { - ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frm_->nb_samples) / - audio_decode_ctx_->sample_rate; - ist->next_dts += ((int64_t)AV_TIME_BASE * decoded_frm_->nb_samples) / - audio_decode_ctx_->sample_rate; + ist->next_pts += + ((int64_t)AV_TIME_BASE * decoded_frm_->nb_samples) / + audio_decode_ctx_->sample_rate; + ist->next_dts += + ((int64_t)AV_TIME_BASE * decoded_frm_->nb_samples) / + audio_decode_ctx_->sample_rate; if (stream && decoded_frm_->pts != AV_NOPTS_VALUE) { - decoded_frame_tb = audio_stream_->time_base; + decoded_frame_tb = audio_stream_->time_base; } else if (stream && pkt && pkt->pts != AV_NOPTS_VALUE) { decoded_frm_->pts = pkt->pts; - decoded_frame_tb = audio_stream_->time_base; + decoded_frame_tb = audio_stream_->time_base; } else { decoded_frm_->pts = ist->dts; - decoded_frame_tb = AV_TIME_BASE_Q; + decoded_frame_tb = AV_TIME_BASE_Q; } if (decoded_frm_->pts != AV_NOPTS_VALUE) - decoded_frm_->pts = av_rescale_delta(decoded_frame_tb, decoded_frm_->pts, - (AVRational){1, audio_decode_ctx_->sample_rate}, - decoded_frm_->nb_samples, - &ist->filter_in_rescale_delta_last, - (AVRational){1, audio_decode_ctx_->sample_rate}); + decoded_frm_->pts = av_rescale_delta( + decoded_frame_tb, decoded_frm_->pts, + (AVRational){1, audio_decode_ctx_->sample_rate}, + decoded_frm_->nb_samples, + &ist->filter_in_rescale_delta_last, + (AVRational){1, audio_decode_ctx_->sample_rate}); } else return 0; } @@ -1118,31 +1220,43 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo } if (filter_graph_[index]) { - int ret = filter_graph_[index]->get_filter_frame(frame, 0, 0, filter_frames); + int ret = filter_graph_[index]->get_filter_frame(frame, 0, 0, + filter_frames); if (durations_.size() > 0) { if (ret == AVERROR_EOF && dur_end_[index] == false) { - //a group of duration trimed finished, switch to another if exist + // a group of duration trimed finished, switch to another if + // exist dur_end_[index] = true; - if (((task.get_outputs().find(0) != task.get_outputs().end() ? dur_end_[0] : true) && - (task.get_outputs().find(1) != task.get_outputs().end() ? dur_end_[1] : true))) { + if (((task.get_outputs().find(0) != task.get_outputs().end() + ? dur_end_[0] + : true) && + (task.get_outputs().find(1) != task.get_outputs().end() + ? dur_end_[1] + : true))) { dur_end_[0] = dur_end_[1] = false; idx_dur_ += 2; if (idx_dur_ >= durations_.size()) { index == 0 ? video_end_ = true : audio_end_ = true; Packet packet = Packet::generate_eof_packet(); assert(packet.timestamp() == BMF_EOF); - if (task.get_outputs().find(index) != task.get_outputs().end() && file_list_.size() == 0) + if (task.get_outputs().find(index) != + task.get_outputs().end() && + file_list_.size() == 0) task.get_outputs()[index]->push(packet); } else { - int64_t timestamp = (int64_t)(durations_[idx_dur_] * AV_TIME_BASE); - int s_ret = avformat_seek_file(input_fmt_ctx_, -1, INT64_MIN, timestamp, timestamp, 0); + int64_t timestamp = + (int64_t)(durations_[idx_dur_] * AV_TIME_BASE); + int s_ret = avformat_seek_file(input_fmt_ctx_, -1, + INT64_MIN, timestamp, + timestamp, 0); if (s_ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << input_path_.c_str() - << "could not seek to position " - << (double)(timestamp / AV_TIME_BASE); + BMFLOG_NODE(BMF_ERROR, node_id_) + << input_path_.c_str() + << "could not seek to position " + << (double)(timestamp / AV_TIME_BASE); return s_ret; } - //clean the graph and make it to be reinit + // clean the graph and make it to be reinit for (int i = 0; i < 2; i++) { if (filter_graph_[i]) { delete filter_graph_[i]; @@ -1154,7 +1268,8 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo } } if (ret != 0 && ret != AVERROR_EOF) { - std::string err_msg = "Failed to inject frame into filter network, in decoder"; + std::string err_msg = + "Failed to inject frame into filter network, in decoder"; BMF_Error(BMF_TranscodeFatalError, err_msg.c_str()); } if (frame) @@ -1163,11 +1278,15 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo filter_frames.push_back(frame); if (index == 0) { - if (has_input_ && !push_raw_stream_) { //Special case: for server mode, the frame in different file will be continued + if (has_input_ && + !push_raw_stream_) { // Special case: for server mode, the frame + // in different file will be continued if (frame->pts == AV_NOPTS_VALUE || frame->pts == last_pts_) { AVRational default_tb = (AVRational){1, fps_}; last_pts_ = frame->pts; - frame->pts = curr_pts_ + av_rescale_q(1, default_tb, video_stream_->time_base); + frame->pts = + curr_pts_ + + av_rescale_q(1, default_tb, video_stream_->time_base); curr_pts_ = frame->pts; } else last_pts_ = frame->pts; @@ -1179,57 +1298,61 @@ int CFFDecoder::handle_output_data(Task &task, int index, AVPacket *pkt, bool eo } for (int i = 0; i < filter_frames.size(); i++) { - std::vector output_extract_frames; - extract_frames(filter_frames[i],output_extract_frames); - for(int j = 0; j < output_extract_frames.size(); j++) - { - Packet packet = generate_video_packet(output_extract_frames[j]); - if (task.get_outputs().find(index) != task.get_outputs().end()) + std::vector output_extract_frames; + extract_frames(filter_frames[i], output_extract_frames); + for (int j = 0; j < output_extract_frames.size(); j++) { + Packet packet = + generate_video_packet(output_extract_frames[j]); + if (task.get_outputs().find(index) != + task.get_outputs().end()) task.get_outputs()[index]->push(packet); - ist->frame_number++; + ist->frame_number++; } } } else { - for (int i = 0; i < filter_frames.size(); i++) { + for (int i = 0; i < filter_frames.size(); i++) { Packet packet = generate_audio_packet(filter_frames[i]); if (task.get_outputs().find(index) != task.get_outputs().end()) task.get_outputs()[index]->push(packet); - ist->frame_number++; + ist->frame_number++; } } } else { std::vector filter_frames; if (filter_graph_[index]) { - int ret = filter_graph_[index]->get_filter_frame(NULL, 0, 0, filter_frames); + int ret = filter_graph_[index]->get_filter_frame(NULL, 0, 0, + filter_frames); if (ret != 0 && ret != AVERROR_EOF) { - std::string err_msg = "Failed to inject frame into filter network, in decoder"; + std::string err_msg = + "Failed to inject frame into filter network, in decoder"; BMF_Error(BMF_TranscodeFatalError, err_msg.c_str()); } } for (int i = 0; i < filter_frames.size(); i++) { - std::vector output_extract_frames; + std::vector output_extract_frames; if (index == 0) { - extract_frames(filter_frames[i],output_extract_frames); - for (int j =0; jpush(packet); - ist->frame_number++; + extract_frames(filter_frames[i], output_extract_frames); + for (int j = 0; j < output_extract_frames.size(); j++) { + auto packet = + generate_video_packet(output_extract_frames[j]); + if (task.get_outputs().find(index) != + task.get_outputs().end()) + task.get_outputs()[index]->push(packet); + ist->frame_number++; } - } - else { + } else { auto packet = generate_audio_packet(filter_frames[i]); if (task.get_outputs().find(index) != task.get_outputs().end()) - task.get_outputs()[index]->push(packet); - ist->frame_number++; + task.get_outputs()[index]->push(packet); + ist->frame_number++; } } Packet packet = Packet::generate_eof_packet(); assert(packet.timestamp() == BMF_EOF); - if (task.get_outputs().find(index) != task.get_outputs().end() && file_list_.size() == 0) + if (task.get_outputs().find(index) != task.get_outputs().end() && + file_list_.size() == 0) task.get_outputs()[index]->push(packet); } push_data_flag_ = true; @@ -1245,43 +1368,54 @@ int CFFDecoder::pkt_ts(AVPacket *pkt, int index) { if (!pkt || (pkt && pkt->size == 0)) return 0; - if (!ist->wrap_correction_done && input_fmt_ctx_->start_time != AV_NOPTS_VALUE && + if (!ist->wrap_correction_done && + input_fmt_ctx_->start_time != AV_NOPTS_VALUE && stream->pts_wrap_bits < 64) { int64_t stime, stime2; - if (ist->next_dts == AV_NOPTS_VALUE - && ts_offset_ == -input_fmt_ctx_->start_time - && (input_fmt_ctx_->iformat->flags & AVFMT_TS_DISCONT)) { + if (ist->next_dts == AV_NOPTS_VALUE && + ts_offset_ == -input_fmt_ctx_->start_time && + (input_fmt_ctx_->iformat->flags & AVFMT_TS_DISCONT)) { int64_t new_start_time = INT64_MAX; for (int i = 0; i < input_fmt_ctx_->nb_streams; i++) { AVStream *st = input_fmt_ctx_->streams[i]; - if(st->discard == AVDISCARD_ALL || st->start_time == AV_NOPTS_VALUE) + if (st->discard == AVDISCARD_ALL || + st->start_time == AV_NOPTS_VALUE) continue; - new_start_time = FFMIN(new_start_time, - av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q)); + new_start_time = FFMIN( + new_start_time, av_rescale_q(st->start_time, st->time_base, + AV_TIME_BASE_Q)); } if (new_start_time > input_fmt_ctx_->start_time) { - BMFLOG_NODE(BMF_INFO, node_id_) << "Correcting start time by " - << new_start_time - input_fmt_ctx_->start_time; + BMFLOG_NODE(BMF_INFO, node_id_) + << "Correcting start time by " + << new_start_time - input_fmt_ctx_->start_time; ts_offset_ = -new_start_time; if (end_time_ > 0) { - end_video_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, - input_fmt_ctx_->streams[video_stream_index_]->time_base); - end_audio_time_ = av_rescale_q(end_time_, AV_TIME_BASE_Q, - input_fmt_ctx_->streams[audio_stream_index_]->time_base); + end_video_time_ = av_rescale_q( + end_time_, AV_TIME_BASE_Q, + input_fmt_ctx_->streams[video_stream_index_] + ->time_base); + end_audio_time_ = av_rescale_q( + end_time_, AV_TIME_BASE_Q, + input_fmt_ctx_->streams[audio_stream_index_] + ->time_base); } } } - stime = av_rescale_q(input_fmt_ctx_->start_time, AV_TIME_BASE_Q, stream->time_base); - stime2= stime + (1ULL<pts_wrap_bits); + stime = av_rescale_q(input_fmt_ctx_->start_time, AV_TIME_BASE_Q, + stream->time_base); + stime2 = stime + (1ULL << stream->pts_wrap_bits); ist->wrap_correction_done = 1; - if (stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(stream->pts_wrap_bits-1))) { - pkt->dts -= 1ULL<pts_wrap_bits; + if (stime2 > stime && pkt->dts != AV_NOPTS_VALUE && + pkt->dts > stime + (1LL << (stream->pts_wrap_bits - 1))) { + pkt->dts -= 1ULL << stream->pts_wrap_bits; ist->wrap_correction_done = 0; } - if (stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(stream->pts_wrap_bits-1))) { - pkt->pts -= 1ULL<pts_wrap_bits; + if (stime2 > stime && pkt->pts != AV_NOPTS_VALUE && + pkt->pts > stime + (1LL << (stream->pts_wrap_bits - 1))) { + pkt->pts -= 1ULL << stream->pts_wrap_bits; ist->wrap_correction_done = 0; } } @@ -1291,35 +1425,37 @@ int CFFDecoder::pkt_ts(AVPacket *pkt, int index) { if (pkt->pts != AV_NOPTS_VALUE) pkt->pts += av_rescale_q(ts_offset_, AV_TIME_BASE_Q, stream->time_base); - //if (pkt->pts != AV_NOPTS_VALUE) + // if (pkt->pts != AV_NOPTS_VALUE) // pkt->pts *= ist->ts_scale; - //if (pkt->dts != AV_NOPTS_VALUE) + // if (pkt->dts != AV_NOPTS_VALUE) // pkt->dts *= ist->ts_scale; float dts_delta_threshold = 10; - pkt_dts = av_rescale_q_rnd(pkt->dts, stream->time_base, - AV_TIME_BASE_Q, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); - if (pkt_dts != AV_NOPTS_VALUE && - ist->next_dts == AV_NOPTS_VALUE && - !copy_ts_ && - (input_fmt_ctx_->iformat->flags & AVFMT_TS_DISCONT) && + pkt_dts = av_rescale_q_rnd( + pkt->dts, stream->time_base, AV_TIME_BASE_Q, + (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); + if (pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && + !copy_ts_ && (input_fmt_ctx_->iformat->flags & AVFMT_TS_DISCONT) && last_ts_ != AV_NOPTS_VALUE - //!force_dts_monotonicity - ) { - int64_t delta = pkt_dts - last_ts_; - if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE || - delta > 1LL*dts_delta_threshold*AV_TIME_BASE) { + //! force_dts_monotonicity + ) { + int64_t delta = pkt_dts - last_ts_; + if (delta < -1LL * dts_delta_threshold * AV_TIME_BASE || + delta > 1LL * dts_delta_threshold * AV_TIME_BASE) { ts_offset_ -= delta; av_log(NULL, AV_LOG_DEBUG, - "Inter stream timestamp discontinuity %" PRId64 ", new offset= %" PRId64 "\n", + "Inter stream timestamp discontinuity %" PRId64 + ", new offset= %" PRId64 "\n", delta, ts_offset_); pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); + pkt->pts -= + av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); } } - //duration = av_rescale_q(duration_, ifile->time_base, stream->time_base); //in loop case + // duration = av_rescale_q(duration_, ifile->time_base, stream->time_base); + // //in loop case duration = 0; if (pkt->pts != AV_NOPTS_VALUE) { pkt->pts += duration; @@ -1329,38 +1465,46 @@ int CFFDecoder::pkt_ts(AVPacket *pkt, int index) { if (pkt->dts != AV_NOPTS_VALUE) pkt->dts += duration; - pkt_dts = av_rescale_q_rnd(pkt->dts, stream->time_base, - AV_TIME_BASE_Q, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); + pkt_dts = av_rescale_q_rnd( + pkt->dts, stream->time_base, AV_TIME_BASE_Q, + (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); if (pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && !copy_ts_ - //!force_dts_monotonicity - ) { - int64_t delta = pkt_dts - ist->next_dts; - float dts_error_threshold = 3600*30; + //! force_dts_monotonicity + ) { + int64_t delta = pkt_dts - ist->next_dts; + float dts_error_threshold = 3600 * 30; if (input_fmt_ctx_->iformat->flags & AVFMT_TS_DISCONT) { - if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE || - delta > 1LL*dts_delta_threshold*AV_TIME_BASE || - pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) { + if (delta < -1LL * dts_delta_threshold * AV_TIME_BASE || + delta > 1LL * dts_delta_threshold * AV_TIME_BASE || + pkt_dts + AV_TIME_BASE / 10 < FFMAX(ist->pts, ist->dts)) { ts_offset_ -= delta; - av_log(NULL, AV_LOG_DEBUG, - "timestamp discontinuity %" PRId64 ", new offset= %" PRId64 "\n", + av_log(NULL, AV_LOG_DEBUG, "timestamp discontinuity %" PRId64 + ", new offset= %" PRId64 "\n", delta, ts_offset_); - pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); + pkt->dts -= + av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); + pkt->pts -= + av_rescale_q(delta, AV_TIME_BASE_Q, stream->time_base); } } else { - if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || - delta > 1LL*dts_error_threshold*AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "DTS %" PRId64 ", next:%" PRId64 " st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index); + if (delta < -1LL * dts_error_threshold * AV_TIME_BASE || + delta > 1LL * dts_error_threshold * AV_TIME_BASE) { + av_log(NULL, AV_LOG_WARNING, "DTS %" PRId64 ", next:%" PRId64 + " st:%d invalid dropping\n", + pkt->dts, ist->next_dts, pkt->stream_index); pkt->dts = AV_NOPTS_VALUE; } if (pkt->pts != AV_NOPTS_VALUE) { - int64_t pkt_pts = av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q); - delta = pkt_pts - ist->next_dts; - if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || - delta > 1LL*dts_error_threshold*AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "PTS %" PRId64 ", next:%" PRId64 " invalid dropping st:%d\n", + int64_t pkt_pts = + av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q); + delta = pkt_pts - ist->next_dts; + if (delta < -1LL * dts_error_threshold * AV_TIME_BASE || + delta > 1LL * dts_error_threshold * AV_TIME_BASE) { + av_log(NULL, AV_LOG_WARNING, + "PTS %" PRId64 ", next:%" PRId64 + " invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index); pkt->pts = AV_NOPTS_VALUE; } @@ -1371,9 +1515,10 @@ int CFFDecoder::pkt_ts(AVPacket *pkt, int index) { if (pkt->dts != AV_NOPTS_VALUE) last_ts_ = av_rescale_q(pkt->dts, stream->time_base, AV_TIME_BASE_Q); - //if (force_dts_monotonicity && + // if (force_dts_monotonicity && // (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) && - // (ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) + // (ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || + // ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) //) return 0; } @@ -1385,17 +1530,24 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { int index = pkt->stream_index == video_stream_index_ ? 0 : 1; InputStream *ist = &ist_[index]; AVStream *stream = (index == 0) ? video_stream_ : audio_stream_; - AVCodecContext *dec_ctx = (index == 0) ? video_decode_ctx_ : audio_decode_ctx_; + AVCodecContext *dec_ctx = + (index == 0) ? video_decode_ctx_ : audio_decode_ctx_; if (!push_raw_stream_) pkt_ts(pkt, index); if (!ist->saw_first_ts) { - ist->dts = (stream && stream->avg_frame_rate.num) ? - dec_ctx->has_b_frames * AV_TIME_BASE / av_q2d(stream->avg_frame_rate) : 0; + ist->dts = (stream && stream->avg_frame_rate.num) + ? -dec_ctx->has_b_frames * AV_TIME_BASE / + av_q2d(stream->avg_frame_rate) + : 0; ist->pts = 0; - if (stream && pkt && pkt->pts != AV_NOPTS_VALUE && !ist->decoding_needed) { - ist->dts += av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q); - ist->pts = ist->dts; //unused but better to set it to a value thats not totally wrong + if (stream && pkt && pkt->pts != AV_NOPTS_VALUE && + !ist->decoding_needed) { + ist->dts += + av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q); + ist->pts = ist->dts; // unused but better to set it to a value thats + // not totally wrong } ist->saw_first_ts = 1; } @@ -1406,7 +1558,8 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { ist->next_pts = ist->pts; if (stream && pkt && pkt->size != 0 && pkt->dts != AV_NOPTS_VALUE) { - ist->next_dts = ist->dts = av_rescale_q(pkt->dts, stream->time_base, AV_TIME_BASE_Q); + ist->next_dts = ist->dts = + av_rescale_q(pkt->dts, stream->time_base, AV_TIME_BASE_Q); if (dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed) ist->next_pts = ist->pts = ist->dts; } @@ -1415,7 +1568,8 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { if (pkt->size == 0) { Packet packet = Packet::generate_eof_packet(); assert(packet.timestamp() == BMF_EOF); - if (task.get_outputs().find(index) != task.get_outputs().end() && file_list_.size() == 0){ + if (task.get_outputs().find(index) != task.get_outputs().end() && + file_list_.size() == 0) { task.get_outputs()[index]->push(packet); if (index == 0) video_end_ = true; @@ -1425,30 +1579,37 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { return AVERROR_EOF; } - AVRational frame_rate = av_guess_frame_rate(input_fmt_ctx_, stream, NULL); + AVRational frame_rate = + av_guess_frame_rate(input_fmt_ctx_, stream, NULL); ist->dts = ist->next_dts; switch (dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: assert(pkt->duration >= 0); if (dec_ctx->sample_rate) { ist->next_dts += ((int64_t)AV_TIME_BASE * dec_ctx->frame_size) / - dec_ctx->sample_rate; + dec_ctx->sample_rate; } else { - ist->next_dts += av_rescale_q(pkt->duration, stream->time_base, AV_TIME_BASE_Q); + ist->next_dts += av_rescale_q(pkt->duration, stream->time_base, + AV_TIME_BASE_Q); } break; case AVMEDIA_TYPE_VIDEO: if (frame_rate.num) { AVRational time_base_q = AV_TIME_BASE_Q; - int64_t next_dts = av_rescale_q(ist->next_dts, time_base_q, av_inv_q(frame_rate)); - ist->next_dts = av_rescale_q(next_dts + 1, av_inv_q(frame_rate), time_base_q); + int64_t next_dts = av_rescale_q(ist->next_dts, time_base_q, + av_inv_q(frame_rate)); + ist->next_dts = av_rescale_q(next_dts + 1, av_inv_q(frame_rate), + time_base_q); } else if (pkt->duration) { - ist->next_dts += av_rescale_q(pkt->duration, stream->time_base, AV_TIME_BASE_Q); - } else if(dec_ctx->framerate.num != 0) { - int ticks= av_stream_get_parser(stream) ? av_stream_get_parser(stream)->repeat_pict + 1 : dec_ctx->ticks_per_frame; - ist->next_dts += ((int64_t)AV_TIME_BASE * - dec_ctx->framerate.den * ticks) / - dec_ctx->framerate.num / dec_ctx->ticks_per_frame; + ist->next_dts += av_rescale_q(pkt->duration, stream->time_base, + AV_TIME_BASE_Q); + } else if (dec_ctx->framerate.num != 0) { + int ticks = av_stream_get_parser(stream) + ? av_stream_get_parser(stream)->repeat_pict + 1 + : dec_ctx->ticks_per_frame; + ist->next_dts += + ((int64_t)AV_TIME_BASE * dec_ctx->framerate.den * ticks) / + dec_ctx->framerate.num / dec_ctx->ticks_per_frame; } break; } @@ -1456,7 +1617,8 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { ist->next_pts = ist->next_dts; if (pkt->dts == AV_NOPTS_VALUE) - pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, stream->time_base); + pkt->dts = + av_rescale_q(ist->dts, AV_TIME_BASE_Q, stream->time_base); if (!ist->codecpar_sended) { auto input_stream = std::make_shared(); @@ -1475,15 +1637,18 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { auto packet = Packet(av_packet); int64_t e_time = (index == 0) ? end_video_time_ : end_audio_time_; - if (e_time <= av_rescale_q(ist->pts, AV_TIME_BASE_Q, stream->time_base)) { + if (e_time <= + av_rescale_q(ist->pts, AV_TIME_BASE_Q, stream->time_base)) { if (e_time < 0) BMFLOG_NODE(BMF_ERROR, node_id_) - << "Error of end time in stream copy, which is shorter than the start offset"; + << "Error of end time in stream copy, which is shorter " + "than the start offset"; AVPacket ept; av_init_packet(&ept); ept.data = NULL; ept.size = 0; - ept.stream_index = (index == 0) ? video_stream_index_ : audio_stream_index_; + ept.stream_index = + (index == 0) ? video_stream_index_ : audio_stream_index_; return decode_send_packet(task, &ept, got_frame); } packet.set_timestamp(pkt->pts * av_q2d(stream->time_base) * 1000000); @@ -1497,8 +1662,9 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { bool repeat = false; AVPacket *in_pkt = pkt; int stream_index = pkt->stream_index; - AVCodecContext *avctx = (pkt->stream_index == video_stream_index_) ? video_decode_ctx_ : - audio_decode_ctx_; + AVCodecContext *avctx = (pkt->stream_index == video_stream_index_) + ? video_decode_ctx_ + : audio_decode_ctx_; do { ist->pts = ist->next_pts; ist->dts = ist->next_dts; @@ -1510,8 +1676,9 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { // The old code used to set dts on the drain packet, which does not work // with the new API anymore. if (index == 0 && pkt && pkt->size == 0) { // eof - void *new_buff = av_realloc_array(ist->dts_buffer, - ist->nb_dts_buffer + 1, sizeof(ist->dts_buffer[0])); + void *new_buff = + av_realloc_array(ist->dts_buffer, ist->nb_dts_buffer + 1, + sizeof(ist->dts_buffer[0])); if (!new_buff) return AVERROR(ENOMEM); ist->dts_buffer = (int64_t *)new_buff; @@ -1520,13 +1687,17 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { if (!repeat) { if (index == 0 && pkt && pkt->size != 0) - pkt->dts = dts; // "ffmpeg.c probably shouldn't do this", but actually it influence + pkt->dts = dts; // "ffmpeg.c probably shouldn't do this", but + // actually it influence ret = avcodec_send_packet(avctx, in_pkt); - if (ret < 0 && ret != AVERROR_EOF ) {//&& ret != AVERROR(EAGAIN)) { - std::string tmp = (in_pkt->stream_index == video_stream_index_) ? "video" : "audio"; + if (ret < 0 && ret != AVERROR_EOF) { //&& ret != AVERROR(EAGAIN)) { + std::string tmp = (in_pkt->stream_index == video_stream_index_) + ? "video" + : "audio"; std::string msg = error_msg(ret); - BMFLOG_NODE(BMF_ERROR, node_id_) << "Error decoding " << tmp << ", " << msg; + BMFLOG_NODE(BMF_ERROR, node_id_) << "Error decoding " << tmp + << ", " << msg; decode_error_[1]++; return ret; } @@ -1540,13 +1711,14 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { if (ret < 0 && ret != AVERROR(EAGAIN)) { if (ret != AVERROR_EOF) BMFLOG_NODE(BMF_ERROR, node_id_) << "Error receiving frame"; - //else //loop case + // else //loop case // avcodec_flush_buffers(avctx); decode_error_[1]++; return ret; } if (ret >= 0) { - //TODO need to judge the hardware data is from hwaccel or hardware decode + // TODO need to judge the hardware data is from hwaccel or hardware + // decode if (decoded_frm_->hw_frames_ctx) { copy_simple_frame(decoded_frm_); } @@ -1558,28 +1730,36 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { } if (stream_index == video_stream_index_ && !video_end_) { - // The following line may be required in some cases where there is no parser + // The following line may be required in some cases where there is + // no parser // or the parser does not has_b_frames correctly - if (video_stream_ && video_stream_->codecpar->video_delay < video_decode_ctx_->has_b_frames) { + if (video_stream_ && + video_stream_->codecpar->video_delay < + video_decode_ctx_->has_b_frames) { if (video_decode_ctx_->codec_id == AV_CODEC_ID_H264) { - video_stream_->codecpar->video_delay = video_decode_ctx_->has_b_frames; + video_stream_->codecpar->video_delay = + video_decode_ctx_->has_b_frames; } else - BMFLOG_NODE(BMF_INFO, node_id_) << "video_delay is larger in decoder than demuxer " - << video_decode_ctx_->has_b_frames << " > " - << video_stream_->codecpar->video_delay; + BMFLOG_NODE(BMF_INFO, node_id_) + << "video_delay is larger in decoder than demuxer " + << video_decode_ctx_->has_b_frames << " > " + << video_stream_->codecpar->video_delay; } if (*got_frame) { if (end_video_time_ < decoded_frm_->pts) { if (end_video_time_ < 0) - BMFLOG_NODE(BMF_ERROR, node_id_) - << "Error of end time in video, which is shorter than the start offset"; - handle_output_data(task, 0, in_pkt, true, repeat, *got_frame); + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Error of end time in video, which is shorter " + "than the start offset"; + handle_output_data(task, 0, in_pkt, true, repeat, + *got_frame); video_end_ = true; return 0; } if (video_stream_ && video_stream_->sample_aspect_ratio.num) - decoded_frm_->sample_aspect_ratio = video_stream_->sample_aspect_ratio; + decoded_frm_->sample_aspect_ratio = + video_stream_->sample_aspect_ratio; } handle_output_data(task, 0, in_pkt, false, repeat, *got_frame); } else if (stream_index == audio_stream_index_ && !audio_end_) { @@ -1592,8 +1772,10 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { if (end_audio_time_ < decoded_frm_->pts) { if (end_audio_time_ < 0) BMFLOG_NODE(BMF_INFO, node_id_) - << "Error of end time in audio, which is shorter than the start offset"; - handle_output_data(task, 1, in_pkt, true, repeat, *got_frame); + << "Error of end time in audio, which is shorter " + "than the start offset"; + handle_output_data(task, 1, in_pkt, true, repeat, + *got_frame); audio_end_ = true; return 0; } @@ -1607,7 +1789,7 @@ int CFFDecoder::decode_send_packet(Task &task, AVPacket *pkt, int *got_frame) { av_frame_unref(decoded_frm_); repeat = true; - } while(*got_frame); + } while (*got_frame); return decoded; } @@ -1623,14 +1805,16 @@ int CFFDecoder::flush(Task &task) { while (1) { fpkt.data = NULL; fpkt.size = 0; - if (check_valid_packet(&fpkt, task)) { //output q may not exist and won't process + if (check_valid_packet( + &fpkt, task)) { // output q may not exist and won't process ret = decode_send_packet(task, &fpkt, &got_frame); if (ret < 0) { if (ret == AVERROR_EOF) break; if (ret != AVERROR(EAGAIN)) { std::string msg = error_msg(ret); - BMFLOG_NODE(BMF_ERROR, node_id_) << "flush decode video error: " << msg; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "flush decode video error: " << msg; } } } else @@ -1650,7 +1834,8 @@ int CFFDecoder::flush(Task &task) { break; if (ret != AVERROR(EAGAIN)) { std::string msg = error_msg(ret); - BMFLOG_NODE(BMF_ERROR, node_id_) << "flush decode audio error" << msg; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "flush decode audio error" << msg; break; } } @@ -1676,9 +1861,11 @@ int CFFDecoder::flush(Task &task) { int CFFDecoder::close() { std::lock_guard lock(mutex_); clean(); - if ((decode_error_[0] + decode_error_[1]) * max_error_rate_ < decode_error_[1]) { - std::string err_msg = "decoded: " + std::to_string(decode_error_[0]) + " , failed to decode: " - + std::to_string(decode_error_[1]) + "."; + if ((decode_error_[0] + decode_error_[1]) * max_error_rate_ < + decode_error_[1]) { + std::string err_msg = "decoded: " + std::to_string(decode_error_[0]) + + " , failed to decode: " + + std::to_string(decode_error_[1]) + "."; BMF_Error(BMF_TranscodeError, err_msg.c_str()); } return 0; @@ -1727,8 +1914,7 @@ int CFFDecoder::clean() { packets_handle_all_ = false; valid_packet_flag_ = false; stream_frame_number_ = 0; - while(!bmf_av_packet_queue_.empty()) - { + while (!bmf_av_packet_queue_.empty()) { bmf_av_packet_queue_.pop(); } return 0; @@ -1741,8 +1927,7 @@ int CFFDecoder::read_packet(uint8_t *buf, int buf_size) { packets_handle_all_ = true; valid_packet_flag_ = false; process_var_.notify_one(); - packet_ready_.wait(lk,[this]{return this->valid_packet_flag_;}); - + packet_ready_.wait(lk, [this] { return this->valid_packet_flag_; }); } while (not bmf_av_packet_queue_.empty()) { BMFAVPacket packet = bmf_av_packet_queue_.front(); @@ -1756,7 +1941,9 @@ int CFFDecoder::read_packet(uint8_t *buf, int buf_size) { int current_packet_valid_size = packet.nbytes() - current_packet_loc_; int need_size = buf_size - valid_size; int got_size = FFMIN(need_size, current_packet_valid_size); - memcpy(buf + valid_size, (unsigned char *) (packet.data_ptr()) + current_packet_loc_, got_size); + memcpy(buf + valid_size, + (unsigned char *)(packet.data_ptr()) + current_packet_loc_, + got_size); valid_size += got_size; if (current_packet_loc_ + got_size >= packet.nbytes()) { @@ -1770,15 +1957,14 @@ int CFFDecoder::read_packet(uint8_t *buf, int buf_size) { } } return valid_size; - } int read_packet_(void *opaque, uint8_t *buf, int buf_size) { - return ((CFFDecoder *) opaque)->read_packet(buf, buf_size); + return ((CFFDecoder *)opaque)->read_packet(buf, buf_size); } int CFFDecoder::init_av_codec() { - //AVDictionary *opts = NULL; + // AVDictionary *opts = NULL; input_fmt_ctx_ = NULL; video_time_base_string_ = ""; video_end_ = false; @@ -1790,33 +1976,38 @@ int CFFDecoder::init_av_codec() { } bool CFFDecoder::check_valid_packet(AVPacket *pkt, Task &task) { - if (pkt->stream_index == video_stream_index_ && !video_end_ && task.get_outputs().count(0) > 0) { + if (pkt->stream_index == video_stream_index_ && !video_end_ && + task.get_outputs().count(0) > 0) { if (max_wh_ > 0 && video_decode_ctx_) { int ret; AVPacket opkt; av_init_packet(&opkt); - ret = av_parser_parse2(parser_, video_decode_ctx_, &opkt.data, &opkt.size, pkt->data, pkt->size, + ret = av_parser_parse2(parser_, video_decode_ctx_, &opkt.data, + &opkt.size, pkt->data, pkt->size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); if (ret < 0) { BMFLOG_NODE(BMF_ERROR, node_id_) << "Error while parsing"; return false; } - if (parser_->coded_width >= max_wh_ || parser_->coded_height >= max_wh_) { - BMFLOG_NODE(BMF_INFO, node_id_) << "the input stream width or height " - << parser_->coded_width << "x" - << parser_->coded_height << " is limited by " - << max_wh_; + if (parser_->coded_width >= max_wh_ || + parser_->coded_height >= max_wh_) { + BMFLOG_NODE(BMF_INFO, node_id_) + << "the input stream width or height " + << parser_->coded_width << "x" << parser_->coded_height + << " is limited by " << max_wh_; if (max_limit_hits_ > 0) { // enabled limit hits if (--max_limit_hits_ == 0) - BMF_Error(BMF_TranscodeError, - "max number of limited resolution frames exceeded"); + BMF_Error( + BMF_TranscodeError, + "max number of limited resolution frames exceeded"); } return false; } } return true; } - if (pkt->stream_index == audio_stream_index_ && !audio_end_ && task.get_outputs().count(1) > 0) { + if (pkt->stream_index == audio_stream_index_ && !audio_end_ && + task.get_outputs().count(1) > 0) { return true; } return false; @@ -1827,10 +2018,10 @@ int CFFDecoder::init_packet_av_codec() { size_t avio_ctx_buffer_size = 1024; input_fmt_ctx_ = avformat_alloc_context(); - avio_ctx_buffer = (unsigned char *) av_malloc(avio_ctx_buffer_size); + avio_ctx_buffer = (unsigned char *)av_malloc(avio_ctx_buffer_size); - avio_ctx_ = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, (void *) this, read_packet_, - NULL, NULL); + avio_ctx_ = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, + (void *)this, read_packet_, NULL, NULL); input_fmt_ctx_->pb = avio_ctx_; input_fmt_ctx_->flags = AVFMT_FLAG_CUSTOM_IO; video_end_ = false; @@ -1845,11 +2036,11 @@ int CFFDecoder::init_packet_av_codec() { return 0; } - -int CFFDecoder::start_decode(std::vector input_index, std::vector output_index) { +int CFFDecoder::start_decode(std::vector input_index, + std::vector output_index) { start_decode_flag_ = true; - int ret =0; + int ret = 0; task_ = Task(node_id_, input_index, output_index); init_packet_av_codec(); if (!video_stream_ && video_end_ != true) { @@ -1868,7 +2059,7 @@ int CFFDecoder::start_decode(std::vector input_index, std::vector outp av_init_packet(&pkt); ret = av_read_frame(input_fmt_ctx_, &pkt); - if (ret < 0 ) { + if (ret < 0) { flush(task_); if (file_list_.size() == 0) { task_.set_timestamp(DONE); @@ -1880,9 +2071,9 @@ int CFFDecoder::start_decode(std::vector input_index, std::vector outp ret = decode_send_packet(task_, &pkt, &got_frame); } av_packet_unref(&pkt); - if (ret == AVERROR_EOF || (video_end_ && audio_end_)) { + if (ret == AVERROR_EOF || (video_end_ && audio_end_)) { flush(task_); - if (file_list_.size() == 0){ + if (file_list_.size() == 0) { task_.set_timestamp(DONE); task_done_ = true; } @@ -1906,18 +2097,15 @@ int64_t CFFDecoder::get_start_time() { if (first_video_start_time_ == -1) { first_video_start_time_ = start_time; } - if (last_output_pts_ == 0) - { + if (last_output_pts_ == 0) { return start_time; } if (start_time < last_output_pts_ - overlap_time_) { adjust_time = last_output_pts_ + cut_off_interval_; - } - else if(start_time <= last_output_pts_) { + } else if (start_time <= last_output_pts_) { adjust_time = last_output_pts_ + cut_off_interval_; - } - else if(start_time < last_output_pts_ + cut_off_time_) { - //the same with normal packet + } else if (start_time < last_output_pts_ + cut_off_time_) { + // the same with normal packet adjust_time = start_time; } else { // correct the timestamp and add @@ -1933,8 +2121,8 @@ int CFFDecoder::process_task_output_packet(int index, Packet &packet) { first_handle_ = false; } adjust_pts = adjust_pts_; - if(packet.is>()){ - if (!stream_copy_av_stream_flag_[index]){ + if (packet.is>()) { + if (!stream_copy_av_stream_flag_[index]) { stream_copy_av_stream_flag_[index] = true; return 0; } else { @@ -1942,56 +2130,71 @@ int CFFDecoder::process_task_output_packet(int index, Packet &packet) { } } - if (adjust_pts + packet.timestamp() <= last_output_pts_){ + if (adjust_pts + packet.timestamp() <= last_output_pts_) { return -1; } - if (adjust_pts + packet.timestamp() > temp_last_output_pts_){ + if (adjust_pts + packet.timestamp() > temp_last_output_pts_) { temp_last_output_pts_ = adjust_pts + packet.timestamp(); } packet.set_timestamp(adjust_pts + packet.timestamp()); - if(packet.is()){ - auto& video_frame = packet.get(); - auto frame = const_cast(video_frame.private_get()); - frame->pts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, video_stream_->time_base) + frame->pts; - video_frame.set_pts(frame->pts); //sync with avframe - } - else if(packet.is()){ - auto& audio_frame = packet.get(); - auto frame = const_cast(audio_frame.private_get()); - + if (packet.is()) { + auto &video_frame = packet.get(); + auto frame = const_cast(video_frame.private_get()); + frame->pts = av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, video_stream_->time_base) + + frame->pts; + video_frame.set_pts(frame->pts); // sync with avframe + } else if (packet.is()) { + auto &audio_frame = packet.get(); + auto frame = const_cast(audio_frame.private_get()); + Rational tb = audio_frame.time_base(); AVRational audio_frame_time_base; audio_frame_time_base.den = tb.den; audio_frame_time_base.num = tb.num; - frame->pts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, audio_frame_time_base) + frame->pts; - - audio_frame.set_pts(frame->pts); //sync with avframe - } - else if(packet.is()){ - auto& bmf_av_packet = packet.get(); - auto av_packet = const_cast(bmf_av_packet.private_get()); - if (index == 0){ - av_packet->pts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, video_stream_->time_base) + av_packet->pts; - av_packet->dts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, video_stream_->time_base) + av_packet->dts; + frame->pts = av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, audio_frame_time_base) + + frame->pts; + + audio_frame.set_pts(frame->pts); // sync with avframe + } else if (packet.is()) { + auto &bmf_av_packet = packet.get(); + auto av_packet = + const_cast(bmf_av_packet.private_get()); + if (index == 0) { + av_packet->pts = + av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, video_stream_->time_base) + + av_packet->pts; + av_packet->dts = + av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, video_stream_->time_base) + + av_packet->dts; } else { - av_packet->pts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, audio_stream_->time_base) + av_packet->pts; - av_packet->dts = av_rescale_q(adjust_pts - first_video_start_time_, AV_TIME_BASE_Q, audio_stream_->time_base) + av_packet->dts; + av_packet->pts = + av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, audio_stream_->time_base) + + av_packet->pts; + av_packet->dts = + av_rescale_q(adjust_pts - first_video_start_time_, + AV_TIME_BASE_Q, audio_stream_->time_base) + + av_packet->dts; } - bmf_av_packet.set_pts(av_packet->pts); //sync with AVPacket + bmf_av_packet.set_pts(av_packet->pts); // sync with AVPacket } return 0; } int CFFDecoder::mv_task_data(Task &dst_task) { std::vector output_indexs = dst_task.get_output_stream_ids(); - - for (int i =0; icodec_type = AVMEDIA_TYPE_AUDIO; audio_decode_ctx_->channels = push_audio_channels_; audio_decode_ctx_->sample_rate = push_audio_sample_rate_; - if (push_audio_sample_fmt_) audio_decode_ctx_->sample_fmt = static_cast(push_audio_sample_fmt_); + if (push_audio_sample_fmt_) + audio_decode_ctx_->sample_fmt = + static_cast(push_audio_sample_fmt_); if (avcodec_open2(audio_decode_ctx_, dec, NULL) < 0) BMFLOG_NODE(BMF_ERROR, node_id_) << "Could not open codec"; } // AVPacket *av_packet = nullptr; - if(bmf_pkt){ + if (bmf_pkt) { av_packet = ffmpeg::from_bmf_av_packet(bmf_pkt, false); - } - else{ + } else { av_packet = av_packet_alloc(); av_packet->size = 0; } int decode_len = decode_send_packet(task, av_packet, &got_frame); av_packet_unref(av_packet); - if (decode_len < 0 && decode_len != AVERROR(EAGAIN) && decode_len != AVERROR_EOF - && !(video_end_ && audio_end_)) + if (decode_len < 0 && decode_len != AVERROR(EAGAIN) && + decode_len != AVERROR_EOF && !(video_end_ && audio_end_)) BMFLOG_NODE(BMF_ERROR, node_id_) << "Error of decode raw stream"; if (eof) { @@ -2083,10 +2287,11 @@ int CFFDecoder::process_raw_stream_packet(Task &task, BMFAVPacket &bmf_pkt, bool return 0; } -int CFFDecoder::process_input_bmf_av_packet(Task &task){ +int CFFDecoder::process_input_bmf_av_packet(Task &task) { Packet packet; if ((task.inputs_queue_.count(0)) <= 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "the av packet should push to stream 0"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "the av packet should push to stream 0"; return -1; } std::unique_lock lck(process_mutex_); @@ -2094,8 +2299,8 @@ int CFFDecoder::process_input_bmf_av_packet(Task &task){ if (packet.timestamp() == BMF_EOF) { input_eof_packet_received_ = true; if (!start_decode_flag_) { - task.fill_output_packet(0,Packet::generate_eof_packet()); - task.fill_output_packet(1,Packet::generate_eof_packet()); + task.fill_output_packet(0, Packet::generate_eof_packet()); + task.fill_output_packet(1, Packet::generate_eof_packet()); task.set_timestamp(DONE); } BMFAVPacket bmf_pkt; @@ -2114,9 +2319,9 @@ int CFFDecoder::process_input_bmf_av_packet(Task &task){ continue; } - // when the bmf_pkt size is 0, which mean the file is end, and need to be ready to recive the another format file - if (bmf_pkt.nbytes() == 0) - { + // when the bmf_pkt size is 0, which mean the file is end, and need to + // be ready to recive the another format file + if (bmf_pkt.nbytes() == 0) { BMFAVPacket bmf_pkt; bmf_pkt.set_pts(BMF_EOF); bmf_av_packet_queue_.push(bmf_pkt); @@ -2129,13 +2334,15 @@ int CFFDecoder::process_input_bmf_av_packet(Task &task){ if (push_raw_stream_) return 0; if (!start_decode_flag_) { - exec_thread_ = std::thread(&CFFDecoder::start_decode, this, task.get_input_stream_ids(),task.get_output_stream_ids()); + exec_thread_ = std::thread(&CFFDecoder::start_decode, this, + task.get_input_stream_ids(), + task.get_output_stream_ids()); } valid_packet_flag_ = true; packet_ready_.notify_one(); - process_var_.wait(lck,[this]{return this->packets_handle_all_;}); + process_var_.wait(lck, [this] { return this->packets_handle_all_; }); mv_task_data(task); - if (task_.timestamp()==DONE){ + if (task_.timestamp() == DONE) { exec_thread_.join(); } return 0; @@ -2148,7 +2355,7 @@ int CFFDecoder::process(Task &task) { if (has_input_) { if (task.get_inputs().size() > 0 && task.get_inputs()[0]->size() > 0) { Packet packet = task.get_inputs()[0]->front(); - if(packet.is() || handle_input_av_packet_flag_){ + if (packet.is() || handle_input_av_packet_flag_) { handle_input_av_packet_flag_ = true; return process_input_bmf_av_packet(task); } @@ -2162,7 +2369,7 @@ int CFFDecoder::process(Task &task) { } // mainly used to cowork with sync inputstream manager if (packet.timestamp() == BMF_PAUSE) { - for (auto output:task.get_outputs()) + for (auto output : task.get_outputs()) output.second->push(packet); break; } @@ -2190,7 +2397,8 @@ int CFFDecoder::process(Task &task) { } if (!input_fmt_ctx_) { - BMFLOG_NODE(BMF_WARNING, node_id_) << "decoder input_fmt_ctx_ is not ready or might be free"; + BMFLOG_NODE(BMF_WARNING, node_id_) + << "decoder input_fmt_ctx_ is not ready or might be free"; return 0; } if (!video_stream_ && video_end_ != true) { @@ -2211,7 +2419,7 @@ int CFFDecoder::process(Task &task) { usleep(10000); continue; } - if (ret < 0 ) { + if (ret < 0) { flush(task); if (file_list_.size() == 0) { task.set_timestamp(DONE); @@ -2222,8 +2430,8 @@ int CFFDecoder::process(Task &task) { if (ret >= 0 && check_valid_packet(&pkt, task)) { ret = decode_send_packet(task, &pkt, &got_frame); - if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF - && !(video_end_ && audio_end_)) + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF && + !(video_end_ && audio_end_)) break; } av_packet_unref(&pkt); @@ -2247,9 +2455,8 @@ int CFFDecoder::process(Task &task) { REGISTER_MODULE_CLASS(CFFDecoder) REGISTER_MODULE_INFO(CFFDecoder, info) { info.module_description = "Builtin FFmpeg-based decoding module."; - info.module_tag = ModuleTag::BMF_TAG_DECODER| - ModuleTag::BMF_TAG_DEMUXER| - ModuleTag::BMF_TAG_IMAGE_PROCESSOR| - ModuleTag::BMF_TAG_AUDIO_PROCESSOR| - ModuleTag::BMF_TAG_VIDEO_PROCESSOR; + info.module_tag = ModuleTag::BMF_TAG_DECODER | ModuleTag::BMF_TAG_DEMUXER | + ModuleTag::BMF_TAG_IMAGE_PROCESSOR | + ModuleTag::BMF_TAG_AUDIO_PROCESSOR | + ModuleTag::BMF_TAG_VIDEO_PROCESSOR; } diff --git a/bmf/c_modules/src/ffmpeg_encoder.cpp b/bmf/c_modules/src/ffmpeg_encoder.cpp index e25aac9b..82f70507 100644 --- a/bmf/c_modules/src/ffmpeg_encoder.cpp +++ b/bmf/c_modules/src/ffmpeg_encoder.cpp @@ -38,14 +38,16 @@ CFFEncoder::CFFEncoder(int node_id, JsonParam option) { /** @addtogroup EncM * @{ - * @arg null_output: to make encoder as a null sink in some cases. "null_output": 1 + * @arg null_output: to make encoder as a null sink in some cases. + * "null_output": 1 * @} */ if (option.has_key("null_output")) null_output_ = true; /** @addtogroup EncM * @{ - * @arg output_path: output file path, exp. out.mp4, which can indicate the output format of the file similiar as ffmpeg. + * @arg output_path: output file path, exp. out.mp4, which can indicate the + * output format of the file similiar as ffmpeg. * @} */ if (option.has_key("output_path")) { option.get_string("output_path", output_path_); @@ -64,13 +66,12 @@ CFFEncoder::CFFEncoder(int node_id, JsonParam option) { if (adjust_pts == 1) { adjust_pts_flag_ = true; } - } if (option.has_key("output_prefix")) { option.get_string("output_prefix", output_prefix_); if (output_prefix_[output_prefix_.size() - 1] != '/') output_prefix_ += '/'; - if(!std::filesystem::is_directory(output_prefix_)){ + if (!std::filesystem::is_directory(output_prefix_)) { mkdir(output_prefix_.c_str(), S_IRWXU); } } @@ -118,12 +119,14 @@ int CFFEncoder::init() { ost_[0] = ost_[1] = {0}; ost_[0].last_mux_dts = ost_[1].last_mux_dts = AV_NOPTS_VALUE; ost_[0].encoding_needed = ost_[1].encoding_needed = true; - ost_[0].filter_in_rescale_delta_last = ost_[1].filter_in_rescale_delta_last = AV_NOPTS_VALUE; + ost_[0].filter_in_rescale_delta_last = + ost_[1].filter_in_rescale_delta_last = AV_NOPTS_VALUE; ost_[0].max_frames = ost_[1].max_frames = INT64_MAX; /** @addtogroup EncM * @{ - * @arg format: similiar as the "-f" in ffmpeg command line to specify the demux/mux format. exp. + * @arg format: similiar as the "-f" in ffmpeg command line to specify the + demux/mux format. exp. * @code * { "format": "flv", @@ -144,7 +147,7 @@ int CFFEncoder::init() { srv_cnt_++; if (input_option_.has_key("output_prefix")) { output_dir_ = output_prefix_ + std::to_string(srv_cnt_); - if(!std::filesystem::is_directory(output_dir_)){ + if (!std::filesystem::is_directory(output_dir_)) { mkdir(output_dir_.c_str(), S_IRWXU); } output_path_ = output_dir_ + "/output." + oformat_; @@ -152,7 +155,10 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg push_output: decide whether to mux the result and where to output the results, available value is 0/1/2. 0: write muxed result to disk, 1: write muxed result to the output queue, 2: write unmuxed result to the output queue. + * @arg push_output: decide whether to mux the result and where to output + the results, available value is 0/1/2. 0: write muxed result to disk, 1: + write muxed result to the output queue, 2: write unmuxed result to the + output queue. * @code "push_output": 1 * @endcode @@ -163,7 +169,8 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg avio_buffer_size: set avio buffer size, when oformat is image2pipe, this paramter is useful, exp. + * @arg avio_buffer_size: set avio buffer size, when oformat is image2pipe, + this paramter is useful, exp. * @code "avio_buffer_size": 16384 * @endcode @@ -194,7 +201,8 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg video_params: video codec related parameters which similiar as ffmpeg. exp. + * @arg video_params: video codec related parameters which similiar as + ffmpeg. exp. * @code "video_params": { "codec": "h264", @@ -239,7 +247,9 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg codec: param in video_params or audio_params to specify the name of the codec which libavcodec included. exp. "h264", "bytevc1", "jpg", "png", "aac"(audio) + * @arg codec: param in video_params or audio_params to specify the name of + * the codec which libavcodec included. exp. "h264", "bytevc1", "jpg", + * "png", "aac"(audio) * @} */ std::string codec; if (video_params_.has_key("codec")) { @@ -263,7 +273,8 @@ int CFFEncoder::init() { * @{ * @arg width: param in video_params to specify the video width * @arg height: param in video_params to specify the video height - * @arg pix_fmt: param in video_params to specify the input format of raw video + * @arg pix_fmt: param in video_params to specify the input format of raw + * video * @} */ if (video_params_.has_key("width") && video_params_.has_key("height")) { video_params_.get_int("width", width_); @@ -272,8 +283,8 @@ int CFFEncoder::init() { video_params_.erase("height"); } - if (video_params_.has_key("pix_fmt") ) { - std::string pix_fmt_str ; + if (video_params_.has_key("pix_fmt")) { + std::string pix_fmt_str; video_params_.get_string("pix_fmt", pix_fmt_str); pix_fmt_ = av_get_pix_fmt(pix_fmt_str.c_str()); video_params_.erase("pix_fmt"); @@ -281,7 +292,8 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg audio_params: audio codec related parameters which similiar as ffmpeg. exp. + * @arg audio_params: audio codec related parameters which similiar as + ffmpeg. exp. * @code "audio_params": { "codec": "aac", @@ -301,23 +313,24 @@ int CFFEncoder::init() { /** @addtogroup EncM * @{ - * @arg loglevel: without using the logbuffer of builder API, to set the ffmpeg av log level: "quiet","panic","fatal","error","warning","info","verbose","debug","trace" + * @arg loglevel: without using the logbuffer of builder API, to set the + * ffmpeg av log level: + * "quiet","panic","fatal","error","warning","info","verbose","debug","trace" * @} */ if (input_option_.has_key("loglevel")) { std::string log_level = ""; input_option_.get_string("loglevel", log_level); if (!LogBuffer::avlog_cb_set()) { av_log_set_level(LogBuffer::infer_level(log_level)); - BMFLOG_NODE(BMF_INFO, node_id_) << "encode setting log level to: " << log_level; + BMFLOG_NODE(BMF_INFO, node_id_) << "encode setting log level to: " + << log_level; } } return 0; } -CFFEncoder::~CFFEncoder() { - clean(); -} +CFFEncoder::~CFFEncoder() { clean(); } int CFFEncoder::clean() { if (!b_init_) @@ -342,7 +355,9 @@ int CFFEncoder::clean() { if (ost_[idx].input_stream) ost_[idx].input_stream = NULL; } - if (push_output_ == OutputMode::OUTPUT_NOTHING && output_fmt_ctx_ && output_fmt_ctx_->oformat && !(output_fmt_ctx_->oformat->flags & AVFMT_NOFILE)) + if (push_output_ == OutputMode::OUTPUT_NOTHING && output_fmt_ctx_ && + output_fmt_ctx_->oformat && + !(output_fmt_ctx_->oformat->flags & AVFMT_NOFILE)) avio_closep(&output_fmt_ctx_->pb); if (output_fmt_ctx_) { @@ -375,7 +390,7 @@ int CFFEncoder::reset() { return 0; } -bool CFFEncoder::check_valid_task(Task& task) { +bool CFFEncoder::check_valid_task(Task &task) { for (int index = 0; index < task.get_inputs().size(); index++) { if (!task.get_inputs()[index]->empty()) { return true; @@ -389,12 +404,15 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { AVPacket *pkt = hpkt; if (idx == 0) { - if(callback_endpoint_ != NULL) { - float curr_time = (in_stream_tbs_[0].den > 0 && in_stream_tbs_[0].num > 0) ? - float(pkt->pts * in_stream_tbs_[0].num / in_stream_tbs_[0].den) : 0; + if (callback_endpoint_ != NULL) { + float curr_time = + (in_stream_tbs_[0].den > 0 && in_stream_tbs_[0].num > 0) + ? float(pkt->pts * in_stream_tbs_[0].num / + in_stream_tbs_[0].den) + : 0; std::string info = "pts: " + std::to_string(curr_time); - auto para = CBytes::make((uint8_t*)info.c_str(), info.size()); + auto para = CBytes::make((uint8_t *)info.c_str(), info.size()); callback_endpoint_(0, para); } } @@ -412,7 +430,7 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { AVStream *st = output_stream_[idx]; OutputStream *ost = &ost_[idx]; - AVPacket out_pkt = { 0 }; + AVPacket out_pkt = {0}; if (!ost->encoding_needed) if (streamcopy(hpkt, &out_pkt, idx) != 0) { BMFLOG_NODE(BMF_ERROR, node_id_) << "stream copy error"; @@ -420,7 +438,8 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { } else pkt = &out_pkt; - if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) { + if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + ost->encoding_needed)) { if (ost->frame_number >= ost->max_frames) { av_packet_unref(pkt); return 0; @@ -428,7 +447,7 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { ost->frame_number++; } - //if (!of->header_written) { + // if (!of->header_written) { // AVPacket tmp_pkt = {0}; // /* the muxer is not initialized yet, buffer the packet */ // if (!av_fifo_space(ost->muxing_queue)) { @@ -448,15 +467,18 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { // if (ret < 0) // exit_program(1); // av_packet_move_ref(&tmp_pkt, pkt); - // av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), NULL); + // av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), + // NULL); // return; //} - if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && vsync_method_ == VSYNC_DROP))// || - //(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0)) + if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + vsync_method_ == VSYNC_DROP)) // || + //(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < + //0)) pkt->pts = pkt->dts = AV_NOPTS_VALUE; - //if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + // if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { // int i; // uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, // NULL); @@ -472,41 +494,51 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { // if (ost->frame_rate.num && ost->is_cfr) { // if (pkt->duration > 0) - // av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n"); + // av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by + // frame rate, this should not happen\n"); // pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate), // ost->mux_timebase); // } //} - //av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base); + // av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base); if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { - if (pkt->dts != AV_NOPTS_VALUE && - pkt->pts != AV_NOPTS_VALUE && + if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->dts > pkt->pts) { - av_log(s, AV_LOG_WARNING, "Invalid DTS: %" PRId64 " PTS: %" PRId64 " in output stream %d:%d, replacing by guess\n", - pkt->dts, pkt->pts, - idx, st->index); - pkt->pts = - pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1 - - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1) - - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1); - } - if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && + av_log(s, AV_LOG_WARNING, + "Invalid DTS: %" PRId64 " PTS: %" PRId64 + " in output stream %d:%d, replacing by guess\n", + pkt->dts, pkt->pts, idx, st->index); + pkt->pts = pkt->dts = + pkt->pts + pkt->dts + ost->last_mux_dts + 1 - + FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1) - + FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1); + } + if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || + st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->dts != AV_NOPTS_VALUE && - !(st->codecpar->codec_id == AV_CODEC_ID_VP9 && !ost->encoding_needed) && + !(st->codecpar->codec_id == AV_CODEC_ID_VP9 && + !ost->encoding_needed) && ost->last_mux_dts != AV_NOPTS_VALUE) { - int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT); + int64_t max = + ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT); if (pkt->dts < max) { - int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG; - av_log(s, loglevel, "Non-monotonous DTS in output stream " + int loglevel = + max - pkt->dts > 2 || + st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO + ? AV_LOG_WARNING + : AV_LOG_DEBUG; + av_log(s, loglevel, + "Non-monotonous DTS in output stream " "%d:%d; previous: %" PRId64 ", current: %" PRId64 "; ", idx, st->index, ost->last_mux_dts, pkt->dts); - //if (exit_on_error) { + // if (exit_on_error) { // av_log(NULL, AV_LOG_FATAL, "aborting.\n"); // exit_program(1); //} - av_log(s, loglevel, "changing to %" PRId64 ". This may result " + av_log(s, loglevel, + "changing to %" PRId64 ". This may result " "in incorrect timestamps in the output file.\n", max); if (pkt->pts >= pkt->dts) @@ -521,9 +553,8 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { ost->packets_written++; pkt->stream_index = streams_idx_[idx]; - if (ost->encoding_needed) //not streamcopy - av_packet_rescale_ts(pkt, - enc_ctxs_[idx]->time_base, + if (ost->encoding_needed) // not streamcopy + av_packet_rescale_ts(pkt, enc_ctxs_[idx]->time_base, output_stream_[idx]->time_base); ret = av_interleaved_write_frame(output_fmt_ctx_, pkt); @@ -535,7 +566,8 @@ int CFFEncoder::handle_output(AVPacket *hpkt, int idx) { return ret; } -int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_packet) { +int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, + int *got_packet) { int ret; int got_packet_local; int av_index; @@ -555,11 +587,13 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack ++last_pts_; } - if (av_index == 0 && frame && oformat_ == "image2pipe" && push_output_) { //only support to carry orig pts time for images + if (av_index == 0 && frame && oformat_ == "image2pipe" && + push_output_) { // only support to carry orig pts time for images std::string stime = ""; if (frame->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(frame->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(tag->key, "orig_pts_time")) { stime = tag->value; break; @@ -573,7 +607,8 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack } else { if (recorded_pts_ >= 0) estimated_time_ = last_orig_pts_time_ + - (frame->pts - recorded_pts_) * av_q2d(enc_ctxs_[idx]->time_base); + (frame->pts - recorded_pts_) * + av_q2d(enc_ctxs_[idx]->time_base); else estimated_time_ += 0.001; @@ -581,7 +616,7 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack } } - if(frame && enc_ctxs_[idx]) + if (frame && enc_ctxs_[idx]) frame->quality = enc_ctxs_[idx]->global_quality; ret = avcodec_send_frame(enc_ctxs_[idx], frame); @@ -591,7 +626,7 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack return ret; } - auto flush_cache = [this] () -> int { + auto flush_cache = [this]() -> int { int ret = 0; while (cache_.size()) { auto tmp = cache_.front(); @@ -618,8 +653,11 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack av_packet_free(&enc_pkt); if (*got_packet == AVERROR_EOF) { if (!stream_inited_) { - BMFLOG_NODE(BMF_WARNING, node_id_) << "The stream at index:" << idx << " ends, " - "but not all streams are initialized, all packets may be dropped."; + BMFLOG_NODE(BMF_WARNING, node_id_) + << "The stream at index:" << idx + << " ends, " + "but not all streams are initialized, all packets " + "may be dropped."; return 0; } if (ret = flush_cache(); ret < 0) @@ -639,26 +677,31 @@ int CFFEncoder::encode_and_write(AVFrame *frame, unsigned int idx, int *got_pack auto stream = std::make_shared(); *stream = *(output_stream_[idx]); stream->codecpar = avcodec_parameters_alloc(); - avcodec_parameters_copy(stream->codecpar, output_stream_[idx]->codecpar); + avcodec_parameters_copy(stream->codecpar, + output_stream_[idx]->codecpar); auto packet = Packet(stream); - //packet.set_data_type(DATA_TYPE_C); - //packet.set_class_name("AVStream"); - if (current_task_ptr_->get_outputs().find(idx) != current_task_ptr_->get_outputs().end()) + // packet.set_data_type(DATA_TYPE_C); + // packet.set_class_name("AVStream"); + if (current_task_ptr_->get_outputs().find(idx) != + current_task_ptr_->get_outputs().end()) current_task_ptr_->get_outputs()[idx]->push(packet); first_packet_[idx] = false; } BMFAVPacket packet_tmp = ffmpeg::to_bmf_av_packet(enc_pkt, true); auto packet = Packet(packet_tmp); - packet.set_timestamp(enc_pkt->pts * av_q2d(output_stream_[idx]->time_base) * 1000000); - //packet.set_data_type(DATA_TYPE_C); - //packet.set_data_class_type(BMFAVPACKET_TYPE); - //packet.set_class_name("libbmf_module_sdk.BMFAVPacket"); - if (current_task_ptr_->get_outputs().find(idx) != current_task_ptr_->get_outputs().end()) + packet.set_timestamp(enc_pkt->pts * + av_q2d(output_stream_[idx]->time_base) * + 1000000); + // packet.set_data_type(DATA_TYPE_C); + // packet.set_data_class_type(BMFAVPACKET_TYPE); + // packet.set_class_name("libbmf_module_sdk.BMFAVPacket"); + if (current_task_ptr_->get_outputs().find(idx) != + current_task_ptr_->get_outputs().end()) current_task_ptr_->get_outputs()[idx]->push(packet); } else { if (!stream_inited_ && *got_packet == 0) { - cache_.push_back(std::pair(enc_pkt, idx)); + cache_.push_back(std::pair(enc_pkt, idx)); continue; } if (ret = flush_cache(); ret < 0) @@ -681,31 +724,38 @@ int CFFEncoder::init_stream() { int ret = 0; if (!output_fmt_ctx_) return 0; - if (push_output_ == OutputMode::OUTPUT_NOTHING && !(output_fmt_ctx_->oformat->flags & AVFMT_NOFILE)) { - ret = avio_open(&output_fmt_ctx_->pb, output_path_.c_str(), AVIO_FLAG_WRITE); + if (push_output_ == OutputMode::OUTPUT_NOTHING && + !(output_fmt_ctx_->oformat->flags & AVFMT_NOFILE)) { + ret = avio_open(&output_fmt_ctx_->pb, output_path_.c_str(), + AVIO_FLAG_WRITE); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", output_path_.c_str()); + av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", + output_path_.c_str()); return ret; } } - if (push_output_ == OutputMode::OUTPUT_NOTHING or push_output_ == OutputMode::OUTPUT_MUXED_PACKET) { + if (push_output_ == OutputMode::OUTPUT_NOTHING or + push_output_ == OutputMode::OUTPUT_MUXED_PACKET) { AVDictionary *opts = NULL; std::vector> params; mux_params_.get_iterated(params); for (int i = 0; i < params.size(); i++) { - av_dict_set(&opts, params[i].first.c_str(), params[i].second.c_str(), 0); + av_dict_set(&opts, params[i].first.c_str(), + params[i].second.c_str(), 0); } { std::vector> params; metadata_params_.get_iterated(params); for (int i = 0; i < params.size(); i++) { - av_dict_set(&output_fmt_ctx_->metadata, params[i].first.c_str(), params[i].second.c_str(), 0); + av_dict_set(&output_fmt_ctx_->metadata, params[i].first.c_str(), + params[i].second.c_str(), 0); } } ret = avformat_write_header(output_fmt_ctx_, &opts); if (ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Error occurred when opening output file"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Error occurred when opening output file"; return ret; } else if (av_dict_count(opts) > 0) { AVDictionaryEntry *t = NULL; @@ -732,11 +782,11 @@ int CFFEncoder::init_stream() { } int write_data(void *opaque, uint8_t *buf, int buf_size) { - return ((CFFEncoder *) opaque)->write_output_data(opaque, buf, buf_size); + return ((CFFEncoder *)opaque)->write_output_data(opaque, buf, buf_size); } int CFFEncoder::write_current_packet_data(uint8_t *buf, int buf_size) { - void* data = nullptr; + void *data = nullptr; AVPacket *avpkt = av_packet_alloc(); av_init_packet(avpkt); av_new_packet(avpkt, buf_size); @@ -749,11 +799,12 @@ int CFFEncoder::write_current_packet_data(uint8_t *buf, int buf_size) { auto packet = Packet(bmf_avpkt); packet.set_timestamp(current_frame_pts_); packet.set_time(orig_pts_time_); - //packet.set_data(packet_tmp); - //packet.set_data_type(DATA_TYPE_C); - //packet.set_data_class_type(BMFAVPACKET_TYPE); - //packet.set_class_name("libbmf_module_sdk.BMFAVPacket"); - if (current_task_ptr_->get_outputs().find(0) != current_task_ptr_->get_outputs().end()) + // packet.set_data(packet_tmp); + // packet.set_data_type(DATA_TYPE_C); + // packet.set_data_class_type(BMFAVPACKET_TYPE); + // packet.set_class_name("libbmf_module_sdk.BMFAVPacket"); + if (current_task_ptr_->get_outputs().find(0) != + current_task_ptr_->get_outputs().end()) current_task_ptr_->get_outputs()[0]->push(packet); return buf_size; @@ -762,26 +813,30 @@ int CFFEncoder::write_current_packet_data(uint8_t *buf, int buf_size) { int CFFEncoder::write_output_data(void *opaque, uint8_t *buf, int buf_size) { if (oformat_ == "image2pipe" && codec_names_[0] == "mjpeg") { bool has_header = buf_size >= 2 && buf[0] == 0xFF && buf[1] == 0xD8; - bool has_trailer = buf_size >= 2 && buf[buf_size - 2] == 0xFF && buf[buf_size - 1] == 0xD9; + bool has_trailer = buf_size >= 2 && buf[buf_size - 2] == 0xFF && + buf[buf_size - 1] == 0xD9; if (!current_image_buffer_.is_packing && has_header && has_trailer) return write_current_packet_data(buf, buf_size); - if (current_image_buffer_.room - current_image_buffer_.size < buf_size) { - current_image_buffer_.buf = (uint8_t*)av_fast_realloc(current_image_buffer_.buf, - ¤t_image_buffer_.room, - current_image_buffer_.size + buf_size); + if (current_image_buffer_.room - current_image_buffer_.size < + buf_size) { + current_image_buffer_.buf = (uint8_t *)av_fast_realloc( + current_image_buffer_.buf, ¤t_image_buffer_.room, + current_image_buffer_.size + buf_size); if (!current_image_buffer_.buf) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Could realloc buffer for image2pipe output"; - return AVERROR(ENOMEM); + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Could realloc buffer for image2pipe output"; + return AVERROR(ENOMEM); } } - memcpy(current_image_buffer_.buf + current_image_buffer_.size, buf, buf_size); + memcpy(current_image_buffer_.buf + current_image_buffer_.size, buf, + buf_size); current_image_buffer_.size += buf_size; if (current_image_buffer_.is_packing) { uint8_t *buffer = current_image_buffer_.buf; - if (current_image_buffer_.size >= 4 && - buffer[0] == 0xFF && buffer[1] == 0xD8 && + if (current_image_buffer_.size >= 4 && buffer[0] == 0xFF && + buffer[1] == 0xD8 && buffer[current_image_buffer_.size - 2] == 0xFF && buffer[current_image_buffer_.size - 1] == 0xD9) { @@ -801,7 +856,7 @@ int CFFEncoder::write_output_data(void *opaque, uint8_t *buf, int buf_size) { } int64_t seek_data(void *opaque, int64_t offset, int whence) { - return ((CFFEncoder *) opaque)->seek_output_data(opaque, offset, whence); + return ((CFFEncoder *)opaque)->seek_output_data(opaque, offset, whence); } int64_t CFFEncoder::seek_output_data(void *opaque, int64_t offset, int whence) { @@ -810,7 +865,7 @@ int64_t CFFEncoder::seek_output_data(void *opaque, int64_t offset, int whence) { return 0; } -int CFFEncoder::init_codec(int idx, AVFrame* frame) { +int CFFEncoder::init_codec(int idx, AVFrame *frame) { AVStream *out_stream; AVBufferRef *device_ref = nullptr; int ret; @@ -825,25 +880,32 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { } if (!output_fmt_ctx_) { - avformat_alloc_output_context2(&output_fmt_ctx_, NULL, (oformat_ != "" ? oformat_.c_str() : NULL), - push_output_ == OutputMode::OUTPUT_NOTHING ? output_path_.c_str() : NULL); + avformat_alloc_output_context2( + &output_fmt_ctx_, NULL, (oformat_ != "" ? oformat_.c_str() : NULL), + push_output_ == OutputMode::OUTPUT_NOTHING ? output_path_.c_str() + : NULL); if (!output_fmt_ctx_) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Could not create output context"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Could not create output context"; return AVERROR_UNKNOWN; } if (push_output_ == OutputMode::OUTPUT_MUXED_PACKET) { unsigned char *avio_ctx_buffer; size_t avio_ctx_buffer_size = avio_buffer_size_; - avio_ctx_buffer = (unsigned char*)av_malloc(avio_ctx_buffer_size); + avio_ctx_buffer = (unsigned char *)av_malloc(avio_ctx_buffer_size); if (!avio_ctx_buffer) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Could not create avio buffer"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Could not create avio buffer"; return AVERROR_UNKNOWN; } - avio_ctx_ = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 1, (void*) this, NULL, write_data, seek_data); + avio_ctx_ = + avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 1, + (void *)this, NULL, write_data, seek_data); avio_ctx_->seekable = AVIO_SEEKABLE_NORMAL; output_fmt_ctx_->pb = avio_ctx_; output_fmt_ctx_->flags = AVFMT_FLAG_CUSTOM_IO; - current_image_buffer_.buf = (unsigned char*)av_malloc(avio_ctx_buffer_size); + current_image_buffer_.buf = + (unsigned char *)av_malloc(avio_ctx_buffer_size); current_image_buffer_.room = avio_ctx_buffer_size; current_image_buffer_.size = 0; } @@ -852,20 +914,25 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { if (ost_[idx].encoding_needed) { codecs_[idx] = avcodec_find_encoder_by_name(codec_names_[idx].c_str()); if (!codecs_[idx]) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Codec '" << codec_names_[idx].c_str() << "' not found"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Codec '" << codec_names_[idx].c_str() << "' not found"; return AVERROR_UNKNOWN; } - if (codec_names_[idx] == "h264_nvenc" || codec_names_[idx] == "hevc_nvenc") { - int err = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_CUDA, nullptr, nullptr, 1); + if (codec_names_[idx] == "h264_nvenc" || + codec_names_[idx] == "hevc_nvenc") { + int err = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_CUDA, + nullptr, nullptr, 1); if (err < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to create hwdevice context"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Failed to create hwdevice context"; } } } enc_ctxs_[idx] = avcodec_alloc_context3(codecs_[idx]); if (!enc_ctxs_[idx]) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to allocate the encoder context"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Failed to allocate the encoder context"; return AVERROR(ENOMEM); } @@ -885,13 +952,15 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { auto input_stream = ost_[idx].input_stream; if (!input_stream) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "input stream info is needed for stream copy"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "input stream info is needed for stream copy"; return AVERROR_INVALIDDATA; } - ret = avcodec_parameters_to_context(enc_ctxs_[idx], input_stream->codecpar); + ret = avcodec_parameters_to_context(enc_ctxs_[idx], + input_stream->codecpar); avcodec_parameters_free(&input_stream->codecpar); - //if (ret >= 0) + // if (ret >= 0) // ret = av_opt_set_dict(enc_ctxs_[idx], &ost_[idx].encoder_opts); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, @@ -904,15 +973,18 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { ret = avcodec_parameters_from_context(par_src, enc_ctxs_[idx]); if (ret < 0) { avcodec_parameters_free(&par_src); - std::string msg = "avcodec_parameters_from_context failed: " + error_msg(ret); + std::string msg = + "avcodec_parameters_from_context failed: " + error_msg(ret); BMF_Error(BMF_TranscodeError, msg.c_str()); } if (!codec_tag) { unsigned int codec_tag_tmp; if (!output_fmt_ctx_->oformat->codec_tag || - av_codec_get_id(output_fmt_ctx_->oformat->codec_tag, par_src->codec_tag) == par_src->codec_id || - !av_codec_get_tag2(output_fmt_ctx_->oformat->codec_tag, par_src->codec_id, &codec_tag_tmp)) + av_codec_get_id(output_fmt_ctx_->oformat->codec_tag, + par_src->codec_tag) == par_src->codec_id || + !av_codec_get_tag2(output_fmt_ctx_->oformat->codec_tag, + par_src->codec_id, &codec_tag_tmp)) codec_tag = par_src->codec_tag; } @@ -926,21 +998,25 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { AVRational sar; switch (par_dst->codec_type) { case AVMEDIA_TYPE_AUDIO: - //if (audio_volume != 256) { - // av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n"); + // if (audio_volume != 256) { + // av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are + // incompatible (frames are not decoded)\n"); // exit_program(1); //} - if((par_dst->block_align == 1 || par_dst->block_align == 1152 || par_dst->block_align == 576) && par_dst->codec_id == AV_CODEC_ID_MP3) - par_dst->block_align= 0; - if(par_dst->codec_id == AV_CODEC_ID_AC3) - par_dst->block_align= 0; + if ((par_dst->block_align == 1 || par_dst->block_align == 1152 || + par_dst->block_align == 576) && + par_dst->codec_id == AV_CODEC_ID_MP3) + par_dst->block_align = 0; + if (par_dst->codec_id == AV_CODEC_ID_AC3) + par_dst->block_align = 0; break; case AVMEDIA_TYPE_VIDEO: if (input_stream->sample_aspect_ratio.num) sar = input_stream->sample_aspect_ratio; else sar = par_src->sample_aspect_ratio; - out_stream->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar; + out_stream->sample_aspect_ratio = par_dst->sample_aspect_ratio = + sar; out_stream->avg_frame_rate = input_stream->avg_frame_rate; out_stream->r_frame_rate = input_stream->r_frame_rate; break; @@ -975,7 +1051,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { enc_ctxs_[idx]->time_base = (AVRational){1, 1000000}; if (frame && frame->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(frame->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(tag->key, "time_base")) { std::string svalue = tag->value; int pos = svalue.find(","); @@ -994,7 +1071,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { r.num = stoi(svalue.substr(0, pos)); r.den = stoi(svalue.substr(pos + 1)); input_video_frame_rate_ = r; - if (input_video_frame_rate_.num > 0 && input_video_frame_rate_.den > 0) + if (input_video_frame_rate_.num > 0 && + input_video_frame_rate_.den > 0) video_frame_rate_ = input_video_frame_rate_; } } @@ -1024,7 +1102,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { } /** @addtogroup EncM * @{ - * @arg threads: specify the number of threads for encoder, "auto" by default + * @arg threads: specify the number of threads for encoder, "auto" by + * default * @} */ if (!video_params_.has_key("threads")) { av_dict_set(&enc_opts, "threads", "auto", 0); @@ -1041,14 +1120,14 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { if (do_psnr != 0) enc_ctxs_[0]->flags |= AV_CODEC_FLAG_PSNR; } - + /** @addtogroup EncM * @{ * @arg in_time_base: to set time base manually * @} */ if (video_params_.has_key("in_time_base")) { std::string svalue; - video_params_.get_string("in_time_base",svalue); + video_params_.get_string("in_time_base", svalue); video_params_.erase("in_time_base"); int pos = svalue.find(","); if (pos > 0) { @@ -1061,7 +1140,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { /** @addtogroup EncM * @{ - * @arg vsync: to set the video sync method on frame rate, "auto" by default. + * @arg vsync: to set the video sync method on frame rate, "auto" by + * default. * and it can be "cfr", "vfr", "passthrough", "drop" similar as ffmpeg * @} */ vsync_method_ = VSYNC_AUTO; @@ -1089,7 +1169,7 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { max_fr_string = std::to_string(max_fr); AVRational frame_rate; av_parse_video_rate(&frame_rate, max_fr_string.c_str()); - //the frame rate set by encode user + // the frame rate set by encode user video_frame_rate_ = frame_rate; video_params_.erase("max_fr"); @@ -1104,27 +1184,30 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { double fr; std::string fr_string; if (video_params_.json_value_["r"].is_string()) { - video_params_.get_string("r",fr_string); - } - else { + video_params_.get_string("r", fr_string); + } else { video_params_.get_double("r", fr); fr_string = std::to_string(fr); } AVRational frame_rate; av_parse_video_rate(&frame_rate, fr_string.c_str()); - //the frame rate set by encode user + // the frame rate set by encode user video_frame_rate_ = frame_rate; video_params_.erase("r"); } if (vsync_method_ == VSYNC_AUTO) { - if(!strcmp(output_fmt_ctx_->oformat->name, "avi")) + if (!strcmp(output_fmt_ctx_->oformat->name, "avi")) vsync_method_ = VSYNC_VFR; else - vsync_method_ = (output_fmt_ctx_->oformat->flags & AVFMT_VARIABLE_FPS) ? - ((output_fmt_ctx_->oformat->flags & AVFMT_NOTIMESTAMPS) ? - VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR; - //if ( ist + vsync_method_ = + (output_fmt_ctx_->oformat->flags & AVFMT_VARIABLE_FPS) + ? ((output_fmt_ctx_->oformat->flags & + AVFMT_NOTIMESTAMPS) + ? VSYNC_PASSTHROUGH + : VSYNC_VFR) + : VSYNC_CFR; + // if ( ist // && vsync_method_ == VSYNC_CFR // && input_files[ist->file_index]->ctx->nb_streams == 1 // && input_files[ist->file_index]->input_ts_offset == 0) { @@ -1143,12 +1226,15 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { if (in_stream_tbs_[idx].num <= 0 && in_stream_tbs_[idx].den <= 0) in_stream_tbs_[idx] = enc_ctxs_[idx]->time_base; - if (input_sample_aspect_ratio_.num > 0 && input_sample_aspect_ratio_.den > 0) { + if (input_sample_aspect_ratio_.num > 0 && + input_sample_aspect_ratio_.den > 0) { enc_ctxs_[idx]->sample_aspect_ratio = input_sample_aspect_ratio_; - output_stream_[idx]->sample_aspect_ratio = enc_ctxs_[idx]->sample_aspect_ratio; + output_stream_[idx]->sample_aspect_ratio = + enc_ctxs_[idx]->sample_aspect_ratio; } else { enc_ctxs_[idx]->sample_aspect_ratio = frame->sample_aspect_ratio; - output_stream_[idx]->sample_aspect_ratio = enc_ctxs_[idx]->sample_aspect_ratio; + output_stream_[idx]->sample_aspect_ratio = + enc_ctxs_[idx]->sample_aspect_ratio; } /** @addtogroup EncM @@ -1186,7 +1272,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { std::vector> params; video_params_.get_iterated(params); for (int i = 0; i < params.size(); i++) { - av_dict_set(&enc_opts, params[i].first.c_str(), params[i].second.c_str(), 0); + av_dict_set(&enc_opts, params[i].first.c_str(), + params[i].second.c_str(), 0); } } if (idx == 1) { @@ -1197,7 +1284,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { enc_ctxs_[idx]->sample_rate = 44100; enc_ctxs_[idx]->time_base = (AVRational){1, 44100}; enc_ctxs_[idx]->channels = 2; - enc_ctxs_[idx]->channel_layout = av_get_default_channel_layout(enc_ctxs_[idx]->channels); + enc_ctxs_[idx]->channel_layout = + av_get_default_channel_layout(enc_ctxs_[idx]->channels); /** @addtogroup EncM * @{ @@ -1206,19 +1294,22 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { if (audio_params_.has_key("channels")) { audio_params_.get_int("channels", enc_ctxs_[idx]->channels); audio_params_.erase("channels"); - enc_ctxs_[idx]->channel_layout = av_get_default_channel_layout(enc_ctxs_[idx]->channels); + enc_ctxs_[idx]->channel_layout = + av_get_default_channel_layout(enc_ctxs_[idx]->channels); } else { if (frame && frame->channels) { enc_ctxs_[idx]->channels = frame->channels; if (frame->channel_layout) enc_ctxs_[idx]->channel_layout = frame->channel_layout; else { - enc_ctxs_[idx]->channel_layout = av_get_default_channel_layout(frame->channels); + enc_ctxs_[idx]->channel_layout = + av_get_default_channel_layout(frame->channels); frame->channel_layout = enc_ctxs_[idx]->channel_layout; } } else if (frame && frame->channel_layout) { enc_ctxs_[idx]->channel_layout = frame->channel_layout; - enc_ctxs_[idx]->channels = av_get_channel_layout_nb_channels(enc_ctxs_[idx]->channel_layout); + enc_ctxs_[idx]->channels = av_get_channel_layout_nb_channels( + enc_ctxs_[idx]->channel_layout); } } @@ -1235,10 +1326,12 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { * @{ * @arg sample_rate: to set the sample_rate for audio encode * @} */ - //set the time base of audio encoder to be same as 1 / encoder sample_rate + // set the time base of audio encoder to be same as 1 / encoder + // sample_rate if (audio_params_.has_key("sample_rate")) { audio_params_.get_int("sample_rate", enc_ctxs_[idx]->sample_rate); - enc_ctxs_[idx]->time_base = (AVRational){1, enc_ctxs_[idx]->sample_rate}; + enc_ctxs_[idx]->time_base = + (AVRational){1, enc_ctxs_[idx]->sample_rate}; audio_params_.erase("sample_rate"); } else if (frame && frame->sample_rate) { enc_ctxs_[idx]->sample_rate = frame->sample_rate; @@ -1250,7 +1343,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { } if (frame && frame->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + while ((tag = av_dict_get(frame->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) if (!strcmp(tag->key, "time_base")) { std::string svalue = tag->value; int pos = svalue.find(","); @@ -1286,24 +1380,27 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { std::vector> params; audio_params_.get_iterated(params); for (int i = 0; i < params.size(); i++) { - av_dict_set(&enc_opts, params[i].first.c_str(), params[i].second.c_str(), 0); + av_dict_set(&enc_opts, params[i].first.c_str(), + params[i].second.c_str(), 0); } } if (output_fmt_ctx_->oformat->flags & AVFMT_GLOBALHEADER) enc_ctxs_[idx]->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; if (frame && frame->hw_frames_ctx) { - AVHWFramesContext* hw_frames_context = (AVHWFramesContext*)frame->hw_frames_ctx->data; - enc_ctxs_[idx]->hw_device_ctx = av_buffer_ref(hw_frames_context->device_ref); + AVHWFramesContext *hw_frames_context = + (AVHWFramesContext *)frame->hw_frames_ctx->data; + enc_ctxs_[idx]->hw_device_ctx = + av_buffer_ref(hw_frames_context->device_ref); enc_ctxs_[idx]->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); - } - else if (frame && device_ref) { + } else if (frame && device_ref) { enc_ctxs_[idx]->hw_device_ctx = av_buffer_ref(device_ref); } ret = avcodec_open2(enc_ctxs_[idx], codecs_[idx], &enc_opts); if (ret < 0) { BMFLOG_NODE(BMF_ERROR, node_id_) << "avcodec_open2 result: " << ret; - BMFLOG_NODE(BMF_ERROR, node_id_) << "Cannot open video/audio encoder for stream #" << idx; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Cannot open video/audio encoder for stream #" << idx; return ret; } else if (av_dict_count(enc_opts) > 0) { AVDictionaryEntry *t = NULL; @@ -1323,7 +1420,8 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctxs_[idx]); if (ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "Failed to copy encoder parameters to output stream"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "Failed to copy encoder parameters to output stream"; return ret; } @@ -1333,8 +1431,7 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { uint32_t tag = strtol(vtag_.c_str(), &next, 0); if (*next) tag = AV_RL32(vtag_.c_str()); - out_stream->codecpar->codec_tag = - enc_ctxs_[idx]->codec_tag = tag; + out_stream->codecpar->codec_tag = enc_ctxs_[idx]->codec_tag = tag; } enc_ctxs_[0]->framerate = video_frame_rate_; @@ -1347,8 +1444,7 @@ int CFFEncoder::init_codec(int idx, AVFrame* frame) { uint32_t tag = strtol(atag_.c_str(), &next, 0); if (*next) tag = AV_RL32(atag_.c_str()); - out_stream->codecpar->codec_tag = - enc_ctxs_[idx]->codec_tag = tag; + out_stream->codecpar->codec_tag = enc_ctxs_[idx]->codec_tag = tag; } } @@ -1381,8 +1477,9 @@ int CFFEncoder::flush() { while (1) { if (codecs_[idx]->type == AVMEDIA_TYPE_VIDEO && video_sync_) { - std::vector sync_frames; - video_sync_->process_video_frame(NULL, sync_frames, ost_[idx].frame_number); + std::vector sync_frames; + video_sync_->process_video_frame(NULL, sync_frames, + ost_[idx].frame_number); for (int j = 0; j < sync_frames.size(); j++) { int got_frame = 0; int ret = encode_and_write(sync_frames[j], idx, &got_frame); @@ -1394,7 +1491,8 @@ int CFFEncoder::flush() { if (got_packet == AVERROR(EAGAIN)) continue; if (ret != AVERROR_EOF && ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "encode and write failed ret:" << ret; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "encode and write failed ret:" << ret; return ret; } if (ret == AVERROR_EOF || got_packet != 0) @@ -1403,7 +1501,8 @@ int CFFEncoder::flush() { } b_flushed_ = true; - if (output_fmt_ctx_ && (push_output_ == OutputMode::OUTPUT_NOTHING or push_output_ == OutputMode::OUTPUT_MUXED_PACKET)) + if (output_fmt_ctx_ && (push_output_ == OutputMode::OUTPUT_NOTHING or + push_output_ == OutputMode::OUTPUT_MUXED_PACKET)) ret = av_write_trailer(output_fmt_ctx_); return ret; @@ -1416,10 +1515,13 @@ int CFFEncoder::close() { return ret; } -int CFFEncoder::handle_audio_frame(AVFrame *frame, bool is_flushing, int index) { +int CFFEncoder::handle_audio_frame(AVFrame *frame, bool is_flushing, + int index) { int ret = 0; - // if the frame is NULL and the audio_resampler is not inited, it should just return 0. - // this situation will happen when the encoder has audio stream but receive no audio packet. + // if the frame is NULL and the audio_resampler is not inited, it should + // just return 0. + // this situation will happen when the encoder has audio stream but receive + // no audio packet. if (output_audio_filter_graph_ == NULL && !frame) { return ret; } @@ -1445,25 +1547,31 @@ int CFFEncoder::handle_audio_frame(AVFrame *frame, bool is_flushing, int index) out_config.frame_size = enc_ctxs_[index]->frame_size; in_cfgs[0] = in_config; out_cfgs[0] = out_config; - if (output_audio_filter_graph_->config_graph(descr, in_cfgs, out_cfgs) != 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "output audio filter graph config failed"; + if (output_audio_filter_graph_->config_graph(descr, in_cfgs, + out_cfgs) != 0) { + BMFLOG_NODE(BMF_ERROR, node_id_) + << "output audio filter graph config failed"; return -1; } } - std::vector filter_frame_list; - ret = output_audio_filter_graph_->get_filter_frame(frame, 0, 0, filter_frame_list); + std::vector filter_frame_list; + ret = output_audio_filter_graph_->get_filter_frame(frame, 0, 0, + filter_frame_list); if (ret != 0 && ret != AVERROR_EOF) { - std::string err_msg = "Failed to inject frame into filter network, in encoder"; + std::string err_msg = + "Failed to inject frame into filter network, in encoder"; BMF_Error(BMF_TranscodeFatalError, err_msg.c_str()); } if (frame) av_frame_free(&frame); int got_frame = 0; - for (int i=0; ibuffer_sink_ctx_[0]); - filter_frame_list[i]->pts = av_rescale_q(filter_frame_list[i]->pts, tb, enc_ctxs_[1]->time_base); + for (int i = 0; i < filter_frame_list.size(); i++) { + AVRational tb = av_buffersink_get_time_base( + output_audio_filter_graph_->buffer_sink_ctx_[0]); + filter_frame_list[i]->pts = av_rescale_q(filter_frame_list[i]->pts, tb, + enc_ctxs_[1]->time_base); int ret = encode_and_write(filter_frame_list[i], index, &got_frame); av_frame_free(&filter_frame_list[i]); } @@ -1476,20 +1584,23 @@ bool CFFEncoder::need_output_video_filter_graph(AVFrame *frame) { width_ = frame->width; height_ = frame->height; } - if (width_!=0 && height_ != 0 && (width_ != frame->width || height_ != frame->height)) + if (width_ != 0 && height_ != 0 && + (width_ != frame->width || height_ != frame->height)) return true; if (frame->format != pix_fmt_) return true; return false; } -int CFFEncoder::handle_video_frame(AVFrame *frame, bool is_flushing, int index) { +int CFFEncoder::handle_video_frame(AVFrame *frame, bool is_flushing, + int index) { AVFrame *resize_frame = NULL; int ret; - std::vector filter_frames; - std::vector sync_frames; + std::vector filter_frames; + std::vector sync_frames; - if (output_video_filter_graph_ == NULL && need_output_video_filter_graph(frame)) { + if (output_video_filter_graph_ == NULL && + need_output_video_filter_graph(frame)) { std::map in_cfgs; std::map out_cfgs; output_video_filter_graph_ = std::make_shared(); @@ -1503,39 +1614,48 @@ int CFFEncoder::handle_video_frame(AVFrame *frame, bool is_flushing, int index) in_cfgs[0] = in_config; out_cfgs[0] = out_config; char args[100]; - snprintf(args, 100, "scale=%d:%d,format=pix_fmts=%s", - width_, height_, av_get_pix_fmt_name(pix_fmt_)); + snprintf(args, 100, "scale=%d:%d,format=pix_fmts=%s", width_, height_, + av_get_pix_fmt_name(pix_fmt_)); std::string args_str = args; std::string descr = "[i0_0]" + args_str + "[o0_0]"; if (frame->hw_frames_ctx) { - output_video_filter_graph_->hw_frames_ctx_map_[0] = av_buffer_ref(frame->hw_frames_ctx); + output_video_filter_graph_->hw_frames_ctx_map_[0] = + av_buffer_ref(frame->hw_frames_ctx); } - if (output_video_filter_graph_->config_graph(descr, in_cfgs, out_cfgs) != 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "output video filter graph config failed"; + if (output_video_filter_graph_->config_graph(descr, in_cfgs, + out_cfgs) != 0) { + BMFLOG_NODE(BMF_ERROR, node_id_) + << "output video filter graph config failed"; return -1; } } if (output_video_filter_graph_) { - ret = output_video_filter_graph_->get_filter_frame(frame, 0, 0, filter_frames); + ret = output_video_filter_graph_->get_filter_frame(frame, 0, 0, + filter_frames); if (ret != 0 && ret != AVERROR_EOF) { - std::string err_msg = "Failed to inject frame into filter network, in encoder"; + std::string err_msg = + "Failed to inject frame into filter network, in encoder"; BMF_Error(BMF_TranscodeFatalError, err_msg.c_str()); } av_frame_free(&frame); - } - else + } else filter_frames.push_back(frame); - for (int i=0; i < filter_frames.size(); i++) { - AVFrame* filter_frame = filter_frames[i]; + for (int i = 0; i < filter_frames.size(); i++) { + AVFrame *filter_frame = filter_frames[i]; if (video_sync_ == NULL) { - video_sync_ = std::make_shared(in_stream_tbs_[0], enc_ctxs_[0]->time_base, input_video_frame_rate_, video_frame_rate_, stream_start_time_, stream_first_dts_, vsync_method_, ost_[0].max_frames, ost_[0].min_frames); + video_sync_ = std::make_shared( + in_stream_tbs_[0], enc_ctxs_[0]->time_base, + input_video_frame_rate_, video_frame_rate_, stream_start_time_, + stream_first_dts_, vsync_method_, ost_[0].max_frames, + ost_[0].min_frames); } - video_sync_->process_video_frame(filter_frame, sync_frames, ost_[0].frame_number); + video_sync_->process_video_frame(filter_frame, sync_frames, + ost_[0].frame_number); for (int j = 0; j < sync_frames.size(); j++) { int got_frame = 0; int ret = encode_and_write(sync_frames[j], index, &got_frame); @@ -1552,25 +1672,26 @@ int CFFEncoder::handle_frame(AVFrame *frame, int index) { int ret = 0; frame->pict_type = AV_PICTURE_TYPE_NONE; - if (index == 0 ) { + if (index == 0) { handle_video_frame(frame, false, 0); return ret; } else if (index == 1) { if (frame->channel_layout == 0) { if (frame->channels) - frame->channel_layout = av_get_default_channel_layout(frame->channels); + frame->channel_layout = + av_get_default_channel_layout(frame->channels); else frame->channel_layout = enc_ctxs_[index]->channel_layout; } if (frame->channels == 0) { if (frame->channel_layout) - frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); + frame->channels = + av_get_channel_layout_nb_channels(frame->channel_layout); else frame->channels = enc_ctxs_[index]->channels; } ret = handle_audio_frame(frame, false, 1); return ret; - } return 0; } @@ -1581,29 +1702,34 @@ int CFFEncoder::streamcopy(AVPacket *ipkt, AVPacket *opkt, int idx) { av_init_packet(opkt); if (ipkt->pts != AV_NOPTS_VALUE) - opkt->pts = av_rescale_q(ipkt->pts, enc_ctxs_[idx]->time_base, output_stream_[idx]->time_base); + opkt->pts = av_rescale_q(ipkt->pts, enc_ctxs_[idx]->time_base, + output_stream_[idx]->time_base); else opkt->pts = AV_NOPTS_VALUE; if (ipkt->dts != AV_NOPTS_VALUE) - opkt->dts = av_rescale_q(ipkt->dts, enc_ctxs_[idx]->time_base, output_stream_[idx]->time_base); + opkt->dts = av_rescale_q(ipkt->dts, enc_ctxs_[idx]->time_base, + output_stream_[idx]->time_base); else opkt->dts = AV_NOPTS_VALUE; - if (output_stream_[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) { + if (output_stream_[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && + ipkt->dts != AV_NOPTS_VALUE) { AVCodecParameters *cpar = output_stream_[idx]->codecpar; int duration = av_get_audio_frame_duration2(cpar, ipkt->size); - if(!duration) + if (!duration) duration = cpar->frame_size; - opkt->dts = opkt->pts = av_rescale_delta(enc_ctxs_[idx]->time_base, ipkt->dts, - (AVRational){1, cpar->sample_rate}, duration, - &ost_[idx].filter_in_rescale_delta_last, - output_stream_[idx]->time_base); + opkt->dts = opkt->pts = + av_rescale_delta(enc_ctxs_[idx]->time_base, ipkt->dts, + (AVRational){1, cpar->sample_rate}, duration, + &ost_[idx].filter_in_rescale_delta_last, + output_stream_[idx]->time_base); } - opkt->duration = av_rescale_q(ipkt->duration, enc_ctxs_[idx]->time_base, output_stream_[idx]->time_base); + opkt->duration = av_rescale_q(ipkt->duration, enc_ctxs_[idx]->time_base, + output_stream_[idx]->time_base); - opkt->flags = ipkt->flags; + opkt->flags = ipkt->flags; if (ipkt->buf) { opkt->buf = av_buffer_ref(ipkt->buf); @@ -1634,8 +1760,11 @@ int CFFEncoder::process(Task &task) { if (!num_input_streams_) num_input_streams_ = task.get_inputs().size(); - while (((task.get_inputs().find(0) != task.get_inputs().end() && !task.get_inputs()[0]->empty()) || - (task.get_inputs().find(1) != task.get_inputs().end() && !task.get_inputs()[1]->empty())) && !b_eof_) { + while (((task.get_inputs().find(0) != task.get_inputs().end() && + !task.get_inputs()[0]->empty()) || + (task.get_inputs().find(1) != task.get_inputs().end() && + !task.get_inputs()[1]->empty())) && + !b_eof_) { for (int index = 0; index < num_input_streams_; index++) { if (task.get_inputs().find(index) == task.get_inputs().end()) continue; @@ -1647,42 +1776,48 @@ int CFFEncoder::process(Task &task) { task.pop_packet_from_input_queue(index, packet); if (packet.timestamp() == BMF_EOF) { b_stream_eof_[index] = true; - b_eof_ = num_input_streams_ == 1 ? b_stream_eof_[0] : (b_stream_eof_[0] & b_stream_eof_[1]); - if (!enc_ctxs_[index] && !null_output_) {//at the begining the stream got EOF + b_eof_ = num_input_streams_ == 1 + ? b_stream_eof_[0] + : (b_stream_eof_[0] & b_stream_eof_[1]); + if (!enc_ctxs_[index] && + !null_output_) { // at the begining the stream got EOF ret = init_codec(index, NULL); if (ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "init codec error when eof got at begining"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "init codec error when eof got at begining"; return ret; } } continue; } - if(packet.is>()){ - ost_[index].input_stream = packet.get>(); + if (packet.is>()) { + ost_[index].input_stream = + packet.get>(); ost_[index].encoding_needed = false; continue; } if (ost_[index].frame_number >= ost_[index].max_frames) continue; - - if(packet.is()){ + + if (packet.is()) { BMFAVPacket av_packet = packet.get(); auto in_pkt = ffmpeg::from_bmf_av_packet(av_packet, false); ost_[index].encoding_needed = false; if (!enc_ctxs_[index]) { ret = init_codec(index, NULL); if (ret < 0) { - BMFLOG_NODE(BMF_ERROR, node_id_) << "init codec error when avpacket input"; + BMFLOG_NODE(BMF_ERROR, node_id_) + << "init codec error when avpacket input"; return ret; } } if (!stream_inited_) { AVPacket *pkt = av_packet_clone(in_pkt); - stream_copy_cache_.push_back(std::pair(pkt, index)); - } - else { + stream_copy_cache_.push_back( + std::pair(pkt, index)); + } else { while (stream_copy_cache_.size()) { auto tmp = stream_copy_cache_.front(); stream_copy_cache_.erase(stream_copy_cache_.begin()); @@ -1700,11 +1835,14 @@ int CFFEncoder::process(Task &task) { auto video_frame = packet.get(); frame = ffmpeg::from_video_frame(video_frame, false); - if (oformat_ == "image2pipe" && push_output_) { //only support to carry orig pts time for images + if (oformat_ == "image2pipe" && + push_output_) { // only support to carry orig pts time for + // images std::string stime = ""; if (frame->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(frame->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(tag->key, "orig_pts_time")) { stime = tag->value; break; @@ -1754,7 +1892,8 @@ int CFFEncoder::process(Task &task) { current_frame_pts_ = frame->pts; handle_frame(frame, index); } else { - frame_cache_.push_back(std::pair(frame, index)); + frame_cache_.push_back( + std::pair(frame, index)); } } else { handle_frame(frame, index); @@ -1777,10 +1916,11 @@ int CFFEncoder::process(Task &task) { } } flush(); - if (task.get_outputs().size() > 0 || push_output_ != OutputMode::OUTPUT_NOTHING) { + if (task.get_outputs().size() > 0 || + push_output_ != OutputMode::OUTPUT_NOTHING) { Packet pkt = Packet::generate_eof_packet(); assert(pkt.timestamp() == BMF_EOF); - for (int i = 0; i < task.get_outputs().size(); i++){ + for (int i = 0; i < task.get_outputs().size(); i++) { task.get_outputs()[i]->push(pkt); } } @@ -1791,16 +1931,16 @@ int CFFEncoder::process(Task &task) { return PROCESS_OK; } -void CFFEncoder::set_callback(std::function callback_endpoint) { +void CFFEncoder::set_callback( + std::function callback_endpoint) { callback_endpoint_ = callback_endpoint; } REGISTER_MODULE_CLASS(CFFEncoder) REGISTER_MODULE_INFO(CFFEncoder, info) { info.module_description = "Builtin FFmpeg-based encoding module."; - info.module_tag = ModuleTag::BMF_TAG_ENCODER| - ModuleTag::BMF_TAG_MUXER| - ModuleTag::BMF_TAG_IMAGE_PROCESSOR| - ModuleTag::BMF_TAG_AUDIO_PROCESSOR| - ModuleTag::BMF_TAG_VIDEO_PROCESSOR; + info.module_tag = ModuleTag::BMF_TAG_ENCODER | ModuleTag::BMF_TAG_MUXER | + ModuleTag::BMF_TAG_IMAGE_PROCESSOR | + ModuleTag::BMF_TAG_AUDIO_PROCESSOR | + ModuleTag::BMF_TAG_VIDEO_PROCESSOR; } diff --git a/bmf/c_modules/src/ffmpeg_filter.cpp b/bmf/c_modules/src/ffmpeg_filter.cpp index ea0523de..8f4b575d 100644 --- a/bmf/c_modules/src/ffmpeg_filter.cpp +++ b/bmf/c_modules/src/ffmpeg_filter.cpp @@ -18,7 +18,6 @@ #include USE_BMF_SDK_NS - CFFFilter::CFFFilter(int node_id, JsonParam option) { node_id_ = node_id; num_input_streams_ = 0; @@ -33,23 +32,20 @@ CFFFilter::CFFFilter(int node_id, JsonParam option) { stream_first_dts_ = AV_NOPTS_VALUE; option_ = option; - //avfilter_register_all(); + // avfilter_register_all(); } -CFFFilter::~CFFFilter() { - clean(); -} +CFFFilter::~CFFFilter() { clean(); } bool CFFFilter::is_hungry(int input_stream_id) { - if (input_cache_.count(input_stream_id) == 0 || input_cache_[input_stream_id].size() < 5 || filter_graph_ == NULL) { + if (input_cache_.count(input_stream_id) == 0 || + input_cache_[input_stream_id].size() < 5 || filter_graph_ == NULL) { return true; } return false; } -bool CFFFilter::is_infinity() { - return is_inf_; -} +bool CFFFilter::is_infinity() { return is_inf_; } int CFFFilter::clean() { reset_check_mutex_.lock(); @@ -71,16 +67,20 @@ int CFFFilter::close() { return 0; } -int CFFFilter::parse_filter(std::vector &f_param, int idx, std::string &result) { +int CFFFilter::parse_filter(std::vector &f_param, int idx, + std::string &result) { std::vector in_param; int ret; f_param[idx].get_object_list("inputs", in_param); //"stream" means the id of input/output stream - //"pin" mainly used for the sequence number of the pin of the filter which the input stream connected to, and for output of the filter, the pin should always be zero now. + //"pin" mainly used for the sequence number of the pin of the filter which + //the input stream connected to, and for output of the filter, the pin + //should always be zero now. - for (int i = 0; i < in_param.size(); i++) {// [i0_0] [i1_0] [i2_0] [i3_0] ... [inputStream_Pin] + for (int i = 0; i < in_param.size(); + i++) { // [i0_0] [i1_0] [i2_0] [i3_0] ... [inputStream_Pin] if (in_param[i].has_key("stream") && in_param[i].has_key("pin")) { int stream_id; in_param[i].get_int("stream", stream_id); @@ -93,7 +93,8 @@ int CFFFilter::parse_filter(std::vector &f_param, int idx, std::strin } std::vector out_param; f_param[idx].get_object_list("outputs", out_param); - for (int i = 0; i < out_param.size(); i++) {// [o0_0] [o1_0] .... [outputStream_Pin] + for (int i = 0; i < out_param.size(); + i++) { // [o0_0] [o1_0] .... [outputStream_Pin] if (out_param[i].has_key("stream") && out_param[i].has_key("pin")) { int stream_id; out_param[i].get_int("stream", stream_id); @@ -149,7 +150,7 @@ int CFFFilter::graph_descr(JsonParam &option, std::string &result) { int ret; if (!option.has_key("filters")) { - //Log: No filter config + // Log: No filter config BMFLOG_NODE(BMF_ERROR, node_id_) << "No filter config"; return -1; } @@ -187,14 +188,17 @@ int CFFFilter::init_filtergraph() { config_[it->first].channels = frm->channels; config_[it->first].channel_layout = frm->channel_layout; - config_[it->first].tb = (frm->width && frm->height) ? (AVRational){1, 25} : (AVRational){1, frm->sample_rate}; + config_[it->first].tb = (frm->width && frm->height) + ? (AVRational){1, 25} + : (AVRational){1, frm->sample_rate}; if (frm->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(frm->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(frm->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(tag->key, "time_base")) { std::string svalue = tag->value; - int pos = svalue.find(",");//"num,den" + int pos = svalue.find(","); //"num,den" if (pos > 0) { AVRational r; r.num = stoi(svalue.substr(0, pos)); @@ -233,12 +237,12 @@ int CFFFilter::init_filtergraph() { filter_graph_ = new FilterGraph(); std::map out_cfgs; - //AVFrame *frame = input_cache_.begin()->second.front(); + // AVFrame *frame = input_cache_.begin()->second.front(); for (auto it : input_cache_) { auto ctx = it.second.front()->hw_frames_ctx; if (ctx) { filter_graph_->hw_frames_ctx_map_[it.first] = av_buffer_ref(ctx); - } + } } ret = filter_graph_->config_graph(g_desc_, config_, out_cfgs); @@ -250,19 +254,23 @@ int CFFFilter::init_filtergraph() { } Packet CFFFilter::convert_avframe_to_packet(AVFrame *frame, int index) { - AVRational tb = av_buffersink_get_time_base(filter_graph_->buffer_sink_ctx_[index]); + AVRational tb = + av_buffersink_get_time_base(filter_graph_->buffer_sink_ctx_[index]); std::string s_tb = std::to_string(tb.num) + "," + std::to_string(tb.den); av_dict_set(&frame->metadata, "time_base", s_tb.c_str(), 0); if (frame->width > 0) { - AVRational frame_rate = av_buffersink_get_frame_rate(filter_graph_->buffer_sink_ctx_[index]); + AVRational frame_rate = av_buffersink_get_frame_rate( + filter_graph_->buffer_sink_ctx_[index]); if (frame_rate.num > 0 && frame_rate.den > 0) - s_tb = std::to_string(frame_rate.num) + "," + std::to_string(frame_rate.den); + s_tb = std::to_string(frame_rate.num) + "," + + std::to_string(frame_rate.den); else s_tb = "0,1"; av_dict_set(&frame->metadata, "frame_rate", s_tb.c_str(), 0); - AVRational sar = av_buffersink_get_sample_aspect_ratio(filter_graph_->buffer_sink_ctx_[index]); + AVRational sar = av_buffersink_get_sample_aspect_ratio( + filter_graph_->buffer_sink_ctx_[index]); if (sar.num > 0 && sar.den > 0) s_tb = std::to_string(sar.num) + "," + std::to_string(sar.den); else @@ -289,8 +297,12 @@ Packet CFFFilter::convert_avframe_to_packet(AVFrame *frame, int index) { auto packet = Packet(video_frame); if (orig_pts_time_cache_.size() > 0) { if (orig_pts_time_cache_.count(frame->coded_picture_number) > 0) { - av_dict_set(&frame->metadata, "orig_pts_time", orig_pts_time_cache_[frame->coded_picture_number].c_str(), 0); - packet.set_time(std::stod(orig_pts_time_cache_[frame->coded_picture_number])); + av_dict_set( + &frame->metadata, "orig_pts_time", + orig_pts_time_cache_[frame->coded_picture_number].c_str(), + 0); + packet.set_time(std::stod( + orig_pts_time_cache_[frame->coded_picture_number])); orig_pts_time_cache_.erase(frame->coded_picture_number); } } @@ -310,11 +322,12 @@ std::string get_meta_info(AVFrame *temp_frame, std::string key) { if (temp_frame != NULL) { if (temp_frame->metadata) { AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(temp_frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(temp_frame->metadata, "", tag, + AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(tag->key, key.c_str())) { std::string svalue = tag->value; - //int64_t stream_frame_number = stol(svalue); - //return stream_frame_number; + // int64_t stream_frame_number = stol(svalue); + // return stream_frame_number; return svalue; } } @@ -324,7 +337,7 @@ std::string get_meta_info(AVFrame *temp_frame, std::string key) { } int CFFFilter::get_cache_frame(int index, AVFrame *&frame, int &choose_index) { - //from input cache, choose the first frame decode from the same node. + // from input cache, choose the first frame decode from the same node. int choose_node_id = -1; int64_t choose_node_frame_number = INT64_MAX; choose_index = index; @@ -344,16 +357,19 @@ int CFFFilter::get_cache_frame(int index, AVFrame *&frame, int &choose_index) { int same_node_index = input_stream_node.first; if (input_cache_[same_node_index].size() > 0) { AVFrame *temp_frame = input_cache_[same_node_index].front(); - std::string svalue = get_meta_info(temp_frame, "stream_frame_number"); + std::string svalue = + get_meta_info(temp_frame, "stream_frame_number"); int64_t stream_frame_number = svalue != "" ? stol(svalue) : -1; - if (stream_frame_number != -1 && stream_frame_number < choose_node_frame_number) { + if (stream_frame_number != -1 && + stream_frame_number < choose_node_frame_number) { choose_node_frame_number = stream_frame_number; choose_index = same_node_index; } svalue = get_meta_info(temp_frame, "orig_pts_time"); if (svalue != "") - orig_pts_time_cache_[temp_frame->coded_picture_number] = svalue; + orig_pts_time_cache_[temp_frame->coded_picture_number] = + svalue; } } } @@ -405,17 +421,20 @@ int CFFFilter::process_filter_graph(Task &task) { if (num_input_streams_ > 0) { while (true) { std::map> output_frames; - int ret = filter_graph_->reap_filters(output_frames, push_frame_flag); + int ret = + filter_graph_->reap_filters(output_frames, push_frame_flag); push_frame_flag = 0; for (auto output_frame : output_frames) { - for (int index = 0; index < output_frame.second.size(); index++) { + for (int index = 0; index < output_frame.second.size(); + index++) { if (output_frame.second[index] == NULL) { out_eof_[output_frame.first] = true; continue; } static int conver_av_frame = 0; conver_av_frame++; - auto packet = convert_avframe_to_packet(output_frame.second[index], output_frame.first); + auto packet = convert_avframe_to_packet( + output_frame.second[index], output_frame.first); av_frame_free(&(output_frame.second[index])); task.fill_output_packet(output_frame.first, packet); } @@ -456,7 +475,8 @@ int CFFFilter::process_filter_graph(Task &task) { } } } else { - // this is a source filter, so we get frame from sink for one time in a process. + // this is a source filter, so we get frame from sink for one time in a + // process. std::map> output_frames; int ret = filter_graph_->reap_filters(output_frames, 0); for (auto output_frame : output_frames) { @@ -465,7 +485,8 @@ int CFFFilter::process_filter_graph(Task &task) { out_eof_[output_frame.first] = true; continue; } - auto packet = convert_avframe_to_packet(output_frame.second[index], output_frame.first); + auto packet = convert_avframe_to_packet( + output_frame.second[index], output_frame.first); av_frame_free(&(output_frame.second[index])); task.fill_output_packet(output_frame.first, packet); } @@ -491,9 +512,11 @@ int CFFFilter::process(Task &task) { bool b_eof = true; int ret = 0; - //in case of possiblity to be used in dynamical remove/add, just return now - if (num_input_streams_ != 0 && num_input_streams_ != task.get_inputs().size()) { - BMFLOG_NODE(BMF_INFO, node_id_) << "the inputs number has changed, just return"; + // in case of possiblity to be used in dynamical remove/add, just return now + if (num_input_streams_ != 0 && + num_input_streams_ != task.get_inputs().size()) { + BMFLOG_NODE(BMF_INFO, node_id_) + << "the inputs number has changed, just return"; return PROCESS_OK; } @@ -514,7 +537,7 @@ int CFFFilter::process(Task &task) { } } - //cache task data to input_cache + // cache task data to input_cache for (int index = 0; index < num_input_streams_; index++) { while (task.pop_packet_from_input_queue(index, packet)) { if (packet.timestamp() == BMF_EOF) { @@ -524,7 +547,8 @@ int CFFFilter::process(Task &task) { } if (packet.timestamp() == BMF_PAUSE) { - BMFLOG_NODE(BMF_INFO, node_id_) << "Got BMF PAUSE in the filter"; + BMFLOG_NODE(BMF_INFO, node_id_) + << "Got BMF PAUSE in the filter"; for (auto &outputs : task.get_outputs()) outputs.second->push(packet); continue; @@ -537,14 +561,12 @@ int CFFFilter::process(Task &task) { } if (packet.is()) { - auto& video_frame = packet.get(); + auto &video_frame = packet.get(); frame = ffmpeg::from_video_frame(video_frame, true); - } - else if (packet.is()) { - auto& audio_frame = packet.get(); + } else if (packet.is()) { + auto &audio_frame = packet.get(); frame = ffmpeg::from_audio_frame(audio_frame, true); - } - else { + } else { return PROCESS_ERROR; } input_cache_[index].push(frame); @@ -563,7 +585,7 @@ int CFFFilter::process(Task &task) { task.fill_output_packet(index, packet); } task.set_timestamp(DONE); - //clear input_cache + // clear input_cache for (auto input : input_cache_) { while (input.second.size() > 0) { AVFrame *frame = input.second.front(); @@ -595,8 +617,7 @@ int CFFFilter::reset() { REGISTER_MODULE_CLASS(CFFFilter); REGISTER_MODULE_INFO(CFFFilter, info) { info.module_description = "Builtin FFmpeg-based filting module."; - info.module_tag = ModuleTag::BMF_TAG_FILTER| - ModuleTag::BMF_TAG_IMAGE_PROCESSOR| - ModuleTag::BMF_TAG_AUDIO_PROCESSOR| - ModuleTag::BMF_TAG_VIDEO_PROCESSOR; + info.module_tag = + ModuleTag::BMF_TAG_FILTER | ModuleTag::BMF_TAG_IMAGE_PROCESSOR | + ModuleTag::BMF_TAG_AUDIO_PROCESSOR | ModuleTag::BMF_TAG_VIDEO_PROCESSOR; } diff --git a/bmf/c_modules/src/ffmpeg_func_registry.cpp b/bmf/c_modules/src/ffmpeg_func_registry.cpp index 94340bf4..92a03610 100644 --- a/bmf/c_modules/src/ffmpeg_func_registry.cpp +++ b/bmf/c_modules/src/ffmpeg_func_registry.cpp @@ -2,18 +2,16 @@ #include #include -namespace bmf_sdk{ +namespace bmf_sdk { namespace { -class FFMPEGRegistry -{ -public: - FFMPEGRegistry() - { - LogBuffer::register_av_log_set_callback((void*)av_log_set_callback); +class FFMPEGRegistry { + public: + FFMPEGRegistry() { + LogBuffer::register_av_log_set_callback((void *)av_log_set_callback); } }; FFMPEGRegistry sFFRegistery; - -}}; //bmf_sdk \ No newline at end of file +} +}; // bmf_sdk \ No newline at end of file diff --git a/bmf/c_modules/src/go_mock_decoder.cpp b/bmf/c_modules/src/go_mock_decoder.cpp index 1584e3ba..ae3b4d20 100644 --- a/bmf/c_modules/src/go_mock_decoder.cpp +++ b/bmf/c_modules/src/go_mock_decoder.cpp @@ -17,7 +17,8 @@ #include #include -GoMockDecoder::GoMockDecoder(int node_id, JsonParam json_param) : Module(node_id, json_param) { +GoMockDecoder::GoMockDecoder(int node_id, JsonParam json_param) + : Module(node_id, json_param) { BMFLOG_NODE(BMF_INFO, node_id_) << "init"; return; } @@ -25,7 +26,7 @@ GoMockDecoder::GoMockDecoder(int node_id, JsonParam json_param) : Module(node_id int GoMockDecoder::process(Task &task) { BMFLOG_NODE(BMF_INFO, node_id_) << "process"; number_++; - for (auto output_queue:task.get_outputs()) { + for (auto output_queue : task.get_outputs()) { auto avpkt = BMFAVPacket(100); avpkt.data().fill_(0); avpkt.set_pts(number_); @@ -33,25 +34,23 @@ int GoMockDecoder::process(Task &task) { auto packet = Packet(avpkt); packet.set_timestamp(number_); - BMFLOG_NODE(BMF_INFO, node_id_) << packet.timestamp() << "data type:" << packet.type_info().name; + BMFLOG_NODE(BMF_INFO, node_id_) + << packet.timestamp() << "data type:" << packet.type_info().name; task.fill_output_packet(output_queue.first, packet); sleep(1); if (number_ == 10) { - task.fill_output_packet(output_queue.first, Packet::generate_eof_packet()); + task.fill_output_packet(output_queue.first, + Packet::generate_eof_packet()); task.set_timestamp(DONE); } } - BMFLOG_NODE(BMF_INFO, node_id_) << "GoMockDecoder process result output queue size: " - << task.get_outputs()[0]->size() - << std::endl; + BMFLOG_NODE(BMF_INFO, node_id_) + << "GoMockDecoder process result output queue size: " + << task.get_outputs()[0]->size() << std::endl; return 0; } -int GoMockDecoder::reset() { - return 0; -} +int GoMockDecoder::reset() { return 0; } -int GoMockDecoder::close() { - return 0; -} +int GoMockDecoder::close() { return 0; } diff --git a/bmf/c_modules/src/mock_decoder.cpp b/bmf/c_modules/src/mock_decoder.cpp index 61ef53f2..8040d8a1 100644 --- a/bmf/c_modules/src/mock_decoder.cpp +++ b/bmf/c_modules/src/mock_decoder.cpp @@ -16,7 +16,8 @@ #include "mock_decoder.h" #include -MockDecoder::MockDecoder(int node_id, JsonParam json_param) : Module(node_id, json_param) { +MockDecoder::MockDecoder(int node_id, JsonParam json_param) + : Module(node_id, json_param) { BMFLOG_NODE(BMF_INFO, node_id_) << "init"; return; } @@ -24,28 +25,27 @@ MockDecoder::MockDecoder(int node_id, JsonParam json_param) : Module(node_id, js int MockDecoder::process(Task &task) { BMFLOG_NODE(BMF_INFO, node_id_) << "process"; number_++; - for (auto output_queue:task.get_outputs()) { + for (auto output_queue : task.get_outputs()) { std::string data = "hello world"; auto packet = Packet(data); packet.set_timestamp(number_); - BMFLOG_NODE(BMF_INFO, node_id_) << packet.timestamp() << "data type:" << packet.type_info().name; - task.fill_output_packet(output_queue.first,packet); + BMFLOG_NODE(BMF_INFO, node_id_) + << packet.timestamp() << "data type:" << packet.type_info().name; + task.fill_output_packet(output_queue.first, packet); sleep(1); if (number_ == 10) { - task.fill_output_packet(output_queue.first, Packet::generate_eof_packet()); + task.fill_output_packet(output_queue.first, + Packet::generate_eof_packet()); task.set_timestamp(DONE); } } - BMFLOG_NODE(BMF_INFO, node_id_) << "MockDecoder process result output queue size: " << task.get_outputs()[0]->size() - << std::endl; + BMFLOG_NODE(BMF_INFO, node_id_) + << "MockDecoder process result output queue size: " + << task.get_outputs()[0]->size() << std::endl; return 0; } -int MockDecoder::reset() { - return 0; -} +int MockDecoder::reset() { return 0; } -int MockDecoder::close() { - return 0; -} +int MockDecoder::close() { return 0; } diff --git a/bmf/c_modules/src/pass_through_module.cpp b/bmf/c_modules/src/pass_through_module.cpp index 6fa0f0f0..5be95a3f 100644 --- a/bmf/c_modules/src/pass_through_module.cpp +++ b/bmf/c_modules/src/pass_through_module.cpp @@ -15,7 +15,8 @@ #include "pass_through_module.h" #include -PassThroughModule::PassThroughModule(int node_id, JsonParam json_param) : Module(node_id, json_param) { +PassThroughModule::PassThroughModule(int node_id, JsonParam json_param) + : Module(node_id, json_param) { BMFLOG_NODE(BMF_INFO, node_id_) << "pass through module"; last_input_num_ = 0; last_output_num_ = 0; @@ -24,23 +25,25 @@ PassThroughModule::PassThroughModule(int node_id, JsonParam json_param) : Module int PassThroughModule::process(Task &task) { if (task.get_inputs().size() != last_input_num_) { - BMFLOG_NODE(BMF_INFO, node_id_) << "Input Queue size changed from " << last_input_num_ - << " to " << task.get_inputs().size(); + BMFLOG_NODE(BMF_INFO, node_id_) << "Input Queue size changed from " + << last_input_num_ << " to " + << task.get_inputs().size(); last_input_num_ = task.get_inputs().size(); } if (task.get_outputs().size() != last_output_num_) { - BMFLOG_NODE(BMF_INFO, node_id_) << "Output Queue size changed from " << last_output_num_ - << " to " << task.get_outputs().size(); + BMFLOG_NODE(BMF_INFO, node_id_) << "Output Queue size changed from " + << last_output_num_ << " to " + << task.get_outputs().size(); last_output_num_ = task.get_outputs().size(); } if (in_eof_.size() != task.get_inputs().size()) { in_eof_.clear(); - for (auto input_queue:task.get_inputs()) + for (auto input_queue : task.get_inputs()) in_eof_[input_queue.first] = false; } - for (auto input_queue:task.get_inputs()) { + for (auto input_queue : task.get_inputs()) { Packet packet; if (in_eof_[input_queue.first] == true) @@ -51,14 +54,15 @@ int PassThroughModule::process(Task &task) { if (packet.timestamp() == BMF_EOF) { in_eof_[input_queue.first] = true; } - BMFLOG_NODE(BMF_INFO, node_id_) << "get packet :" << packet.timestamp() << " data:" - << packet.type_info().name << " in queue:" - << input_queue.first; + BMFLOG_NODE(BMF_INFO, node_id_) + << "get packet :" << packet.timestamp() + << " data:" << packet.type_info().name + << " in queue:" << input_queue.first; } } bool all_eof = true; - for (auto f_eof:in_eof_) { + for (auto f_eof : in_eof_) { if (f_eof.second == false) { all_eof = false; break; @@ -75,6 +79,4 @@ int PassThroughModule::reset() { return 0; } -int PassThroughModule::close() { - return 0; -} +int PassThroughModule::close() { return 0; } diff --git a/bmf/c_modules/src/video_sync.cpp b/bmf/c_modules/src/video_sync.cpp index fc5b5911..b4983607 100644 --- a/bmf/c_modules/src/video_sync.cpp +++ b/bmf/c_modules/src/video_sync.cpp @@ -12,26 +12,33 @@ * Lesser General Public License for more details. */ -#include"video_sync.h" - -static inline av_const int mid_pred(int a, int b, int c) -{ - if(a>b) { - if(c>b) { - if(c>a) b=a; - else b=c; +#include "video_sync.h" + +static inline av_const int mid_pred(int a, int b, int c) { + if (a > b) { + if (c > b) { + if (c > a) + b = a; + else + b = c; } } else { - if(b>c) { - if(c>a) b=c; - else b=a; + if (b > c) { + if (c > a) + b = c; + else + b = a; } } return b; } -VideoSync::VideoSync(AVRational input_stream_time_base, AVRational encode_time_base, AVRational filter_in_frame_rate, AVRational video_frame_rate, int64_t stream_start_time, int64_t stream_first_dts, int sync_method, int64_t max_frames, int64_t min_frames) -{ +VideoSync::VideoSync(AVRational input_stream_time_base, + AVRational encode_time_base, + AVRational filter_in_frame_rate, + AVRational video_frame_rate, int64_t stream_start_time, + int64_t stream_first_dts, int sync_method, + int64_t max_frames, int64_t min_frames) { input_stream_time_base_ = input_stream_time_base; encode_time_base_ = encode_time_base; filter_in_frame_rate_ = filter_in_frame_rate; @@ -44,17 +51,17 @@ VideoSync::VideoSync(AVRational input_stream_time_base, AVRational encode_time_b min_frames_ = min_frames; } -VideoSync::~VideoSync() -{ +VideoSync::~VideoSync() { if (nb_frames_drop_ > 0) BMFLOG(BMF_INFO) << "drop frames:" << nb_frames_drop_; if (nb_frames_dup_ > 0) BMFLOG(BMF_INFO) << "dup frames:" << nb_frames_dup_; } -int VideoSync::process_video_frame(AVFrame *frame, std::vector &output_frame, int64_t &frame_number) -{ - //translate to float pts +int VideoSync::process_video_frame(AVFrame *frame, + std::vector &output_frame, + int64_t &frame_number) { + // translate to float pts double float_pts = 0; AVRational temp_encode_time_base = encode_time_base_; int extra_bits = 0; @@ -63,7 +70,8 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu double delta0, delta; if (!frame) { - nb0_frames = nb_frames = mid_pred(last_nb0_frames_[0], last_nb0_frames_[1], last_nb0_frames_[2]); + nb0_frames = nb_frames = mid_pred( + last_nb0_frames_[0], last_nb0_frames_[1], last_nb0_frames_[2]); if (min_frames_ > 0 && frame_number <= min_frames_) nb0_frames = nb_frames = min_frames_ - frame_number; } else { @@ -71,22 +79,30 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu nb_frames = 1; extra_bits = av_clip(29 - av_log2(temp_encode_time_base.den), 0, 16); temp_encode_time_base.den <<= extra_bits; - float_pts = av_rescale_q(frame->pts, input_stream_time_base_, temp_encode_time_base); - //- (ost_start_time_ != AV_NOPTS_VALUE ? - // av_rescale_q(ost_start_time_, AV_TIME_BASE_Q, temp_encode_time_base) : 0); + float_pts = av_rescale_q(frame->pts, input_stream_time_base_, + temp_encode_time_base); + //- (ost_start_time_ != AV_NOPTS_VALUE ? + // av_rescale_q(ost_start_time_, AV_TIME_BASE_Q, + // temp_encode_time_base) : 0); float_pts /= 1 << extra_bits; - float_pts += FFSIGN(float_pts) * 1.0 / (1<<17); + float_pts += FFSIGN(float_pts) * 1.0 / (1 << 17); if (filter_in_frame_rate_.num > 0 && filter_in_frame_rate_.den > 0) { - duration = 1 / (av_q2d(filter_in_frame_rate_) * av_q2d(encode_time_base_)); + duration = + 1 / (av_q2d(filter_in_frame_rate_) * av_q2d(encode_time_base_)); } - if (stream_start_time_ != AV_NOPTS_VALUE && stream_first_dts_ != AV_NOPTS_VALUE && video_frame_rate_.num) - duration = FFMIN(duration, 1/(av_q2d(video_frame_rate_) * av_q2d(encode_time_base_))); + if (stream_start_time_ != AV_NOPTS_VALUE && + stream_first_dts_ != AV_NOPTS_VALUE && video_frame_rate_.num) + duration = FFMIN(duration, 1 / (av_q2d(video_frame_rate_) * + av_q2d(encode_time_base_))); - if (filter_in_frame_rate_.num == 0 && filter_in_frame_rate_.den == 0 - && lrint(frame->pkt_duration * av_q2d(input_stream_time_base_) / av_q2d(encode_time_base_)) > 0) - duration = lrintf(frame->pkt_duration * av_q2d(input_stream_time_base_) / av_q2d(encode_time_base_)); + if (filter_in_frame_rate_.num == 0 && filter_in_frame_rate_.den == 0 && + lrint(frame->pkt_duration * av_q2d(input_stream_time_base_) / + av_q2d(encode_time_base_)) > 0) + duration = + lrintf(frame->pkt_duration * av_q2d(input_stream_time_base_) / + av_q2d(encode_time_base_)); delta0 = float_pts - sync_opts_; delta = delta0 + duration; @@ -96,7 +112,8 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu if (delta0 < -0.6) { BMFLOG(BMF_INFO) << "Past duration" << -delta0 << " too large"; } else - BMFLOG(BMF_DEBUG) << "Clipping frame in rate conversion by " << -delta0; + BMFLOG(BMF_DEBUG) << "Clipping frame in rate conversion by " + << -delta0; float_pts = sync_opts_; duration += delta0; delta0 = 0; @@ -105,13 +122,15 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu switch (sync_method_) { case VSYNC_VSCFR: if (frame_number == 0 && delta0 >= 0.5) { - BMFLOG(BMF_DEBUG) << "Not duplicating " << (int)lrintf(delta0) << "initial frames"; + BMFLOG(BMF_DEBUG) << "Not duplicating " << (int)lrintf(delta0) + << "initial frames"; delta = duration; delta0 = 0; sync_opts_ = lrint(float_pts); } case VSYNC_CFR: - //if (frame_drop_threshold && delta < frame_drop_threshold && ost->frame_number) + // if (frame_drop_threshold && delta < frame_drop_threshold && + // ost->frame_number) if (delta < -1.1) nb_frames = 0; else if (delta > 1.1) { @@ -138,26 +157,30 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu nb_frames = FFMIN(nb_frames, max_frames_ - frame_number); nb0_frames = FFMIN(nb0_frames, nb_frames); - memmove(last_nb0_frames_ + 1, - last_nb0_frames_, - sizeof(last_nb0_frames_[0]) * (FF_ARRAY_ELEMS(last_nb0_frames_) - 1)); + memmove(last_nb0_frames_ + 1, last_nb0_frames_, + sizeof(last_nb0_frames_[0]) * + (FF_ARRAY_ELEMS(last_nb0_frames_) - 1)); last_nb0_frames_[0] = nb0_frames; if (nb0_frames == 0 && last_dropped_) { nb_frames_drop_++; - BMFLOG(BMF_INFO) << "*** dropping frame " << frame_number_ << " at ts " << last_frame_->pts; + BMFLOG(BMF_INFO) << "*** dropping frame " << frame_number_ << " at ts " + << last_frame_->pts; } if (nb_frames > (nb0_frames && last_dropped_) + (nb_frames > nb0_frames)) { - float dts_error_threshold = 3600*30; + float dts_error_threshold = 3600 * 30; if (nb_frames > dts_error_threshold * 30) { - av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1); + av_log(NULL, AV_LOG_ERROR, + "%d frame duplication too large, skipping\n", nb_frames - 1); nb_frames_drop_++; return -1; } - nb_frames_dup_ += nb_frames - (nb0_frames && last_dropped_) - (nb_frames > nb0_frames); - BMFLOG(BMF_INFO) << "*** " << nb_frames -1 << " dup!"; + nb_frames_dup_ += nb_frames - (nb0_frames && last_dropped_) - + (nb_frames > nb0_frames); + BMFLOG(BMF_INFO) << "*** " << nb_frames - 1 << " dup!"; if (nb_frames_dup_ > dup_warning_) { - BMFLOG(BMF_WARNING) << "More than " << dup_warning_ << " frames duplicated"; + BMFLOG(BMF_WARNING) << "More than " << dup_warning_ + << " frames duplicated"; dup_warning_ *= 10; } } @@ -169,8 +192,7 @@ int VideoSync::process_video_frame(AVFrame *frame, std::vector &outpu if (i < nb0_frames && last_frame_) { in_picture = av_frame_clone(last_frame_); - } - else + } else in_picture = av_frame_clone(frame); in_picture->pts = sync_opts_; diff --git a/bmf/c_modules/test/test_python_module.cpp b/bmf/c_modules/test/test_python_module.cpp index 1243b94a..16a3cdc2 100644 --- a/bmf/c_modules/test/test_python_module.cpp +++ b/bmf/c_modules/test/test_python_module.cpp @@ -23,36 +23,41 @@ void dump_node_json(JsonParam &json_param) { std::cout << "********node json:" << json_param.dump() << std::endl; } -void create_python_module(JsonParam &node_param, std::shared_ptr &python_module) { +void create_python_module(JsonParam &node_param, + std::shared_ptr &python_module) { std::string module_name; dump_node_json(node_param); node_param.get_string("module", module_name); JsonParam node_option_json; node_param.get_object("option", node_option_json); - python_module = std::make_shared(module_name, module_name, 0, node_option_json); + python_module = std::make_shared(module_name, module_name, 0, + node_option_json); } -void get_python_module_info(JsonParam &node_param, std::string &module_name, std::string &option) { -// dump_node_json(node_param); +void get_python_module_info(JsonParam &node_param, std::string &module_name, + std::string &option) { + // dump_node_json(node_param); node_param.get_string("module", module_name); JsonParam node_option_json; node_param.get_object("option", node_option_json); option = node_option_json.dump(); } -void create_python_module_from_string(std::string module_name, std::string option, - std::shared_ptr &python_module) { +void create_python_module_from_string( + std::string module_name, std::string option, + std::shared_ptr &python_module) { std::istringstream s; nlohmann::json opt; s.str(option); s >> opt; - python_module = std::make_shared(module_name, module_name, 0, JsonParam(opt)); + python_module = std::make_shared(module_name, module_name, 0, + JsonParam(opt)); } TEST(python_module, ffmpeg_module) { - setenv("PYTHONPATH", - "../../../3rd_party/pyav/:.:../../python_modules:../../python_module_sdk", + setenv("PYTHONPATH", "../../../3rd_party/pyav/:.:../../python_modules:../" + "../python_module_sdk", 1); Py_Initialize(); JsonParam graph_config; @@ -60,7 +65,7 @@ TEST(python_module, ffmpeg_module) { std::vector node_jsons; graph_config.get_object_list("nodes", node_jsons); std::shared_ptr python_module; - std::cout< input_labels; std::vector output_labels; @@ -71,17 +76,17 @@ TEST(python_module, ffmpeg_module) { } void thread_decode(std::shared_ptr decoder_module2) { -// setenv("PYTHONPATH", -// "/Users/bytedance/Project/company/python3/bmf_python3/bmf/3rd_party/pyav:.:/Users/bytedance/Project/company/python2/bmf_master/bmf/bmf/c_engine/python_sdk", -// 1); -// Py_Initialize(); + // setenv("PYTHONPATH", + // "/Users/bytedance/Project/company/python3/bmf_python3/bmf/3rd_party/pyav:.:/Users/bytedance/Project/company/python2/bmf_master/bmf/bmf/c_engine/python_sdk", + // 1); + // Py_Initialize(); PyGILState_STATE gstate; gstate = PyGILState_Ensure(); boost::python::object python_file = boost::python::import("timestamp"); sleep(1); -// PyGILState_Release(gstate); -// sleep(10); -// gstate = PyGILState_Ensure(); + // PyGILState_Release(gstate); + // sleep(10); + // gstate = PyGILState_Ensure(); std::string decoder_name; std::string decoder_option; @@ -94,23 +99,24 @@ void thread_decode(std::shared_ptr decoder_module2) { std::shared_ptr decoder_module; get_python_module_info(node_jsons[0], decoder_name, decoder_option); get_python_module_info(node_jsons[1], encoder_name, encoder_option); - create_python_module_from_string(decoder_name, decoder_option, decoder_module); + create_python_module_from_string(decoder_name, decoder_option, + decoder_module); bool decoder_finished = false; -// while (true) { -// -// Task task = Task(0, 0, 2); -// std::cout << "decoder_module start" << std::endl; -// if (not decoder_finished) { -// decoder_module->process(task); -// } -// std::cout << "decoder_module end" << std::endl; -// if (task.get_timestamp() == DONE) { -// decoder_finished = true; -// break; -// } -//// sleep(1); -// } + // while (true) { + // + // Task task = Task(0, 0, 2); + // std::cout << "decoder_module start" << std::endl; + // if (not decoder_finished) { + // decoder_module->process(task); + // } + // std::cout << "decoder_module end" << std::endl; + // if (task.get_timestamp() == DONE) { + // decoder_finished = true; + // break; + // } + //// sleep(1); + // } /* Release the thread. No Python API allowed beyond this point. */ PyGILState_Release(gstate); } @@ -138,12 +144,12 @@ void SignalHandle(const char *data, int size) { } TEST(python_module, decode) { -// google::InitGoogleLogging("main"); -// google::SetStderrLogging(google::INFO); -// google::InstallFailureSignalHandler(); -// google::InstallFailureWriter(&SignalHandle); - setenv("PYTHONPATH", - "../../../3rd_party/pyav/:.:../../python_modules:../../python_module_sdk", + // google::InitGoogleLogging("main"); + // google::SetStderrLogging(google::INFO); + // google::InstallFailureSignalHandler(); + // google::InstallFailureWriter(&SignalHandle); + setenv("PYTHONPATH", "../../../3rd_party/pyav/:.:../../python_modules:../" + "../python_module_sdk", 1); time_t time1 = clock(); Py_Initialize(); @@ -156,15 +162,15 @@ TEST(python_module, decode) { std::vector node_jsons; graph_config.get_object_list("nodes", node_jsons); std::shared_ptr decoder_module; -// std::shared_ptr encode_module; + // std::shared_ptr encode_module; get_python_module_info(node_jsons[0], decoder_name, decoder_option); std::cout << "create_python_module_from_string start" << std::endl; - create_python_module_from_string(decoder_name, decoder_option, decoder_module); + create_python_module_from_string(decoder_name, decoder_option, + decoder_module); std::cout << "create_python_module_from_string end" << std::endl; bool decoder_finished = false; bool encoder_finished = false; - while (true) { std::vector input_labels; std::vector output_labels; @@ -187,16 +193,15 @@ TEST(python_module, decode) { } time_t time2 = clock(); LOG(INFO) << "time:" << time2 - time1 << std::endl; - } TEST(python_module, decode_encode) { -// google::InitGoogleLogging("main"); -// google::SetStderrLogging(google::INFO); -// google::InstallFailureSignalHandler(); -// google::InstallFailureWriter(&SignalHandle); - setenv("PYTHONPATH", - "../../../3rd_party/pyav/:.:../../python_modules:../../python_module_sdk", + // google::InitGoogleLogging("main"); + // google::SetStderrLogging(google::INFO); + // google::InstallFailureSignalHandler(); + // google::InstallFailureWriter(&SignalHandle); + setenv("PYTHONPATH", "../../../3rd_party/pyav/:.:../../python_modules:../" + "../python_module_sdk", 1); Py_Initialize(); std::string decoder_name; @@ -211,14 +216,15 @@ TEST(python_module, decode_encode) { std::shared_ptr encode_module; get_python_module_info(node_jsons[0], decoder_name, decoder_option); get_python_module_info(node_jsons[1], encoder_name, encoder_option); - create_python_module_from_string(decoder_name, decoder_option, decoder_module); -// create_python_module(node_jsons[0],decoder_module); - create_python_module_from_string(encoder_name, encoder_option, encode_module); -// create_python_module(node_jsons[1],encode_module); + create_python_module_from_string(decoder_name, decoder_option, + decoder_module); + // create_python_module(node_jsons[0],decoder_module); + create_python_module_from_string(encoder_name, encoder_option, + encode_module); + // create_python_module(node_jsons[1],encode_module); bool decoder_finished = false; bool encoder_finished = false; -// return ; - + // return ; while (true) { std::vector input_labels; @@ -255,12 +261,12 @@ TEST(python_module, decode_encode) { } TEST(python_module, gil) { - setenv("PYTHONPATH", - "../../../3rd_party/pyav/:.:../../python_modules:../../python_module_sdk", + setenv("PYTHONPATH", "../../../3rd_party/pyav/:.:../../python_modules:../" + "../python_module_sdk", 1); Py_Initialize(); PyEval_InitThreads(); -// PyEval_ReleaseThread(PyThreadState_Get()); + // PyEval_ReleaseThread(PyThreadState_Get()); PyThreadState *state = PyEval_SaveThread(); PyGILState_STATE new_state = PyGILState_Ensure(); boost::python::object python_file = boost::python::import("timestamp"); @@ -269,12 +275,11 @@ TEST(python_module, gil) { /* Release the thread. No Python API allowed beyond this point. */ PyGILState_Release(new_state); PyGILState_Ensure(); - } TEST(python_module, decode_filter_encoder) { - setenv("PYTHONPATH", - "../../../3rd_party/pyav/:.:../../python_modules:../../python_module_sdk", + setenv("PYTHONPATH", "../../../3rd_party/pyav/:.:../../python_modules:../" + "../python_module_sdk", 1); Py_Initialize(); std::string decoder_name; @@ -293,18 +298,21 @@ TEST(python_module, decode_filter_encoder) { get_python_module_info(node_jsons[0], decoder_name, decoder_option); get_python_module_info(node_jsons[1], filter_name, filter_opiton); get_python_module_info(node_jsons[2], encoder_name, encoder_option); - create_python_module_from_string(decoder_name, decoder_option, decoder_module); + create_python_module_from_string(decoder_name, decoder_option, + decoder_module); -// create_python_module(node_jsons[0],decoder_module); -// filter_opiton= "{\"filters\": [{\"inputs\": [{\"stream\": 0,\"pin\": 0}],\"name\": \"scale\",\"para\": \"100:200\",\"outputs\": [ {\"stream\": 0,\"pin\": 0}]}]}"; + // create_python_module(node_jsons[0],decoder_module); + // filter_opiton= "{\"filters\": [{\"inputs\": [{\"stream\": 0,\"pin\": + // 0}],\"name\": \"scale\",\"para\": \"100:200\",\"outputs\": [ + // {\"stream\": 0,\"pin\": 0}]}]}"; create_python_module_from_string(filter_name, filter_opiton, filter_module); - create_python_module_from_string(encoder_name, encoder_option, encode_module); -// create_python_module(node_jsons[1],encode_module); + create_python_module_from_string(encoder_name, encoder_option, + encode_module); + // create_python_module(node_jsons[1],encode_module); bool decoder_finished = false; bool encoder_finished = false; -// return ; - + // return ; while (true) { std::vector input_labels; diff --git a/bmf/cmd/src/menu.cpp b/bmf/cmd/src/menu.cpp index 072a0308..08fead0a 100644 --- a/bmf/cmd/src/menu.cpp +++ b/bmf/cmd/src/menu.cpp @@ -23,7 +23,7 @@ void Menu::update_screen() { prefix = " [ ]"; } else if (cursor == i) prefix = " > "; - + mvprintw(next_row, 0, (prefix + options[i].title).c_str()); next_row++; } @@ -78,17 +78,17 @@ bool Menu::select_option() { return false; } -Menu& Menu::Text(std::string text) { +Menu &Menu::Text(std::string text) { pretext.push_back(text); return *this; } -Menu& Menu::SubMenu(Menu submenu) { +Menu &Menu::SubMenu(Menu submenu) { options.push_back(submenu); return *this; } -Menu& Menu::Option(std::string text, MenuOptionTag tag) { +Menu &Menu::Option(std::string text, MenuOptionTag tag) { Menu menu = Menu(text); menu_type = MENU_MULTI; menu.menu_type = MENU_OPTION; @@ -97,7 +97,7 @@ Menu& Menu::Option(std::string text, MenuOptionTag tag) { return *this; } -Menu& Menu::Back(std::string text) { +Menu &Menu::Back(std::string text) { Menu menu = Menu(text); menu.menu_type = MENU_BACK; options.push_back(menu); @@ -106,29 +106,29 @@ Menu& Menu::Back(std::string text) { Menu Menu::CreateQuitMenu() { Menu menu = Menu("退出(或按ESC)") - .Text("你想退出吗?") - .Text("[YES] 如果想退出,请按 Y,SPACE 或 ENTER。") - .Text("[NO] 想继续菜单,请按任何其他键。"); + .Text("你想退出吗?") + .Text("[YES] 如果想退出,请按 Y,SPACE 或 ENTER。") + .Text("[NO] 想继续菜单,请按任何其他键。"); menu.menu_type = MENU_QUIT; return menu; } -Menu& Menu::Quit() { +Menu &Menu::Quit() { options.push_back(CreateQuitMenu()); return *this; } -Menu& Menu::Confirmation() { +Menu &Menu::Confirmation() { menu_type = MENU_CONFIRM; return *this; } -Menu& Menu::get_selected_menu() { - Menu& selected_menu = options[cursor]; +Menu &Menu::get_selected_menu() { + Menu &selected_menu = options[cursor]; return selected_menu; } -Menu& Menu::Acceptance(std::function cb) { +Menu &Menu::Acceptance(std::function cb) { callback = cb; return *this; } \ No newline at end of file diff --git a/bmf/cmd/src/module_manager.cpp b/bmf/cmd/src/module_manager.cpp index aff80cb3..96149b84 100644 --- a/bmf/cmd/src/module_manager.cpp +++ b/bmf/cmd/src/module_manager.cpp @@ -16,143 +16,147 @@ #include #include - const fs::path module_root_path = bmf_sdk::s_bmf_repo_root; int list_modules() { - auto &M = bmf_sdk::ModuleManager::instance(); - auto known_modules = M.resolve_all_modules(); + auto &M = bmf_sdk::ModuleManager::instance(); + auto known_modules = M.resolve_all_modules(); - for (const auto &[module_name, module_info] : known_modules) { - std::cout << module_name << std::endl; - } - return 0; + for (const auto & [ module_name, module_info ] : known_modules) { + std::cout << module_name << std::endl; + } + return 0; } int dump_module(std::string module_name) { - auto &M = bmf_sdk::ModuleManager::instance(); - bmf_sdk::ModuleInfo info(module_name); - std::shared_ptr factory; - bool get_module_register_info = false; - try { - factory = M.load_module(info, &info); - get_module_register_info = - factory->module_info(info); // XXX: will throw an exception when dump a - // python non-module package - } catch (const std::exception &e) { - BMFLOG(BMF_ERROR) << "could not find module:" << module_name << ", " - << e.what() << std::endl; - return -1; - } + auto &M = bmf_sdk::ModuleManager::instance(); + bmf_sdk::ModuleInfo info(module_name); + std::shared_ptr factory; + bool get_module_register_info = false; + try { + factory = M.load_module(info, &info); + get_module_register_info = factory->module_info( + info); // XXX: will throw an exception when dump a + // python non-module package + } catch (const std::exception &e) { + BMFLOG(BMF_ERROR) << "could not find module:" << module_name << ", " + << e.what() << std::endl; + return -1; + } - int w = std::string("module_entry: ").size(); - if (get_module_register_info) { - w = std::string("module_description: ").size(); - } - std::cout << std::setw(w) << std::setfill(' ') - << "module_name: " << info.module_name << std::endl; - std::cout << std::setw(w) << std::setfill(' ') - << "module_entry: " << info.module_entry << std::endl; - std::cout << std::setw(w) << std::setfill(' ') - << "module_type: " << info.module_type << std::endl; - std::cout << std::setw(w) << std::setfill(' ') - << "module_path: " << info.module_path << std::endl; - if (get_module_register_info) { + int w = std::string("module_entry: ").size(); + if (get_module_register_info) { + w = std::string("module_description: ").size(); + } + std::cout << std::setw(w) << std::setfill(' ') + << "module_name: " << info.module_name << std::endl; + std::cout << std::setw(w) << std::setfill(' ') + << "module_entry: " << info.module_entry << std::endl; std::cout << std::setw(w) << std::setfill(' ') - << "module_description: " << info.module_description << std::endl; + << "module_type: " << info.module_type << std::endl; std::cout << std::setw(w) << std::setfill(' ') - << "module_tag: " << info.module_tag << std::endl; - } - return 0; + << "module_path: " << info.module_path << std::endl; + if (get_module_register_info) { + std::cout << std::setw(w) << std::setfill(' ') + << "module_description: " << info.module_description + << std::endl; + std::cout << std::setw(w) << std::setfill(' ') + << "module_tag: " << info.module_tag << std::endl; + } + return 0; } int install_module(const bmf_sdk::ModuleInfo &info, bool force) { - // check module_path - auto original_path = fs::path(info.module_path); - if (!fs::exists(original_path) || !fs::is_directory(original_path)) { - BMFLOG(BMF_ERROR) << "invalid module_path:" << info.module_path - << std::endl; - return -1; - } + // check module_path + auto original_path = fs::path(info.module_path); + if (!fs::exists(original_path) || !fs::is_directory(original_path)) { + BMFLOG(BMF_ERROR) << "invalid module_path:" << info.module_path + << std::endl; + return -1; + } - // check module_type and module_entry - // for c++ and python, check that the entry is correct. - // for go, parse the entry to get the dynamic library name - std::string module_file, _; - auto &M = bmf_sdk::ModuleManager::instance(); - if (info.module_type == "c++" || info.module_type == "python" || - info.module_type == "go") { + // check module_type and module_entry + // for c++ and python, check that the entry is correct. + // for go, parse the entry to get the dynamic library name + std::string module_file, _; auto &M = bmf_sdk::ModuleManager::instance(); - try { - std::tie(module_file, _) = M.parse_entry(info.module_entry, true); - } catch (std::exception &e) { - BMFLOG(BMF_ERROR) << e.what() << std::endl; - BMFLOG(BMF_ERROR) << "invalid module_entry:" << info.module_entry - << std::endl; - return -1; - } + if (info.module_type == "c++" || info.module_type == "python" || + info.module_type == "go") { + auto &M = bmf_sdk::ModuleManager::instance(); + try { + std::tie(module_file, _) = M.parse_entry(info.module_entry, true); + } catch (std::exception &e) { + BMFLOG(BMF_ERROR) << e.what() << std::endl; + BMFLOG(BMF_ERROR) << "invalid module_entry:" << info.module_entry + << std::endl; + return -1; + } - // check module file - if (info.module_type == "c++" || info.module_type == "go") { - module_file = fs::path(info.module_path) / (module_file + bmf_sdk::SharedLibrary::default_extension()); + // check module file + if (info.module_type == "c++" || info.module_type == "go") { + module_file = + fs::path(info.module_path) / + (module_file + bmf_sdk::SharedLibrary::default_extension()); + } else { + module_file = fs::path(info.module_path) / (module_file + ".py"); + } + if (!fs::exists(module_file)) { + BMFLOG(BMF_ERROR) << "cannot find the module file:" << module_file + << std::endl; + return -1; + } } else { - module_file = fs::path(info.module_path) / (module_file + ".py"); - } - if (!fs::exists(module_file)) { - BMFLOG(BMF_ERROR) << "cannot find the module file:" << module_file - << std::endl; - return -1; + BMFLOG(BMF_ERROR) << "invalid module_type, must be one of c++/python/go" + << std::endl; + return -1; } - } else { - BMFLOG(BMF_ERROR) << "invalid module_type, must be one of c++/python/go" - << std::endl; - return -1; - } - if (!fs::exists(module_root_path) and !fs::create_directories(module_root_path)) { - BMFLOG(BMF_ERROR) << "create module root directory failed." << std::endl; - return -1; - } - - auto installed_path = - module_root_path / ("Module_" + info.module_name); - if (fs::exists(installed_path)) { - if (force) { - fs::remove_all(installed_path); - } else { - BMFLOG(BMF_WARNING) << info.module_name << " has already installed." + if (!fs::exists(module_root_path) and + !fs::create_directories(module_root_path)) { + BMFLOG(BMF_ERROR) << "create module root directory failed." << std::endl; - return -1; + return -1; } - } - fs::copy(original_path, installed_path); - // bmf_sdk::JsonParam meta; - nlohmann::json meta; - meta["name"] = info.module_name; - meta["revision"] = info.module_revision; - meta["type"] = info.module_type; - meta["entry"] = info.module_entry; - // XXX: When "path" is empty, module_manager loader will automatically calculate - bmf_sdk::JsonParam(meta).store((installed_path / "meta.info").string()); + auto installed_path = module_root_path / ("Module_" + info.module_name); + if (fs::exists(installed_path)) { + if (force) { + fs::remove_all(installed_path); + } else { + BMFLOG(BMF_WARNING) << info.module_name << " has already installed." + << std::endl; + return -1; + } + } + fs::copy(original_path, installed_path); + + // bmf_sdk::JsonParam meta; + nlohmann::json meta; + meta["name"] = info.module_name; + meta["revision"] = info.module_revision; + meta["type"] = info.module_type; + meta["entry"] = info.module_entry; + // XXX: When "path" is empty, module_manager loader will automatically + // calculate + bmf_sdk::JsonParam(meta).store((installed_path / "meta.info").string()); - std::cout << "Installing the module:" << info.module_name << " in " - << installed_path << " success." << std::endl; + std::cout << "Installing the module:" << info.module_name << " in " + << installed_path << " success." << std::endl; - return 0; + return 0; } int uninstall_module(std::string module_name) { - auto module_path = module_root_path / ("Module_" + module_name); - if (!fs::exists(module_path) or !fs::is_directory(module_path)) { - BMFLOG(BMF_WARNING) << "Module:" << module_name << " is not exist" - << std::endl; - return -1; - } - fs::remove_all(module_path); - std::cout << "Uninstalling the module:" << module_name << " from " - << module_path << " success." << std::endl; - return 0; + auto module_path = module_root_path / ("Module_" + module_name); + if (!fs::exists(module_path) or !fs::is_directory(module_path)) { + BMFLOG(BMF_WARNING) << "Module:" << module_name << " is not exist" + << std::endl; + return -1; + } + fs::remove_all(module_path); + std::cout << "Uninstalling the module:" << module_name << " from " + << module_path << " success." << std::endl; + return 0; } std::map> help_infos{ @@ -160,124 +164,126 @@ std::map> help_infos{ []() { std::cout << "\thelp\t\tshow this help message" << std::endl; }}, {"list", []() { - std::cout << "\tlist\t\tlist all locally installed modules" << std::endl; + std::cout << "\tlist\t\tlist all locally installed modules" + << std::endl; }}, {"dump", []() { - std::cout << "\tdump\t\t" << std::endl; - std::cout << "\t\t\tdump installed module infos specified by module_name" - << std::endl; + std::cout << "\tdump\t\t" << std::endl; + std::cout + << "\t\t\tdump installed module infos specified by module_name" + << std::endl; }}, {"install", []() { - std::cout - << "\tinstall\t\t[-f] " - " [module_revision]" - << std::endl; - std::cout << "\t\t\tinstall the module to BMF installation path(" - << module_root_path << ")." << std::endl; - std::cout << "\t\t\tthe module_revision is optional, default is v0.0.1" - << std::endl; + std::cout + << "\tinstall\t\t[-f] " + " [module_revision]" + << std::endl; + std::cout << "\t\t\tinstall the module to BMF installation path(" + << module_root_path << ")." << std::endl; + std::cout << "\t\t\tthe module_revision is optional, default is v0.0.1" + << std::endl; }}, {"uninstall", []() { - std::cout << "\tuninstall\t" << std::endl; - std::cout << "\t\t\tuninstall the module from BMF installation path" - << std::endl; + std::cout << "\tuninstall\t" << std::endl; + std::cout << "\t\t\tuninstall the module from BMF installation path" + << std::endl; }}}; void help(const char *name, const char *cmd) { - std::cout << "Usage:" << std::endl; - if (!cmd || help_infos.find(cmd) == help_infos.end()) { - for (const auto &p : help_infos) { - p.second(); + std::cout << "Usage:" << std::endl; + if (!cmd || help_infos.find(cmd) == help_infos.end()) { + for (const auto &p : help_infos) { + p.second(); + } + return; } - return; - } - help_infos[cmd](); + help_infos[cmd](); } int main(int argc, char **argv) { - if (argc < 2) { - help(argv[0], nullptr); - exit(EXIT_FAILURE); - } - - if (char *log_level = getenv("BMF_LOG_LEVEL"); log_level) { - char buf[256]; - sprintf(buf, "BMF_LOG_LEVEL=%s", log_level); - putenv(buf); - } else { - putenv("BMF_LOG_LEVEL=WARNING"); - } - configure_bmf_log(); - - const std::string operation = argv[1]; - if (operation == "help") { - const char *cmd = argc >= 3 ? argv[2] : nullptr; - help(argv[0], cmd); - return 0; - } else if (operation == "list") { - int ret = list_modules(); - if (ret < 0) { - BMFLOG(BMF_ERROR) << "list modules failed." << std::endl; - exit(EXIT_FAILURE); - } - } else if (operation == "dump") { - if (argc < 3) { - help(argv[0], operation.c_str()); - exit(EXIT_FAILURE); - } - const char *module_name = argv[2]; - int ret = dump_module(module_name); - if (ret < 0) { - BMFLOG(BMF_ERROR) << "dump module info failed." << std::endl; - exit(EXIT_FAILURE); - } - } else if (operation == "install") { - bool force = false; - int arg_start = 2; - if (argc < arg_start + 1) { - help(argv[0], operation.c_str()); - exit(EXIT_FAILURE); + if (argc < 2) { + help(argv[0], nullptr); + exit(EXIT_FAILURE); } - if (std::string(argv[arg_start]) == "-f") { - force = true; - arg_start++; + if (char *log_level = getenv("BMF_LOG_LEVEL"); log_level) { + char buf[256]; + sprintf(buf, "BMF_LOG_LEVEL=%s", log_level); + putenv(buf); + } else { + putenv("BMF_LOG_LEVEL=WARNING"); } + configure_bmf_log(); - if (argc < arg_start + 4) { - help(argv[0], operation.c_str()); - exit(EXIT_FAILURE); - } + const std::string operation = argv[1]; + if (operation == "help") { + const char *cmd = argc >= 3 ? argv[2] : nullptr; + help(argv[0], cmd); + return 0; + } else if (operation == "list") { + int ret = list_modules(); + if (ret < 0) { + BMFLOG(BMF_ERROR) << "list modules failed." << std::endl; + exit(EXIT_FAILURE); + } + } else if (operation == "dump") { + if (argc < 3) { + help(argv[0], operation.c_str()); + exit(EXIT_FAILURE); + } + const char *module_name = argv[2]; + int ret = dump_module(module_name); + if (ret < 0) { + BMFLOG(BMF_ERROR) << "dump module info failed." << std::endl; + exit(EXIT_FAILURE); + } + } else if (operation == "install") { + bool force = false; + int arg_start = 2; + if (argc < arg_start + 1) { + help(argv[0], operation.c_str()); + exit(EXIT_FAILURE); + } - const char *module_revision = "v0.0.1"; - if (argc >= arg_start + 5) { - module_revision = argv[arg_start + 4]; - } - bmf_sdk::ModuleInfo info(argv[arg_start], argv[arg_start + 1], - argv[arg_start + 2], argv[arg_start + 3], - module_revision); - int ret = install_module(info, force); - if (ret < 0) { - BMFLOG(BMF_ERROR) << "install module failed." << std::endl; - exit(EXIT_FAILURE); - } - } else if (operation == "uninstall") { - if (argc < 3) { - help(argv[0], operation.c_str()); - exit(EXIT_FAILURE); - } - const char *module_name = argv[2]; - int ret = uninstall_module(module_name); - if (ret < 0) { - BMFLOG(BMF_ERROR) << "uninstall module failed." << std::endl; - exit(EXIT_FAILURE); + if (std::string(argv[arg_start]) == "-f") { + force = true; + arg_start++; + } + + if (argc < arg_start + 4) { + help(argv[0], operation.c_str()); + exit(EXIT_FAILURE); + } + + const char *module_revision = "v0.0.1"; + if (argc >= arg_start + 5) { + module_revision = argv[arg_start + 4]; + } + bmf_sdk::ModuleInfo info(argv[arg_start], argv[arg_start + 1], + argv[arg_start + 2], argv[arg_start + 3], + module_revision); + int ret = install_module(info, force); + if (ret < 0) { + BMFLOG(BMF_ERROR) << "install module failed." << std::endl; + exit(EXIT_FAILURE); + } + } else if (operation == "uninstall") { + if (argc < 3) { + help(argv[0], operation.c_str()); + exit(EXIT_FAILURE); + } + const char *module_name = argv[2]; + int ret = uninstall_module(module_name); + if (ret < 0) { + BMFLOG(BMF_ERROR) << "uninstall module failed." << std::endl; + exit(EXIT_FAILURE); + } + } else { + std::cerr << "Invalid operation:" << operation << "!" << std::endl; + help(argv[0], nullptr); + exit(EXIT_FAILURE); } - } else { - std::cerr << "Invalid operation:" << operation << "!" << std::endl; - help(argv[0], nullptr); - exit(EXIT_FAILURE); - } - return 0; + return 0; } diff --git a/bmf/cmd/src/run_graph.cpp b/bmf/cmd/src/run_graph.cpp index fe203b29..07d17d3e 100644 --- a/bmf/cmd/src/run_graph.cpp +++ b/bmf/cmd/src/run_graph.cpp @@ -17,13 +17,11 @@ USE_BMF_ENGINE_NS USE_BMF_SDK_NS -int main(int argc, char ** argv) { +int main(int argc, char **argv) { if (argc != 2) { - std::cerr - << "Invalid arguments!" - << std::endl - << "Please use: run_bmf_graph /path_to_graph_config.json" - << std::endl; + std::cerr << "Invalid arguments!" << std::endl + << "Please use: run_bmf_graph /path_to_graph_config.json" + << std::endl; exit(EXIT_FAILURE); } @@ -50,9 +48,8 @@ int main(int argc, char ** argv) { std::string input_path; node.get_option().get_string(input_path_key, input_path); if (!fs::exists(input_path)) { - std::cerr - << "Input file path " << input_path - << " does not exists!" << std::endl; + std::cerr << "Input file path " << input_path + << " does not exists!" << std::endl; exit(EXIT_FAILURE); } } @@ -66,31 +63,17 @@ int main(int argc, char ** argv) { return 0; } #ifdef BMF_USE_MEDIACODEC -extern "C" JNIEXPORT void InitializeSignalChain() { +extern "C" JNIEXPORT void InitializeSignalChain() {} -} - -extern "C" JNIEXPORT void ClaimSignalChain() { - -} - -extern "C" JNIEXPORT void UnclaimSignalChain() { - -} +extern "C" JNIEXPORT void ClaimSignalChain() {} -extern "C" JNIEXPORT void InvokeUserSignalHandler() { +extern "C" JNIEXPORT void UnclaimSignalChain() {} -} - -extern "C" JNIEXPORT void EnsureFrontOfChain() { +extern "C" JNIEXPORT void InvokeUserSignalHandler() {} -} +extern "C" JNIEXPORT void EnsureFrontOfChain() {} -extern "C" JNIEXPORT void AddSpecialSignalHandlerFn() { +extern "C" JNIEXPORT void AddSpecialSignalHandlerFn() {} -} - -extern "C" JNIEXPORT void RemoveSpecialSignalHandlerFn() { - -} +extern "C" JNIEXPORT void RemoveSpecialSignalHandlerFn() {} #endif diff --git a/bmf/cmd/src/suite.cpp b/bmf/cmd/src/suite.cpp index 597e89da..e8792a2c 100644 --- a/bmf/cmd/src/suite.cpp +++ b/bmf/cmd/src/suite.cpp @@ -11,62 +11,63 @@ int main() { bool terminated = false; MenuNavMode nav_mode = NAV_NORMAL; - Menu root = Menu("Main Menu") - .Text("BMF 工具集") - .Text("请选择任务:") - .SubMenu(Menu("配置Trace工具") - .Text("配置Trace工具") - .Text("请选择:") - .SubMenu(TraceMenu("启动Trace") - .SetTraceSelection() - .Text("启动Trace") - .Text("请选择(按SPACE键选择一个或多个Trace类型,按ENTER确认):") - .Option("所有Trace类型", TAG_SELECT_ALL) - .Option("PROCESSING") - .Option("SCHEDULE") - .Option("QUEUE_INFO") - .Option("INTERLATENCY") - .Option("THROUGHPUT") - .Option("CUSTOM") - .Back("放弃更改,返回上一页") - .Quit() - ) - .SubMenu(TraceMenu("禁用Printing") - .SetPrintDisable() - .Text("确认禁用Printing,是否要继续?") - .Text("[YES] 如果想禁用Printing,请按 SPACE,ENTER 或 y。") - .Text("[NO] 想继续菜单,请按任何其他键。") - .Confirmation() - ) - .SubMenu(TraceMenu("禁用Tracelog生成") - .SetTracelogDisable() - .Text("确认禁用Tracelog生成,是否要继续?") - .Text("[YES] 如果想禁用Tracelog生成,请按 SPACE,ENTER 或 y。") - .Text("[NO] 想继续菜单,请按任何其他键。") - .Confirmation() - ) - .SubMenu(TraceMenu("完成配置") - .SetTraceConfigSave() - .Text("退出后,在terminal上执行:") - .Text("$ source env.sh") - .Text("以上命令行会部署有关Trace的环境变量。\n") - .Text("按任意键继续") - .Confirmation() - ) - .Back() - .Quit() - ) - .Quit(); + Menu root = + Menu("Main Menu") + .Text("BMF 工具集") + .Text("请选择任务:") + .SubMenu( + Menu("配置Trace工具") + .Text("配置Trace工具") + .Text("请选择:") + .SubMenu(TraceMenu("启动Trace") + .SetTraceSelection() + .Text("启动Trace") + .Text("请选择(按SPACE键选择一个或多个Trace类" + "型,按ENTER确认):") + .Option("所有Trace类型", TAG_SELECT_ALL) + .Option("PROCESSING") + .Option("SCHEDULE") + .Option("QUEUE_INFO") + .Option("INTERLATENCY") + .Option("THROUGHPUT") + .Option("CUSTOM") + .Back("放弃更改,返回上一页") + .Quit()) + .SubMenu(TraceMenu("禁用Printing") + .SetPrintDisable() + .Text("确认禁用Printing,是否要继续?") + .Text("[YES] 如果想禁用Printing,请按 " + "SPACE,ENTER 或 y。") + .Text("[NO] 想继续菜单,请按任何其他键。") + .Confirmation()) + .SubMenu(TraceMenu("禁用Tracelog生成") + .SetTracelogDisable() + .Text("确认禁用Tracelog生成,是否要继续?") + .Text("[YES] 如果想禁用Tracelog生成,请按 " + "SPACE,ENTER 或 y。") + .Text("[NO] 想继续菜单,请按任何其他键。") + .Confirmation()) + .SubMenu( + TraceMenu("完成配置") + .SetTraceConfigSave() + .Text("退出后,在terminal上执行:") + .Text("$ source env.sh") + .Text("以上命令行会部署有关Trace的环境变量。\n") + .Text("按任意键继续") + .Confirmation()) + .Back() + .Quit()) + .Quit(); Menu quit = root.CreateQuitMenu(); - std::stack menu_stack; + std::stack menu_stack; menu_stack.push(&root); menu_stack.top()->display(); while (!terminated) { // Await input - ch=getch(); + ch = getch(); if (nav_mode == NAV_NORMAL) { switch (ch) { @@ -78,15 +79,18 @@ int main() { break; case ' ': - if (menu_stack.top()->menu_type == MENU_MULTI && menu_stack.top()->select_option()) + if (menu_stack.top()->menu_type == MENU_MULTI && + menu_stack.top()->select_option()) break; case 10: case KEY_ENTER: - if (menu_stack.top()->get_selected_menu().menu_type == MENU_OPTION) { + if (menu_stack.top()->get_selected_menu().menu_type == + MENU_OPTION) { selected_options = menu_stack.top()->selections; menu_stack.top()->callback(); menu_stack.pop(); - } else if (menu_stack.top()->get_selected_menu().menu_type == MENU_BACK) { + } else if (menu_stack.top()->get_selected_menu().menu_type == + MENU_BACK) { menu_stack.pop(); } else { menu_stack.push(&menu_stack.top()->get_selected_menu()); @@ -98,7 +102,7 @@ int main() { nav_mode = NAV_PEND_CONFIRM; selected_options.clear(); break; - + // Up Button case KEY_UP: menu_stack.top()->prev(); @@ -108,7 +112,7 @@ int main() { case KEY_DOWN: menu_stack.top()->next(); break; - + default: break; } @@ -130,7 +134,7 @@ int main() { nav_mode = NAV_NORMAL; } } - + clear(); endwin(); return 0; diff --git a/bmf/cmd/src/trace_format_log.cpp b/bmf/cmd/src/trace_format_log.cpp index 834ab54e..bb1b7f2a 100644 --- a/bmf/cmd/src/trace_format_log.cpp +++ b/bmf/cmd/src/trace_format_log.cpp @@ -4,7 +4,7 @@ USE_BMF_SDK_NS -int main(int argc, char ** argv) { +int main(int argc, char **argv) { #ifndef NO_TRACE // Perform log formatting to tracelog without including trace tool's // additional information e.g. on buffer capacity etc diff --git a/bmf/demo/gpu_module/cvtcolor.cpp b/bmf/demo/gpu_module/cvtcolor.cpp index ab4b0927..30eebb2e 100644 --- a/bmf/demo/gpu_module/cvtcolor.cpp +++ b/bmf/demo/gpu_module/cvtcolor.cpp @@ -5,12 +5,12 @@ USE_BMF_SDK_NS -class TestCvtColorModule : public Module -{ -public: - TestCvtColorModule(int node_id,JsonParam option) : Module(node_id,option) { } +class TestCvtColorModule : public Module { + public: + TestCvtColorModule(int node_id, JsonParam option) + : Module(node_id, option) {} - ~TestCvtColorModule() { } + ~TestCvtColorModule() {} virtual int process(Task &task); }; @@ -44,18 +44,23 @@ int TestCvtColorModule::process(Task &task) { vframe = vframe.cuda(); } // yuv2yuv - hmp::PixelInfo nv12info{hmp::PF_NV12, hmp::CS_BT470BG, hmp::CR_MPEG}; - VideoFrame vframe_nv12{vframe.width(), vframe.height(), nv12info, kCUDA}; + hmp::PixelInfo nv12info{hmp::PF_NV12, hmp::CS_BT470BG, + hmp::CR_MPEG}; + VideoFrame vframe_nv12{vframe.width(), vframe.height(), nv12info, + kCUDA}; hmp::TensorList nv12_tensor = vframe_nv12.frame().data(); hmp::img::yuv_to_yuv(nv12_tensor, vframe.frame().data(), - vframe_nv12.frame().pix_info(), vframe.frame().pix_info()); + vframe_nv12.frame().pix_info(), + vframe.frame().pix_info()); // yuv2rgb hmp::PixelInfo cinfo{hmp::PF_RGB24, hmp::CS_BT709, hmp::CR_MPEG}; hmp::PixelInfo pinfo{hmp::PF_YUV420P, hmp::CS_BT709, hmp::CR_MPEG}; - VideoFrame vframe_out{vframe.width(), vframe.height(), cinfo, kCUDA}; + VideoFrame vframe_out{vframe.width(), vframe.height(), cinfo, + kCUDA}; hmp::Tensor out_tensor = vframe_out.frame().plane(0); - hmp::img::yuv_to_rgb(out_tensor, vframe.frame().data(), vframe.frame().pix_info(), hmp::kNHWC); + hmp::img::yuv_to_rgb(out_tensor, vframe.frame().data(), + vframe.frame().pix_info(), hmp::kNHWC); // Add output frame to output queue vframe_nv12.copy_props(vframe); diff --git a/bmf/demo/video_frame_extraction/jpeg_encoder.cpp b/bmf/demo/video_frame_extraction/jpeg_encoder.cpp index b5a3d26f..075f4d3c 100644 --- a/bmf/demo/video_frame_extraction/jpeg_encoder.cpp +++ b/bmf/demo/video_frame_extraction/jpeg_encoder.cpp @@ -38,28 +38,32 @@ extern "C" { USE_BMF_SDK_NS -#define CHECK_NVJPEG(func, errer_log, _ret, WHETHER_RET) \ - do { \ - auto status = func; \ - if (status != NVJPEG_STATUS_SUCCESS) { \ - BMFLOG_NODE(BMF_ERROR, node_id_) << errer_log; \ - if (WHETHER_RET) \ - return _ret; \ - } \ +#define CHECK_NVJPEG(func, errer_log, _ret, WHETHER_RET) \ + do { \ + auto status = func; \ + if (status != NVJPEG_STATUS_SUCCESS) { \ + BMFLOG_NODE(BMF_ERROR, node_id_) << errer_log; \ + if (WHETHER_RET) \ + return _ret; \ + } \ } while (0); class jpeg_encoder : public bmf_sdk::Module { -public: - jpeg_encoder(int node_id, bmf_sdk::JsonParam option) : bmf_sdk::Module(node_id, option) { - if (option.has_key("width") && option.json_value_["width"].is_number()) { + public: + jpeg_encoder(int node_id, bmf_sdk::JsonParam option) + : bmf_sdk::Module(node_id, option) { + if (option.has_key("width") && + option.json_value_["width"].is_number()) { m_encode_w = option.json_value_["width"]; } - if (option.has_key("height") && option.json_value_["height"].is_number()) { + if (option.has_key("height") && + option.json_value_["height"].is_number()) { m_encode_h = option.json_value_["height"]; } - BMFLOG_NODE(BMF_INFO, node_id_) << "encode frame size is: " - << m_encode_w << "x" << m_encode_h; - if (option.has_key("quality") && option.json_value_["quality"].is_number()) { + BMFLOG_NODE(BMF_INFO, node_id_) + << "encode frame size is: " << m_encode_w << "x" << m_encode_h; + if (option.has_key("quality") && + option.json_value_["quality"].is_number()) { m_encode_q = option.json_value_["quality"]; } BMFLOG_NODE(BMF_INFO, node_id_) << "encode param set to " << m_encode_q; @@ -74,19 +78,22 @@ class jpeg_encoder : public bmf_sdk::Module { // nvjpeg CHECK_NVJPEG(nvjpegCreateSimple(&m_handle), "nvjpeg create handle error. ", -1, true); - CHECK_NVJPEG(nvjpegEncoderParamsCreate(m_handle, &m_enc_param, m_stream), - "nvjpeg create enc param error. ", -1, true); + CHECK_NVJPEG( + nvjpegEncoderParamsCreate(m_handle, &m_enc_param, m_stream), + "nvjpeg create enc param error. ", -1, true); CHECK_NVJPEG(nvjpegEncoderStateCreate(m_handle, &m_enc_state, m_stream), "nvjpeg create jpeg enc state error. ", -1, true); // set param - CHECK_NVJPEG(nvjpegEncoderParamsSetQuality(m_enc_param, m_encode_q, m_stream), - "nvjpeg set enc quality error. ", -1, true); - auto status = nvjpegEncoderParamsSetEncoding(m_enc_param, - NVJPEG_ENCODING_BASELINE_DCT, - m_stream); - status = nvjpegEncoderParamsSetOptimizedHuffman(m_enc_param, 2, m_stream); - status = nvjpegEncoderParamsSetSamplingFactors(m_enc_param, NVJPEG_CSS_420, m_stream); + CHECK_NVJPEG( + nvjpegEncoderParamsSetQuality(m_enc_param, m_encode_q, m_stream), + "nvjpeg set enc quality error. ", -1, true); + auto status = nvjpegEncoderParamsSetEncoding( + m_enc_param, NVJPEG_ENCODING_BASELINE_DCT, m_stream); + status = + nvjpegEncoderParamsSetOptimizedHuffman(m_enc_param, 2, m_stream); + status = nvjpegEncoderParamsSetSamplingFactors( + m_enc_param, NVJPEG_CSS_420, m_stream); return 0; } @@ -109,7 +116,8 @@ class jpeg_encoder : public bmf_sdk::Module { cudaStreamDestroy(m_stream); m_stream = nullptr; } - BMFLOG_NODE(BMF_INFO, node_id_) << "encode " << m_frame_count << " frames."; + BMFLOG_NODE(BMF_INFO, node_id_) << "encode " << m_frame_count + << " frames."; return 0; } @@ -121,7 +129,8 @@ class jpeg_encoder : public bmf_sdk::Module { bmf_sdk::Packet pkt; while (task.pop_packet_from_input_queue(label, pkt)) { if (pkt.timestamp() == bmf_sdk::Timestamp::BMF_EOF) { - task.fill_output_packet(label, bmf_sdk::Packet::generate_eof_packet()); + task.fill_output_packet( + label, bmf_sdk::Packet::generate_eof_packet()); task.set_timestamp(bmf_sdk::Timestamp::DONE); return 0; } @@ -137,8 +146,10 @@ class jpeg_encoder : public bmf_sdk::Module { nvjpegImage_t image = {0}; if (vf.device() == kCUDA) { if (2 != vf.frame().nplanes()) { - BMFLOG_NODE(BMF_INFO, node_id_) << "input video frame error. must be nv12 format has 2 planes. this has " - << vf.frame().nplanes() << " planes."; + BMFLOG_NODE(BMF_INFO, node_id_) + << "input video frame error. must be nv12 format " + "has 2 planes. this has " + << vf.frame().nplanes() << " planes."; } if (!vf_rgb) @@ -146,29 +157,34 @@ class jpeg_encoder : public bmf_sdk::Module { Tensor t_img = vf_rgb.frame().plane(0); hmp::img::yuv_to_rgb(t_img, vf.frame().data(), NV12, kNHWC); if (!vf_yuv_from_rgb) - vf_yuv_from_rgb = VideoFrame::make(width, height, H420, kCUDA); + vf_yuv_from_rgb = + VideoFrame::make(width, height, H420, kCUDA); TensorList tl = vf_yuv_from_rgb.frame().data(); - hmp::img::rgb_to_yuv(tl, vf_rgb.frame().plane(0), H420, kNHWC); + hmp::img::rgb_to_yuv(tl, vf_rgb.frame().plane(0), H420, + kNHWC); vf_final_p = &vf_yuv_from_rgb; } else { - BMFLOG_NODE(BMF_INFO, node_id_) << "frame comes from cpu decoder."; + BMFLOG_NODE(BMF_INFO, node_id_) + << "frame comes from cpu decoder."; if (format != hmp::PF_YUV420P) { vf_rfmt = ffmpeg::reformat(vf, "yuv420p"); - BMFLOG_NODE(BMF_INFO, node_id_) << "encode: frame pixel format to yuv420p."; + BMFLOG_NODE(BMF_INFO, node_id_) + << "encode: frame pixel format to yuv420p."; vf_final_p = &vf_rfmt; } else { vf_final_p = &vf; } - } if (m_encode_w && m_encode_h) { if (!vf_resize) - vf_resize = VideoFrame::make(m_encode_w, m_encode_h, H420, kCUDA); + vf_resize = VideoFrame::make(m_encode_w, m_encode_h, + H420, kCUDA); TensorList tl_resize = vf_resize.frame().data(); vf_cuda = vf_final_p->cuda(); - hmp::img::yuv_resize(tl_resize, vf_cuda.frame().data(), H420); + hmp::img::yuv_resize(tl_resize, vf_cuda.frame().data(), + H420); vf_final_p = &vf_resize; width = m_encode_w; @@ -183,16 +199,21 @@ class jpeg_encoder : public bmf_sdk::Module { size_t length = 0; CHECK_NVJPEG(nvjpegEncodeYUV(m_handle, m_enc_state, m_enc_param, - &image, NVJPEG_CSS_420, width, height, m_stream), + &image, NVJPEG_CSS_420, width, + height, m_stream), "nvjpeg encode error. ", -1, true); - CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream(m_handle, m_enc_state, nullptr, &length, m_stream), + CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream(m_handle, + m_enc_state, nullptr, + &length, m_stream), "nvjpeg get bit stream data error. ", -1, true); cudaStreamSynchronize(m_stream); // init output auto bmf_avpkt = BMFAVPacket(length); auto data = bmf_avpkt.data_ptr(); - CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream(m_handle, m_enc_state, (uint8_t *) data, &length, m_stream), + CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream( + m_handle, m_enc_state, (uint8_t *)data, + &length, m_stream), "nvjpeg get bit stream data error. ", -1, true); cudaStreamSynchronize(m_stream); @@ -202,17 +223,21 @@ class jpeg_encoder : public bmf_sdk::Module { task.fill_output_packet(label, packet); auto end = std::chrono::steady_clock::now(); - auto duration = std::chrono::duration_cast(end - start).count(); - BMFLOG_NODE(BMF_INFO, node_id_) << "encode jpeg " << width << "x" - << height << " to " << length << " bytes. using " - << ((float) duration) * 0.001f << " ms"; + auto duration = + std::chrono::duration_cast(end - + start) + .count(); + BMFLOG_NODE(BMF_INFO, node_id_) + << "encode jpeg " << width << "x" << height << " to " + << length << " bytes. using " << ((float)duration) * 0.001f + << " ms"; m_frame_count++; } } return 0; } -private: + private: nvjpegHandle_t m_handle = nullptr; nvjpegEncoderParams_t m_enc_param = nullptr; nvjpegEncoderState_t m_enc_state = nullptr; @@ -224,7 +249,7 @@ class jpeg_encoder : public bmf_sdk::Module { VideoFrame vf_resize; VideoFrame vf_rfmt; VideoFrame vf_cuda; - VideoFrame* vf_final_p; + VideoFrame *vf_final_p; int32_t m_encode_w = 0; int32_t m_encode_h = 0; int32_t m_encode_q = 99; diff --git a/bmf/engine/c_engine/src/callback_layer.cpp b/bmf/engine/c_engine/src/callback_layer.cpp index 73386b42..e3fd5b35 100644 --- a/bmf/engine/c_engine/src/callback_layer.cpp +++ b/bmf/engine/c_engine/src/callback_layer.cpp @@ -19,13 +19,14 @@ #include BEGIN_BMF_ENGINE_NS - void ModuleCallbackLayer::add_callback(int64_t key, std::function callback) { - callback_binding[key] = std::move(callback); - } +void ModuleCallbackLayer::add_callback(int64_t key, + std::function callback) { + callback_binding[key] = std::move(callback); +} - CBytes ModuleCallbackLayer::call(int64_t key, CBytes para) { - if (!callback_binding.count(key)) - return CBytes::make(nullptr, 0); - return callback_binding[key](para); - } +CBytes ModuleCallbackLayer::call(int64_t key, CBytes para) { + if (!callback_binding.count(key)) + return CBytes::make(nullptr, 0); + return callback_binding[key](para); +} END_BMF_ENGINE_NS \ No newline at end of file diff --git a/bmf/engine/c_engine/src/graph.cpp b/bmf/engine/c_engine/src/graph.cpp index 9bec0ac1..a72d4e5e 100644 --- a/bmf/engine/c_engine/src/graph.cpp +++ b/bmf/engine/c_engine/src/graph.cpp @@ -28,848 +28,958 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - std::vector g_ptr; - - void terminate(int signum) { - std::cout << "terminated, ending bmf gracefully..." << std::endl; - for (auto p:g_ptr) - p->quit_gracefully(); +USE_BMF_SDK_NS +std::vector g_ptr; + +void terminate(int signum) { + std::cout << "terminated, ending bmf gracefully..." << std::endl; + for (auto p : g_ptr) + p->quit_gracefully(); +} + +void interrupted(int signum) { + std::cout << "interrupted, ending bmf gracefully..." << std::endl; + for (auto p : g_ptr) + p->quit_gracefully(); +} + +Graph::Graph( + GraphConfig graph_config, + std::map> pre_modules, + std::map> callback_bindings) { + std::signal(SIGTERM, terminate); + std::signal(SIGINT, interrupted); + configure_bmf_log(); + BMFLOG(BMF_INFO) << "BMF Version: " << BMF_VERSION; + BMFLOG(BMF_INFO) << "BMF Commit: " << BMF_COMMIT; + BMFLOG(BMF_INFO) << "start init graph"; + BMF_TRACE(GRAPH_START, "Init"); + init(graph_config, pre_modules, callback_bindings); + g_ptr.push_back(this); +} + +void Graph::init( + GraphConfig graph_config, + std::map> &pre_modules, + std::map> &callback_bindings) { + graph_config_ = graph_config; + pre_modules_ = pre_modules; + callback_bindings_ = callback_bindings; + mode_ = graph_config.get_mode(); + + int max_scheduler_index = 0; + for (auto &node_config : graph_config_.get_nodes()) { + max_scheduler_index = + std::max(node_config.get_scheduler(), max_scheduler_index); } + scheduler_count_ = max_scheduler_index + 1; + + if (graph_config.get_option().json_value_.count("scheduler_count")) + scheduler_count_ = graph_config.get_option() + .json_value_.at("scheduler_count") + .get(); + + SchedulerCallBack scheduler_callback; + scheduler_callback.get_node_ = [this](int node_id, + std::shared_ptr &node) -> int { + return this->get_node(node_id, node); + }; + + scheduler_callback.close_report_ = [this](int node_id, + bool is_exception) -> int { + std::lock_guard _(this->con_var_mutex_); + this->closed_count_++; + if (is_exception) { + if (node_id == -1) { + this->exception_from_scheduler_ = true; + BMFLOG(BMF_INFO) + << "got exception not from any node, close directly"; + } else + BMFLOG(BMF_INFO) << "node " << node_id + << " got exception, close directly"; - void interrupted(int signum) { - std::cout << "interrupted, ending bmf gracefully..." << std::endl; - for (auto p:g_ptr) - p->quit_gracefully(); - } + if (this->output_streams_.size() > 0) { + for (auto &outputs : this->output_streams_) { + Packet eof_pkt = Packet::generate_eof_packet(); + outputs.second->inject_packet(eof_pkt); + } + } + } else + BMFLOG(BMF_INFO) + << "node " << node_id + << " close report, closed count: " << this->closed_count_; + if (this->closed_count_ == this->nodes_.size() || is_exception) + this->cond_close_.notify_one(); + return 0; + }; - - - Graph::Graph(GraphConfig graph_config, std::map > pre_modules, - std::map > callback_bindings) { - std::signal(SIGTERM, terminate); - std::signal(SIGINT, interrupted); - configure_bmf_log(); - BMFLOG(BMF_INFO) << "BMF Version: " << BMF_VERSION; - BMFLOG(BMF_INFO) << "BMF Commit: " << BMF_COMMIT; - BMFLOG(BMF_INFO) << "start init graph"; - BMF_TRACE(GRAPH_START, "Init"); - init(graph_config, pre_modules, callback_bindings); - g_ptr.push_back(this); + double time_out = 0; + if (graph_config.get_option().json_value_.count("time_out")) { + time_out = + graph_config.get_option().json_value_.at("time_out").get(); + BMFLOG(BMF_INFO) << "scheduler time out: " << time_out << " seconds"; } - void Graph::init(GraphConfig graph_config, std::map > &pre_modules, - std::map > &callback_bindings) { - graph_config_ = graph_config; - pre_modules_ = pre_modules; - callback_bindings_ = callback_bindings; - mode_ = graph_config.get_mode(); - - int max_scheduler_index = 0; - for (auto &node_config:graph_config_.get_nodes()) { - max_scheduler_index = std::max(node_config.get_scheduler(), max_scheduler_index); + scheduler_ = std::make_shared(scheduler_callback, + scheduler_count_, time_out); + BMFLOG(BMF_INFO) << "scheduler count" << scheduler_count_; + + // create all nodes and output streams + init_nodes(); + // retrieve all hungry check functions for all sources + get_hungry_check_func_for_sources(); + + // Init all graph input stream + // graph input stream contains an output stream manager + // which connect downstream input stream manager + init_input_streams(); + + // input streams that are not connected + find_orphan_input_streams(); + + // delete useless orphan output stream to avoid graph build issue + delete_orphan_output_streams(); + + for (auto &node : source_nodes_) + scheduler_->add_or_remove_node(node->get_id(), true); +} + +int Graph::get_hungry_check_func(std::shared_ptr &root_node, + int output_idx, + std::shared_ptr &curr_node) { + std::map> output_streams; + curr_node->get_output_streams(output_streams); + for (auto &output_stream : output_streams) { + if (curr_node == root_node && output_stream.first != output_idx) { + continue; } - scheduler_count_ = max_scheduler_index + 1; - - if (graph_config.get_option().json_value_.count("scheduler_count")) - scheduler_count_ = graph_config.get_option().json_value_.at("scheduler_count").get(); - - SchedulerCallBack scheduler_callback; - scheduler_callback.get_node_ = [this](int node_id, std::shared_ptr &node) -> int { - return this->get_node(node_id, node); - }; - - scheduler_callback.close_report_ = [this](int node_id, bool is_exception) -> int { - std::lock_guard _(this->con_var_mutex_); - this->closed_count_++; - if (is_exception) { - if (node_id == -1) { - this->exception_from_scheduler_ = true; - BMFLOG(BMF_INFO) << "got exception not from any node, close directly"; - } else - BMFLOG(BMF_INFO) << "node " << node_id << " got exception, close directly"; - - if (this->output_streams_.size() > 0) { - for (auto &outputs:this->output_streams_) { - Packet eof_pkt = Packet::generate_eof_packet(); - outputs.second->inject_packet(eof_pkt); - } - } - } else - BMFLOG(BMF_INFO) << "node " << node_id << " close report, closed count: " << this->closed_count_; - if (this->closed_count_ == this->nodes_.size() || is_exception) - this->cond_close_.notify_one(); - return 0; - }; - - double time_out = 0; - if (graph_config.get_option().json_value_.count("time_out")) { - time_out = graph_config.get_option().json_value_.at("time_out").get(); - BMFLOG(BMF_INFO) << "scheduler time out: " << time_out << " seconds"; + for (auto &mirror_stream : output_stream.second->mirror_streams_) { + int node_id = (mirror_stream.input_stream_manager_->node_id_); + std::shared_ptr node; + get_node(node_id, node); + int stream_id = mirror_stream.stream_id_; + if (node != nullptr) { + std::vector> funcs; + node->get_hungry_check_func(stream_id, funcs); + for (auto func : funcs) + root_node->register_hungry_check_func(output_idx, func); + get_hungry_check_func(root_node, output_idx, node); + } } + } + return 0; +} - scheduler_ = std::make_shared(scheduler_callback, scheduler_count_, time_out); - BMFLOG(BMF_INFO) << "scheduler count" << scheduler_count_; - - // create all nodes and output streams - init_nodes(); - // retrieve all hungry check functions for all sources - get_hungry_check_func_for_sources(); - - // Init all graph input stream - // graph input stream contains an output stream manager - // which connect downstream input stream manager - init_input_streams(); - - // input streams that are not connected - find_orphan_input_streams(); - - // delete useless orphan output stream to avoid graph build issue - delete_orphan_output_streams(); +int Graph::get_hungry_check_func_for_sources() { + for (auto node : source_nodes_) { + get_hungry_check_func(node, 0, node); + get_hungry_check_func(node, 1, node); + } + return 0; +} + +int Graph::init_nodes() { + NodeCallBack callback; + callback.get_node = [this](int node_id, + std::shared_ptr &node) -> int { + return this->get_node(node_id, node); + }; + callback.throttled_cb = [this](int node_id, bool is_add) -> int { + return this->scheduler_->add_or_remove_node(node_id, is_add); + }; + callback.sched_required = [this](int node_id, bool is_add) -> int { + return this->scheduler_->sched_required(node_id, is_add); + }; + callback.scheduler_cb = [this](Task &task) -> int { + return this->scheduler_->schedule_node(task); + }; + callback.clear_cb = [this](int node_id, int scheduler_queue_id) -> int { + return this->scheduler_->clear_task(node_id, scheduler_queue_id); + }; + // init node + for (auto &node_config : graph_config_.get_nodes()) { + std::shared_ptr module_pre_allocated; + auto node_id = node_config.get_id(); + if (pre_modules_.count(node_id) > 0) + module_pre_allocated = pre_modules_[node_id]; + std::shared_ptr node; + + if (!callback_bindings_.count(node_id)) + callback_bindings_[node_id] = + std::make_shared(); + node = std::make_shared(node_id, node_config, callback, + module_pre_allocated, mode_, + callback_bindings_[node_id]); + + if (node_config.get_scheduler() < scheduler_count_) { + node->set_scheduler_queue_id((node_config.get_scheduler())); + BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " + << node->get_id() << " scheduler " + << node_config.get_scheduler(); + } else { + node->set_scheduler_queue_id(0); + BMFLOG(BMF_WARNING) << "Node[" << node->get_id() << "](" + << node->get_type() + << ") scheduler exceed limit, will set to 0."; + BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " + << node->get_id() << " scheduler " << 0; + } + nodes_[node_config.get_id()] = node; - for (auto &node:source_nodes_) - scheduler_->add_or_remove_node(node->get_id(), true); + if ((node_config.get_input_streams().size()) == 0) { + // if no input stream, it's a source node + source_nodes_.push_back(node); + } } - int - Graph::get_hungry_check_func(std::shared_ptr &root_node, int output_idx, std::shared_ptr &curr_node) { + // create connections + for (auto &node_iter : nodes_) { std::map> output_streams; - curr_node->get_output_streams(output_streams); - for (auto &output_stream:output_streams) { - if (curr_node == root_node && output_stream.first != output_idx) { - continue; - } - for (auto &mirror_stream :output_stream.second->mirror_streams_) { - int node_id = (mirror_stream.input_stream_manager_->node_id_); - std::shared_ptr node; - get_node(node_id, node); - int stream_id = mirror_stream.stream_id_; - if (node != nullptr) { - std::vector > funcs; - node->get_hungry_check_func(stream_id, funcs); - for (auto func:funcs) - root_node->register_hungry_check_func(output_idx, func); - get_hungry_check_func(root_node, output_idx, node); + node_iter.second->get_output_streams(output_streams); + // find all downstream connections for every output stream + for (auto &output_stream : output_streams) { + add_all_mirrors_for_output_stream(output_stream.second); + } + } + for (auto &node_iter : nodes_) { + std::map> output_streams; + node_iter.second->get_output_streams(output_streams); + for (auto &output_stream : output_streams) + output_stream.second->add_upstream_nodes(node_iter.first); + } + // create graph output streams + for (auto &graph_output_stream : graph_config_.output_streams) { + for (auto &node : graph_config_.nodes) { + int idx = 0; + for (auto &out_s : node.output_streams) { + if (out_s.get_identifier() == + graph_output_stream.get_identifier()) { + std::shared_ptr input_manager; + create_input_stream_manager("immediate", -1, {out_s}, {}, + InputStreamManagerCallBack(), 5, + input_manager); + auto g_out_s = std::make_shared(); + g_out_s->set_manager(input_manager); + + std::map> output_streams; + nodes_[node.id]->get_output_streams(output_streams); + output_streams[idx]->add_mirror_stream(input_manager, 0); + + output_streams_[graph_output_stream.get_identifier()] = + g_out_s; } + ++idx; + } + } + } + return 0; +} + +int Graph::init_input_streams() { + // init all graph input streams + for (auto &stream : graph_config_.get_input_streams()) { + // create graph input stream + std::shared_ptr graph_input_stream = + std::make_shared(); + // create output stream manager and set it into input stream + std::vector ss = {stream}; + std::shared_ptr manager = + std::make_shared(ss); + graph_input_stream->set_manager(manager); + + input_streams_[stream.get_identifier()] = graph_input_stream; + + std::shared_ptr output_stream; + manager->get_stream(0, output_stream); + // link downstream nodes + add_all_mirrors_for_output_stream(output_stream); + } + return 0; +} + +int Graph::add_all_mirrors_for_output_stream( + std::shared_ptr &output_stream) { + // go through all the nodes, find the input stream that + // connected with graph input stream, add it to mirrors + for (auto &node_iter : nodes_) { + if (not node_iter.second->is_source()) { + std::shared_ptr input_stream_manager; + node_iter.second->get_input_stream_manager(input_stream_manager); + for (auto &input_stream : input_stream_manager->input_streams_) { + if (output_stream->identifier_ == + input_stream.second->identifier_) { + output_stream->add_mirror_stream(input_stream_manager, + input_stream.first); + input_stream.second->set_connected(true); + } } } - return 0; } + return 0; +} + +int Graph::find_orphan_input_streams() { + for (auto &node : nodes_) { + std::map> input_streams; + node.second->get_input_streams(input_streams); + for (auto &input_stream : input_streams) { + if (not input_stream.second->is_connected()) { + orphan_streams_.push_back(input_stream.second); + } + } + } + return 0; +} - int Graph::get_hungry_check_func_for_sources() { - for (auto node:source_nodes_) { - get_hungry_check_func(node, 0, node); - get_hungry_check_func(node, 1, node); +int Graph::delete_orphan_output_streams() { + for (auto &node_iter : nodes_) { + std::shared_ptr output_stream_manager; + std::map> output_streams; + node_iter.second->get_output_stream_manager(output_stream_manager); + node_iter.second->get_output_streams(output_streams); + std::vector rm_streams_id; + for (auto &output_stream : output_streams) { + if (output_stream.second->mirror_streams_.size() == + 0) { // orphan output stream + BMFLOG(BMF_INFO) + << "node:" << node_iter.second->get_type() << " " + << node_iter.second->get_id() + << " will delete orphan output stream which is useless: " + << output_stream.second->identifier_; + rm_streams_id.push_back(output_stream.first); + } + } + for (auto streams_id : rm_streams_id) { + output_stream_manager->remove_stream(streams_id, -1); } - return 0; + } + return 0; +} + +int Graph::start() { + // start scheduler and it will start to schedule source nodes + scheduler_->start(); + + // TODO push eof to the orphan streams + for (auto &stream : orphan_streams_) { + std::shared_ptr> q = + std::make_shared>(); + q->push(Packet::generate_eof_packet()); + stream->add_packets(q); + BMFLOG(BMF_INFO) << "push eof to orphan stream " + << stream->get_identifier(); + } + return 0; +} + +int Graph::update(GraphConfig update_config) { + BMFLOG(BMF_INFO) << "dynamic update start: " + << update_config.to_json().dump(); + // convert filter para to new format + bmf_engine::Optimizer::convert_filter_para_for_graph(update_config.nodes); + // replace stream name with stream id in filter option + bmf_engine::Optimizer::replace_stream_name_for_graph(update_config.nodes); + + JsonParam option = update_config.get_option(); + std::vector nodes_opt; + option.get_object_list("nodes", nodes_opt); + + std::vector nodes_add; + std::vector nodes_remove; + std::vector nodes_reset; + + for (auto &node_config : update_config.get_nodes()) { + std::string action = node_config.get_action(); + if (action == "add") + nodes_add.push_back(node_config); + else if (action == "remove") + nodes_remove.push_back(node_config); + else if (action == "reset") + nodes_reset.push_back(node_config); } - int Graph::init_nodes() { - NodeCallBack callback; - callback.get_node = [this](int node_id, std::shared_ptr &node) -> int { - return this->get_node(node_id, node); - }; - callback.throttled_cb = [this](int node_id, bool is_add) -> int { - return this->scheduler_->add_or_remove_node(node_id, is_add); - }; - callback.sched_required = [this](int node_id, bool is_add) -> int { - return this->scheduler_->sched_required(node_id, is_add); - }; - callback.scheduler_cb = [this](Task &task) -> int { - return this->scheduler_->schedule_node(task); - }; - callback.clear_cb = [this](int node_id, int scheduler_queue_id) -> int { - return this->scheduler_->clear_task(node_id, scheduler_queue_id); - }; - // init node - for (auto &node_config:graph_config_.get_nodes()) { + // dynamical add + if (nodes_add.size()) { + // find the node config of add + std::map> added_nodes; + std::vector> added_src_nodes; + for (auto &node_config : nodes_add) { std::shared_ptr module_pre_allocated; - auto node_id = node_config.get_id(); + int node_id = node_config.get_id(); if (pre_modules_.count(node_id) > 0) module_pre_allocated = pre_modules_[node_id]; std::shared_ptr node; + NodeCallBack callback; + callback.get_node = + std::bind(&Graph::get_node, this, std::placeholders::_1, + std::placeholders::_2); + callback.throttled_cb = + std::bind(&Scheduler::add_or_remove_node, scheduler_, + std::placeholders::_1, std::placeholders::_2); + callback.scheduler_cb = std::bind( + &Scheduler::schedule_node, scheduler_, std::placeholders::_1); + callback.clear_cb = + std::bind(&Scheduler::clear_task, scheduler_, + std::placeholders::_1, std::placeholders::_2); + + callback.sched_required = + std::bind(&Scheduler::sched_required, scheduler_, + std::placeholders::_1, std::placeholders::_2); if (!callback_bindings_.count(node_id)) - callback_bindings_[node_id] = std::make_shared(); - node = std::make_shared(node_id, node_config, callback, module_pre_allocated, mode_, + callback_bindings_[node_id] = + std::make_shared(); + node = std::make_shared(node_id, node_config, callback, + module_pre_allocated, mode_, callback_bindings_[node_id]); if (node_config.get_scheduler() < scheduler_count_) { node->set_scheduler_queue_id((node_config.get_scheduler())); - BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " << node->get_id() << " scheduler " + BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " + << node->get_id() << " scheduler " << node_config.get_scheduler(); } else { node->set_scheduler_queue_id(0); - BMFLOG(BMF_WARNING) << "Node[" << node->get_id() << "](" << node->get_type() - << ") scheduler exceed limit, will set to 0."; - BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " << node->get_id() << " scheduler " << 0; + BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " + << node->get_id() << " scheduler " << 0; } nodes_[node_config.get_id()] = node; + added_nodes[node_config.get_id()] = node; if ((node_config.get_input_streams().size()) == 0) { - // if no input stream, it's a source node source_nodes_.push_back(node); + added_src_nodes.push_back(node); } } - // create connections - for (auto &node_iter:nodes_) { + // create connections and pause relevant orginal nodes + for (auto &node_iter : added_nodes) { std::map> output_streams; node_iter.second->get_output_streams(output_streams); // find all downstream connections for every output stream - for (auto &output_stream:output_streams) { - add_all_mirrors_for_output_stream(output_stream.second); - } - } - for (auto &node_iter:nodes_) { - std::map> output_streams; - node_iter.second->get_output_streams(output_streams); - for (auto &output_stream:output_streams) - output_stream.second->add_upstream_nodes(node_iter.first); - } - // create graph output streams - for (auto &graph_output_stream:graph_config_.output_streams) { - for (auto &node:graph_config_.nodes) { - int idx = 0; - for (auto &out_s:node.output_streams) { - if (out_s.get_identifier() == graph_output_stream.get_identifier()) { - std::shared_ptr input_manager; - create_input_stream_manager("immediate", -1, {out_s}, {}, InputStreamManagerCallBack(), 5, - input_manager); - auto g_out_s = std::make_shared(); - g_out_s->set_manager(input_manager); - - std::map> output_streams; - nodes_[node.id]->get_output_streams(output_streams); - output_streams[idx]->add_mirror_stream(input_manager, 0); - - output_streams_[graph_output_stream.get_identifier()] = g_out_s; + for (auto &output_stream : output_streams) { + bool b_matched; + b_matched = false; + for (auto node_iter_other : added_nodes) { + if (not node_iter_other.second->is_source()) { + std::shared_ptr + input_stream_manager; + node_iter_other.second->get_input_stream_manager( + input_stream_manager); + for (auto input_stream : + input_stream_manager->input_streams_) { + if (output_stream.second->identifier_ == + input_stream.second->identifier_) { + output_stream.second->add_mirror_stream( + input_stream_manager, input_stream.first); + + if (!input_stream_manager->find_upstream_nodes( + node_iter.second->get_id())) { + input_stream_manager->add_upstream_nodes( + node_iter.second->get_id()); + } + input_stream.second->set_connected(true); + b_matched = true; + break; + } + } } - ++idx; } - } - } - - return 0; - } + if (not b_matched) { + // connect added inputs/outputs with original graph + // by check the not connected inputs/outputs + std::string prefix_name = + output_stream.second->identifier_.substr( + 0, output_stream.second->identifier_.find_first_of( + ".")); + for (auto &node : nodes_) { + // find the matched link in original nodes + if (not node.second->is_source()) { + std::shared_ptr + input_stream_manager; + // if the new node output name prefix point to the + // node alias + if (prefix_name == node.second->get_alias()) { + node.second->get_input_stream_manager( + input_stream_manager); + int new_id = input_stream_manager->add_stream( + output_stream.second->identifier_, + node.second->get_id()); + output_stream.second->add_mirror_stream( + input_stream_manager, new_id); + if (!input_stream_manager->find_upstream_nodes( + node_iter.second->get_id())) { + input_stream_manager->add_upstream_nodes( + node_iter.second->get_id()); + BMFLOG(BMF_INFO) + << "node: " << node.second->get_id() + << " add upstream node: " + << node_iter.second->get_id(); + } - int Graph::init_input_streams() { - // init all graph input streams - for (auto &stream:graph_config_.get_input_streams()) { - // create graph input stream - std::shared_ptr graph_input_stream = std::make_shared(); - // create output stream manager and set it into input stream - std::vector ss = {stream}; - std::shared_ptr manager = std::make_shared(ss); - graph_input_stream->set_manager(manager); - - input_streams_[stream.get_identifier()] = graph_input_stream; - - std::shared_ptr output_stream; - manager->get_stream(0, output_stream); - // link downstream nodes - add_all_mirrors_for_output_stream(output_stream); - } - return 0; - } + input_stream_manager->input_streams_[new_id] + ->set_connected(true); - int Graph::add_all_mirrors_for_output_stream(std::shared_ptr &output_stream) { - // go through all the nodes, find the input stream that - // connected with graph input stream, add it to mirrors - for (auto &node_iter :nodes_) { - if (not node_iter.second->is_source()) { - std::shared_ptr input_stream_manager; - node_iter.second->get_input_stream_manager(input_stream_manager); - for (auto &input_stream:input_stream_manager->input_streams_) { - if (output_stream->identifier_ == input_stream.second->identifier_) { - output_stream->add_mirror_stream(input_stream_manager, input_stream.first); - input_stream.second->set_connected(true); + BMFLOG(BMF_INFO) + << "adding node " + << node_iter.second->get_type() + << ", downstream: " << prefix_name + << ", as input of " + << output_stream.second->identifier_; + } + } } } } } - return 0; - } - int Graph::find_orphan_input_streams() { - for (auto &node:nodes_) { - std::map > input_streams; - node.second->get_input_streams(input_streams); - for (auto &input_stream:input_streams) { + // for upstream connections + for (auto &node_iter : added_nodes) { + std::shared_ptr input_stream_manager; + node_iter.second->get_input_stream_manager(input_stream_manager); + // bool b_matched = false; + for (auto input_stream : input_stream_manager->input_streams_) { if (not input_stream.second->is_connected()) { - orphan_streams_.push_back(input_stream.second); - } - } - } - return 0; - } + std::string prefix_name = + input_stream.second->identifier_.substr( + 0, input_stream.second->identifier_.find_first_of( + ".")); + for (auto &node : nodes_) { + if (prefix_name == node.second->get_alias()) { + std::shared_ptr + output_stream_manager; + node.second->get_output_stream_manager( + output_stream_manager); + int new_id = output_stream_manager->add_stream( + input_stream.second->identifier_); + output_stream_manager->output_streams_[new_id] + ->add_mirror_stream( + input_stream_manager, + input_stream.second->get_id()); + input_stream_manager + ->input_streams_[input_stream.second->get_id()] + ->set_connected(true); + node.second->set_outputstream_updated(true); + + // set upstream nodes + if (!input_stream_manager->find_upstream_nodes( + node.second->get_id())) { + input_stream_manager->add_upstream_nodes( + node.second->get_id()); + } - int Graph::delete_orphan_output_streams() { - for (auto &node_iter:nodes_) { - std::shared_ptr output_stream_manager; - std::map> output_streams; - node_iter.second->get_output_stream_manager(output_stream_manager); - node_iter.second->get_output_streams(output_streams); - std::vector rm_streams_id; - for (auto &output_stream:output_streams) { - if (output_stream.second->mirror_streams_.size() == 0) {//orphan output stream - BMFLOG(BMF_INFO) << "node:" << node_iter.second->get_type() << " " - << node_iter.second->get_id() - << " will delete orphan output stream which is useless: " - << output_stream.second->identifier_; - rm_streams_id.push_back(output_stream.first); + // b_matched = true; + BMFLOG(BMF_INFO) + << "adding node " + << node_iter.second->get_type() + << ", upstream: " << prefix_name + << ", as output of " + << input_stream.second->identifier_; + } + } } - } - for (auto streams_id:rm_streams_id) { - output_stream_manager->remove_stream(streams_id, -1); + // if (not b_matched) + // orphan_streams_.push_back(input_stream.second); } } - return 0; - } - - int Graph::start() { - // start scheduler and it will start to schedule source nodes - scheduler_->start(); - //TODO push eof to the orphan streams - for (auto &stream:orphan_streams_) { - std::shared_ptr > q = std::make_shared >(); - q->push(Packet::generate_eof_packet()); - stream->add_packets(q); - BMFLOG(BMF_INFO) << "push eof to orphan stream " << stream->get_identifier(); - } - return 0; + for (auto &node : added_src_nodes) + scheduler_->add_or_remove_node(node->get_id(), true); } - int Graph::update(GraphConfig update_config) { - BMFLOG(BMF_INFO) << "dynamic update start: " << update_config.to_json().dump(); - // convert filter para to new format - bmf_engine::Optimizer::convert_filter_para_for_graph(update_config.nodes); - // replace stream name with stream id in filter option - bmf_engine::Optimizer::replace_stream_name_for_graph(update_config.nodes); - - JsonParam option = update_config.get_option(); - std::vector nodes_opt; - option.get_object_list("nodes", nodes_opt); - - std::vector nodes_add; - std::vector nodes_remove; - std::vector nodes_reset; - - for (auto &node_config:update_config.get_nodes()) { - std::string action = node_config.get_action(); - if (action == "add") - nodes_add.push_back(node_config); - else if (action == "remove") - nodes_remove.push_back(node_config); - else if (action == "reset") - nodes_reset.push_back(node_config); - } - - //dynamical add - if (nodes_add.size()) { - //find the node config of add - std::map> added_nodes; - std::vector> added_src_nodes; - for (auto &node_config:nodes_add) { - std::shared_ptr module_pre_allocated; - int node_id = node_config.get_id(); - if (pre_modules_.count(node_id) > 0) - module_pre_allocated = pre_modules_[node_id]; - std::shared_ptr node; - NodeCallBack callback; - callback.get_node = std::bind(&Graph::get_node, this, std::placeholders::_1, std::placeholders::_2); - callback.throttled_cb = std::bind(&Scheduler::add_or_remove_node, scheduler_, std::placeholders::_1, - std::placeholders::_2); - callback.scheduler_cb = std::bind(&Scheduler::schedule_node, scheduler_, std::placeholders::_1); - callback.clear_cb = std::bind(&Scheduler::clear_task, scheduler_, std::placeholders::_1, - std::placeholders::_2); - - callback.sched_required = std::bind(&Scheduler::sched_required, scheduler_, std::placeholders::_1, std::placeholders::_2); - - if (!callback_bindings_.count(node_id)) - callback_bindings_[node_id] = std::make_shared(); - node = std::make_shared(node_id, node_config, callback, module_pre_allocated, mode_, - callback_bindings_[node_id]); - - if (node_config.get_scheduler() < scheduler_count_) { - node->set_scheduler_queue_id((node_config.get_scheduler())); - BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " << node->get_id() << " scheduler " - << node_config.get_scheduler(); - } else { - node->set_scheduler_queue_id(0); - BMFLOG(BMF_INFO) << "node:" << node->get_type() << " " << node->get_id() << " scheduler " << 0; - } - nodes_[node_config.get_id()] = node; - added_nodes[node_config.get_id()] = node; - - if ((node_config.get_input_streams().size()) == 0) { - source_nodes_.push_back(node); - added_src_nodes.push_back(node); + // dynamical remove + if (nodes_remove.size()) { + for (auto &node_config : nodes_remove) { + int id_of_rm_node = -1; + for (auto &node : nodes_) { + if (node.second->get_alias() == node_config.get_alias()) { + BMFLOG(BMF_INFO) << "found the node to be removed: " + << node.second->get_alias(); + id_of_rm_node = node.first; + break; } } + if (id_of_rm_node == -1) { + BMFLOG(BMF_ERROR) << "cannot find the node to be removed"; + return -1; + } + std::shared_ptr rm_node = nodes_[id_of_rm_node]; - // create connections and pause relevant orginal nodes - for (auto &node_iter:added_nodes) { - std::map> output_streams; - node_iter.second->get_output_streams(output_streams); - // find all downstream connections for every output stream - for (auto &output_stream:output_streams) { - bool b_matched; - b_matched = false; - for (auto node_iter_other:added_nodes) { - if (not node_iter_other.second->is_source()) { - std::shared_ptr input_stream_manager; - node_iter_other.second->get_input_stream_manager(input_stream_manager); - for (auto input_stream:input_stream_manager->input_streams_) { - if (output_stream.second->identifier_ == input_stream.second->identifier_) { - output_stream.second->add_mirror_stream(input_stream_manager, - input_stream.first); - - if (!input_stream_manager->find_upstream_nodes(node_iter.second->get_id())) { - input_stream_manager->add_upstream_nodes(node_iter.second->get_id()); + std::vector> paused_nodes; + std::shared_ptr input_stream_manager; + std::shared_ptr output_stream_manager; + std::vector> upstream_output_streams; + rm_node->get_input_stream_manager(input_stream_manager); + rm_node->get_output_stream_manager(output_stream_manager); + if (not rm_node->is_source()) { + for (auto input_stream : input_stream_manager->input_streams_) { + bool b_matched = false; + if (input_stream.second->is_connected()) { + for (auto &node : nodes_) { + std::map> + output_streams; + node.second->get_output_streams(output_streams); + for (auto output_stream : output_streams) { + if (output_stream.second->identifier_ == + input_stream.second->identifier_) { + // got the connected upstream + BMFLOG(BMF_INFO) + << "found the upstream node: " + << node.second->get_type() << std::endl; + bool already_paused = false; + for (auto pn : paused_nodes) { + if (pn->get_id() == + node.second->get_id()) { + already_paused = true; + break; + } } - - input_stream.second->set_connected(true); - b_matched = true; + if (already_paused == false) { + node.second->wait_paused(); + paused_nodes.push_back(node.second); + } + upstream_output_streams.push_back( + output_streams[output_stream.first]); break; } } } } - if (not b_matched) { - //connect added inputs/outputs with original graph - //by check the not connected inputs/outputs - std::string prefix_name = output_stream.second->identifier_.substr(0, - output_stream.second->identifier_.find_first_of(".")); - for (auto &node:nodes_) { - //find the matched link in original nodes - if (not node.second->is_source()) { - std::shared_ptr input_stream_manager; - //if the new node output name prefix point to the node alias - if (prefix_name == node.second->get_alias()) { - node.second->get_input_stream_manager(input_stream_manager); - int new_id = input_stream_manager->add_stream(output_stream.second->identifier_, - node.second->get_id()); - output_stream.second->add_mirror_stream(input_stream_manager, - new_id); - if (!input_stream_manager->find_upstream_nodes(node_iter.second->get_id())){ - input_stream_manager->add_upstream_nodes(node_iter.second->get_id()); - BMFLOG(BMF_INFO) << "node: " << node.second->get_id() << " add upstream node: " << node_iter.second->get_id(); - } - + } - input_stream_manager->input_streams_[new_id]->set_connected(true); + // probe on the output about the specail EOF signal, avoid to + // passdown + output_stream_manager->probe_eof(); + + // push EOF into the input streams of the node + for (auto stream : input_stream_manager->input_streams_) { + std::shared_ptr> q = + std::make_shared>(); + BMFLOG(BMF_INFO) + << "push eof to inputstream of removed node: " + << stream.second->identifier_; + q->push(Packet::generate_eof_packet()); + stream.second->add_packets(q); + } - BMFLOG(BMF_INFO) << "adding node " << node_iter.second->get_type() - << ", downstream: "<< prefix_name - << ", as input of " << output_stream.second->identifier_; - } + // wait utile the EOF was consumed + for (auto input_stream : input_stream_manager->input_streams_) + input_stream_manager->wait_on_stream_empty( + input_stream.first); + + rm_node->wait_paused(); + + // remove the upstream after output stream consumed + for (auto node : paused_nodes) { + std::shared_ptr out_str_mng; + std::map> output_streams; + node->get_output_stream_manager(out_str_mng); + node->get_output_streams(output_streams); + for (auto &output_stream : output_streams) { + for (auto rm_stream : upstream_output_streams) { + if (output_stream.second->identifier_ == + rm_stream->identifier_) { + out_str_mng->remove_stream( + output_stream.first, rm_stream->stream_id_); + BMFLOG(BMF_INFO) + << "remove stream: " + << rm_stream->identifier_ + << "stream id: " << rm_stream->stream_id_; + // make sure to notify the output streams of the + // upstream nodes are changed + node->set_outputstream_updated(true); + rm_stream->stream_id_ = -1; // removed tag + break; } } } } + } else { + rm_node->wait_paused(); + + output_stream_manager->probe_eof(); + + for (auto output_stream : + output_stream_manager->output_streams_) { + std::shared_ptr> q = + std::make_shared>(); + BMFLOG(BMF_INFO) + << "push eof to outputstream of removing node"; + q->push(Packet::generate_eof_packet()); + output_stream.second->propagate_packets(q); + } } - //for upstream connections - for (auto &node_iter:added_nodes) { - std::shared_ptr input_stream_manager; - node_iter.second->get_input_stream_manager(input_stream_manager); - //bool b_matched = false; - for (auto input_stream:input_stream_manager->input_streams_) { - if (not input_stream.second->is_connected()) { - std::string prefix_name = input_stream.second->identifier_.substr(0, - input_stream.second->identifier_.find_first_of(".")); - for (auto &node:nodes_) { - if (prefix_name == node.second->get_alias()) { - std::shared_ptr output_stream_manager; - node.second->get_output_stream_manager(output_stream_manager); - int new_id = output_stream_manager->add_stream(input_stream.second->identifier_); - output_stream_manager->output_streams_[new_id]->add_mirror_stream( - input_stream_manager, - input_stream.second->get_id()); - input_stream_manager->input_streams_[input_stream.second->get_id()]-> - set_connected(true); - node.second->set_outputstream_updated(true); - - //set upstream nodes - if (!input_stream_manager->find_upstream_nodes(node.second->get_id())) { - input_stream_manager->add_upstream_nodes(node.second->get_id()); - } - - //b_matched = true; - BMFLOG(BMF_INFO) << "adding node " << node_iter.second->get_type() - << ", upstream: "<< prefix_name << ", as output of " - << input_stream.second->identifier_; - } - } - } - //if (not b_matched) - // orphan_streams_.push_back(input_stream.second); - } + for (auto node : paused_nodes) { + BMFLOG(BMF_INFO) << "paused us node recover: " << node->get_id() + << " alias: " << node->get_alias(); + node->set_status(NodeState::PENDING); } - for (auto &node:added_src_nodes) - scheduler_->add_or_remove_node(node->get_id(), true); - } + // remove the downstream + for (auto output_stream : output_stream_manager->output_streams_) + output_stream_manager->wait_on_stream_empty( + output_stream.first); + // pause the down stream nodes + std::vector ds_nodes_id; + output_stream_manager->get_outlink_nodes_id(ds_nodes_id); + int ret; + std::vector> paused_ds_nodes; + for (int i = 0; i < ds_nodes_id.size(); i++) { + std::shared_ptr nd; + if (get_node(ds_nodes_id[i], nd) == 0) { + nd->wait_paused(); + paused_ds_nodes.push_back(nd); + + // remove upstream_nodes_ + std::shared_ptr input_stream_manager; + nd->get_input_stream_manager(input_stream_manager); + input_stream_manager->remove_upstream_nodes(id_of_rm_node); - //dynamical remove - if (nodes_remove.size()) { - for (auto &node_config:nodes_remove) { - int id_of_rm_node = -1; - for (auto &node:nodes_) { - if (node.second->get_alias() == node_config.get_alias()) { - BMFLOG(BMF_INFO) << "found the node to be removed: " << node.second->get_alias(); - id_of_rm_node = node.first; - break; - } - } - if (id_of_rm_node == -1) { - BMFLOG(BMF_ERROR) << "cannot find the node to be removed"; + } else { + BMFLOG(BMF_ERROR) << "down stream node can't be got: " << i; return -1; } - std::shared_ptr rm_node = nodes_[id_of_rm_node]; - - std::vector> paused_nodes; - std::shared_ptr input_stream_manager; - std::shared_ptr output_stream_manager; - std::vector> upstream_output_streams; - rm_node->get_input_stream_manager(input_stream_manager); - rm_node->get_output_stream_manager(output_stream_manager); - if (not rm_node->is_source()) { - for (auto input_stream:input_stream_manager->input_streams_) { - bool b_matched = false; - if (input_stream.second->is_connected()) { - for (auto &node:nodes_) { - std::map> output_streams; - node.second->get_output_streams(output_streams); - for (auto output_stream:output_streams) { - if (output_stream.second->identifier_ == input_stream.second->identifier_) { - //got the connected upstream - BMFLOG(BMF_INFO) << "found the upstream node: " - << node.second->get_type() << std::endl; - bool already_paused = false; - for (auto pn:paused_nodes) { - if (pn->get_id() == node.second->get_id()) { - already_paused = true; - break; - } - } - if (already_paused == false) { - node.second->wait_paused(); - paused_nodes.push_back(node.second); - } - upstream_output_streams.push_back(output_streams[output_stream.first]); - break; - } - } - } - } - } - - //probe on the output about the specail EOF signal, avoid to passdown - output_stream_manager->probe_eof(); - - //push EOF into the input streams of the node - for (auto stream:input_stream_manager->input_streams_) { - std::shared_ptr > q = std::make_shared>(); - BMFLOG(BMF_INFO) << "push eof to inputstream of removed node: " << stream.second->identifier_; - q->push(Packet::generate_eof_packet()); - stream.second->add_packets(q); - } + } - //wait utile the EOF was consumed - for (auto input_stream:input_stream_manager->input_streams_) - input_stream_manager->wait_on_stream_empty(input_stream.first); - - rm_node->wait_paused(); - - //remove the upstream after output stream consumed - for (auto node:paused_nodes) { - std::shared_ptr out_str_mng; - std::map> output_streams; - node->get_output_stream_manager(out_str_mng); - node->get_output_streams(output_streams); - for (auto &output_stream:output_streams) { - for (auto rm_stream:upstream_output_streams) { - if (output_stream.second->identifier_ == rm_stream->identifier_) { - out_str_mng->remove_stream(output_stream.first, rm_stream->stream_id_); - BMFLOG(BMF_INFO) << "remove stream: " << rm_stream->identifier_ - << "stream id: " << rm_stream->stream_id_; - //make sure to notify the output streams of the upstream nodes are changed - node->set_outputstream_updated(true); - rm_stream->stream_id_ = -1;//removed tag - break; - } - } - } - } - } else { - rm_node->wait_paused(); + std::vector rm_streams_id; + for (auto output_stream : output_stream_manager->output_streams_) + rm_streams_id.push_back(output_stream.first); + for (auto streams_id : rm_streams_id) { + BMFLOG(BMF_INFO) + << "remove down stream: " + << output_stream_manager->output_streams_[streams_id] + ->identifier_; + output_stream_manager->remove_stream(streams_id, -1); + } - output_stream_manager->probe_eof(); + // remove the nodes in scheduler + while (scheduler_->nodes_to_schedule_.find(rm_node->get_id()) != + scheduler_->nodes_to_schedule_.end()) + scheduler_->add_or_remove_node(rm_node->get_id(), false); - for (auto output_stream:output_stream_manager->output_streams_) { - std::shared_ptr > q = std::make_shared>(); - BMFLOG(BMF_INFO) << "push eof to outputstream of removing node"; - q->push(Packet::generate_eof_packet()); - output_stream.second->propagate_packets(q); - } - } + rm_node->close(); + nodes_.erase(rm_node->get_id()); + BMFLOG(BMF_INFO) << "remove node: " << rm_node->get_id() + << " alias: " << rm_node->get_alias(); - for (auto node:paused_nodes) { - BMFLOG(BMF_INFO) << "paused us node recover: " << node->get_id() << " alias: " - << node->get_alias(); + for (auto node : paused_ds_nodes) { + BMFLOG(BMF_INFO) << "paused ds node recover: " << node->get_id() + << " alias: " << node->get_alias(); + std::shared_ptr input_stream_manager; + node->get_input_stream_manager(input_stream_manager); + if (input_stream_manager->input_streams_.size() == 0) { + node->set_source(true); + BMFLOG(BMF_INFO) << "set source: id " << node->get_id() + << " " << node->get_alias(); + scheduler_->add_or_remove_node(node->get_id(), true); + } else node->set_status(NodeState::PENDING); - } - - //remove the downstream - for (auto output_stream:output_stream_manager->output_streams_) - output_stream_manager->wait_on_stream_empty(output_stream.first); - //pause the down stream nodes - std::vector ds_nodes_id; - output_stream_manager->get_outlink_nodes_id(ds_nodes_id); - int ret; - std::vector> paused_ds_nodes; - for (int i = 0 ; i < ds_nodes_id.size(); i++) { - std::shared_ptr nd; - if (get_node(ds_nodes_id[i], nd) == 0) { - nd->wait_paused(); - paused_ds_nodes.push_back(nd); - - //remove upstream_nodes_ - std::shared_ptr input_stream_manager; - nd->get_input_stream_manager(input_stream_manager); - input_stream_manager->remove_upstream_nodes(id_of_rm_node); - - } else { - BMFLOG(BMF_ERROR) << "down stream node can't be got: " << i; - return -1; - } - } - - std::vector rm_streams_id; - for (auto output_stream:output_stream_manager->output_streams_) - rm_streams_id.push_back(output_stream.first); - for (auto streams_id:rm_streams_id) { - BMFLOG(BMF_INFO) << "remove down stream: " - << output_stream_manager->output_streams_[streams_id]->identifier_; - output_stream_manager->remove_stream(streams_id, -1); - } - - //remove the nodes in scheduler - while (scheduler_->nodes_to_schedule_.find(rm_node->get_id()) != - scheduler_->nodes_to_schedule_.end()) - scheduler_->add_or_remove_node(rm_node->get_id(), false); - - rm_node->close(); - nodes_.erase(rm_node->get_id()); - BMFLOG(BMF_INFO) << "remove node: " << rm_node->get_id() << " alias: " << rm_node->get_alias(); - - for (auto node:paused_ds_nodes) { - BMFLOG(BMF_INFO) << "paused ds node recover: " << node->get_id() << " alias: " - << node->get_alias(); - std::shared_ptr input_stream_manager; - node->get_input_stream_manager(input_stream_manager); - if (input_stream_manager->input_streams_.size() == 0) { - node->set_source(true); - BMFLOG(BMF_INFO) << "set source: id " << node->get_id() << " " << node->get_alias(); - scheduler_->add_or_remove_node(node->get_id(), true); - } else - node->set_status(NodeState::PENDING); - } } } + } - if (nodes_reset.size()) { - for (auto &node_config:nodes_reset) { - int id_of_reset_node = -1; - for (auto &node:nodes_) { - if (node.second->get_alias() == node_config.get_alias()) { - BMFLOG(BMF_INFO) << "found the node to be reset: " << node.second->get_alias(); - id_of_reset_node = node.first; - break; - } - } - if (id_of_reset_node == -1) { - BMFLOG(BMF_ERROR) << "cannot find the node to be removed"; - return -1; + if (nodes_reset.size()) { + for (auto &node_config : nodes_reset) { + int id_of_reset_node = -1; + for (auto &node : nodes_) { + if (node.second->get_alias() == node_config.get_alias()) { + BMFLOG(BMF_INFO) << "found the node to be reset: " + << node.second->get_alias(); + id_of_reset_node = node.first; + break; } - std::shared_ptr reset_node = nodes_[id_of_reset_node]; - - //update the option - reset_node->need_opt_reset(node_config.get_option()); } - } - BMFLOG(BMF_INFO) << "dynamic update done"; - - return 0; - } - - bool Graph::all_nodes_done() { - for (auto &node_iter: nodes_) { - if (not node_iter.second->is_closed()) { - return false; + if (id_of_reset_node == -1) { + BMFLOG(BMF_ERROR) << "cannot find the node to be removed"; + return -1; } - } - return true; - } - - int Graph::close() { - { - std::unique_lock lk(con_var_mutex_); - if (closed_count_ != nodes_.size() && !scheduler_->eptr_) - cond_close_.wait(lk); - } + std::shared_ptr reset_node = nodes_[id_of_reset_node]; - if (not exception_from_scheduler_) - scheduler_->close(); - else - std::cerr << "!!Coredump may occured due to unfinished schedule threads and node process, please refer the detail information to debug or optimze the graph..." << std::endl; - - g_ptr.clear(); - if (scheduler_->eptr_) { - auto graph_info = status(); - std::cerr << "Graph status when exception occured: " << graph_info.jsonify().dump() - << std::endl; - std::rethrow_exception(scheduler_->eptr_); + // update the option + reset_node->need_opt_reset(node_config.get_option()); } - return 0; } + BMFLOG(BMF_INFO) << "dynamic update done"; - int Graph::get_node(int node_id, std::shared_ptr &node) { - if (nodes_.count(node_id)) { - node = nodes_[node_id]; - return 0; - } - return -1; - } + return 0; +} - int Graph::force_close() { - for (auto &node :nodes_) { - node.second->close(); +bool Graph::all_nodes_done() { + for (auto &node_iter : nodes_) { + if (not node_iter.second->is_closed()) { + return false; } - scheduler_->close(); - return 0; } - - // manually insert C++ packet to graph - int Graph::add_input_stream_packet(std::string const &stream_name, Packet &packet, bool block) { - if (input_streams_.count(stream_name) > 0) { - if (block){ - - while (input_streams_[stream_name]->manager_->any_of_downstream_full()){ - { - usleep(1000); - } - } - } - input_streams_[stream_name]->add_packet(packet); - } - return 0; + return true; +} + +int Graph::close() { + { + std::unique_lock lk(con_var_mutex_); + if (closed_count_ != nodes_.size() && !scheduler_->eptr_) + cond_close_.wait(lk); } - // manually poll output packet and return C++ packet - Packet Graph::poll_output_stream_packet(std::string const &stream_name, bool block) { - Packet packet; - if (output_streams_.count(stream_name) > 0) { - output_streams_[stream_name]->poll_packet(packet, block); - } - return packet; + if (not exception_from_scheduler_) + scheduler_->close(); + else + std::cerr << "!!Coredump may occured due to unfinished schedule " + "threads and node process, please refer the detail " + "information to debug or optimze the graph..." + << std::endl; + + g_ptr.clear(); + if (scheduler_->eptr_) { + auto graph_info = status(); + std::cerr << "Graph status when exception occured: " + << graph_info.jsonify().dump() << std::endl; + std::rethrow_exception(scheduler_->eptr_); } + return 0; +} -//TODO manually insert a eos packet to indicate the graph input stream is done - int Graph::add_eos_packet(std::string const &stream_name) { - if (input_streams_.count(stream_name) > 0) { - Packet packet = Packet::generate_eos_packet(); - input_streams_[stream_name]->add_packet(packet); - } +int Graph::get_node(int node_id, std::shared_ptr &node) { + if (nodes_.count(node_id)) { + node = nodes_[node_id]; return 0; } + return -1; +} - void Graph::pause_running(double_t timeout) { - if (paused_) - return; - scheduler_->pause(); - paused_ = true; - if (timeout > 0) { - auto f = [](Graph *g, int timout) { - usleep(timout); - g->resume_running(); - }; - std::thread(f, this, timeout * 1000); - } - } - - void Graph::resume_running() { - if (!paused_) - return; - scheduler_->resume(); - paused_ = false; +int Graph::force_close() { + for (auto &node : nodes_) { + node.second->close(); } - - void Graph::print_node_info_pretty() { -#define LEFTW(width) std::setiosflags(std::ios::left)<get_id() << LEFTW(30) << nd.second->get_type() << LEFTW(10) - << nd.second->get_status() - << LEFTW(20) << nd.second->get_schedule_attempt_cnt() << LEFTW(20) - << nd.second->get_schedule_success_cnt() << LEFTW(20) << nd.second->get_last_timestamp() - << LEFTW(10) << (nd.second->is_source() ? "YES" : "NO") << std::endl; - } -#undef LEFTW - } - - void Graph::quit_gracefully() { - std::cerr << "quitting..." << std::endl; - for (auto g:g_ptr) { - g->print_node_info_pretty(); - g->force_close(); + scheduler_->close(); + return 0; +} + +// manually insert C++ packet to graph +int Graph::add_input_stream_packet(std::string const &stream_name, + Packet &packet, bool block) { + if (input_streams_.count(stream_name) > 0) { + if (block) { + + while (input_streams_[stream_name] + ->manager_->any_of_downstream_full()) { + { usleep(1000); } + } } + input_streams_[stream_name]->add_packet(packet); } - - Graph::~Graph() { - if (not exception_from_scheduler_) - scheduler_->close(); - } - - bmf::GraphRunningInfo Graph::status() { - return RunningInfoCollector().collect_graph_info(this); + return 0; +} + +// manually poll output packet and return C++ packet +Packet Graph::poll_output_stream_packet(std::string const &stream_name, + bool block) { + Packet packet; + if (output_streams_.count(stream_name) > 0) { + output_streams_[stream_name]->poll_packet(packet, block); } - - void GraphInputStream::set_manager(std::shared_ptr &manager) { - manager_ = manager; + return packet; +} + +// TODO manually insert a eos packet to indicate the graph input stream is done +int Graph::add_eos_packet(std::string const &stream_name) { + if (input_streams_.count(stream_name) > 0) { + Packet packet = Packet::generate_eos_packet(); + input_streams_[stream_name]->add_packet(packet); } - - void GraphInputStream::add_packet(Packet &packet) { - std::shared_ptr > packets = std::make_shared >(); - packets->push(packet); - manager_->propagate_packets(0, packets); + return 0; +} + +void Graph::pause_running(double_t timeout) { + if (paused_) + return; + scheduler_->pause(); + paused_ = true; + if (timeout > 0) { + auto f = [](Graph *g, int timout) { + usleep(timout); + g->resume_running(); + }; + std::thread(f, this, timeout * 1000); } - - void GraphOutputStream::set_manager(std::shared_ptr &input_manager) { - input_manager_ = input_manager; +} + +void Graph::resume_running() { + if (!paused_) + return; + scheduler_->resume(); + paused_ = false; +} + +void Graph::print_node_info_pretty() { +#define LEFTW(width) std::setiosflags(std::ios::left) << std::setw(width) + + std::cerr << LEFTW(10) << "NODE" << LEFTW(30) << "TYPE" << LEFTW(10) + << "STATUS" << LEFTW(20) << "SCHEDULE_COUNT" << LEFTW(20) + << "SCHEDULE_SUCCESS" << LEFTW(20) << "TIMESTAMP" << LEFTW(10) + << "IS_SOURCE" << std::endl; + for (auto nd : nodes_) { + std::cerr << LEFTW(10) << nd.second->get_id() << LEFTW(30) + << nd.second->get_type() << LEFTW(10) + << nd.second->get_status() << LEFTW(20) + << nd.second->get_schedule_attempt_cnt() << LEFTW(20) + << nd.second->get_schedule_success_cnt() << LEFTW(20) + << nd.second->get_last_timestamp() << LEFTW(10) + << (nd.second->is_source() ? "YES" : "NO") << std::endl; } +#undef LEFTW +} - void GraphOutputStream::poll_packet(Packet &packet, bool block) { - packet = input_manager_->pop_next_packet(0, block); +void Graph::quit_gracefully() { + std::cerr << "quitting..." << std::endl; + for (auto g : g_ptr) { + g->print_node_info_pretty(); + g->force_close(); } +} - void GraphOutputStream::inject_packet(Packet &packet, int index) { - std::shared_ptr> packets = std::make_shared>(); - packets->push(packet); - if (index < 0) { - for (auto &input_stream:input_manager_->input_streams_) { - input_manager_->add_packets(input_stream.first, packets); - } - } else - input_manager_->add_packets(index, packets); - } +Graph::~Graph() { + if (not exception_from_scheduler_) + scheduler_->close(); +} + +bmf::GraphRunningInfo Graph::status() { + return RunningInfoCollector().collect_graph_info(this); +} + +void GraphInputStream::set_manager( + std::shared_ptr &manager) { + manager_ = manager; +} + +void GraphInputStream::add_packet(Packet &packet) { + std::shared_ptr> packets = + std::make_shared>(); + packets->push(packet); + manager_->propagate_packets(0, packets); +} + +void GraphOutputStream::set_manager( + std::shared_ptr &input_manager) { + input_manager_ = input_manager; +} + +void GraphOutputStream::poll_packet(Packet &packet, bool block) { + packet = input_manager_->pop_next_packet(0, block); +} + +void GraphOutputStream::inject_packet(Packet &packet, int index) { + std::shared_ptr> packets = + std::make_shared>(); + packets->push(packet); + if (index < 0) { + for (auto &input_stream : input_manager_->input_streams_) { + input_manager_->add_packets(input_stream.first, packets); + } + } else + input_manager_->add_packets(index, packets); +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/graph_config.cpp b/bmf/engine/c_engine/src/graph_config.cpp index 1974645f..0947651d 100644 --- a/bmf/engine/c_engine/src/graph_config.cpp +++ b/bmf/engine/c_engine/src/graph_config.cpp @@ -29,493 +29,471 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - StreamConfig::StreamConfig(JsonParam &stream_config) { - init(stream_config.json_value_); - } - - StreamConfig::StreamConfig(nlohmann::json &stream_config) { - init(stream_config); - } - - void StreamConfig::init(nlohmann::json &stream_config) { - identifier = stream_config.at("identifier").get(); - auto p = identifier.find(':'); - if (p != std::string::npos) { - notify = identifier.substr(0, p); - identifier = identifier.substr(p + 1, identifier.length() - p); - } else { - notify = ""; +USE_BMF_SDK_NS + +StreamConfig::StreamConfig(JsonParam &stream_config) { + init(stream_config.json_value_); +} + +StreamConfig::StreamConfig(nlohmann::json &stream_config) { + init(stream_config); +} + +void StreamConfig::init(nlohmann::json &stream_config) { + identifier = stream_config.at("identifier").get(); + auto p = identifier.find(':'); + if (p != std::string::npos) { + notify = identifier.substr(0, p); + identifier = identifier.substr(p + 1, identifier.length() - p); + } else { + notify = ""; + } + if (stream_config.count("alias")) + alias = stream_config.at("alias").get(); +} + +std::string StreamConfig::get_identifier() { return identifier; } + +std::string StreamConfig::get_notify() { return notify; } + +std::string StreamConfig::get_alias() { return alias; } + +nlohmann::json StreamConfig::to_json() { + nlohmann::json json_stream_info; + json_stream_info["identifier"] = identifier; + json_stream_info["notify"] = notify; + json_stream_info["alias"] = alias; + return json_stream_info; +} + +ModuleConfig::ModuleConfig(JsonParam &module_config) { + init(module_config.json_value_); +} + +ModuleConfig::ModuleConfig(nlohmann::json &module_config) { + init(module_config); +} + +void ModuleConfig::init(nlohmann::json &module_config) { + if (module_config.count("name")) + module_name = module_config.at("name").get(); + if (module_config.count("type")) + module_type = module_config.at("type").get(); + if (module_config.count("path")) + module_path = module_config.at("path").get(); + if (module_config.count("entry")) + module_entry = module_config.at("entry").get(); +} + +std::string ModuleConfig::get_module_name() { return module_name; } + +std::string ModuleConfig::get_module_type() { return module_type; } + +std::string ModuleConfig::get_module_path() { return module_path; } + +std::string ModuleConfig::get_module_entry() { return module_entry; } + +nlohmann::json ModuleConfig::to_json() { + nlohmann::json json_module_info; + json_module_info["name"] = module_name; + json_module_info["type"] = module_type; + json_module_info["path"] = module_path; + json_module_info["entry"] = module_entry; + return json_module_info; +} + +NodeMetaInfo::NodeMetaInfo(JsonParam &node_meta) { + init(node_meta.json_value_); +} + +NodeMetaInfo::NodeMetaInfo(nlohmann::json &node_meta) { init(node_meta); } + +void NodeMetaInfo::init(nlohmann::json &node_meta) { + if (node_meta.count("bundle_id")) + bundle = node_meta.at("bundle_id").get(); + if (node_meta.count("premodule_id")) + premodule_id = node_meta.at("premodule_id").get(); + if (node_meta.count("callback_binding")) + for (auto &cb : node_meta.at("callback_binding")) { + auto binding = cb.get(); + auto p = binding.find(':'); + if (p == std::string::npos) + throw std::logic_error("Wrong callback binding."); + callback_binding[std::stoll(binding.substr(0, p))] = + std::stoul(binding.substr(p + 1, binding.length() - p)); } - if (stream_config.count("alias")) - alias = stream_config.at("alias").get(); - } + if (node_meta.count("queue_length_limit")) + queue_size_limit = node_meta.at("queue_length_limit").get(); +} - std::string StreamConfig::get_identifier() { - return identifier; - } +int32_t NodeMetaInfo::get_premodule_id() { return premodule_id; } - std::string StreamConfig::get_notify() { - return notify; - } +int32_t NodeMetaInfo::get_bundle() { return bundle; } - std::string StreamConfig::get_alias() { - return alias; - } - - nlohmann::json StreamConfig::to_json(){ - nlohmann::json json_stream_info; - json_stream_info["identifier"] = identifier; - json_stream_info["notify"] = notify; - json_stream_info["alias"] = alias; - return json_stream_info; - } +uint32_t NodeMetaInfo::get_queue_size_limit() { return queue_size_limit; } - ModuleConfig::ModuleConfig(JsonParam &module_config) { - init(module_config.json_value_); - } +std::map NodeMetaInfo::get_callback_binding() { + return callback_binding; +} - ModuleConfig::ModuleConfig(nlohmann::json &module_config) { - init(module_config); +nlohmann::json NodeMetaInfo::to_json() { + nlohmann::json json_meta_info; + json_meta_info["premodule_id"] = premodule_id; + json_meta_info["callback_binding"] = + nlohmann::json(std::vector()); + for (auto &it : callback_binding) { + json_meta_info["callback_binding"].push_back( + std::to_string(it.first) + ":" + std::to_string(it.second)); } + return json_meta_info; +} - void ModuleConfig::init(nlohmann::json &module_config) { - if (module_config.count("name")) - module_name = module_config.at("name").get(); - if (module_config.count("type")) - module_type = module_config.at("type").get(); - if (module_config.count("path")) - module_path = module_config.at("path").get(); - if (module_config.count("entry")) - module_entry = module_config.at("entry").get(); - } +NodeConfig::NodeConfig(JsonParam &node_config) { + init(node_config.json_value_); +} - std::string ModuleConfig::get_module_name(){ - return module_name; - } +NodeConfig::NodeConfig(nlohmann::json &node_config) { init(node_config); } - std::string ModuleConfig::get_module_type(){ - return module_type; - } +std::string NodeConfig::get_alias() { return alias; } - std::string ModuleConfig::get_module_path(){ - return module_path; - } +std::string NodeConfig::get_action() { return action; } - std::string ModuleConfig::get_module_entry(){ - return module_entry; - } +void NodeConfig::init(nlohmann::json &node_config) { + if (node_config.count("id")) + id = node_config.at("id").get(); - nlohmann::json ModuleConfig::to_json(){ - nlohmann::json json_module_info; - json_module_info["name"] = module_name; - json_module_info["type"] = module_type; - json_module_info["path"] = module_path; - json_module_info["entry"] = module_entry; - return json_module_info; - } + if (node_config.count("module_info")) + module = ModuleConfig(node_config.at("module_info")); - NodeMetaInfo::NodeMetaInfo(JsonParam &node_meta) { - init(node_meta.json_value_); - } + if (node_config.count("meta_info")) + meta = NodeMetaInfo(node_config.at("meta_info")); - NodeMetaInfo::NodeMetaInfo(nlohmann::json &node_meta) { - init(node_meta); - } + if (node_config.count("input_streams")) + for (auto s : node_config.at("input_streams")) + input_streams.emplace_back(s); + if (node_config.count("output_streams")) + for (auto s : node_config.at("output_streams")) + output_streams.emplace_back(s); + if (node_config.count("option")) + option = JsonParam(node_config.at("option")); + if (node_config.count("scheduler")) + scheduler = node_config.at("scheduler").get(); + if (node_config.count("input_manager")) + input_manager = node_config.at("input_manager").get(); + if (node_config.count("alias")) + alias = node_config.at("alias").get(); + if (node_config.count("action")) + action = node_config.at("action").get(); +} - void NodeMetaInfo::init(nlohmann::json &node_meta) { - if (node_meta.count("bundle_id")) - bundle = node_meta.at("bundle_id").get(); - if (node_meta.count("premodule_id")) - premodule_id = node_meta.at("premodule_id").get(); - if (node_meta.count("callback_binding")) - for (auto &cb:node_meta.at("callback_binding")) { - auto binding = cb.get(); - auto p = binding.find(':'); - if (p == std::string::npos) - throw std::logic_error("Wrong callback binding."); - callback_binding[std::stoll(binding.substr(0, p))] = - std::stoul(binding.substr(p + 1, binding.length() - p)); - } - if (node_meta.count("queue_length_limit")) - queue_size_limit = node_meta.at("queue_length_limit").get(); - } +ModuleConfig NodeConfig::get_module_info() { return module; } - int32_t NodeMetaInfo::get_premodule_id() { - return premodule_id; - } +JsonParam NodeConfig::get_option() { return option; } - int32_t NodeMetaInfo::get_bundle() { - return bundle; - } +void NodeConfig::set_option(JsonParam node_option) { option = node_option; } - uint32_t NodeMetaInfo::get_queue_size_limit() { - return queue_size_limit; - } +std::string NodeConfig::get_input_manager() { return input_manager; } - std::map NodeMetaInfo::get_callback_binding() { - return callback_binding; - } +NodeMetaInfo NodeConfig::get_node_meta() { return meta; } - nlohmann::json NodeMetaInfo::to_json(){ - nlohmann::json json_meta_info; - json_meta_info["premodule_id"] = premodule_id; - json_meta_info["callback_binding"] = nlohmann::json(std::vector()); - for (auto &it:callback_binding){ - json_meta_info["callback_binding"].push_back(std::to_string(it.first)+":"+std::to_string(it.second)); - } - return json_meta_info; - } +std::vector &NodeConfig::get_input_streams() { + return input_streams; +} - NodeConfig::NodeConfig(JsonParam &node_config) { - init(node_config.json_value_); - } +std::vector &NodeConfig::get_output_streams() { + return output_streams; +} - NodeConfig::NodeConfig(nlohmann::json &node_config) { - init(node_config); - } +void NodeConfig::add_input_stream(StreamConfig input_stream) { + input_streams.push_back(input_stream); +} - std::string NodeConfig::get_alias() { - return alias; - } +void NodeConfig::add_output_stream(StreamConfig output_stream) { + output_streams.push_back(output_stream); +} - std::string NodeConfig::get_action() { - return action; - } +int NodeConfig::get_id() { return id; } - void NodeConfig::init(nlohmann::json &node_config) { - if (node_config.count("id")) - id = node_config.at("id").get(); - - if (node_config.count("module_info")) - module = ModuleConfig(node_config.at("module_info")); - - if (node_config.count("meta_info")) - meta = NodeMetaInfo(node_config.at("meta_info")); - - if (node_config.count("input_streams")) - for (auto s:node_config.at("input_streams")) - input_streams.emplace_back(s); - if (node_config.count("output_streams")) - for (auto s:node_config.at("output_streams")) - output_streams.emplace_back(s); - if (node_config.count("option")) - option = JsonParam(node_config.at("option")); - if (node_config.count("scheduler")) - scheduler = node_config.at("scheduler").get(); - if (node_config.count("input_manager")) - input_manager = node_config.at("input_manager").get(); - if (node_config.count("alias")) - alias = node_config.at("alias").get(); - if (node_config.count("action")) - action = node_config.at("action").get(); - } +int NodeConfig::get_scheduler() { return scheduler; } - ModuleConfig NodeConfig::get_module_info() { - return module; - } +nlohmann::json NodeConfig::to_json() { + nlohmann::json json_node_config; + json_node_config["id"] = id; + json_node_config["scheduler"] = scheduler; + json_node_config["input_manager"] = input_manager; + json_node_config["module_info"] = module.to_json(); + json_node_config["meta_info"] = meta.to_json(); + json_node_config["option"] = option.json_value_; - JsonParam NodeConfig::get_option() { - return option; + json_node_config["input_streams"] = + nlohmann::json(std::vector()); + for (StreamConfig input_stream : input_streams) { + json_node_config["input_streams"].push_back(input_stream.to_json()); } - void NodeConfig::set_option(JsonParam node_option){ - option = node_option; + json_node_config["output_streams"] = + nlohmann::json(std::vector()); + for (StreamConfig output_stream : output_streams) { + json_node_config["output_streams"].push_back(output_stream.to_json()); } - std::string NodeConfig::get_input_manager() { - return input_manager; - } + return json_node_config; +} + +GraphConfig::GraphConfig(std::string config_file) { + if (config_file == "") + throw std::logic_error("No config file for graph config!"); - NodeMetaInfo NodeConfig::get_node_meta() { - return meta; - } + nlohmann::json graph_json; + std::ifstream gs(config_file); + gs >> graph_json; + init(graph_json); +} - std::vector& NodeConfig::get_input_streams() { - return input_streams; - } +GraphConfig::GraphConfig(JsonParam &graph_config) { + init(graph_config.json_value_); +} - std::vector& NodeConfig::get_output_streams() { - return output_streams; - } +GraphConfig::GraphConfig(nlohmann::json &graph_config) { init(graph_config); } - void NodeConfig::add_input_stream(StreamConfig input_stream){ - input_streams.push_back(input_stream); - } +void GraphConfig::init(nlohmann::json &graph_config) { + auto validate = [](nlohmann::json graph) -> void { + std::unordered_map input_streams; + std::unordered_map output_streams; + std::unordered_map> edges; - void NodeConfig::add_output_stream(StreamConfig output_stream){ - output_streams.push_back(output_stream); - } + auto unwrap_identifier = + [](std::string const &identifier) -> std::string { + auto p = identifier.find(':'); + if (p != std::string::npos) + return identifier.substr(p + 1, identifier.length() - p); + return identifier; + }; - int NodeConfig::get_id() { - return id; - } + auto validation_insert_output_stream = [&unwrap_identifier]( + std::string const &module, std::string const &stream, + std::unordered_map &stream_set) -> void { + auto s = unwrap_identifier(stream); + if (stream_set.count(s)) + throw std::logic_error("Duplicated input_stream in graph!"); + stream_set[s] = module; + }; - int NodeConfig::get_scheduler() { - return scheduler; - } + auto validation_decoder_output = [](std::string const &stream) -> void { + auto p = stream.find(':'); + if (p != std::string::npos) { + std::string stream_name = stream.substr(0, p); + if (!(stream_name == "video" || stream_name == "audio")) + throw std::logic_error( + "Incorrect stream notify for decoder!"); + } + }; - nlohmann::json NodeConfig::to_json() { - nlohmann::json json_node_config; - json_node_config["id"] = id; - json_node_config["scheduler"] = scheduler; - json_node_config["input_manager"] = input_manager; - json_node_config["module_info"] = module.to_json(); - json_node_config["meta_info"] = meta.to_json(); - json_node_config["option"] = option.json_value_; - - json_node_config["input_streams"] = nlohmann::json(std::vector()); - for (StreamConfig input_stream:input_streams){ - json_node_config["input_streams"].push_back(input_stream.to_json()); - } + auto validation_insert_edge = [&unwrap_identifier, &edges]( + std::string const &in_s, std::string const &out_s) -> void { + auto s1 = unwrap_identifier(in_s), s2 = unwrap_identifier(out_s); + if (!edges.count(s1)) + edges[s1] = std::unordered_set(); + if (edges[s1].count(s2)) + throw std::logic_error("Duplicated edge in graph!"); + edges[s1].insert(s2); + }; - json_node_config["output_streams"] = nlohmann::json(std::vector()); - for (StreamConfig output_stream:output_streams){ - json_node_config["output_streams"].push_back(output_stream.to_json()); + // Graph mode is necessary. + std::string run_mode = ""; + if (graph.count("mode")) + run_mode = graph.at("mode").get(); + + // In Server/Generator mode, graph must have input_stream/output_stream; + // Otherwise, graph may have some, but validator will ignore them. + if (run_mode == "Server" || run_mode == "Generator" || + run_mode == "Pushdata") { + for (auto stream : graph.at("input_streams")) + validation_insert_output_stream( + "BMF_SUPER_SOURCE", + stream.at("identifier").get(), input_streams); + for (auto stream : graph.at("output_streams")) + edges[stream.at("identifier").get()] = + std::unordered_set(); + if (run_mode == "Server" && input_streams.empty()) + throw std::logic_error( + "Server Mode require input_streams of graph to execute."); + if (edges.empty() && run_mode != "Pushdata") + throw std::logic_error("Server/Generator Mode require " + "output_streams of graph to execute."); } - return json_node_config; - } - - GraphConfig::GraphConfig(std::string config_file) { - if (config_file == "") - throw std::logic_error("No config file for graph config!"); - - nlohmann::json graph_json; - std::ifstream gs(config_file); - gs >> graph_json; - init(graph_json); - } - - GraphConfig::GraphConfig(JsonParam &graph_config) { - init(graph_config.json_value_); - } - - GraphConfig::GraphConfig(nlohmann::json &graph_config) { - init(graph_config); - } - - void GraphConfig::init(nlohmann::json &graph_config) { - auto validate = [](nlohmann::json graph) -> void { - std::unordered_map input_streams; - std::unordered_map output_streams; - std::unordered_map > edges; - - auto unwrap_identifier = [](std::string const &identifier) -> std::string { - auto p = identifier.find(':'); - if (p != std::string::npos) - return identifier.substr(p + 1, identifier.length() - p); - return identifier; - }; - - auto validation_insert_output_stream = [&unwrap_identifier](std::string const &module, - std::string const &stream, - std::unordered_map &stream_set) -> void { - auto s = unwrap_identifier(stream); - if (stream_set.count(s)) - throw std::logic_error("Duplicated input_stream in graph!"); - stream_set[s] = module; - }; - - auto validation_decoder_output = [](std::string const &stream) -> void { - auto p = stream.find(':'); - if (p != std::string::npos){ - std::string stream_name = stream.substr(0, p); - if (!(stream_name == "video" || stream_name == "audio")) - throw std::logic_error("Incorrect stream notify for decoder!"); - } - }; - - auto validation_insert_edge = [&unwrap_identifier, &edges](std::string const &in_s, - std::string const &out_s) -> void { - auto s1 = unwrap_identifier(in_s), s2 = unwrap_identifier(out_s); - if (!edges.count(s1)) - edges[s1] = std::unordered_set(); - if (edges[s1].count(s2)) - throw std::logic_error("Duplicated edge in graph!"); - edges[s1].insert(s2); - }; - - // Graph mode is necessary. - std::string run_mode = ""; - if (graph.count("mode")) - run_mode = graph.at("mode").get(); - - // In Server/Generator mode, graph must have input_stream/output_stream; - // Otherwise, graph may have some, but validator will ignore them. - if (run_mode == "Server" || run_mode == "Generator" || run_mode == "Pushdata") { - for (auto stream:graph.at("input_streams")) - validation_insert_output_stream("BMF_SUPER_SOURCE", stream.at("identifier").get(), - input_streams); - for (auto stream:graph.at("output_streams")) - edges[stream.at("identifier").get()] = std::unordered_set(); - if (run_mode == "Server" && input_streams.empty()) - throw std::logic_error("Server Mode require input_streams of graph to execute."); - if (edges.empty() && run_mode != "Pushdata") - throw std::logic_error("Server/Generator Mode require output_streams of graph to execute."); + //--------------------------------VALIDATION----------------------------------------- + // Collect info and check some basic syntax errors. + for (auto node : graph.at("nodes")) { + // Check whether "id" exists. + if (!node.count("action") && !node.count("id")) + throw std::logic_error("Missing 'id' parameter."); + // Check whether "module" exists. + if ((!node.count("action") || + (node.count("action") && + node.at("action").get() == "add")) && + !node.count("module_info")) + throw std::logic_error("Missing 'module_info' parameter."); + // Collect stream info. + std::string name = ""; + if (node.count("module_info")) + name = node.at("module_info").at("name").get() + + "_" + std::to_string(node.at("id").get()); + if (node.count("output_streams") && + node.at("output_streams").empty()) { } - - //--------------------------------VALIDATION----------------------------------------- - // Collect info and check some basic syntax errors. - for (auto node:graph.at("nodes")) { - // Check whether "id" exists. - if (!node.count("action") && !node.count("id")) - throw std::logic_error("Missing 'id' parameter."); - // Check whether "module" exists. - if ((!node.count("action") - || (node.count("action") && node.at("action").get() == "add")) - && !node.count("module_info")) - throw std::logic_error("Missing 'module_info' parameter."); - // Collect stream info. - std::string name = ""; - if (node.count("module_info")) - name = node.at("module_info").at("name").get() + "_" + - std::to_string(node.at("id").get()); - if (node.count("output_streams") && node.at("output_streams").empty()) {} - //for (auto in_s:node.at("input_streams")) - // validation_insert_edge(in_s.at("identifier").get(), "BMF_SUPER_DESTINATION"); - else { - // Check output for decoder - if (node.count("module_info") && node.at("module_info").at("name").get() == "c_ffmpeg_decoder") { - if (node.count("output_streams")) - for (auto out_s:node.at("output_streams")) { - validation_decoder_output(out_s.at("identifier").get()); - } - } + // for (auto in_s:node.at("input_streams")) + // validation_insert_edge(in_s.at("identifier").get(), + // "BMF_SUPER_DESTINATION"); + else { + // Check output for decoder + if (node.count("module_info") && + node.at("module_info").at("name").get() == + "c_ffmpeg_decoder") { if (node.count("output_streams")) - for (auto out_s:node.at("output_streams")) { - validation_insert_output_stream(name, out_s.at("identifier").get(), - output_streams); - for (auto in_s:node.at("input_streams")) - validation_insert_edge(in_s.at("identifier").get(), - out_s.at("identifier").get()); + for (auto out_s : node.at("output_streams")) { + validation_decoder_output( + out_s.at("identifier").get()); } } + if (node.count("output_streams")) + for (auto out_s : node.at("output_streams")) { + validation_insert_output_stream( + name, out_s.at("identifier").get(), + output_streams); + for (auto in_s : node.at("input_streams")) + validation_insert_edge( + in_s.at("identifier").get(), + out_s.at("identifier").get()); + } } -// TODO: Possibility of input_stream existing as a placeholder, ignore this check temporally. -// // Check whether in/out pin matches. -// for (auto &edge:edges) -// if (!output_streams.count(edge.first)) { -// throw std::logic_error("Using unexisting input_stream."); -// } - // Check looping, using DFS. - std::unordered_map vis; - std::unordered_set checked; - std::function dfs; - dfs = [&vis, &edges, &dfs](const std::string &in_s) -> bool { - if (vis.count(in_s) && vis[in_s]) + } + // TODO: Possibility of input_stream existing as a placeholder, ignore + // this check temporally. + // // Check whether in/out pin matches. + // for (auto &edge:edges) + // if (!output_streams.count(edge.first)) { + // throw std::logic_error("Using unexisting + // input_stream."); + // } + // Check looping, using DFS. + std::unordered_map vis; + std::unordered_set checked; + std::function dfs; + dfs = [&vis, &edges, &dfs](const std::string &in_s) -> bool { + if (vis.count(in_s) && vis[in_s]) + return true; + vis[in_s] = true; + for (auto &out_s : edges[in_s]) + if (dfs(out_s)) return true; - vis[in_s] = true; - for (auto &out_s:edges[in_s]) - if (dfs(out_s)) - return true; - vis[in_s] = false; - return false; - }; - for (auto &edge:edges) - if (!checked.count(input_streams[edge.first]) && dfs(edge.first)) - throw std::logic_error("Loop in graph!"); - else - checked.insert(input_streams[edge.first]); - // TODO: Server/Generator mode need extra checking? + vis[in_s] = false; + return false; }; - - validate(graph_config); - - mode = BmfMode::NORMAL_MODE; - if (graph_config.count("mode")) - mode = [](std::string mod) -> BmfMode { - if (mod == "Server") - return BmfMode::SERVER_MODE; - if (mod == "Generator") - return BmfMode::GENERATOR_MODE; - if (mod == "Subgraph") - return BmfMode::SUBGRAPH_MODE; - if (mod == "Pushdata") - return BmfMode::PUSHDATA_MODE; - return BmfMode::NORMAL_MODE; - }(graph_config.at("mode").get()); - - // Get option if needed. - if (graph_config.count("option")) - option = JsonParam(graph_config.at("option")); - - if (!graph_config.count("nodes")) - throw std::logic_error("Missing nodes in graph config."); - for (auto nd:graph_config.at("nodes")) - nodes.emplace_back(NodeConfig(nd)); - if (mode == BmfMode::SERVER_MODE || mode == BmfMode::GENERATOR_MODE || mode == BmfMode::SUBGRAPH_MODE) { - if (!graph_config.count("input_streams")) - throw std::logic_error("Missing input_steams in graph_config at server/generator mode."); - for (auto s:graph_config.at("input_streams")) - input_streams.emplace_back(StreamConfig(s)); - if (!graph_config.count("output_streams")) - throw std::logic_error("Missing output_steams in graph_config at server/generator mode."); - for (auto s:graph_config.at("output_streams")) - output_streams.emplace_back(StreamConfig(s)); - } - if (mode == BmfMode::PUSHDATA_MODE) { - if (!graph_config.count("input_streams")) - throw std::logic_error("Missing input_steams in graph_config at push data mode."); - for (auto s:graph_config.at("input_streams")) - input_streams.emplace_back(StreamConfig(s)); - } - } - - JsonParam GraphConfig::get_option() { - return option; - } - - BmfMode GraphConfig::get_mode() { - return mode; - } - - std::vector GraphConfig::get_nodes() { - return nodes; - } - - std::vector GraphConfig::get_input_streams() { - return input_streams; - } - - std::vector GraphConfig::get_output_streams() { - return output_streams; - } - - nlohmann::json GraphConfig::to_json(){ - nlohmann::json json_graph_config; - json_graph_config["option"] = option.json_value_; - - if (mode == BmfMode::NORMAL_MODE){ - json_graph_config["mode"] = "Normal"; - }else if (mode == BmfMode::SERVER_MODE){ - json_graph_config["mode"] = "Server"; - }else if (mode == BmfMode::GENERATOR_MODE){ - json_graph_config["mode"] = "Generator"; - }else if (mode == BmfMode::SUBGRAPH_MODE){ - json_graph_config["mode"] = "Subgraph"; - }else if (mode == BmfMode::PUSHDATA_MODE){ - json_graph_config["mode"] = "Pushdata"; - } - - json_graph_config["input_streams"] = nlohmann::json(std::vector()); - - for (StreamConfig input_stream:input_streams){ - json_graph_config["input_streams"].push_back(input_stream.to_json()); - } - - json_graph_config["output_streams"] = nlohmann::json(std::vector()); - for (StreamConfig output_stream:output_streams){ - json_graph_config["output_streams"].push_back(output_stream.to_json()); - } - - json_graph_config["nodes"] = nlohmann::json(std::vector()); - for (NodeConfig node_config:nodes){ - json_graph_config["nodes"].push_back(node_config.to_json()); - } - - return json_graph_config; - } + for (auto &edge : edges) + if (!checked.count(input_streams[edge.first]) && dfs(edge.first)) + throw std::logic_error("Loop in graph!"); + else + checked.insert(input_streams[edge.first]); + // TODO: Server/Generator mode need extra checking? + }; + + validate(graph_config); + + mode = BmfMode::NORMAL_MODE; + if (graph_config.count("mode")) + mode = [](std::string mod) -> BmfMode { + if (mod == "Server") + return BmfMode::SERVER_MODE; + if (mod == "Generator") + return BmfMode::GENERATOR_MODE; + if (mod == "Subgraph") + return BmfMode::SUBGRAPH_MODE; + if (mod == "Pushdata") + return BmfMode::PUSHDATA_MODE; + return BmfMode::NORMAL_MODE; + }(graph_config.at("mode").get()); + + // Get option if needed. + if (graph_config.count("option")) + option = JsonParam(graph_config.at("option")); + + if (!graph_config.count("nodes")) + throw std::logic_error("Missing nodes in graph config."); + for (auto nd : graph_config.at("nodes")) + nodes.emplace_back(NodeConfig(nd)); + if (mode == BmfMode::SERVER_MODE || mode == BmfMode::GENERATOR_MODE || + mode == BmfMode::SUBGRAPH_MODE) { + if (!graph_config.count("input_streams")) + throw std::logic_error("Missing input_steams in graph_config at " + "server/generator mode."); + for (auto s : graph_config.at("input_streams")) + input_streams.emplace_back(StreamConfig(s)); + if (!graph_config.count("output_streams")) + throw std::logic_error("Missing output_steams in graph_config at " + "server/generator mode."); + for (auto s : graph_config.at("output_streams")) + output_streams.emplace_back(StreamConfig(s)); + } + if (mode == BmfMode::PUSHDATA_MODE) { + if (!graph_config.count("input_streams")) + throw std::logic_error( + "Missing input_steams in graph_config at push data mode."); + for (auto s : graph_config.at("input_streams")) + input_streams.emplace_back(StreamConfig(s)); + } +} + +JsonParam GraphConfig::get_option() { return option; } + +BmfMode GraphConfig::get_mode() { return mode; } + +std::vector GraphConfig::get_nodes() { return nodes; } + +std::vector GraphConfig::get_input_streams() { + return input_streams; +} + +std::vector GraphConfig::get_output_streams() { + return output_streams; +} + +nlohmann::json GraphConfig::to_json() { + nlohmann::json json_graph_config; + json_graph_config["option"] = option.json_value_; + + if (mode == BmfMode::NORMAL_MODE) { + json_graph_config["mode"] = "Normal"; + } else if (mode == BmfMode::SERVER_MODE) { + json_graph_config["mode"] = "Server"; + } else if (mode == BmfMode::GENERATOR_MODE) { + json_graph_config["mode"] = "Generator"; + } else if (mode == BmfMode::SUBGRAPH_MODE) { + json_graph_config["mode"] = "Subgraph"; + } else if (mode == BmfMode::PUSHDATA_MODE) { + json_graph_config["mode"] = "Pushdata"; + } + + json_graph_config["input_streams"] = + nlohmann::json(std::vector()); + + for (StreamConfig input_stream : input_streams) { + json_graph_config["input_streams"].push_back(input_stream.to_json()); + } + + json_graph_config["output_streams"] = + nlohmann::json(std::vector()); + for (StreamConfig output_stream : output_streams) { + json_graph_config["output_streams"].push_back(output_stream.to_json()); + } + + json_graph_config["nodes"] = nlohmann::json(std::vector()); + for (NodeConfig node_config : nodes) { + json_graph_config["nodes"].push_back(node_config.to_json()); + } + + return json_graph_config; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/input_stream.cpp b/bmf/engine/c_engine/src/input_stream.cpp index b5b3a931..ac47d2c4 100644 --- a/bmf/engine/c_engine/src/input_stream.cpp +++ b/bmf/engine/c_engine/src/input_stream.cpp @@ -17,29 +17,36 @@ #include -#include +#include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - InputStream::InputStream(int stream_id, std::string const &identifier, std::string const &alias, - std::string const ¬ify, int node_id, std::function &throttled_cb, - int max_queue_size) - : stream_id_(stream_id), identifier_(identifier), alias_(alias), notify_(notify), - node_id_(node_id), throttled_cb_(throttled_cb), max_queue_size_(max_queue_size), - queue_(std::make_shared>()) { - queue_->set_identifier(identifier_); - } - - InputStream::InputStream(int stream_id, StreamConfig &stream_config, int node_id, - std::function &throttled_cb, size_t max_queue_size) - : stream_id_(stream_id), identifier_(stream_config.get_identifier()), alias_(stream_config.get_alias()), - notify_(stream_config.get_notify()), node_id_(node_id), throttled_cb_(throttled_cb), - max_queue_size_(max_queue_size), queue_(std::make_shared>()) { - queue_->set_identifier(identifier_); - } - -//InputStream::InputStream(const InputStream &input_stream) { +USE_BMF_SDK_NS + +InputStream::InputStream(int stream_id, std::string const &identifier, + std::string const &alias, std::string const ¬ify, + int node_id, + std::function &throttled_cb, + int max_queue_size) + : stream_id_(stream_id), identifier_(identifier), alias_(alias), + notify_(notify), node_id_(node_id), throttled_cb_(throttled_cb), + max_queue_size_(max_queue_size), + queue_(std::make_shared>()) { + queue_->set_identifier(identifier_); +} + +InputStream::InputStream(int stream_id, StreamConfig &stream_config, + int node_id, + std::function &throttled_cb, + size_t max_queue_size) + : stream_id_(stream_id), identifier_(stream_config.get_identifier()), + alias_(stream_config.get_alias()), notify_(stream_config.get_notify()), + node_id_(node_id), throttled_cb_(throttled_cb), + max_queue_size_(max_queue_size), + queue_(std::make_shared>()) { + queue_->set_identifier(identifier_); +} + +// InputStream::InputStream(const InputStream &input_stream) { // stream_id_ = input_stream.stream_id_; // name_ = input_stream.name_; // stream_manager_name_ = input_stream.stream_manager_name_; @@ -48,7 +55,7 @@ BEGIN_BMF_ENGINE_NS // node_id_ = input_stream.node_id_; //} // -//InputStream &InputStream::operator=(const InputStream &input_stream) { +// InputStream &InputStream::operator=(const InputStream &input_stream) { // stream_id_ = input_stream.stream_id_; // name_ = input_stream.name_; // stream_manager_name_ = input_stream.stream_manager_name_; @@ -57,153 +64,131 @@ BEGIN_BMF_ENGINE_NS // node_id_ = input_stream.node_id_; //} - int InputStream::add_packets(std::shared_ptr > &packets) { - Packet pkt; - while (packets->pop(pkt)) { - queue_->push(pkt); - // advance time bounding - next_time_bounding_ = pkt.timestamp() + 1; - // if received EOS, set stream done - // here we can't use pkt.get_timestamp() + 1 since - // Timestamp.DONE = Timestamp.EOS + 2 - if (pkt.timestamp() == EOS or pkt.timestamp() == BMF_EOF) { - next_time_bounding_ = DONE; - BMFLOG_NODE(BMF_INFO, node_id_) << "eof received"; - // add node to scheduler thread until this EOS is processed - // graph_output_stream may not have attribute node - //if (node_id_ >= 0) { - // throttled_cb_(node_id_, true); - //} - } - // wake up event - fill_packet_event_.notify_all(); - } - return 0; - } - - Packet InputStream::pop_packet_at_timestamp(int64_t timestamp) { - //TODO return the exactly same timestamp or the most closest one - Packet pkt; - Packet temp_pkt; - while (queue_->front(temp_pkt)) { - int64_t queue_front_timestamp = temp_pkt.timestamp(); - if (queue_front_timestamp <= timestamp) { - queue_->pop(pkt); - } else { - break; - } - } +int InputStream::add_packets(std::shared_ptr> &packets) { + Packet pkt; + while (packets->pop(pkt)) { + queue_->push(pkt); + // advance time bounding + next_time_bounding_ = pkt.timestamp() + 1; + // if received EOS, set stream done + // here we can't use pkt.get_timestamp() + 1 since + // Timestamp.DONE = Timestamp.EOS + 2 if (pkt.timestamp() == EOS or pkt.timestamp() == BMF_EOF) { - // EOS is popped, remove node from scheduler thread - BMFLOG_NODE(BMF_INFO, node_id_) << "eof processed, remove node from scheduler"; - //if (node_id_ >= 0) - // throttled_cb_(node_id_, false); + next_time_bounding_ = DONE; + BMFLOG_NODE(BMF_INFO, node_id_) << "eof received"; + // add node to scheduler thread until this EOS is processed + // graph_output_stream may not have attribute node + // if (node_id_ >= 0) { + // throttled_cb_(node_id_, true); + //} + } + // wake up event + fill_packet_event_.notify_all(); + } + return 0; +} + +Packet InputStream::pop_packet_at_timestamp(int64_t timestamp) { + // TODO return the exactly same timestamp or the most closest one + Packet pkt; + Packet temp_pkt; + while (queue_->front(temp_pkt)) { + int64_t queue_front_timestamp = temp_pkt.timestamp(); + if (queue_front_timestamp <= timestamp) { + queue_->pop(pkt); + } else { + break; } - return pkt; } - - bool InputStream::is_empty() { - return queue_->empty(); + if (pkt.timestamp() == EOS or pkt.timestamp() == BMF_EOF) { + // EOS is popped, remove node from scheduler thread + BMFLOG_NODE(BMF_INFO, node_id_) + << "eof processed, remove node from scheduler"; + // if (node_id_ >= 0) + // throttled_cb_(node_id_, false); } + return pkt; +} - void InputStream::wait_on_empty() { - while (not queue_->empty()) { - if (next_time_bounding_ == DONE) - break; - if (node_id_ >= 0) - throttled_cb_(node_id_, false);//tobefix - std::unique_lock lk(stream_m_); - stream_ept_.wait_for(lk, std::chrono::microseconds(40)); - } +bool InputStream::is_empty() { return queue_->empty(); } - return; +void InputStream::wait_on_empty() { + while (not queue_->empty()) { + if (next_time_bounding_ == DONE) + break; + if (node_id_ >= 0) + throttled_cb_(node_id_, false); // tobefix + std::unique_lock lk(stream_m_); + stream_ept_.wait_for(lk, std::chrono::microseconds(40)); } - int64_t InputStream::get_time_bounding() { - return next_time_bounding_; - } + return; +} - int InputStream::get_id() { - return stream_id_; - } +int64_t InputStream::get_time_bounding() { return next_time_bounding_; } - Packet InputStream::pop_next_packet(bool block) { - Packet pkt; - if (queue_->pop(pkt)) { - if (pkt.timestamp() == EOS or pkt.timestamp() == BMF_EOF) { - // EOS is popped, remove node from scheduler thread - BMFLOG_NODE(BMF_INFO, node_id_) << "eof processed, remove node from scheduler"; - //if (node_id_ >= 0) - // throttled_cb_(node_id_, false); - } - return pkt; - } else { - std::lock_guard lk(stream_m_); - stream_ept_.notify_all(); - - if (block) { - while (queue_->empty()) { - //fill_packet_event_.wait(lk); - std::unique_lock lk(mutex_); - fill_packet_event_.wait_for(lk, std::chrono::milliseconds(5)); - } - } - queue_->pop(pkt); +int InputStream::get_id() { return stream_id_; } + +Packet InputStream::pop_next_packet(bool block) { + Packet pkt; + if (queue_->pop(pkt)) { + if (pkt.timestamp() == EOS or pkt.timestamp() == BMF_EOF) { + // EOS is popped, remove node from scheduler thread + BMFLOG_NODE(BMF_INFO, node_id_) + << "eof processed, remove node from scheduler"; + // if (node_id_ >= 0) + // throttled_cb_(node_id_, false); } return pkt; + } else { + std::lock_guard lk(stream_m_); + stream_ept_.notify_all(); + + if (block) { + while (queue_->empty()) { + // fill_packet_event_.wait(lk); + std::unique_lock lk(mutex_); + fill_packet_event_.wait_for(lk, std::chrono::milliseconds(5)); + } + } + queue_->pop(pkt); } + return pkt; +} - bool InputStream::is_full() { - return queue_->size() >= max_queue_size_; - } +bool InputStream::is_full() { return queue_->size() >= max_queue_size_; } - void InputStream::set_connected(bool connected) { - connected_ = connected; - } +void InputStream::set_connected(bool connected) { connected_ = connected; } - bool InputStream::is_connected() { - return connected_; - } +bool InputStream::is_connected() { return connected_; } - std::string InputStream::get_identifier() { - return identifier_; - } +std::string InputStream::get_identifier() { return identifier_; } - std::string InputStream::get_alias() { - return alias_; - } +std::string InputStream::get_alias() { return alias_; } - std::string InputStream::get_notify() { - return notify_; - } +std::string InputStream::get_notify() { return notify_; } - void InputStream::clear_queue() { - Packet pkt; - while (not queue_->empty()) { - queue_->pop(pkt); - } +void InputStream::clear_queue() { + Packet pkt; + while (not queue_->empty()) { + queue_->pop(pkt); } +} - bool InputStream::get_min_timestamp(int64_t &min_timestamp) { - if (queue_->empty()) { - min_timestamp = next_time_bounding_; - return true; - } - Packet pkt; - queue_->front(pkt); - min_timestamp = pkt.timestamp(); - return false; +bool InputStream::get_min_timestamp(int64_t &min_timestamp) { + if (queue_->empty()) { + min_timestamp = next_time_bounding_; + return true; } + Packet pkt; + queue_->front(pkt); + min_timestamp = pkt.timestamp(); + return false; +} - bool InputStream::get_block() { - return block_; - } +bool InputStream::get_block() { return block_; } - void InputStream::set_block(bool block) { - block_ = block; - } +void InputStream::set_block(bool block) { block_ = block; } - void InputStream::probe_eof(bool probed) { - probed_ = true; - } +void InputStream::probe_eof(bool probed) { probed_ = true; } END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/input_stream_manager.cpp b/bmf/engine/c_engine/src/input_stream_manager.cpp index 51e8674d..5fc4091b 100644 --- a/bmf/engine/c_engine/src/input_stream_manager.cpp +++ b/bmf/engine/c_engine/src/input_stream_manager.cpp @@ -25,597 +25,628 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - InputStreamManager::InputStreamManager(int node_id, std::vector &input_streams, - std::vector &output_stream_id_list, uint32_t max_queue_size, - InputStreamManagerCallBack &callback) - : node_id_(node_id), callback_(callback), output_stream_id_list_(output_stream_id_list) { - std::function empt;// no need to send callback to input streamer now - for (auto i = 0; i < input_streams.size(); ++i) { - input_stream_names_.push_back(input_streams[i].get_identifier()); - input_streams_[i] = std::make_shared(i, input_streams[i], node_id, empt, max_queue_size); - stream_id_list_.push_back(i); - } - max_id_ = input_streams.size() - 1; +USE_BMF_SDK_NS + +InputStreamManager::InputStreamManager(int node_id, + std::vector &input_streams, + std::vector &output_stream_id_list, + uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : node_id_(node_id), callback_(callback), + output_stream_id_list_(output_stream_id_list) { + std::function + empt; // no need to send callback to input streamer now + for (auto i = 0; i < input_streams.size(); ++i) { + input_stream_names_.push_back(input_streams[i].get_identifier()); + input_streams_[i] = std::make_shared( + i, input_streams[i], node_id, empt, max_queue_size); + stream_id_list_.push_back(i); + } + max_id_ = input_streams.size() - 1; +} + +bool InputStreamManager::get_stream( + int stream_id, std::shared_ptr &input_stream) { + if (input_streams_.count(stream_id) > 0) { + input_stream = input_streams_[stream_id]; + return true; } + return false; +} +int InputStreamManager::add_stream(std::string name, int id) { + int stream_id; - bool InputStreamManager::get_stream(int stream_id, std::shared_ptr &input_stream) { - if (input_streams_.count(stream_id) > 0) { - input_stream = input_streams_[stream_id]; - return true; - } - return false; - } - - int InputStreamManager::add_stream(std::string name, int id) { - int stream_id; + max_id_ += 1; + stream_id = max_id_; - max_id_ += 1; - stream_id = max_id_; + int max_queue_size = 5; + input_streams_[stream_id] = std::make_shared( + stream_id, name, "", "", id, callback_.sched_required, max_queue_size); + // list add to ensure the queue can be picked up into the task + stream_id_list_.push_back(stream_id); - int max_queue_size = 5; - input_streams_[stream_id] = std::make_shared(stream_id, name, "", "", id, - callback_.sched_required, max_queue_size); - //list add to ensure the queue can be picked up into the task - stream_id_list_.push_back(stream_id); + return stream_id; +} - return stream_id; - } - - int InputStreamManager::remove_stream(int stream_id) { - std::lock_guard _(mtx_); - - std::shared_ptr input_stream = input_streams_[stream_id]; - - input_stream->wait_on_empty(); - input_streams_.erase(stream_id); - int i; - for (i = 0; i < stream_id_list_.size(); i++) { - if (stream_id_list_[i] == stream_id) - break; - } - stream_id_list_.erase(stream_id_list_.begin() + i); +int InputStreamManager::remove_stream(int stream_id) { + std::lock_guard _(mtx_); - if (stream_done_.find(stream_id) != stream_done_.end()) - stream_done_.erase(stream_id); + std::shared_ptr input_stream = input_streams_[stream_id]; - return 0; + input_stream->wait_on_empty(); + input_streams_.erase(stream_id); + int i; + for (i = 0; i < stream_id_list_.size(); i++) { + if (stream_id_list_[i] == stream_id) + break; } + stream_id_list_.erase(stream_id_list_.begin() + i); - int InputStreamManager::wait_on_stream_empty(int stream_id) { - std::shared_ptr input_stream = input_streams_[stream_id]; + if (stream_done_.find(stream_id) != stream_done_.end()) + stream_done_.erase(stream_id); - input_stream->wait_on_empty(); - return 0; - } + return 0; +} - bool InputStreamManager::schedule_node() { - int64_t min_timestamp; - NodeReadiness node_readiness = get_node_readiness(min_timestamp); - if (node_readiness == NodeReadiness::READY_FOR_PROCESS) { +int InputStreamManager::wait_on_stream_empty(int stream_id) { + std::shared_ptr input_stream = input_streams_[stream_id]; - Task task = Task(node_id_, stream_id_list_, output_stream_id_list_); - task.set_timestamp(min_timestamp); + input_stream->wait_on_empty(); + return 0; +} - bool result = fill_task_input(task); - if (not result) { - BMFLOG_NODE(BMF_INFO, node_id_) << "Failed to fill packet to task"; - return false; - } - callback_.scheduler_cb(task); - //TODO update node schedule_node_success cnt - //remove to node to add - return true; +bool InputStreamManager::schedule_node() { + int64_t min_timestamp; + NodeReadiness node_readiness = get_node_readiness(min_timestamp); + if (node_readiness == NodeReadiness::READY_FOR_PROCESS) { - } - return false; - } + Task task = Task(node_id_, stream_id_list_, output_stream_id_list_); + task.set_timestamp(min_timestamp); - void InputStreamManager::add_packets(int stream_id, std::shared_ptr > packets) { - // immediately return when node is closed - // graph_output_stream has no node_callback - if (callback_.node_is_closed_cb != NULL && callback_.node_is_closed_cb()) { - return; - } - // won't need to notify if empty pkt was passed in order to save schedule cost - if (packets->size() == 0) - return; - if (input_streams_.count(stream_id) > 0) { - //bool is_empty = input_streams_[stream_id]->is_empty(); - input_streams_[stream_id]->add_packets(packets); - if (callback_.sched_required != NULL) { - //if (this->type() != "Immediate" || (this->type() == "Immediate" && is_empty)) - //callback_.notify_cb(); - callback_.sched_required(node_id_, false); - } + bool result = fill_task_input(task); + if (not result) { + BMFLOG_NODE(BMF_INFO, node_id_) << "Failed to fill packet to task"; + return false; } + callback_.scheduler_cb(task); + // TODO update node schedule_node_success cnt + // remove to node to add + return true; } - - Packet InputStreamManager::pop_next_packet(int stream_id, bool block) { - if (input_streams_.count(stream_id)) { - auto stream = input_streams_[stream_id]; - return stream->pop_next_packet(block); - } else return Packet(0); - } - - int InputStreamManager::add_upstream_nodes(int node_id) { - upstream_nodes_.insert(node_id); - return 0; - } - - void InputStreamManager::remove_upstream_nodes(int node_id) { - upstream_nodes_.erase(node_id); - } - - bool InputStreamManager::find_upstream_nodes(int node_id) { - return upstream_nodes_.find(node_id) != upstream_nodes_.end(); - } - - ImmediateInputStreamManager::ImmediateInputStreamManager(int node_id, std::vector &input_streams, - std::vector &output_stream_id_list, - uint32_t max_queue_size, - InputStreamManagerCallBack &callback) - : InputStreamManager(node_id, input_streams, output_stream_id_list, max_queue_size, callback) { - next_timestamp_ = 1; - } - - std::string ImmediateInputStreamManager::type() { - return "Immediate"; - } - - int64_t ImmediateInputStreamManager::get_next_timestamp() { - std::lock_guard _(mtx_); - next_timestamp_++; - return next_timestamp_; - } - - NodeReadiness ImmediateInputStreamManager::get_node_readiness(int64_t &min_timestamp) { - for (auto &input_stream : input_streams_) { - if (not input_stream.second->is_empty()) { - min_timestamp = get_next_timestamp(); - return NodeReadiness::READY_FOR_PROCESS; - } + return false; +} + +void InputStreamManager::add_packets( + int stream_id, std::shared_ptr> packets) { + // immediately return when node is closed + // graph_output_stream has no node_callback + if (callback_.node_is_closed_cb != NULL && callback_.node_is_closed_cb()) { + return; + } + // won't need to notify if empty pkt was passed in order to save schedule + // cost + if (packets->size() == 0) + return; + if (input_streams_.count(stream_id) > 0) { + // bool is_empty = input_streams_[stream_id]->is_empty(); + input_streams_[stream_id]->add_packets(packets); + if (callback_.sched_required != NULL) { + // if (this->type() != "Immediate" || (this->type() == "Immediate" + // && is_empty)) + // callback_.notify_cb(); + callback_.sched_required(node_id_, false); } - return NodeReadiness::NOT_READY; } - - bool ImmediateInputStreamManager::fill_task_input(Task &task) { - bool task_filled = false; - for (auto & input_stream : input_streams_) { - if (input_stream.second->is_empty()) { -// task.fill_input_packet(iter->second->get_id(), Packet()); - continue; - } - - while (not input_stream.second->is_empty()) { - Packet pkt = input_stream.second->pop_next_packet(false); - if (pkt.timestamp() == BMF_EOF) { - if (input_stream.second->probed_) { - BMFLOG(BMF_INFO) << "immediate sync got EOF from dynamical update"; - pkt.set_timestamp(DYN_EOS); - input_stream.second->probed_ = false; - } else - stream_done_[input_stream.first] = 1; - } - task.fill_input_packet(input_stream.second->get_id(), pkt); - task_filled = true; - } - } - - if (stream_done_.size() == input_streams_.size()) { - task.set_timestamp(BMF_EOF); +} + +Packet InputStreamManager::pop_next_packet(int stream_id, bool block) { + if (input_streams_.count(stream_id)) { + auto stream = input_streams_[stream_id]; + return stream->pop_next_packet(block); + } else + return Packet(0); +} + +int InputStreamManager::add_upstream_nodes(int node_id) { + upstream_nodes_.insert(node_id); + return 0; +} + +void InputStreamManager::remove_upstream_nodes(int node_id) { + upstream_nodes_.erase(node_id); +} + +bool InputStreamManager::find_upstream_nodes(int node_id) { + return upstream_nodes_.find(node_id) != upstream_nodes_.end(); +} + +ImmediateInputStreamManager::ImmediateInputStreamManager( + int node_id, std::vector &input_streams, + std::vector &output_stream_id_list, uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : InputStreamManager(node_id, input_streams, output_stream_id_list, + max_queue_size, callback) { + next_timestamp_ = 1; +} + +std::string ImmediateInputStreamManager::type() { return "Immediate"; } + +int64_t ImmediateInputStreamManager::get_next_timestamp() { + std::lock_guard _(mtx_); + next_timestamp_++; + return next_timestamp_; +} + +NodeReadiness +ImmediateInputStreamManager::get_node_readiness(int64_t &min_timestamp) { + for (auto &input_stream : input_streams_) { + if (not input_stream.second->is_empty()) { + min_timestamp = get_next_timestamp(); + return NodeReadiness::READY_FOR_PROCESS; } - return task_filled; } + return NodeReadiness::NOT_READY; +} - DefaultInputManager::DefaultInputManager(int node_id, std::vector &input_streams, - std::vector &output_stream_id_list, uint32_t max_queue_size, - InputStreamManagerCallBack &callback) - : InputStreamManager(node_id, input_streams, output_stream_id_list, max_queue_size, callback) {} - - std::string DefaultInputManager::type() { - return "Default"; - } - - NodeReadiness DefaultInputManager::get_node_readiness(int64_t &min_timestamp) { - int64_t min_bound = DONE; - min_timestamp = DONE; - for (auto &input_stream:input_streams_) { - int64_t min_stream_timestamp; - if (input_stream.second->get_min_timestamp(min_stream_timestamp)) - min_bound = std::min(min_bound, min_stream_timestamp); - min_timestamp = std::min(min_timestamp, min_stream_timestamp); +bool ImmediateInputStreamManager::fill_task_input(Task &task) { + bool task_filled = false; + for (auto &input_stream : input_streams_) { + if (input_stream.second->is_empty()) { + // task.fill_input_packet(iter->second->get_id(), + // Packet()); + continue; } - if (min_timestamp == DONE) - return NodeReadiness::READY_FOR_CLOSE; - if (min_bound > min_timestamp) - return NodeReadiness::READY_FOR_PROCESS; - return NodeReadiness::NOT_READY; - } - bool DefaultInputManager::fill_task_input(Task &task) { - for (auto &input_stream:input_streams_) { - auto pkt = input_stream.second->pop_packet_at_timestamp(task.timestamp()); - if (pkt.timestamp() == UNSET) { - continue; + while (not input_stream.second->is_empty()) { + Packet pkt = input_stream.second->pop_next_packet(false); + if (pkt.timestamp() == BMF_EOF) { + if (input_stream.second->probed_) { + BMFLOG(BMF_INFO) + << "immediate sync got EOF from dynamical update"; + pkt.set_timestamp(DYN_EOS); + input_stream.second->probed_ = false; + } else + stream_done_[input_stream.first] = 1; } - if (not task.fill_input_packet(input_stream.second->get_id(), pkt)) - return false; + task.fill_input_packet(input_stream.second->get_id(), pkt); + task_filled = true; } - return true; } - ServerInputStreamManager::ServerInputStreamManager(int node_id, std::vector &input_streams, - std::vector &output_stream_id_list, uint32_t max_queue_size, - InputStreamManagerCallBack &callback) : InputStreamManager( - node_id, input_streams, output_stream_id_list, max_queue_size, callback) { - next_timestamp_ = 1; - for (auto &stream_key:input_streams_) - stream_eof_[stream_key.second] = 0; + if (stream_done_.size() == input_streams_.size()) { + task.set_timestamp(BMF_EOF); } + return task_filled; +} - std::string ServerInputStreamManager::type() { - return "Server"; - } +DefaultInputManager::DefaultInputManager( + int node_id, std::vector &input_streams, + std::vector &output_stream_id_list, uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : InputStreamManager(node_id, input_streams, output_stream_id_list, + max_queue_size, callback) {} - int64_t ServerInputStreamManager::get_next_time_stamp() { - std::lock_guard _(mtx_); - next_timestamp_++; - return next_timestamp_; - } +std::string DefaultInputManager::type() { return "Default"; } - NodeReadiness ServerInputStreamManager::get_node_readiness(int64_t &next_timestamp) { - for (auto input_stream:input_streams_) { - if (!input_stream.second->is_empty()) { - next_timestamp = get_next_time_stamp(); - return NodeReadiness::READY_FOR_PROCESS; - } - } - return NodeReadiness::NOT_READY; +NodeReadiness DefaultInputManager::get_node_readiness(int64_t &min_timestamp) { + int64_t min_bound = DONE; + min_timestamp = DONE; + for (auto &input_stream : input_streams_) { + int64_t min_stream_timestamp; + if (input_stream.second->get_min_timestamp(min_stream_timestamp)) + min_bound = std::min(min_bound, min_stream_timestamp); + min_timestamp = std::min(min_timestamp, min_stream_timestamp); } - - int ServerInputStreamManager::get_positive_stream_eof_number() { - int cnt = 0; - for (auto input_stream:stream_eof_) - if (input_stream.second > 0) - cnt++; - return cnt; - } - - void ServerInputStreamManager::update_stream_eof() { - for (auto &input_stream:stream_eof_) - input_stream.second--; + if (min_timestamp == DONE) + return NodeReadiness::READY_FOR_CLOSE; + if (min_bound > min_timestamp) + return NodeReadiness::READY_FOR_PROCESS; + return NodeReadiness::NOT_READY; +} + +bool DefaultInputManager::fill_task_input(Task &task) { + for (auto &input_stream : input_streams_) { + auto pkt = + input_stream.second->pop_packet_at_timestamp(task.timestamp()); + if (pkt.timestamp() == UNSET) { + continue; + } + if (not task.fill_input_packet(input_stream.second->get_id(), pkt)) + return false; + } + return true; +} + +ServerInputStreamManager::ServerInputStreamManager( + int node_id, std::vector &input_streams, + std::vector &output_stream_id_list, uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : InputStreamManager(node_id, input_streams, output_stream_id_list, + max_queue_size, callback) { + next_timestamp_ = 1; + for (auto &stream_key : input_streams_) + stream_eof_[stream_key.second] = 0; +} + +std::string ServerInputStreamManager::type() { return "Server"; } + +int64_t ServerInputStreamManager::get_next_time_stamp() { + std::lock_guard _(mtx_); + next_timestamp_++; + return next_timestamp_; +} + +NodeReadiness +ServerInputStreamManager::get_node_readiness(int64_t &next_timestamp) { + for (auto input_stream : input_streams_) { + if (!input_stream.second->is_empty()) { + next_timestamp = get_next_time_stamp(); + return NodeReadiness::READY_FOR_PROCESS; + } } - - bool ServerInputStreamManager::fill_task_input(Task &task) { - for (auto input_stream:input_streams_) { - if (input_stream.second->get_block()) - continue; - if (input_stream.second->is_empty()) - continue; - while (!input_stream.second->is_empty()) { - auto pkt = input_stream.second->pop_next_packet(false); - if (pkt.timestamp() == BMF_EOF) { - input_stream.second->set_block(true); - stream_eof_[input_stream.second]++; - task.fill_input_packet(input_stream.second->get_id(), pkt); - break; - } else if (pkt.timestamp() == EOS) { - stream_done_[input_stream.first] = 1; - break; - } + return NodeReadiness::NOT_READY; +} + +int ServerInputStreamManager::get_positive_stream_eof_number() { + int cnt = 0; + for (auto input_stream : stream_eof_) + if (input_stream.second > 0) + cnt++; + return cnt; +} + +void ServerInputStreamManager::update_stream_eof() { + for (auto &input_stream : stream_eof_) + input_stream.second--; +} + +bool ServerInputStreamManager::fill_task_input(Task &task) { + for (auto input_stream : input_streams_) { + if (input_stream.second->get_block()) + continue; + if (input_stream.second->is_empty()) + continue; + while (!input_stream.second->is_empty()) { + auto pkt = input_stream.second->pop_next_packet(false); + if (pkt.timestamp() == BMF_EOF) { + input_stream.second->set_block(true); + stream_eof_[input_stream.second]++; task.fill_input_packet(input_stream.second->get_id(), pkt); + break; + } else if (pkt.timestamp() == EOS) { + stream_done_[input_stream.first] = 1; + break; } + task.fill_input_packet(input_stream.second->get_id(), pkt); } - if (get_positive_stream_eof_number() == input_streams_.size()) { - update_stream_eof(); - task.set_timestamp(BMF_EOF); - } - if (stream_done_.size() == input_streams_.size()) - task.set_timestamp(EOS); - return true; - } - - FrameSyncInputStreamManager::FrameSyncInputStreamManager(int node_id, std::vector &input_streams, - std::vector &output_stream_id_list, - uint32_t max_queue_size, - InputStreamManagerCallBack &callback) - : InputStreamManager(node_id, input_streams, output_stream_id_list, max_queue_size, callback) { - frames_ready_ = false; - sync_level_ = input_streams_.begin()->first; - next_timestamp_ = 1; } + if (get_positive_stream_eof_number() == input_streams_.size()) { + update_stream_eof(); + task.set_timestamp(BMF_EOF); + } + if (stream_done_.size() == input_streams_.size()) + task.set_timestamp(EOS); + return true; +} + +FrameSyncInputStreamManager::FrameSyncInputStreamManager( + int node_id, std::vector &input_streams, + std::vector &output_stream_id_list, uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : InputStreamManager(node_id, input_streams, output_stream_id_list, + max_queue_size, callback) { + frames_ready_ = false; + sync_level_ = input_streams_.begin()->first; + next_timestamp_ = 1; +} + +std::string FrameSyncInputStreamManager::type() { return "FrameSync"; } + +NodeReadiness +FrameSyncInputStreamManager::get_node_readiness(int64_t &min_timestamp) { + std::lock_guard _(mtx_); + + while (!frames_ready_ && stream_done_.size() != input_streams_.size()) { + int nb_miss = 0; + for (auto input_stream : input_streams_) { + if (have_next_.count(input_stream.first) <= 0) { + have_next_[input_stream.first] = false; + sync_frm_state_[input_stream.first] = UNSET; + pkt_ready_[input_stream.first] = + std::make_shared>(); + } + if (have_next_[input_stream.first] || + sync_frm_state_[input_stream.first] == BMF_EOF) + continue; - std::string FrameSyncInputStreamManager::type() { - return "FrameSync"; - } - - NodeReadiness FrameSyncInputStreamManager::get_node_readiness(int64_t &min_timestamp) { - std::lock_guard _(mtx_); - - while (!frames_ready_ && stream_done_.size() != input_streams_.size()) { - int nb_miss = 0; - for (auto input_stream:input_streams_) { - if (have_next_.count(input_stream.first) <= 0) { - have_next_[input_stream.first] = false; - sync_frm_state_[input_stream.first] = UNSET; - pkt_ready_[input_stream.first] = std::make_shared>(); - } - if (have_next_[input_stream.first] || sync_frm_state_[input_stream.first] == BMF_EOF) - continue; + if (input_stream.second->is_empty()) { + if (sync_frm_state_[input_stream.first] != BMF_PAUSE) + nb_miss++; - if (input_stream.second->is_empty()) { - if (sync_frm_state_[input_stream.first] != BMF_PAUSE) - nb_miss++; + continue; + } else { + auto pkt = input_stream.second->pop_next_packet(false); - continue; - } else { - auto pkt = input_stream.second->pop_next_packet(false); - - if (pkt.timestamp() == BMF_EOF || pkt.timestamp() == DYN_EOS) { - sync_frm_state_[input_stream.first] = BMF_EOF; - if (sync_level_ == input_stream.first) { - auto pos = input_streams_.find(input_stream.first); - while (true) { - pos++; - if (pos == input_streams_.end()) - break; - - if (sync_frm_state_[pos->first] == BMF_EOF) - continue; - else { - sync_level_ = pos->first; - break; - } + if (pkt.timestamp() == BMF_EOF || pkt.timestamp() == DYN_EOS) { + sync_frm_state_[input_stream.first] = BMF_EOF; + if (sync_level_ == input_stream.first) { + auto pos = input_streams_.find(input_stream.first); + while (true) { + pos++; + if (pos == input_streams_.end()) + break; + + if (sync_frm_state_[pos->first] == BMF_EOF) + continue; + else { + sync_level_ = pos->first; + break; } } - } else if (pkt.timestamp() == BMF_PAUSE) { - sync_frm_state_[input_stream.first] = BMF_PAUSE; - continue; - } else if (sync_frm_state_[input_stream.first] == BMF_PAUSE) - sync_frm_state_[input_stream.first] = UNSET; - - next_pkt_[input_stream.first] = pkt; - timestamp_next_[input_stream.first] = pkt.timestamp(); - have_next_[input_stream.first] = true; - } - } - - if (nb_miss) - return NodeReadiness::NOT_READY; + } + } else if (pkt.timestamp() == BMF_PAUSE) { + sync_frm_state_[input_stream.first] = BMF_PAUSE; + continue; + } else if (sync_frm_state_[input_stream.first] == BMF_PAUSE) + sync_frm_state_[input_stream.first] = UNSET; - int64_t timestamp = INT64_MAX; - for (auto &input_stream:input_streams_) { - if (have_next_[input_stream.first] && timestamp_next_[input_stream.first] < timestamp) - timestamp = timestamp_next_[input_stream.first]; + next_pkt_[input_stream.first] = pkt; + timestamp_next_[input_stream.first] = pkt.timestamp(); + have_next_[input_stream.first] = true; } + } - for (auto &input_stream:input_streams_) { - if (have_next_[input_stream.first] && timestamp == timestamp_next_[input_stream.first]) { - curr_pkt_[input_stream.first] = next_pkt_[input_stream.first]; - timestamp_[input_stream.first] = timestamp_next_[input_stream.first]; - timestamp_next_[input_stream.first] = INT64_MAX; - have_next_[input_stream.first] = false; + if (nb_miss) + return NodeReadiness::NOT_READY; - if (input_stream.first == sync_level_) { - frames_ready_ = true; - } - } - } + int64_t timestamp = INT64_MAX; + for (auto &input_stream : input_streams_) { + if (have_next_[input_stream.first] && + timestamp_next_[input_stream.first] < timestamp) + timestamp = timestamp_next_[input_stream.first]; } - if (frames_ready_) { - for (auto &input_stream:input_streams_) { - if (sync_frm_state_[input_stream.first] != BMF_PAUSE) { - curr_pkt_[input_stream.first].set_timestamp(timestamp_[sync_level_]); - pkt_ready_[input_stream.first]->push(curr_pkt_[input_stream.first]); + for (auto &input_stream : input_streams_) { + if (have_next_[input_stream.first] && + timestamp == timestamp_next_[input_stream.first]) { + curr_pkt_[input_stream.first] = next_pkt_[input_stream.first]; + timestamp_[input_stream.first] = + timestamp_next_[input_stream.first]; + timestamp_next_[input_stream.first] = INT64_MAX; + have_next_[input_stream.first] = false; + + if (input_stream.first == sync_level_) { + frames_ready_ = true; } } - frames_ready_ = false; - next_timestamp_++; - min_timestamp = next_timestamp_; - return NodeReadiness::READY_FOR_PROCESS; - } else - return NodeReadiness::NOT_READY; + } } - bool FrameSyncInputStreamManager::fill_task_input(Task &task) { - std::lock_guard _(mtx_); + if (frames_ready_) { + for (auto &input_stream : input_streams_) { + if (sync_frm_state_[input_stream.first] != BMF_PAUSE) { + curr_pkt_[input_stream.first].set_timestamp( + timestamp_[sync_level_]); + pkt_ready_[input_stream.first]->push( + curr_pkt_[input_stream.first]); + } + } + frames_ready_ = false; + next_timestamp_++; + min_timestamp = next_timestamp_; + return NodeReadiness::READY_FOR_PROCESS; + } else + return NodeReadiness::NOT_READY; +} - for (auto iter = input_streams_.begin(); iter != input_streams_.end(); iter++) { - if (stream_done_.find(iter->first) != stream_done_.end()) - continue; +bool FrameSyncInputStreamManager::fill_task_input(Task &task) { + std::lock_guard _(mtx_); - Packet pkt; - if (pkt_ready_[iter->second->get_id()]->pop(pkt) == true) { - if (pkt.timestamp() == BMF_EOF) { - if (iter->second->probed_) { - pkt.set_timestamp(DYN_EOS); - iter->second->probed_ = false; - } else - stream_done_[iter->first] = 1; - } + for (auto iter = input_streams_.begin(); iter != input_streams_.end(); + iter++) { + if (stream_done_.find(iter->first) != stream_done_.end()) + continue; - task.fill_input_packet(iter->second->get_id(), pkt); + Packet pkt; + if (pkt_ready_[iter->second->get_id()]->pop(pkt) == true) { + if (pkt.timestamp() == BMF_EOF) { + if (iter->second->probed_) { + pkt.set_timestamp(DYN_EOS); + iter->second->probed_ = false; + } else + stream_done_[iter->first] = 1; } + + task.fill_input_packet(iter->second->get_id(), pkt); } - if (stream_done_.size() == input_streams_.size()) { - task.set_timestamp(BMF_EOF); - } - return true; } - - ClockBasedSyncInputStreamManager::ClockBasedSyncInputStreamManager(int node_id, - std::vector &input_streams, - std::vector &output_stream_id_list, - uint32_t max_queue_size, - InputStreamManagerCallBack &callback) - : InputStreamManager(node_id, input_streams, output_stream_id_list, max_queue_size, callback) { - zeropoint_offset_ = -1; - first_frame_offset_ = -1; - // Ignore the clock stream (aka. stream[0]). - for (auto input_stream:input_streams_) { - //skip the 0 stream which is clock by default - if (input_stream.first == 0) - continue; - cache_[input_stream.first] = std::queue(); - last_pkt_[input_stream.first] = Packet(0); - last_pkt_[input_stream.first].set_timestamp(UNSET); + if (stream_done_.size() == input_streams_.size()) { + task.set_timestamp(BMF_EOF); + } + return true; +} + +ClockBasedSyncInputStreamManager::ClockBasedSyncInputStreamManager( + int node_id, std::vector &input_streams, + std::vector &output_stream_id_list, uint32_t max_queue_size, + InputStreamManagerCallBack &callback) + : InputStreamManager(node_id, input_streams, output_stream_id_list, + max_queue_size, callback) { + zeropoint_offset_ = -1; + first_frame_offset_ = -1; + // Ignore the clock stream (aka. stream[0]). + for (auto input_stream : input_streams_) { + // skip the 0 stream which is clock by default + if (input_stream.first == 0) + continue; + cache_[input_stream.first] = std::queue(); + last_pkt_[input_stream.first] = Packet(0); + last_pkt_[input_stream.first].set_timestamp(UNSET); + } + next_timestamp_ = 1; +} + +std::string ClockBasedSyncInputStreamManager::type() { + return "ClockBasedSync"; +} + +NodeReadiness +ClockBasedSyncInputStreamManager::get_node_readiness(int64_t &min_timestamp) { + std::lock_guard _(mtx_); + + for (auto input_stream : input_streams_) { + if (input_stream.first == 0) + continue; + if (stream_done_.count(input_stream.first) > 0) + continue; + while (!input_stream.second->is_empty()) { + auto pkt = input_stream.second->pop_next_packet(false); + // if engine probe it, timestamp should be set to DYN_EOS even it's + // EOF to avoid downstream EOF + if (pkt.timestamp() == BMF_EOF && + input_streams_[input_stream.first]->probed_) { + BMFLOG(BMF_INFO) << "sync got EOF from dynamical update"; + pkt.set_timestamp(DYN_EOS); + input_streams_[input_stream.first]->probed_ = false; + + // pop all the old data to pass the DYN_EOS at the shortest time + // before the stream was removed + while (!cache_[input_stream.first].empty()) + cache_[input_stream.first].pop(); + cache_[input_stream.first].push(pkt); + } else + cache_[input_stream.first].push(pkt); } - next_timestamp_ = 1; } - - std::string ClockBasedSyncInputStreamManager::type() { - return "ClockBasedSync"; + // Wait a frame gap to get more available frames. + if (input_streams_[0]->queue_->size() < 2) { + return NodeReadiness::NOT_READY; } - NodeReadiness ClockBasedSyncInputStreamManager::get_node_readiness(int64_t &min_timestamp) { - std::lock_guard _(mtx_); + next_timestamp_++; + min_timestamp = next_timestamp_; + return NodeReadiness::READY_FOR_PROCESS; +} - for (auto input_stream:input_streams_) { - if (input_stream.first == 0) - continue; - if (stream_done_.count(input_stream.first) > 0) - continue; - while (!input_stream.second->is_empty()) { - auto pkt = input_stream.second->pop_next_packet(false); - //if engine probe it, timestamp should be set to DYN_EOS even it's EOF to avoid downstream EOF - if (pkt.timestamp() == BMF_EOF && input_streams_[input_stream.first]->probed_) { - BMFLOG(BMF_INFO) << "sync got EOF from dynamical update"; - pkt.set_timestamp(DYN_EOS); - input_streams_[input_stream.first]->probed_ = false; +bool ClockBasedSyncInputStreamManager::fill_task_input(Task &task) { + std::lock_guard _(mtx_); - //pop all the old data to pass the DYN_EOS at the shortest time before the stream was removed - while (!cache_[input_stream.first].empty()) - cache_[input_stream.first].pop(); - cache_[input_stream.first].push(pkt); - } else - cache_[input_stream.first].push(pkt); + auto ts = input_streams_[0]->pop_next_packet(false).timestamp(); + if (zeropoint_offset_ < 0) { + for (auto &s : cache_) + if (!s.second.empty()) { + auto tmp = s.second.front().timestamp(); + if (tmp == BMF_EOF || tmp == BMF_PAUSE) + continue; + first_frame_offset_ = tmp; + break; } - } - // Wait a frame gap to get more available frames. - if (input_streams_[0]->queue_->size() < 2) { - return NodeReadiness::NOT_READY; - } - - next_timestamp_++; - min_timestamp = next_timestamp_; - return NodeReadiness::READY_FOR_PROCESS; + if (first_frame_offset_ >= 0) + zeropoint_offset_ = ts; } + int64_t target_pts = (ts - zeropoint_offset_) + first_frame_offset_; - bool ClockBasedSyncInputStreamManager::fill_task_input(Task &task) { - std::lock_guard _(mtx_); - - auto ts = input_streams_[0]->pop_next_packet(false).timestamp(); - if (zeropoint_offset_ < 0) { - for (auto &s:cache_) - if (!s.second.empty()) { - auto tmp = s.second.front().timestamp(); - if (tmp == BMF_EOF || tmp == BMF_PAUSE) - continue; - first_frame_offset_ = tmp; - break; - } - if (first_frame_offset_ >= 0) - zeropoint_offset_ = ts; + for (auto &s : cache_) { + // If EOF met, ignore all packets after that. + if (stream_done_.count(s.first)) { + while (!s.second.empty()) + s.second.pop(); + continue; } - int64_t target_pts = (ts - zeropoint_offset_) + first_frame_offset_; - - for (auto &s:cache_) { - // If EOF met, ignore all packets after that. - if (stream_done_.count(s.first)) { - while (!s.second.empty()) - s.second.pop(); - continue; - } - // Pick the packet closest to the target pts. - int64_t offset = LLONG_MAX; - int64_t cal_offset; - while (!s.second.empty()) { - auto cur_ts = s.second.front().timestamp(); - // When EOF met, shut down stream immediately. - if (cur_ts == BMF_EOF) { - last_pkt_[s.first] = s.second.front(); - s.second.pop(); - break; - } - // PAUSE have higher priority and should be treated at once. - if (cur_ts != BMF_PAUSE) { - cal_offset = std::abs(cur_ts - target_pts); - if (cal_offset > offset) - break; - offset = cal_offset; - } + // Pick the packet closest to the target pts. + int64_t offset = LLONG_MAX; + int64_t cal_offset; + while (!s.second.empty()) { + auto cur_ts = s.second.front().timestamp(); + // When EOF met, shut down stream immediately. + if (cur_ts == BMF_EOF) { last_pkt_[s.first] = s.second.front(); s.second.pop(); + break; } - } - - for (auto &s:last_pkt_) { - if (stream_done_.count(s.first)) - continue; - - auto pkt = s.second; - // Ignore empty stream or just resumed stream. - if (pkt.timestamp() == UNSET) - continue; - - if (pkt.timestamp() == BMF_EOF) {// || pkt.get_timestamp() == DYN_EOS) { - stream_done_[s.first] = 1; - } else if (pkt.timestamp() == BMF_PAUSE) { - // Pass PAUSE only once. - if (stream_paused_.count(s.first)) - continue; - stream_paused_.insert(s.first); - } else { - if (stream_paused_.count(s.first)) - stream_paused_.erase(s.first); - if (ts != BMF_EOF) - pkt.set_timestamp(target_pts); + // PAUSE have higher priority and should be treated at once. + if (cur_ts != BMF_PAUSE) { + cal_offset = std::abs(cur_ts - target_pts); + if (cal_offset > offset) + break; + offset = cal_offset; } - task.fill_input_packet(s.first, pkt); - } - if (ts == BMF_EOF || stream_done_.size() == input_streams_.size()) { - task.set_timestamp(BMF_EOF); + last_pkt_[s.first] = s.second.front(); + s.second.pop(); } + } - // Clock stream index is 0 by hard code now. Erase it in task directly. - task.get_inputs().erase(0); + for (auto &s : last_pkt_) { + if (stream_done_.count(s.first)) + continue; - return true; - } + auto pkt = s.second; + // Ignore empty stream or just resumed stream. + if (pkt.timestamp() == UNSET) + continue; - int create_input_stream_manager( - std::string const &manager_type, int node_id, std::vector input_streams, - std::vector output_stream_id_list, InputStreamManagerCallBack callback, - uint32_t queue_size_limit, std::shared_ptr &input_stream_manager) { - if (manager_type == "immediate") { - input_stream_manager = std::make_shared - (node_id, input_streams, output_stream_id_list, queue_size_limit, callback); - } else if (manager_type == "default") { - input_stream_manager = std::make_shared(node_id, input_streams, output_stream_id_list, - queue_size_limit, callback); - } else if (manager_type == "server") { - input_stream_manager = std::make_shared(node_id, input_streams, - output_stream_id_list, queue_size_limit, - callback); - } else if (manager_type == "framesync") { - input_stream_manager = std::make_shared(node_id, input_streams, - output_stream_id_list, - queue_size_limit, callback); - } else if (manager_type == "clocksync") { - input_stream_manager = std::make_shared(node_id, input_streams, - output_stream_id_list, - queue_size_limit, callback); + if (pkt.timestamp() == + BMF_EOF) { // || pkt.get_timestamp() == DYN_EOS) { + stream_done_[s.first] = 1; + } else if (pkt.timestamp() == BMF_PAUSE) { + // Pass PAUSE only once. + if (stream_paused_.count(s.first)) + continue; + stream_paused_.insert(s.first); } else { - BMFLOG(BMF_WARNING) - << "Unknown input_manager for node[" << node_id << "], will use 'default' to initialize."; - input_stream_manager = std::make_shared(node_id, input_streams, output_stream_id_list, - queue_size_limit, callback); + if (stream_paused_.count(s.first)) + stream_paused_.erase(s.first); + if (ts != BMF_EOF) + pkt.set_timestamp(target_pts); } - return 0; - } + task.fill_input_packet(s.first, pkt); + } + if (ts == BMF_EOF || stream_done_.size() == input_streams_.size()) { + task.set_timestamp(BMF_EOF); + } + + // Clock stream index is 0 by hard code now. Erase it in task directly. + task.get_inputs().erase(0); + + return true; +} + +int create_input_stream_manager( + std::string const &manager_type, int node_id, + std::vector input_streams, + std::vector output_stream_id_list, InputStreamManagerCallBack callback, + uint32_t queue_size_limit, + std::shared_ptr &input_stream_manager) { + if (manager_type == "immediate") { + input_stream_manager = std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } else if (manager_type == "default") { + input_stream_manager = std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } else if (manager_type == "server") { + input_stream_manager = std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } else if (manager_type == "framesync") { + input_stream_manager = std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } else if (manager_type == "clocksync") { + input_stream_manager = + std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } else { + BMFLOG(BMF_WARNING) << "Unknown input_manager for node[" << node_id + << "], will use 'default' to initialize."; + input_stream_manager = std::make_shared( + node_id, input_streams, output_stream_id_list, queue_size_limit, + callback); + } + return 0; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/loader/go_module_loader.cpp b/bmf/engine/c_engine/src/loader/go_module_loader.cpp index f21b9f1d..6a355482 100644 --- a/bmf/engine/c_engine/src/loader/go_module_loader.cpp +++ b/bmf/engine/c_engine/src/loader/go_module_loader.cpp @@ -5,61 +5,58 @@ #include #include -namespace bmf_sdk{ +namespace bmf_sdk { namespace { /** - * @brief Go Module Proxy - * + * @brief Go Module Proxy + * */ -class GoModule : public Module -{ +class GoModule : public Module { int id_; std::shared_ptr lib_; - char*(*process_func_)(int32_t, Task*); - char*(*init_func_)(int32_t); - char*(*close_func_)(int32_t); - char*(*reset_func_)(int32_t); - char*(*module_info_func_)(int32_t); + char *(*process_func_)(int32_t, Task *); + char *(*init_func_)(int32_t); + char *(*close_func_)(int32_t); + char *(*reset_func_)(int32_t); + char *(*module_info_func_)(int32_t); bool (*hungry_check_func_)(int32_t, int32_t); bool (*is_hungry_func_)(int32_t, int32_t); bool (*is_infinity_func_)(int32_t); - template - void check_result(F &f, Args&&...args) - { + template + void check_result(F &f, Args &&... args) { auto cstr = f(std::forward(args)...); - if(cstr != nullptr){ + if (cstr != nullptr) { auto str = std::string(cstr); free(cstr); throw std::runtime_error(str); } } -public: + public: GoModule(int id, const std::shared_ptr &lib) - : id_(id), lib_(lib) - { + : id_(id), lib_(lib) { process_func_ = lib->symbol("ModuleProcess"); init_func_ = lib->symbol("ModuleInit"); reset_func_ = lib->symbol("ModuleReset"); close_func_ = lib->symbol("ModuleClose"); - module_info_func_ = lib->symbol("ModuleGetInfo"); - hungry_check_func_ = lib->symbol("ModuleNeedHungryCheck"); - is_hungry_func_ = lib->symbol("ModuleIsHungry"); - is_infinity_func_ = lib->symbol("ModuleIsInfinity"); + module_info_func_ = + lib->symbol("ModuleGetInfo"); + hungry_check_func_ = + lib->symbol("ModuleNeedHungryCheck"); + is_hungry_func_ = + lib->symbol("ModuleIsHungry"); + is_infinity_func_ = + lib->symbol("ModuleIsInfinity"); } - ~GoModule() - { - close(); - } + ~GoModule() { close(); } - int get_module_info(JsonParam &module_info) override - { + int get_module_info(JsonParam &module_info) override { auto info = module_info_func_(id_); - if(info != nullptr){ + if (info != nullptr) { auto sinfo = std::string(info); free(info); @@ -69,118 +66,102 @@ class GoModule : public Module return 0; } - int process(Task &task) override - { + int process(Task &task) override { check_result(process_func_, id_, &task); return 0; } - int32_t init() override - { + int32_t init() override { check_result(init_func_, id_); return 0; } - int32_t reset() override - { + int32_t reset() override { check_result(reset_func_, id_); return 0; } - int32_t close() override - { - if(lib_){ + int32_t close() override { + if (lib_) { check_result(close_func_, id_); } return 0; } - bool need_hungry_check(int input_stream_id) override - { + bool need_hungry_check(int input_stream_id) override { return hungry_check_func_(id_, input_stream_id); } - bool is_hungry(int input_stream_id) override - { + bool is_hungry(int input_stream_id) override { return is_hungry_func_(id_, input_stream_id); } - bool is_infinity() override - { - return is_infinity_func_(id_); - } + bool is_infinity() override { return is_infinity_func_(id_); } }; - -class GoModuleFactory : public ModuleFactoryI -{ +class GoModuleFactory : public ModuleFactoryI { std::shared_ptr lib_; std::string cls_; std::string sdk_version_; -public: - GoModuleFactory(const std::string &path, const std::string &cls) - { + + public: + GoModuleFactory(const std::string &path, const std::string &cls) { lib_ = std::make_shared(path); - lib_->symbol("ConstructorRegister")(); + lib_->symbol("ConstructorRegister")(); cls_ = cls; - auto cstr = lib_->symbol("BmfSdkVersion")(); + auto cstr = lib_->symbol("BmfSdkVersion")(); sdk_version_ = std::string(cstr); - lib_->symbol("FreeCString")(cstr); - } - - const std::string &sdk_version() const override - { - return sdk_version_; + lib_->symbol("FreeCString")(cstr); } + const std::string &sdk_version() const override { return sdk_version_; } - std::shared_ptr make(int32_t node_id, const JsonParam &json_param) override - { + std::shared_ptr make(int32_t node_id, + const JsonParam &json_param) override { auto option = json_param.dump(); - auto construct_func = lib_->symbol("ModuleConstruct"); + auto construct_func = + lib_->symbol( + "ModuleConstruct"); auto id = construct_func(cls_.c_str(), node_id, option.c_str()); - if(id == -1){ + if (id == -1) { throw std::runtime_error("Consturct module " + cls_ + " failed"); - } - else if(id == -2){ + } else if (id == -2) { throw std::runtime_error("Module " + cls_ + " not found"); - } - else if(id < 0){ - throw std::runtime_error("Unknown error when construct module " + cls_); + } else if (id < 0) { + throw std::runtime_error("Unknown error when construct module " + + cls_); } return std::make_shared(id, lib_); } - const bool module_info(ModuleInfo &info) const override - { - int32_t(* module_info_func)(const char*, ModuleInfo*); + const bool module_info(ModuleInfo &info) const override { + int32_t (*module_info_func)(const char *, ModuleInfo *); try { - module_info_func = lib_->symbol("GetModuleInfoRegister"); + module_info_func = lib_->symbol( + "GetModuleInfoRegister"); } catch (const std::exception &e) { return false; } return module_info_func(cls_.c_str(), &info); } }; // +} +} // bmf_sdk - -}} // bmf_sdk - - -//TODO: make it as a plugin -extern "C" bmf_sdk::ModuleFactoryI* bmf_import_go_module( - const char *module_path, const char *module, char **errstr) -{ - try{ +// TODO: make it as a plugin +extern "C" bmf_sdk::ModuleFactoryI * +bmf_import_go_module(const char *module_path, const char *module, + char **errstr) { + try { return new bmf_sdk::GoModuleFactory(module_path, module); - } - catch(std::exception &e){ - if(errstr){ + } catch (std::exception &e) { + if (errstr) { *errstr = strdup(e.what()); } - BMFLOG(BMF_ERROR) << "Load go module " << module << " failed, " << e.what(); + BMFLOG(BMF_ERROR) << "Load go module " << module << " failed, " + << e.what(); return nullptr; } } diff --git a/bmf/engine/c_engine/src/loader/py_module_loader.cpp b/bmf/engine/c_engine/src/loader/py_module_loader.cpp index 3a03de55..66ce6df9 100644 --- a/bmf/engine/c_engine/src/loader/py_module_loader.cpp +++ b/bmf/engine/c_engine/src/loader/py_module_loader.cpp @@ -7,280 +7,234 @@ #include #include - namespace py = pybind11; namespace fs = std::filesystem; - -namespace bmf_sdk{ +namespace bmf_sdk { /** - * @brief Python Module Proxy - * + * @brief Python Module Proxy + * */ -#pragma GCC visibility push(hidden) //remove visibility warning -class PyModule : public Module -{ - py::object self; // python module implementation -public: - template - py::object call_func(const char *name, Args&&...args) - { - if(!py::hasattr(self, name)){ - throw std::runtime_error(fmt::format("{} is not implemented", name)); +#pragma GCC visibility push(hidden) // remove visibility warning +class PyModule : public Module { + py::object self; // python module implementation + public: + template + py::object call_func(const char *name, Args &&... args) { + if (!py::hasattr(self, name)) { + throw std::runtime_error( + fmt::format("{} is not implemented", name)); } return self.attr(name)(std::forward(args)...); } - template - Ret guard_call(const Func &f, Ret ok = 0, Ret nok = -1) - { + template + Ret guard_call(const Func &f, Ret ok = 0, Ret nok = -1) { py::gil_scoped_acquire gil; - try{ + try { f(); return ok; - } - catch(std::exception &e){ + } catch (std::exception &e) { BMFLOG(BMF_WARNING) << e.what(); return nok; } } - PyModule(const py::object &cls, int32_t node_id = -1, JsonParam json_param = {}) - { + PyModule(const py::object &cls, int32_t node_id = -1, + JsonParam json_param = {}) { py::gil_scoped_acquire gil; self = cls(node_id, json_param); } - ~PyModule() - { + ~PyModule() { py::gil_scoped_acquire gil; self = py::object(); } - int32_t get_input_stream_info(JsonParam &json_param) override - { - return guard_call([&](){ - json_param = py::cast(call_func("get_input_stream_info")); + int32_t get_input_stream_info(JsonParam &json_param) override { + return guard_call([&]() { + json_param = + py::cast(call_func("get_input_stream_info")); }); } - int32_t set_input_stream_info(JsonParam &json_param) override - { - return guard_call([&](){ - call_func("get_input_stream_info", json_param); - }); + int32_t set_input_stream_info(JsonParam &json_param) override { + return guard_call( + [&]() { call_func("get_input_stream_info", json_param); }); } - - int32_t get_output_stream_info(JsonParam &json_param) override - { - return guard_call([&](){ - json_param = py::cast(call_func("get_output_stream_info")); + int32_t get_output_stream_info(JsonParam &json_param) override { + return guard_call([&]() { + json_param = + py::cast(call_func("get_output_stream_info")); }); } - int32_t set_output_stream_info(JsonParam &json_param) override - { - return guard_call([&](){ - call_func("get_output_stream_info", json_param); - }); + int32_t set_output_stream_info(JsonParam &json_param) override { + return guard_call( + [&]() { call_func("get_output_stream_info", json_param); }); } - - int32_t get_module_info(JsonParam &json_param) override - { - return guard_call([&](){ + int32_t get_module_info(JsonParam &json_param) override { + return guard_call([&]() { json_param = py::cast(call_func("get_module_info")); }); } - - int32_t init() override - { - return guard_call([&](){ - call_func("init"); - }); + int32_t init() override { + return guard_call([&]() { call_func("init"); }); } - int32_t reset() override - { - return guard_call([&](){ - call_func("reset"); - }); + int32_t reset() override { + return guard_call([&]() { call_func("reset"); }); } - int32_t flush() override - { - return guard_call([&](){ - call_func("flush"); - }); + int32_t flush() override { + return guard_call([&]() { call_func("flush"); }); } - - int32_t dynamic_reset(JsonParam json_param) override - { - return guard_call([&](){ - call_func("dynamic_reset", json_param); - }); + int32_t dynamic_reset(JsonParam json_param) override { + return guard_call( + [&]() { call_func("dynamic_reset", json_param); }); } - - int32_t process(Task &task) override - { + int32_t process(Task &task) override { py::gil_scoped_acquire gil; auto task_obj = py::cast(task); auto ret = call_func("process", task_obj); - task = py::cast(task_obj); //copy changes back - if(ret.is_none()){ + task = py::cast(task_obj); // copy changes back + if (ret.is_none()) { throw std::runtime_error("PyModule.process return None"); - } - else{ + } else { return py::cast(ret); // enable exception throw } } - int32_t close() override - { - return guard_call([&](){ - call_func("close"); - }); + int32_t close() override { + return guard_call([&]() { call_func("close"); }); } - bool need_hungry_check(int input_stream_id) override - { + bool need_hungry_check(int input_stream_id) override { py::gil_scoped_acquire gil; - return py::cast( - call_func("need_hungry_check", input_stream_id)); + return py::cast(call_func("need_hungry_check", input_stream_id)); } - bool is_hungry(int input_stream_id) override - { + bool is_hungry(int input_stream_id) override { py::gil_scoped_acquire gil; - return py::cast( - call_func("is_hungry", input_stream_id)); + return py::cast(call_func("is_hungry", input_stream_id)); } - bool is_infinity() override - { + bool is_infinity() override { py::gil_scoped_acquire gil; - return py::cast( - call_func("is_infinity")); + return py::cast(call_func("is_infinity")); } - //set_callback(...) - void set_callback(std::function callback_endpoint) override - { + // set_callback(...) + void set_callback( + std::function callback_endpoint) override { py::gil_scoped_acquire gil; - auto py_func = py::cpp_function([=](int64_t key, py::bytes &value){ + auto py_func = py::cpp_function([=](int64_t key, py::bytes &value) { auto ret = callback_endpoint(key, py::cast(value)); - return py::cast(ret); //cbytes + return py::cast(ret); // cbytes }); call_func("set_callback", py_func); } - - bool is_subgraph() override - { + bool is_subgraph() override { py::gil_scoped_acquire gil; - return py::cast( - call_func("is_subgraph")); + return py::cast(call_func("is_subgraph")); } - bool get_graph_config(JsonParam &json_param) override - { - return guard_call([&](){ - auto json_str = py::cast(call_func("get_graph_config").attr("dump")()); + bool get_graph_config(JsonParam &json_param) override { + return guard_call([&]() { + auto json_str = py::cast( + call_func("get_graph_config").attr("dump")()); json_param = JsonParam(json_str); }); } }; #pragma GCC visibility pop - -class PyModuleFactory : public ModuleFactoryI -{ -public: +class PyModuleFactory : public ModuleFactoryI { + public: using FactoryFunc = std::function()>; - PyModuleFactory(const FactoryFunc &factory) : factory_(factory) - { + PyModuleFactory(const FactoryFunc &factory) : factory_(factory) { sdk_version_ = BMF_SDK_VERSION; } - std::shared_ptr make(int32_t node_id, const JsonParam &json_param) override - { - auto [module_cls, _] = factory_(); - return std::make_shared(module_cls, node_id, json_param); + std::shared_ptr make(int32_t node_id, + const JsonParam &json_param) override { + auto[module_cls, _] = factory_(); + return std::make_shared(module_cls, node_id, + json_param); } - const bool module_info(ModuleInfo &info) const override - { - auto [_, module_register] = factory_(); + const bool module_info(ModuleInfo &info) const override { + auto[_, module_register] = factory_(); if (module_register.is_none()) - return false; + return false; py::gil_scoped_acquire gil; module_register(&info); return true; } - const std::string &sdk_version() const override - { - return sdk_version_; - } + const std::string &sdk_version() const override { return sdk_version_; } -private: + private: std::string sdk_version_; FactoryFunc factory_; }; // - } // - -//TODO: make it as a plugin -extern "C" bmf_sdk::ModuleFactoryI* bmf_import_py_module( - const char *module_path, const char *module, const char *cls, char **errstr) -{ - if(!Py_IsInitialized()){ - //Py_Initialize(); //don't use it: ref:https://pybind11.readthedocs.io/en/stable/advanced/embedding.html +// TODO: make it as a plugin +extern "C" bmf_sdk::ModuleFactoryI * +bmf_import_py_module(const char *module_path, const char *module, + const char *cls, char **errstr) { + if (!Py_IsInitialized()) { + // Py_Initialize(); //don't use it: + // ref:https://pybind11.readthedocs.io/en/stable/advanced/embedding.html py::initialize_interpreter(); py::gil_scoped_release nogil; - nogil.disarm(); //release gil + nogil.disarm(); // release gil } // try to use top most path as module path, which can fix import ambiguity - // when module have same module.cls + // when module have same module.cls std::string temp_module_path = fs::absolute(module_path); std::string temp_module_name = module; // if module_path last charector is '/' or '.', remove it - while(temp_module_path.size() && (temp_module_path.back() == '/' || temp_module_path.back() == '.')){ + while (temp_module_path.size() && + (temp_module_path.back() == '/' || temp_module_path.back() == '.')) { temp_module_path.pop_back(); } - while(fs::exists(fs::path(temp_module_path)/"__init__.py")){ + while (fs::exists(fs::path(temp_module_path) / "__init__.py")) { auto p = fs::path(temp_module_path); temp_module_name = std::string(p.filename()) + "." + temp_module_name; temp_module_path = p.parent_path(); } // - try{ - //check + try { + // check { py::gil_scoped_acquire gil; - auto sys_path = py::module_::import("sys").attr("path").cast(); + auto sys_path = + py::module_::import("sys").attr("path").cast(); bool has = false; - for(int i = 0; i < sys_path.size(); ++i){ - if(sys_path[i].cast() == temp_module_path){ + for (int i = 0; i < sys_path.size(); ++i) { + if (sys_path[i].cast() == temp_module_path) { has = true; break; } } - if(!has){ + if (!has) { sys_path.append(temp_module_path); } py::module_::import(temp_module_name.c_str()).attr(cls); @@ -295,18 +249,19 @@ extern "C" bmf_sdk::ModuleFactoryI* bmf_import_py_module( auto module_cls = py_module.attr(cls_s.c_str()); py::object module_info_register = py::none(); if (hasattr(py_module, register_info_func.c_str())) { - module_info_register = py_module.attr(register_info_func.c_str()); + module_info_register = + py_module.attr(register_info_func.c_str()); } return std::make_tuple(module_cls, module_info_register); }; return new bmf_sdk::PyModuleFactory(module_factory); - } - catch(std::exception &e){ - if(errstr){ + } catch (std::exception &e) { + if (errstr) { *errstr = strdup(e.what()); } - BMFLOG(BMF_ERROR) << "Load python module " << module << " failed, " << e.what(); + BMFLOG(BMF_ERROR) << "Load python module " << module << " failed, " + << e.what(); return nullptr; } } diff --git a/bmf/engine/c_engine/src/module_factory.cpp b/bmf/engine/c_engine/src/module_factory.cpp index 91c13a39..4d0c224b 100644 --- a/bmf/engine/c_engine/src/module_factory.cpp +++ b/bmf/engine/c_engine/src/module_factory.cpp @@ -26,57 +26,64 @@ #include #include - BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS +USE_BMF_SDK_NS - ModuleInfo ModuleFactory::create_module(std::string module_name, int node_id, JsonParam &option, - std::string module_type, std::string module_path, std::string module_entry, - std::shared_ptr &module) { - auto &M = bmf_sdk::ModuleManager::instance(); +ModuleInfo ModuleFactory::create_module(std::string module_name, int node_id, + JsonParam &option, + std::string module_type, + std::string module_path, + std::string module_entry, + std::shared_ptr &module) { + auto &M = bmf_sdk::ModuleManager::instance(); - ModuleInfo module_info; - auto factory = M.load_module(module_name, module_type, module_path, module_entry, &module_info); - if(factory == nullptr){ - throw std::runtime_error(fmt::format("create module {} failed", module_name)); - } - module = factory->make(node_id, option); - return module_info; + ModuleInfo module_info; + auto factory = M.load_module(module_name, module_type, module_path, + module_entry, &module_info); + if (factory == nullptr) { + throw std::runtime_error( + fmt::format("create module {} failed", module_name)); } + module = factory->make(node_id, option); + return module_info; +} - JsonParam - ModuleFactory::get_subgraph_config(std::shared_ptr module_instance) { - JsonParam graph_config; - module_instance->get_graph_config(graph_config); - return graph_config; - } +JsonParam +ModuleFactory::get_subgraph_config(std::shared_ptr module_instance) { + JsonParam graph_config; + module_instance->get_graph_config(graph_config); + return graph_config; +} - JsonParam - ModuleFactory::create_and_get_subgraph_config(std::string module_info, int node_id, std::string option) { - auto tmp = nlohmann::json::parse(module_info); - auto info = ModuleConfig(tmp); - auto opt = JsonParam(nlohmann::json::parse(option)); - std::shared_ptr module; - create_module(info.module_name, node_id, opt, info.module_type, info.module_path, info.module_entry, module); - // get graph_config of subgraph - JsonParam graph_config; - module->get_graph_config(graph_config); - return graph_config; - } +JsonParam ModuleFactory::create_and_get_subgraph_config(std::string module_info, + int node_id, + std::string option) { + auto tmp = nlohmann::json::parse(module_info); + auto info = ModuleConfig(tmp); + auto opt = JsonParam(nlohmann::json::parse(option)); + std::shared_ptr module; + create_module(info.module_name, node_id, opt, info.module_type, + info.module_path, info.module_entry, module); + // get graph_config of subgraph + JsonParam graph_config; + module->get_graph_config(graph_config); + return graph_config; +} - bool ModuleFactory::test_subgraph(std::shared_ptr module_instance) { - return module_instance->is_subgraph(); - } +bool ModuleFactory::test_subgraph(std::shared_ptr module_instance) { + return module_instance->is_subgraph(); +} - std::pair> - ModuleFactory::create_and_test_subgraph(std::string module_info, int node_id, std::string option) { - auto tmp = nlohmann::json::parse(module_info); - auto info = ModuleConfig(tmp); - auto opt = JsonParam(nlohmann::json::parse(option)); - std::shared_ptr module_instance; - create_module(info.module_name, node_id, opt, info.module_type, info.module_path, info.module_entry, - module_instance); - return {module_instance->is_subgraph(), module_instance}; - } +std::pair> +ModuleFactory::create_and_test_subgraph(std::string module_info, int node_id, + std::string option) { + auto tmp = nlohmann::json::parse(module_info); + auto info = ModuleConfig(tmp); + auto opt = JsonParam(nlohmann::json::parse(option)); + std::shared_ptr module_instance; + create_module(info.module_name, node_id, opt, info.module_type, + info.module_path, info.module_entry, module_instance); + return {module_instance->is_subgraph(), module_instance}; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/node.cpp b/bmf/engine/c_engine/src/node.cpp index b1546d67..0cde8656 100644 --- a/bmf/engine/c_engine/src/node.cpp +++ b/bmf/engine/c_engine/src/node.cpp @@ -27,527 +27,525 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS +USE_BMF_SDK_NS - Node::Node(int node_id, NodeConfig &node_config, NodeCallBack &node_callback, - std::shared_ptr pre_allocated_module, BmfMode mode, - std::shared_ptr callbacks) - : id_(node_id), node_config_(node_config), callback_(node_callback), mode_(mode), - module_callbacks_(callbacks) { - type_ = node_config_.get_module_info().module_name; - module_name_ = type_; - node_name_ = "Node_" + std::to_string(id_) + "_" + module_name_; +Node::Node(int node_id, NodeConfig &node_config, NodeCallBack &node_callback, + std::shared_ptr pre_allocated_module, BmfMode mode, + std::shared_ptr callbacks) + : id_(node_id), node_config_(node_config), callback_(node_callback), + mode_(mode), module_callbacks_(callbacks) { + type_ = node_config_.get_module_info().module_name; + module_name_ = type_; + node_name_ = "Node_" + std::to_string(id_) + "_" + module_name_; #ifndef NO_TRACE - TraceProcessEmitter trace_emitter = TraceProcessEmitter(PROCESSING, node_name_); + TraceProcessEmitter trace_emitter = + TraceProcessEmitter(PROCESSING, node_name_); #endif - is_source_ = node_config.input_streams.empty(); - queue_size_limit_ = node_config_.get_node_meta().get_queue_size_limit(); - // pending task means the task has been added to scheduler queue - // but haven't been executed, for source node, we need use this - // value to control task filling speed - pending_tasks_ = 0; - //max_pending_tasks_ = 5; - max_pending_tasks_ = queue_size_limit_; - printf("debug queue size, node %d, queue size: %d\n", node_id, queue_size_limit_); - task_processed_cnt_ = 0; + is_source_ = node_config.input_streams.empty(); + queue_size_limit_ = node_config_.get_node_meta().get_queue_size_limit(); + // pending task means the task has been added to scheduler queue + // but haven't been executed, for source node, we need use this + // value to control task filling speed + pending_tasks_ = 0; + // max_pending_tasks_ = 5; + max_pending_tasks_ = queue_size_limit_; + printf("debug queue size, node %d, queue size: %d\n", node_id, + queue_size_limit_); + task_processed_cnt_ = 0; + is_premodule_ = false; + + if (pre_allocated_module == nullptr) { is_premodule_ = false; - - if (pre_allocated_module == nullptr) { - is_premodule_ = false; - JsonParam node_option_param = node_config_.get_option(); - module_info_ = ModuleFactory::create_module(type_, id_, node_option_param, node_config_.module.module_type, - node_config_.module.module_path, - node_config_.module.module_entry, module_); - - BMF_TRACE_PROCESS(module_name_.c_str(), "init", START); + JsonParam node_option_param = node_config_.get_option(); + module_info_ = ModuleFactory::create_module( + type_, id_, node_option_param, node_config_.module.module_type, + node_config_.module.module_path, node_config_.module.module_entry, + module_); + + BMF_TRACE_PROCESS(module_name_.c_str(), "init", START); + module_->init(); + BMF_TRACE_PROCESS(module_name_.c_str(), "init", END); + } else { + module_ = pre_allocated_module; + // for real premodule coming from user + if (node_config.get_node_meta().get_premodule_id() > 0) { + is_premodule_ = true; + module_->reset(); + } else module_->init(); - BMF_TRACE_PROCESS(module_name_.c_str(), "init", END); - } else { - module_ = pre_allocated_module; - //for real premodule coming from user - if (node_config.get_node_meta().get_premodule_id() > 0) { - is_premodule_ = true; - module_->reset(); - } - else - module_->init(); - module_->node_id_ = node_id; - } - - module_->set_callback([this](int64_t key, CBytes para) -> CBytes { - return this->module_callbacks_->call(key, para); - }); - - // some special nodes can keep producing outputs even no inputs - // e.g. loop, for this kind of node, it will be closed only if all - // downstream nodes are closed, and the task priority of this node - // should be set to low - infinity_node_ = module_->is_infinity(); - - output_stream_manager_ = std::make_shared(node_config.get_output_streams()); - - InputStreamManagerCallBack callback; - callback.scheduler_cb = callback_.scheduler_cb; - callback.throttled_cb = callback_.throttled_cb; - callback.sched_required = callback_.sched_required; - callback.get_node_cb = callback_.get_node; - callback.notify_cb = [this]() -> bool { - return this->schedule_node(); - }; - callback.node_is_closed_cb = [this]() -> bool { - return this->is_closed(); - }; - - create_input_stream_manager(node_config.get_input_manager(), node_id, node_config.get_input_streams(), - output_stream_manager_->get_stream_id_list(), callback, queue_size_limit_, - input_stream_manager_); - - //register hungry_check - for (auto stream_id : input_stream_manager_->stream_id_list_) { - if (module_->need_hungry_check(stream_id)) { - hungry_check_func_[stream_id].push_back([this, stream_id]() -> bool { + module_->node_id_ = node_id; + } + + module_->set_callback([this](int64_t key, CBytes para) -> CBytes { + return this->module_callbacks_->call(key, para); + }); + + // some special nodes can keep producing outputs even no inputs + // e.g. loop, for this kind of node, it will be closed only if all + // downstream nodes are closed, and the task priority of this node + // should be set to low + infinity_node_ = module_->is_infinity(); + + output_stream_manager_ = + std::make_shared(node_config.get_output_streams()); + + InputStreamManagerCallBack callback; + callback.scheduler_cb = callback_.scheduler_cb; + callback.throttled_cb = callback_.throttled_cb; + callback.sched_required = callback_.sched_required; + callback.get_node_cb = callback_.get_node; + callback.notify_cb = [this]() -> bool { return this->schedule_node(); }; + callback.node_is_closed_cb = [this]() -> bool { return this->is_closed(); }; + + create_input_stream_manager(node_config.get_input_manager(), node_id, + node_config.get_input_streams(), + output_stream_manager_->get_stream_id_list(), + callback, queue_size_limit_, + input_stream_manager_); + + // register hungry_check + for (auto stream_id : input_stream_manager_->stream_id_list_) { + if (module_->need_hungry_check(stream_id)) { + hungry_check_func_[stream_id].push_back( + [this, stream_id]() -> bool { return this->module_->is_hungry(stream_id); }); - } } - - force_close_ = false; - if (!node_config.get_output_streams().empty()) { - force_close_ = true; - } - - state_ = NodeState::RUNNING; - schedule_node_cnt_ = 0; - schedule_node_success_cnt_ = 0; - source_timestamp_ = 0; - last_timestamp_ = 0; - - wait_pause_ = false; - need_opt_reset_ = false; - } - - int Node::inc_pending_task() { - mutex_.lock(); - pending_tasks_++; - mutex_.unlock(); - return 0; - } - - int Node::dec_pending_task() { - mutex_.lock(); - pending_tasks_--; - mutex_.unlock(); - return 0; } - bool Node::is_source() { - return is_source_; + force_close_ = false; + if (!node_config.get_output_streams().empty()) { + force_close_ = true; } - int Node::get_id() { - return id_; - } + state_ = NodeState::RUNNING; + schedule_node_cnt_ = 0; + schedule_node_success_cnt_ = 0; + source_timestamp_ = 0; + last_timestamp_ = 0; - std::string Node::get_alias() { - return node_config_.get_alias(); - } + wait_pause_ = false; + need_opt_reset_ = false; +} - std::string Node::get_action() { - return node_config_.get_action(); - } +int Node::inc_pending_task() { + mutex_.lock(); + pending_tasks_++; + mutex_.unlock(); + return 0; +} - void Node::set_source(bool flag) { - is_source_ = flag; - } +int Node::dec_pending_task() { + mutex_.lock(); + pending_tasks_--; + mutex_.unlock(); + return 0; +} - int Node::close() { - mutex_.lock(); - //callback_.throttled_cb(id_, false); - for (auto &input_stream:input_stream_manager_->input_streams_) - if (input_stream.second->is_full()) - input_stream.second->clear_queue(); - if (!is_premodule_){ - module_->close(); - } - state_ = NodeState::CLOSED; - BMFLOG_NODE(BMF_INFO, id_) << "close node"; - callback_.sched_required(id_, true); - mutex_.unlock(); - return 0; - } +bool Node::is_source() { return is_source_; } - int Node::reset() { - mutex_.lock(); - // reset module of this node - module_->reset(); - // remove from source nodes - set_source(false); +int Node::get_id() { return id_; } - // clear remaining node task from schedule queue - callback_.clear_cb(id_, get_scheduler_queue_id()); +std::string Node::get_alias() { return node_config_.get_alias(); } - // reset all input_streams of node - for (auto &input_stream : input_stream_manager_->input_streams_) { - if (input_stream.second->get_block()) { - input_stream.second->set_block(false); - } - } +std::string Node::get_action() { return node_config_.get_action(); } - if (!all_input_queue_empty()) {//in some case such as server mode previous blocked - int res = input_stream_manager_->schedule_node(); - if (res) - schedule_node_success_cnt_++; - } +void Node::set_source(bool flag) { is_source_ = flag; } - mutex_.unlock(); - return 0; +int Node::close() { + mutex_.lock(); + // callback_.throttled_cb(id_, false); + for (auto &input_stream : input_stream_manager_->input_streams_) + if (input_stream.second->is_full()) + input_stream.second->clear_queue(); + if (!is_premodule_) { + module_->close(); } + state_ = NodeState::CLOSED; + BMFLOG_NODE(BMF_INFO, id_) << "close node"; + callback_.sched_required(id_, true); + mutex_.unlock(); + return 0; +} - bool Node::is_closed() { - return state_ == NodeState::CLOSED; - } +int Node::reset() { + mutex_.lock(); + // reset module of this node + module_->reset(); + // remove from source nodes + set_source(false); - void Node::register_hungry_check_func(int input_idx, std::function &func) { - hungry_check_func_[input_idx].push_back(func); - } + // clear remaining node task from schedule queue + callback_.clear_cb(id_, get_scheduler_queue_id()); - void Node::get_hungry_check_func(int input_idx, std::vector > &funcs) { - if (hungry_check_func_.count(input_idx)) { - funcs = hungry_check_func_[input_idx]; + // reset all input_streams of node + for (auto &input_stream : input_stream_manager_->input_streams_) { + if (input_stream.second->get_block()) { + input_stream.second->set_block(false); } } - bool Node::is_hungry() { - if (hungry_check_func_.empty()) { - return true; - } - for (auto &hungry_check_func:hungry_check_func_) { - for (auto &func:hungry_check_func.second) { - if (func()) { - return true; - } - } - } - return false; + if (!all_input_queue_empty()) { // in some case such as server mode previous + // blocked + int res = input_stream_manager_->schedule_node(); + if (res) + schedule_node_success_cnt_++; } - int64_t Node::get_source_timestamp() { - source_timestamp_++; - return source_timestamp_; - } + mutex_.unlock(); + return 0; +} - bool Node::any_of_downstream_full() { +bool Node::is_closed() { return state_ == NodeState::CLOSED; } - return output_stream_manager_->any_of_downstream_full(); +void Node::register_hungry_check_func(int input_idx, + std::function &func) { + hungry_check_func_[input_idx].push_back(func); +} +void Node::get_hungry_check_func(int input_idx, + std::vector> &funcs) { + if (hungry_check_func_.count(input_idx)) { + funcs = hungry_check_func_[input_idx]; } +} - bool Node::any_of_input_queue_full() { - for (auto input_stream = input_stream_manager_->input_streams_.begin(); - input_stream != input_stream_manager_->input_streams_.end(); input_stream++) { - if (input_stream->second->is_full()) +bool Node::is_hungry() { + if (hungry_check_func_.empty()) { + return true; + } + for (auto &hungry_check_func : hungry_check_func_) { + for (auto &func : hungry_check_func.second) { + if (func()) { return true; + } } - return false; } + return false; +} - bool Node::all_input_queue_empty() { - for (auto input_stream = input_stream_manager_->input_streams_.begin(); - input_stream != input_stream_manager_->input_streams_.end(); input_stream++) { - if (!input_stream->second->is_empty()) - return false; - } - return true; +int64_t Node::get_source_timestamp() { + source_timestamp_++; + return source_timestamp_; +} + +bool Node::any_of_downstream_full() { + + return output_stream_manager_->any_of_downstream_full(); +} + +bool Node::any_of_input_queue_full() { + for (auto input_stream = input_stream_manager_->input_streams_.begin(); + input_stream != input_stream_manager_->input_streams_.end(); + input_stream++) { + if (input_stream->second->is_full()) + return true; } + return false; +} - bool Node::too_many_tasks_pending() { - return pending_tasks_ >= max_pending_tasks_; +bool Node::all_input_queue_empty() { + for (auto input_stream = input_stream_manager_->input_streams_.begin(); + input_stream != input_stream_manager_->input_streams_.end(); + input_stream++) { + if (!input_stream->second->is_empty()) + return false; } + return true; +} + +bool Node::too_many_tasks_pending() { + return pending_tasks_ >= max_pending_tasks_; +} - int Node::all_downstream_nodes_closed() { - for (auto &output_stream:output_stream_manager_->output_streams_) { - for (auto &mirror_stream : output_stream.second->mirror_streams_) { - int node_id = mirror_stream.input_stream_manager_->node_id_; - std::shared_ptr node = nullptr; - callback_.get_node(node_id, node); - if (node == nullptr or not node->is_closed()) { - return false; - } +int Node::all_downstream_nodes_closed() { + for (auto &output_stream : output_stream_manager_->output_streams_) { + for (auto &mirror_stream : output_stream.second->mirror_streams_) { + int node_id = mirror_stream.input_stream_manager_->node_id_; + std::shared_ptr node = nullptr; + callback_.get_node(node_id, node); + if (node == nullptr or not node->is_closed()) { + return false; } } - return true; } + return true; +} - int Node::need_force_close() { - return force_close_; - } +int Node::need_force_close() { return force_close_; } - int Node::need_opt_reset(JsonParam reset_opt) { - opt_reset_mutex_.lock(); - need_opt_reset_ = true; - reset_option_ = reset_opt; - BMFLOG(BMF_INFO) << "need_opt_reset option: " << reset_opt.dump(); - opt_reset_mutex_.unlock(); - return 0; - } +int Node::need_opt_reset(JsonParam reset_opt) { + opt_reset_mutex_.lock(); + need_opt_reset_ = true; + reset_option_ = reset_opt; + BMFLOG(BMF_INFO) << "need_opt_reset option: " << reset_opt.dump(); + opt_reset_mutex_.unlock(); + return 0; +} // In current design, this function will not be called in parallel // since one node is only scheduled by one scheduler queue - int Node::process_node(Task &task) { - if (state_ == NodeState::CLOSED || state_ == NodeState::PAUSE_DONE) { - dec_pending_task(); - return 0; - } +int Node::process_node(Task &task) { + if (state_ == NodeState::CLOSED || state_ == NodeState::PAUSE_DONE) { + dec_pending_task(); + return 0; + } #ifndef NO_TRACE - TraceProcessEmitter trace_emitter = TraceProcessEmitter(PROCESSING, node_name_); + TraceProcessEmitter trace_emitter = + TraceProcessEmitter(PROCESSING, node_name_); #endif - //TODO check the task is valid - - last_timestamp_ = task.timestamp(); -// std::cout<<"timestamp="<push(Packet::generate_eos_packet()); - } - output_stream_manager_->post_process(task); - close(); - return 0; + // TODO check the task is valid + + last_timestamp_ = task.timestamp(); + // std::cout<<"timestamp="<push(Packet::generate_eos_packet()); } + output_stream_manager_->post_process(task); + close(); + return 0; + } - auto cleanup = [this] { - this->task_processed_cnt_++; - this->dec_pending_task(); - BMFLOG_NODE(BMF_ERROR, this->id_) << "Process node failed, will exit."; - }; - - int result = 0; - try { - opt_reset_mutex_.lock(); - if (need_opt_reset_) { - module_->dynamic_reset(reset_option_); - need_opt_reset_ = false; - } - opt_reset_mutex_.unlock(); - - BMF_TRACE_PROCESS(module_name_.c_str(), "process", START); - state_ = NodeState::RUNNING; - result = module_->process(task); - state_ = NodeState::PENDING; - BMF_TRACE_PROCESS(module_name_.c_str(), "process", END); - if (result != 0) - BMF_Error_(BMF_StsBadArg, "[%s] Process result != 0.\n", node_name_.c_str()); - } - //catch (boost::python::error_already_set const &) { - // std::cerr << "python module exec failed" << std::endl; - // PyErr_Print(); - // cleanup(); - // throw std::runtime_error("[" + node_name_ + "] " + "Python error already set."); - //} - catch (std::exception& e){ - BMFLOG_NODE(BMF_ERROR, id_) << "catch exception: " << e.what(); - cleanup(); - std::rethrow_exception(std::current_exception()); + auto cleanup = [this] { + this->task_processed_cnt_++; + this->dec_pending_task(); + BMFLOG_NODE(BMF_ERROR, this->id_) << "Process node failed, will exit."; + }; + + int result = 0; + try { + opt_reset_mutex_.lock(); + if (need_opt_reset_) { + module_->dynamic_reset(reset_option_); + need_opt_reset_ = false; } + opt_reset_mutex_.unlock(); - task_processed_cnt_++; - if (task.timestamp() == DONE && not is_closed()) { - BMFLOG_NODE(BMF_INFO, id_) << "Process node end"; - if (mode_ == BmfMode::SERVER_MODE) { - reset(); - } else { - close(); - } + BMF_TRACE_PROCESS(module_name_.c_str(), "process", START); + state_ = NodeState::RUNNING; + result = module_->process(task); + state_ = NodeState::PENDING; + BMF_TRACE_PROCESS(module_name_.c_str(), "process", END); + if (result != 0) + BMF_Error_(BMF_StsBadArg, "[%s] Process result != 0.\n", + node_name_.c_str()); + } + // catch (boost::python::error_already_set const &) { + // std::cerr << "python module exec failed" << std::endl; + // PyErr_Print(); + // cleanup(); + // throw std::runtime_error("[" + node_name_ + "] " + "Python error + // already set."); + //} + catch (std::exception &e) { + BMFLOG_NODE(BMF_ERROR, id_) << "catch exception: " << e.what(); + cleanup(); + std::rethrow_exception(std::current_exception()); + } + + task_processed_cnt_++; + if (task.timestamp() == DONE && not is_closed()) { + BMFLOG_NODE(BMF_INFO, id_) << "Process node end"; + if (mode_ == BmfMode::SERVER_MODE) { + reset(); + } else { + close(); } + } - // call post process, propagate packets to downstream node - output_stream_manager_->post_process(task); + // call post process, propagate packets to downstream node + output_stream_manager_->post_process(task); - dec_pending_task(); + dec_pending_task(); - if ((wait_pause_ == true && pending_tasks_ == 0)) { - state_ = NodeState::PAUSE_DONE; - pause_event_.notify_all(); - return 0; - } + if ((wait_pause_ == true && pending_tasks_ == 0)) { + state_ = NodeState::PAUSE_DONE; + pause_event_.notify_all(); + return 0; + } - bool is_blocked = false; - if (mode_ == BmfMode::SERVER_MODE && !is_source()) { - uint8_t blk_num = 0; - for (auto &input_stream : input_stream_manager_->input_streams_) { - if (input_stream.second->get_block()) { - blk_num++; - } + bool is_blocked = false; + if (mode_ == BmfMode::SERVER_MODE && !is_source()) { + uint8_t blk_num = 0; + for (auto &input_stream : input_stream_manager_->input_streams_) { + if (input_stream.second->get_block()) { + blk_num++; } - if (blk_num == input_stream_manager_->input_streams_.size()) - is_blocked = true; } + if (blk_num == input_stream_manager_->input_streams_.size()) + is_blocked = true; + } - if (!is_blocked) - if (state_ != NodeState::CLOSED) - callback_.sched_required(id_, false); + if (!is_blocked) + if (state_ != NodeState::CLOSED) + callback_.sched_required(id_, false); - return 0; - } + return 0; +} /* There are two cases which will run into schedule_node, so we need a mutex here -1. while an input packet is added to input_stream, this is called by input_stream_manager -2. while node is in PENDING or all input streams done, it's scheduled by scheduler +1. while an input packet is added to input_stream, this is called by +input_stream_manager +2. while node is in PENDING or all input streams done, it's scheduled by +scheduler */ - bool Node::schedule_node() { +bool Node::schedule_node() { #ifndef NO_TRACE - TraceProcessEmitter trace_emitter = TraceProcessEmitter(SCHEDULE, node_name_); + TraceProcessEmitter trace_emitter = + TraceProcessEmitter(SCHEDULE, node_name_); #endif - mutex_.lock(); -// BMFLOG_NODE(BMF_INFO, id_) << "scheduling..."; - schedule_node_cnt_++; - if (state_ == NodeState::PAUSE_DONE) { - mutex_.unlock(); - return false; - } - //we don't need schedule node if it's closed or set to pause - if (state_ == NodeState::CLOSED || (wait_pause_ == true && pending_tasks_ != 0)) { + mutex_.lock(); + // BMFLOG_NODE(BMF_INFO, id_) << "scheduling..."; + schedule_node_cnt_++; + if (state_ == NodeState::PAUSE_DONE) { + mutex_.unlock(); + return false; + } + // we don't need schedule node if it's closed or set to pause + if (state_ == NodeState::CLOSED || + (wait_pause_ == true && pending_tasks_ != 0)) { + mutex_.unlock(); + return false; + } + // for node that need force_close, check if all downstream nodes are closed + // already + // if yes, set it to closed, and remove it from node scheduler + if (need_force_close()) { + if (all_downstream_nodes_closed()) { + close(); mutex_.unlock(); + BMFLOG_NODE(BMF_INFO, id_) + << "scheduling failed, all downstream node closed: " << type_; return false; } - // for node that need force_close, check if all downstream nodes are closed already - // if yes, set it to closed, and remove it from node scheduler - if (need_force_close()) { - if (all_downstream_nodes_closed()) { - close(); - mutex_.unlock(); - BMFLOG_NODE(BMF_INFO, id_) << "scheduling failed, all downstream node closed: " << type_; - return false; - } - } - - bool result = false; - if (is_source()) { - Task task = Task(id_, input_stream_manager_->stream_id_list_, output_stream_manager_->get_stream_id_list()); - if (infinity_node_) { - task.set_timestamp(INF_SRC); - } else { - task.set_timestamp(get_source_timestamp()); - } - callback_.scheduler_cb(task); - schedule_node_success_cnt_++; - result = true; - } else { - if (node_output_updated_) { - input_stream_manager_->output_stream_id_list_ = output_stream_manager_->get_stream_id_list(); - node_output_updated_ = false; - } - result = input_stream_manager_->schedule_node(); - if (result) - schedule_node_success_cnt_++; - } - mutex_.unlock(); - return result; } - void Node::wait_paused() { - std::unique_lock lk(pause_mutex_); - wait_pause_ = true; - while (state_ != NodeState::PAUSE_DONE && state_ != NodeState::CLOSED) { - pause_event_.wait_for(lk, std::chrono::microseconds(40)); - if (pending_tasks_ == 0) { - BMFLOG_NODE(BMF_INFO, id_) << "wait pause: pending task is zero"; - state_ = NodeState::PAUSE_DONE; - break; - } + bool result = false; + if (is_source()) { + Task task = Task(id_, input_stream_manager_->stream_id_list_, + output_stream_manager_->get_stream_id_list()); + if (infinity_node_) { + task.set_timestamp(INF_SRC); + } else { + task.set_timestamp(get_source_timestamp()); } - wait_pause_ = false; - } - - void Node::set_scheduler_queue_id(int scheduler_queue_id) { - scheduler_queue_id_ = scheduler_queue_id; - } - - int Node::get_scheduler_queue_id() { - return scheduler_queue_id_; - } - - int Node::get_input_stream_manager(std::shared_ptr &input_stream_manager) { - input_stream_manager = input_stream_manager_; - return 0; - } - - int Node::get_input_streams(std::map > &input_streams) { - if (input_stream_manager_ != NULL) { - input_streams = input_stream_manager_->input_streams_; + callback_.scheduler_cb(task); + schedule_node_success_cnt_++; + result = true; + } else { + if (node_output_updated_) { + input_stream_manager_->output_stream_id_list_ = + output_stream_manager_->get_stream_id_list(); + node_output_updated_ = false; } - return 0; - } - - int Node::get_output_stream_manager(std::shared_ptr &output_stream_manager) { - output_stream_manager = output_stream_manager_; - return 0; - } - - int Node::get_output_streams(std::map> &output_streams) { - output_streams = output_stream_manager_->output_streams_; - return 0; - } - - std::string Node::get_type() { - return type_; + result = input_stream_manager_->schedule_node(); + if (result) + schedule_node_success_cnt_++; } - - std::string Node::get_status() { - switch (state_) { - case NodeState::PENDING: - return "PENDING"; - case NodeState::NOT_INITED: - return "NOT_INITED"; - case NodeState::RUNNING: - return "RUNNING"; - case NodeState::CLOSED: - return "CLOSE"; - case NodeState::PAUSE_DONE: - return "PAUSE_DONE"; + mutex_.unlock(); + return result; +} + +void Node::wait_paused() { + std::unique_lock lk(pause_mutex_); + wait_pause_ = true; + while (state_ != NodeState::PAUSE_DONE && state_ != NodeState::CLOSED) { + pause_event_.wait_for(lk, std::chrono::microseconds(40)); + if (pending_tasks_ == 0) { + BMFLOG_NODE(BMF_INFO, id_) << "wait pause: pending task is zero"; + state_ = NodeState::PAUSE_DONE; + break; } - return "UNKNOWN"; - } - - void Node::set_status(NodeState state) { - mutex_.lock(); - state_ = state; - mutex_.unlock(); - } - - void Node::set_outputstream_updated(bool update) { - node_output_updated_ = update; - } - - int Node::get_schedule_attempt_cnt() { - return schedule_node_cnt_; - } - - int Node::get_schedule_success_cnt() { - return schedule_node_success_cnt_; - } - - int64_t Node::get_last_timestamp() { - return last_timestamp_; } + wait_pause_ = false; +} + +void Node::set_scheduler_queue_id(int scheduler_queue_id) { + scheduler_queue_id_ = scheduler_queue_id; +} + +int Node::get_scheduler_queue_id() { return scheduler_queue_id_; } + +int Node::get_input_stream_manager( + std::shared_ptr &input_stream_manager) { + input_stream_manager = input_stream_manager_; + return 0; +} + +int Node::get_input_streams( + std::map> &input_streams) { + if (input_stream_manager_ != NULL) { + input_streams = input_stream_manager_->input_streams_; + } + return 0; +} + +int Node::get_output_stream_manager( + std::shared_ptr &output_stream_manager) { + output_stream_manager = output_stream_manager_; + return 0; +} + +int Node::get_output_streams( + std::map> &output_streams) { + output_streams = output_stream_manager_->output_streams_; + return 0; +} + +std::string Node::get_type() { return type_; } + +std::string Node::get_status() { + switch (state_) { + case NodeState::PENDING: + return "PENDING"; + case NodeState::NOT_INITED: + return "NOT_INITED"; + case NodeState::RUNNING: + return "RUNNING"; + case NodeState::CLOSED: + return "CLOSE"; + case NodeState::PAUSE_DONE: + return "PAUSE_DONE"; + } + return "UNKNOWN"; +} + +void Node::set_status(NodeState state) { + mutex_.lock(); + state_ = state; + mutex_.unlock(); +} + +void Node::set_outputstream_updated(bool update) { + node_output_updated_ = update; +} + +int Node::get_schedule_attempt_cnt() { return schedule_node_cnt_; } + +int Node::get_schedule_success_cnt() { return schedule_node_success_cnt_; } + +int64_t Node::get_last_timestamp() { return last_timestamp_; } END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/optimizer.cpp b/bmf/engine/c_engine/src/optimizer.cpp index f2f0c2a0..b1985e5b 100644 --- a/bmf/engine/c_engine/src/optimizer.cpp +++ b/bmf/engine/c_engine/src/optimizer.cpp @@ -16,438 +16,480 @@ #include "../include/optimizer.h" - BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - namespace Optimizer { - void convert_filter_para(NodeConfig &node) { - json new_option; - json f; - f["inputs"] = json(std::vector()); - f["outputs"] = json(std::vector()); - - for (int index = 0; index < node.get_input_streams().size(); index++) { - json input_pin; - input_pin["stream"] = node.get_input_streams()[index].get_identifier(); - input_pin["pin"] = index; - f["inputs"].push_back(input_pin); - } +USE_BMF_SDK_NS + +namespace Optimizer { +void convert_filter_para(NodeConfig &node) { + json new_option; + json f; + f["inputs"] = json(std::vector()); + f["outputs"] = json(std::vector()); + + for (int index = 0; index < node.get_input_streams().size(); index++) { + json input_pin; + input_pin["stream"] = node.get_input_streams()[index].get_identifier(); + input_pin["pin"] = index; + f["inputs"].push_back(input_pin); + } - for (int index = 0; index < node.get_output_streams().size(); index++) { - json output_pin; - output_pin["stream"] = node.get_output_streams()[index].get_identifier(); - output_pin["pin"] = index; - f["outputs"].push_back(output_pin); - } + for (int index = 0; index < node.get_output_streams().size(); index++) { + json output_pin; + output_pin["stream"] = + node.get_output_streams()[index].get_identifier(); + output_pin["pin"] = index; + f["outputs"].push_back(output_pin); + } - std::string name; - node.get_option().get_string("name", name); - f["name"] = name; + std::string name; + node.get_option().get_string("name", name); + f["name"] = name; - if (node.get_option().has_key("para")) { - std::string para; - node.get_option().get_string("para", para); - f["para"] = para; - } + if (node.get_option().has_key("para")) { + std::string para; + node.get_option().get_string("para", para); + f["para"] = para; + } - new_option["filters"].push_back(f); - node.set_option(JsonParam(new_option)); - } + new_option["filters"].push_back(f); + node.set_option(JsonParam(new_option)); +} - void convert_filter_para_for_graph(std::vector &nodes) { - for (NodeConfig &node:nodes) { - if (node.get_module_info().get_module_name() == "c_ffmpeg_filter") { - convert_filter_para(node); - } - } +void convert_filter_para_for_graph(std::vector &nodes) { + for (NodeConfig &node : nodes) { + if (node.get_module_info().get_module_name() == "c_ffmpeg_filter") { + convert_filter_para(node); } + } +} - int find_merged_link(json &links, StreamConfig stream) { - int pin = -1; - json link_remove; - - for (json link:links) { - if (link["stream"] == stream.get_identifier()) { - pin = link["pin"]; - link_remove = link; - break; - } - } - - if (link_remove.size() > 0) { - links.erase(std::remove(links.begin(), links.end(), link_remove), links.end()); - } +int find_merged_link(json &links, StreamConfig stream) { + int pin = -1; + json link_remove; - return pin; + for (json link : links) { + if (link["stream"] == stream.get_identifier()) { + pin = link["pin"]; + link_remove = link; + break; } + } - void replace_stream_name_with_id(NodeConfig &node) { - json option = node.get_option().json_value_; - json &filter_option = option["filters"]; - bool stream_found; - - for (int index = 0; index < node.get_input_streams().size(); index++) { - stream_found = false; - for (json &f:filter_option) { - if (f.find("inputs") != f.end()) { - for (json &input_pin:f["inputs"]) { - if (input_pin["stream"] == node.get_input_streams()[index].get_identifier()) { - input_pin["stream"] = index; - stream_found = true; - break; - } - } - } - if (stream_found) - break; - } - } + if (link_remove.size() > 0) { + links.erase(std::remove(links.begin(), links.end(), link_remove), + links.end()); + } - for (int index = 0; index < node.get_output_streams().size(); index++) { - stream_found = false; - for (json &f:filter_option) { - if (f.find("outputs") != f.end()) { - for (json &output_pin:f["outputs"]) { - if (output_pin["stream"] == node.get_output_streams()[index].get_identifier()) { - output_pin["stream"] = index; - stream_found = true; - break; - } - } - } - if (stream_found) + return pin; +} + +void replace_stream_name_with_id(NodeConfig &node) { + json option = node.get_option().json_value_; + json &filter_option = option["filters"]; + bool stream_found; + + for (int index = 0; index < node.get_input_streams().size(); index++) { + stream_found = false; + for (json &f : filter_option) { + if (f.find("inputs") != f.end()) { + for (json &input_pin : f["inputs"]) { + if (input_pin["stream"] == + node.get_input_streams()[index].get_identifier()) { + input_pin["stream"] = index; + stream_found = true; break; + } } } - - node.set_option(JsonParam(option)); + if (stream_found) + break; } + } - void replace_stream_name_for_graph(std::vector &nodes) { - for (NodeConfig &node:nodes) { - if (node.get_module_info().get_module_name() == "c_ffmpeg_filter") { - replace_stream_name_with_id(node); + for (int index = 0; index < node.get_output_streams().size(); index++) { + stream_found = false; + for (json &f : filter_option) { + if (f.find("outputs") != f.end()) { + for (json &output_pin : f["outputs"]) { + if (output_pin["stream"] == + node.get_output_streams()[index].get_identifier()) { + output_pin["stream"] = index; + stream_found = true; + break; + } } } + if (stream_found) + break; } + } - void merge_two_nodes(NodeConfig &n1, NodeConfig &n2) { - for (StreamConfig input_stream:n2.get_input_streams()) { - n1.add_input_stream(input_stream); - } - - for (StreamConfig output_stream:n2.get_output_streams()) { - n1.add_output_stream(output_stream); - } - - json option = n1.get_option().json_value_; - json filter_option_1 = option["filters"]; - json filter_option_2 = n2.get_option().json_value_["filters"]; + node.set_option(JsonParam(option)); +} - for (json filter:filter_option_2) { - filter_option_1.push_back(filter); - } +void replace_stream_name_for_graph(std::vector &nodes) { + for (NodeConfig &node : nodes) { + if (node.get_module_info().get_module_name() == "c_ffmpeg_filter") { + replace_stream_name_with_id(node); + } + } +} - std::vector removed_stream; - std::vector &input_streams = n1.get_input_streams(); - std::vector &output_streams = n1.get_output_streams(); - - for (StreamConfig input_stream:input_streams) { - if (std::find(output_streams.begin(), output_streams.end(), input_stream) != output_streams.end()) { - removed_stream.push_back(input_stream); - - int filter_id; - int out_pin; - - for (int index = 0; index < filter_option_1.size(); index++) { - json &f = filter_option_1[index]; - if (f.find("inputs") != f.end()) { - out_pin = find_merged_link(f["inputs"], input_stream); - if (out_pin != -1) { - filter_id = index; - break; - } - } - } +void merge_two_nodes(NodeConfig &n1, NodeConfig &n2) { + for (StreamConfig input_stream : n2.get_input_streams()) { + n1.add_input_stream(input_stream); + } - for (int index = 0; index < filter_option_1.size(); index++) { - json &f = filter_option_1[index]; - if (f.find("outputs") != f.end()) { - int in_pin = find_merged_link(f["outputs"], input_stream); - if (in_pin != -1) { - json link; - link["input_pin"] = in_pin; - link["output_pin"] = out_pin; - link["output_filter"] = filter_id; - if (f.find("links") == f.end()) { - f["links"] = json(std::vector()); - } - f["links"].push_back(link); - } - } - } - } - } + for (StreamConfig output_stream : n2.get_output_streams()) { + n1.add_output_stream(output_stream); + } - for (StreamConfig stream:removed_stream) { - if (std::find(input_streams.begin(), input_streams.end(), stream) != input_streams.end()) { - input_streams.erase(std::remove(input_streams.begin(), input_streams.end(), stream), - input_streams.end()); - } - if (std::find(output_streams.begin(), output_streams.end(), stream) != output_streams.end()) { - output_streams.erase(std::remove(output_streams.begin(), output_streams.end(), stream), - output_streams.end()); - } - } + json option = n1.get_option().json_value_; + json filter_option_1 = option["filters"]; + json filter_option_2 = n2.get_option().json_value_["filters"]; - option["filters"] = filter_option_1; - n1.set_option(JsonParam(option)); - } + for (json filter : filter_option_2) { + filter_option_1.push_back(filter); + } - NodeConfig merge_ffmpeg_filter_nodes(std::vector &merge_nodes) { - NodeConfig merge_node; - if (merge_nodes.size() == 0) { - return merge_node; - } + std::vector removed_stream; + std::vector &input_streams = n1.get_input_streams(); + std::vector &output_streams = n1.get_output_streams(); - merge_node = merge_nodes[0]; - for (int i = 1; i < merge_nodes.size(); i++) { - merge_two_nodes(merge_node, merge_nodes[i]); - } + for (StreamConfig input_stream : input_streams) { + if (std::find(output_streams.begin(), output_streams.end(), + input_stream) != output_streams.end()) { + removed_stream.push_back(input_stream); - return merge_node; - } + int filter_id; + int out_pin; - std::vector find_all_neighbours(std::vector opt_nodes, NodeConfig merged_node) { - std::vector neighbours; - - for (StreamConfig output_stream:merged_node.get_output_streams()) { - for (NodeConfig node:opt_nodes) { - std::vector input_streams = node.get_input_streams(); - if (std::find(input_streams.begin(), input_streams.end(), output_stream) != input_streams.end()) { - Neighbour nb; - nb.node = node; - nb.root_stream = output_stream; - neighbours.push_back(nb); + for (int index = 0; index < filter_option_1.size(); index++) { + json &f = filter_option_1[index]; + if (f.find("inputs") != f.end()) { + out_pin = find_merged_link(f["inputs"], input_stream); + if (out_pin != -1) { + filter_id = index; + break; } } } - return neighbours; - } - StreamConfig - has_circle(std::vector opt_nodes, NodeConfig merged_node, std::map &rec_stack) { - StreamConfig s; - rec_stack[merged_node.get_id()] = true; - std::vector neighbours = find_all_neighbours(opt_nodes, merged_node); - - for (Neighbour nb:neighbours) { - if (rec_stack.count(nb.node.get_id()) == 0 || !rec_stack[nb.node.get_id()]) { - StreamConfig circle_stream = has_circle(opt_nodes, nb.node, rec_stack); - if (circle_stream.get_identifier().length() > 0) { - return circle_stream; + for (int index = 0; index < filter_option_1.size(); index++) { + json &f = filter_option_1[index]; + if (f.find("outputs") != f.end()) { + int in_pin = find_merged_link(f["outputs"], input_stream); + if (in_pin != -1) { + json link; + link["input_pin"] = in_pin; + link["output_pin"] = out_pin; + link["output_filter"] = filter_id; + if (f.find("links") == f.end()) { + f["links"] = json(std::vector()); + } + f["links"].push_back(link); } - } else { - return nb.root_stream; } } - rec_stack[merged_node.get_id()] = false; - return s; } + } - StreamConfig find_first_circle_node(std::vector opt_nodes, NodeConfig merged_node) { - std::map rec_stack; - - StreamConfig stream = has_circle(opt_nodes, merged_node, rec_stack); - return stream; + for (StreamConfig stream : removed_stream) { + if (std::find(input_streams.begin(), input_streams.end(), stream) != + input_streams.end()) { + input_streams.erase( + std::remove(input_streams.begin(), input_streams.end(), stream), + input_streams.end()); + } + if (std::find(output_streams.begin(), output_streams.end(), stream) != + output_streams.end()) { + output_streams.erase(std::remove(output_streams.begin(), + output_streams.end(), stream), + output_streams.end()); } + } - void optimize(std::vector &nodes) { - // nodes_done is used to record ffmpeg_filter node that already optimized - std::vector nodes_done; + option["filters"] = filter_option_1; + n1.set_option(JsonParam(option)); +} - while (true) { - std::vector nodes_to_merge; +NodeConfig merge_ffmpeg_filter_nodes(std::vector &merge_nodes) { + NodeConfig merge_node; + if (merge_nodes.size() == 0) { + return merge_node; + } - // put all ffmpeg_filter nodes into nodes_to_merge and try to combine it to one node - for (NodeConfig &node:nodes) { - if (node.get_module_info().get_module_name() == "c_ffmpeg_filter" && - std::find(nodes_done.begin(), nodes_done.end(), node) == nodes_done.end()) { - nodes_to_merge.push_back(node); - } - } + merge_node = merge_nodes[0]; + for (int i = 1; i < merge_nodes.size(); i++) { + merge_two_nodes(merge_node, merge_nodes[i]); + } - for (NodeConfig node:nodes_to_merge) { - nodes.erase(std::remove(nodes.begin(), nodes.end(), node), nodes.end()); - } + return merge_node; +} + +std::vector find_all_neighbours(std::vector opt_nodes, + NodeConfig merged_node) { + std::vector neighbours; + + for (StreamConfig output_stream : merged_node.get_output_streams()) { + for (NodeConfig node : opt_nodes) { + std::vector input_streams = node.get_input_streams(); + if (std::find(input_streams.begin(), input_streams.end(), + output_stream) != input_streams.end()) { + Neighbour nb; + nb.node = node; + nb.root_stream = output_stream; + neighbours.push_back(nb); + } + } + } + return neighbours; +} + +StreamConfig has_circle(std::vector opt_nodes, + NodeConfig merged_node, + std::map &rec_stack) { + StreamConfig s; + rec_stack[merged_node.get_id()] = true; + std::vector neighbours = + find_all_neighbours(opt_nodes, merged_node); + + for (Neighbour nb : neighbours) { + if (rec_stack.count(nb.node.get_id()) == 0 || + !rec_stack[nb.node.get_id()]) { + StreamConfig circle_stream = + has_circle(opt_nodes, nb.node, rec_stack); + if (circle_stream.get_identifier().length() > 0) { + return circle_stream; + } + } else { + return nb.root_stream; + } + } + rec_stack[merged_node.get_id()] = false; + return s; +} + +StreamConfig find_first_circle_node(std::vector opt_nodes, + NodeConfig merged_node) { + std::map rec_stack; + + StreamConfig stream = has_circle(opt_nodes, merged_node, rec_stack); + return stream; +} + +void optimize(std::vector &nodes) { + // nodes_done is used to record ffmpeg_filter node that already optimized + std::vector nodes_done; + + while (true) { + std::vector nodes_to_merge; + + // put all ffmpeg_filter nodes into nodes_to_merge and try to combine it + // to one node + for (NodeConfig &node : nodes) { + if (node.get_module_info().get_module_name() == "c_ffmpeg_filter" && + std::find(nodes_done.begin(), nodes_done.end(), node) == + nodes_done.end()) { + nodes_to_merge.push_back(node); + } + } - if (nodes_to_merge.size() == 0) { - break; - } + for (NodeConfig node : nodes_to_merge) { + nodes.erase(std::remove(nodes.begin(), nodes.end(), node), + nodes.end()); + } - // nodes to merge should have the same scheduler id - int scheduler_id = nodes_to_merge[0].get_scheduler(); - for (int i = 1; i < nodes_to_merge.size(); i++) { - NodeConfig node = nodes_to_merge[i]; - if (node.get_scheduler() != scheduler_id){ - // remove node from nodes_to_merge and add back to node list - nodes_to_merge.erase(std::remove(nodes_to_merge.begin(), nodes_to_merge.end(), node), nodes_to_merge.end()); - nodes.push_back(node); - i--; - } - } + if (nodes_to_merge.size() == 0) { + break; + } - while (true) { - // do node merge - NodeConfig merged_node = merge_ffmpeg_filter_nodes(nodes_to_merge); - nodes.push_back(merged_node); - - // check if has a circle - StreamConfig circle_stream = find_first_circle_node(nodes, merged_node); - - if (circle_stream.get_identifier().length() > 0) { - NodeConfig circle_node; - // find circle-end node according to stream - for (NodeConfig node:nodes_to_merge) { - std::vector input_streams = node.get_input_streams(); - if (std::find(input_streams.begin(), input_streams.end(), circle_stream) != - input_streams.end()) { - circle_node = node; - break; - } - } + // nodes to merge should have the same scheduler id + int scheduler_id = nodes_to_merge[0].get_scheduler(); + for (int i = 1; i < nodes_to_merge.size(); i++) { + NodeConfig node = nodes_to_merge[i]; + if (node.get_scheduler() != scheduler_id) { + // remove node from nodes_to_merge and add back to node list + nodes_to_merge.erase(std::remove(nodes_to_merge.begin(), + nodes_to_merge.end(), node), + nodes_to_merge.end()); + nodes.push_back(node); + i--; + } + } - // remove it from nodes_to_merge and add it back to node list - nodes_to_merge.erase(std::remove(nodes_to_merge.begin(), nodes_to_merge.end(), circle_node), - nodes_to_merge.end()); - nodes.push_back(circle_node); - nodes.erase(std::remove(nodes.begin(), nodes.end(), merged_node), nodes.end()); - continue; - } else { - nodes_done.push_back(merged_node); + while (true) { + // do node merge + NodeConfig merged_node = merge_ffmpeg_filter_nodes(nodes_to_merge); + nodes.push_back(merged_node); + + // check if has a circle + StreamConfig circle_stream = + find_first_circle_node(nodes, merged_node); + + if (circle_stream.get_identifier().length() > 0) { + NodeConfig circle_node; + // find circle-end node according to stream + for (NodeConfig node : nodes_to_merge) { + std::vector input_streams = + node.get_input_streams(); + if (std::find(input_streams.begin(), input_streams.end(), + circle_stream) != input_streams.end()) { + circle_node = node; break; } } + + // remove it from nodes_to_merge and add it back to node list + nodes_to_merge.erase(std::remove(nodes_to_merge.begin(), + nodes_to_merge.end(), + circle_node), + nodes_to_merge.end()); + nodes.push_back(circle_node); + nodes.erase( + std::remove(nodes.begin(), nodes.end(), merged_node), + nodes.end()); + continue; + } else { + nodes_done.push_back(merged_node); + break; } } + } +} - void merge_subgraph(GraphConfig &main_config, GraphConfig &sub_config, int sub_node_id) { - NodeConfig sub_graph_node; +void merge_subgraph(GraphConfig &main_config, GraphConfig &sub_config, + int sub_node_id) { + NodeConfig sub_graph_node; - // find subgraph node from main graph - for (NodeConfig &node:main_config.nodes) { - if (node.get_id() == sub_node_id) { - sub_graph_node = node; - break; - } - } + // find subgraph node from main graph + for (NodeConfig &node : main_config.nodes) { + if (node.get_id() == sub_node_id) { + sub_graph_node = node; + break; + } + } - // find source nodes from subgraph-inside-nodes and replace their input_streams - for (int i = 0; i < sub_config.get_input_streams().size(); i++) { - StreamConfig in_stream = sub_config.get_input_streams()[i]; - for (NodeConfig &node:sub_config.nodes) { - for (int j = 0; j < node.get_input_streams().size(); j++) { - StreamConfig node_in_stream = node.get_input_streams()[j]; - if (in_stream.get_identifier() == node_in_stream.get_identifier()) { - node.input_streams[j] = sub_graph_node.input_streams[i]; - break; - } - } + // find source nodes from subgraph-inside-nodes and replace their + // input_streams + for (int i = 0; i < sub_config.get_input_streams().size(); i++) { + StreamConfig in_stream = sub_config.get_input_streams()[i]; + for (NodeConfig &node : sub_config.nodes) { + for (int j = 0; j < node.get_input_streams().size(); j++) { + StreamConfig node_in_stream = node.get_input_streams()[j]; + if (in_stream.get_identifier() == + node_in_stream.get_identifier()) { + node.input_streams[j] = sub_graph_node.input_streams[i]; + break; } } + } + } - // find tail nodes from subgraph-inside-nodes and replace their output_streams - for (int i = 0; i < sub_config.get_output_streams().size(); i++) { - StreamConfig out_stream = sub_config.get_output_streams()[i]; - for (NodeConfig &node:sub_config.nodes) { - for (int j = 0; j < node.get_output_streams().size(); j++) { - StreamConfig node_out_stream = node.get_output_streams()[j]; - if (out_stream.get_identifier() == node_out_stream.get_identifier()) { - node.output_streams[j] = sub_graph_node.output_streams[i]; - break; - } - } + // find tail nodes from subgraph-inside-nodes and replace their + // output_streams + for (int i = 0; i < sub_config.get_output_streams().size(); i++) { + StreamConfig out_stream = sub_config.get_output_streams()[i]; + for (NodeConfig &node : sub_config.nodes) { + for (int j = 0; j < node.get_output_streams().size(); j++) { + StreamConfig node_out_stream = node.get_output_streams()[j]; + if (out_stream.get_identifier() == + node_out_stream.get_identifier()) { + node.output_streams[j] = sub_graph_node.output_streams[i]; + break; } } - - // remove subgraph node from main graph - main_config.nodes.erase(std::remove(main_config.nodes.begin(), main_config.nodes.end(), sub_graph_node), - main_config.nodes.end()); - - // add all subgraph-inside-nodes into main graph - for (NodeConfig &node:sub_config.nodes) { - main_config.nodes.push_back(node); - } } + } - void subgraph_preprocess(GraphConfig &main_graph_config, std::map > &created_modules) { - GraphConfig main_graph_config_tmp = main_graph_config; + // remove subgraph node from main graph + main_config.nodes.erase(std::remove(main_config.nodes.begin(), + main_config.nodes.end(), + sub_graph_node), + main_config.nodes.end()); - for (NodeConfig &node:main_graph_config.nodes) { - // skip pre-module - if (node.get_node_meta().get_premodule_id() != -1) { - continue; - } + // add all subgraph-inside-nodes into main graph + for (NodeConfig &node : sub_config.nodes) { + main_config.nodes.push_back(node); + } +} - int node_id = node.get_id(); - std::string module_info = node.get_module_info().to_json().dump(); - std::string module_opt = node.get_option().dump(); - // judge subgraph - std::pair > subgraph_check; - if (created_modules.count(node_id)) - subgraph_check = {bmf_engine::ModuleFactory::test_subgraph(created_modules[node_id]), - created_modules[node_id]}; - else - subgraph_check = bmf_engine::ModuleFactory::create_and_test_subgraph(module_info, node_id, - module_opt); - - if (subgraph_check.first) { - // get subgraph config - JsonParam subgraph_config_ = bmf_engine::ModuleFactory::get_subgraph_config(subgraph_check.second); - json subgraph_json = subgraph_config_.json_value_; - GraphConfig subgraph_config = bmf_engine::GraphConfig(subgraph_json); - subgraph_preprocess(subgraph_config, created_modules); - - // Merge sub-graph with main graph - merge_subgraph(main_graph_config_tmp, subgraph_config, node_id); - } else - created_modules[node_id] = subgraph_check.second; - } - main_graph_config = main_graph_config_tmp; +void subgraph_preprocess( + GraphConfig &main_graph_config, + std::map> &created_modules) { + GraphConfig main_graph_config_tmp = main_graph_config; + + for (NodeConfig &node : main_graph_config.nodes) { + // skip pre-module + if (node.get_node_meta().get_premodule_id() != -1) { + continue; } - void dump_graph(GraphConfig graph_config, bool merged) { - json option = graph_config.get_option().json_value_; + int node_id = node.get_id(); + std::string module_info = node.get_module_info().to_json().dump(); + std::string module_opt = node.get_option().dump(); + // judge subgraph + std::pair> subgraph_check; + if (created_modules.count(node_id)) + subgraph_check = {bmf_engine::ModuleFactory::test_subgraph( + created_modules[node_id]), + created_modules[node_id]}; + else + subgraph_check = + bmf_engine::ModuleFactory::create_and_test_subgraph( + module_info, node_id, module_opt); + + if (subgraph_check.first) { + // get subgraph config + JsonParam subgraph_config_ = + bmf_engine::ModuleFactory::get_subgraph_config( + subgraph_check.second); + json subgraph_json = subgraph_config_.json_value_; + GraphConfig subgraph_config = + bmf_engine::GraphConfig(subgraph_json); + subgraph_preprocess(subgraph_config, created_modules); + + // Merge sub-graph with main graph + merge_subgraph(main_graph_config_tmp, subgraph_config, node_id); + } else + created_modules[node_id] = subgraph_check.second; + } + main_graph_config = main_graph_config_tmp; +} - // need dump - if (option.find("dump_graph") != option.end() && option["dump_graph"] == 1) { - std::string graph_config_info = graph_config.to_json().dump(4, ' '); +void dump_graph(GraphConfig graph_config, bool merged) { + json option = graph_config.get_option().json_value_; - std::string file_name; + // need dump + if (option.find("dump_graph") != option.end() && + option["dump_graph"] == 1) { + std::string graph_config_info = graph_config.to_json().dump(4, ' '); - // file name - if (option.find("graph_name") == option.end()) { - if (!merged) { - file_name = "graph_unmerged.json"; - } else { - file_name = "graph.json"; - } - } else { - if (!merged) { - file_name = option["graph_name"].get() + "_unmerged.json"; - } else { - file_name = option["graph_name"].get() + ".json"; - } - } + std::string file_name; - // write graph info into file - std::ofstream fout; - fout.open(file_name); - fout << graph_config_info << std::endl; - fout.close(); + // file name + if (option.find("graph_name") == option.end()) { + if (!merged) { + file_name = "graph_unmerged.json"; + } else { + file_name = "graph.json"; + } + } else { + if (!merged) { + file_name = + option["graph_name"].get() + "_unmerged.json"; + } else { + file_name = option["graph_name"].get() + ".json"; } } + + // write graph info into file + std::ofstream fout; + fout.open(file_name); + fout << graph_config_info << std::endl; + fout.close(); } +} +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/output_stream.cpp b/bmf/engine/c_engine/src/output_stream.cpp index 3943329f..ceb9631d 100644 --- a/bmf/engine/c_engine/src/output_stream.cpp +++ b/bmf/engine/c_engine/src/output_stream.cpp @@ -19,32 +19,36 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS +USE_BMF_SDK_NS - MirrorStream::MirrorStream(std::shared_ptr input_stream_manager, int stream_id) - : input_stream_manager_(input_stream_manager), stream_id_(stream_id) {} +MirrorStream::MirrorStream( + std::shared_ptr input_stream_manager, int stream_id) + : input_stream_manager_(input_stream_manager), stream_id_(stream_id) {} - OutputStream::OutputStream(int stream_id, std::string const &identifier, std::string const &alias, - std::string const ¬ify) : stream_id_(stream_id), identifier_(identifier), - alias_(alias), notify_(notify) {} +OutputStream::OutputStream(int stream_id, std::string const &identifier, + std::string const &alias, std::string const ¬ify) + : stream_id_(stream_id), identifier_(identifier), alias_(alias), + notify_(notify) {} - int OutputStream::add_mirror_stream(std::shared_ptr input_stream_manager, int stream_id) { - mirror_streams_.emplace_back(MirrorStream(input_stream_manager, stream_id)); - return 0; - } +int OutputStream::add_mirror_stream( + std::shared_ptr input_stream_manager, int stream_id) { + mirror_streams_.emplace_back(MirrorStream(input_stream_manager, stream_id)); + return 0; +} - int OutputStream::propagate_packets(std::shared_ptr > packets) { - for (auto &s:mirror_streams_) { - auto copy_queue = std::make_shared >(*packets.get()); - copy_queue->set_identifier(identifier_); - s.input_stream_manager_->add_packets(s.stream_id_, copy_queue); - } - return 0; +int OutputStream::propagate_packets( + std::shared_ptr> packets) { + for (auto &s : mirror_streams_) { + auto copy_queue = std::make_shared>(*packets.get()); + copy_queue->set_identifier(identifier_); + s.input_stream_manager_->add_packets(s.stream_id_, copy_queue); } - int OutputStream::add_upstream_nodes(int node_id) { - for (auto &s:mirror_streams_) { - s.input_stream_manager_->add_upstream_nodes(node_id); - } - return 0; + return 0; +} +int OutputStream::add_upstream_nodes(int node_id) { + for (auto &s : mirror_streams_) { + s.input_stream_manager_->add_upstream_nodes(node_id); } + return 0; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/output_stream_manager.cpp b/bmf/engine/c_engine/src/output_stream_manager.cpp index 7edb6a62..45ccad40 100644 --- a/bmf/engine/c_engine/src/output_stream_manager.cpp +++ b/bmf/engine/c_engine/src/output_stream_manager.cpp @@ -23,142 +23,156 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - OutputStreamManager::OutputStreamManager(std::vector output_streams) { - // Rearrange 'video' and 'audio' streams to 1st & 2nd positions. - // Notice that if 'video' or 'audio' appears at nor 1st or 2nd stream, it will not be rearranged. - if (output_streams.size() > 1 && output_streams[1].get_notify() == "video") - std::swap(output_streams[0], output_streams[1]); - - // Handling the situation that only an 'audio' stream exists, will force it to be the 2nd stream. - // An ugly patch, waiting for a better solution. - if (output_streams.size() ==1 && output_streams[0].get_notify() == "audio"){ - output_streams_[1] = std::make_shared(0, output_streams[0].get_identifier(), - output_streams[0].get_alias(), - output_streams[0].get_notify()); - stream_id_list_.push_back(1); - return; - } - - for (int i = 0; i < output_streams.size(); i++) { - output_streams_[i] = std::make_shared(i, output_streams[i].get_identifier(), - output_streams[i].get_alias(), - output_streams[i].get_notify()); - - stream_id_list_.push_back(i); - } - +USE_BMF_SDK_NS + +OutputStreamManager::OutputStreamManager( + std::vector output_streams) { + // Rearrange 'video' and 'audio' streams to 1st & 2nd positions. + // Notice that if 'video' or 'audio' appears at nor 1st or 2nd stream, it + // will not be rearranged. + if (output_streams.size() > 1 && output_streams[1].get_notify() == "video") + std::swap(output_streams[0], output_streams[1]); + + // Handling the situation that only an 'audio' stream exists, will force it + // to be the 2nd stream. + // An ugly patch, waiting for a better solution. + if (output_streams.size() == 1 && + output_streams[0].get_notify() == "audio") { + output_streams_[1] = std::make_shared( + 0, output_streams[0].get_identifier(), + output_streams[0].get_alias(), output_streams[0].get_notify()); + stream_id_list_.push_back(1); + return; } - int OutputStreamManager::post_process(Task &task) { - for (auto &t:task.outputs_queue_) { - auto q = std::make_shared >(t.second); - output_streams_[t.first]->propagate_packets(q); - } - return 0; - } + for (int i = 0; i < output_streams.size(); i++) { + output_streams_[i] = std::make_shared( + i, output_streams[i].get_identifier(), + output_streams[i].get_alias(), output_streams[i].get_notify()); - bool OutputStreamManager::get_stream(int stream_id, std::shared_ptr &output_stream) { - if (output_streams_.count(stream_id) > 0) { - output_stream = output_streams_[stream_id]; - return true; - } - return false; + stream_id_list_.push_back(i); } +} - int OutputStreamManager::propagate_packets(int stream_id, std::shared_ptr> packets) { - output_streams_[stream_id]->propagate_packets(packets); - return 0; +int OutputStreamManager::post_process(Task &task) { + for (auto &t : task.outputs_queue_) { + auto q = std::make_shared>(t.second); + output_streams_[t.first]->propagate_packets(q); } - - bool OutputStreamManager::any_of_downstream_full() { - for (auto &out_s : output_streams_) { - for (auto &mirror_stream:(out_s.second->mirror_streams_)) { - std::shared_ptr downstream; - if (mirror_stream.input_stream_manager_->node_id_ < 0) - continue; - mirror_stream.input_stream_manager_->get_stream(mirror_stream.stream_id_, downstream); - if (downstream->is_full()) { - return true; - } + return 0; +} + +bool OutputStreamManager::get_stream( + int stream_id, std::shared_ptr &output_stream) { + if (output_streams_.count(stream_id) > 0) { + output_stream = output_streams_[stream_id]; + return true; + } + return false; +} + +int OutputStreamManager::propagate_packets( + int stream_id, std::shared_ptr> packets) { + output_streams_[stream_id]->propagate_packets(packets); + return 0; +} + +bool OutputStreamManager::any_of_downstream_full() { + for (auto &out_s : output_streams_) { + for (auto &mirror_stream : (out_s.second->mirror_streams_)) { + std::shared_ptr downstream; + if (mirror_stream.input_stream_manager_->node_id_ < 0) + continue; + mirror_stream.input_stream_manager_->get_stream( + mirror_stream.stream_id_, downstream); + if (downstream->is_full()) { + return true; } } - return false; } - - std::vector OutputStreamManager::get_stream_id_list() { - return stream_id_list_; + return false; +} + +std::vector OutputStreamManager::get_stream_id_list() { + return stream_id_list_; +} + +int OutputStreamManager::add_stream(std::string name) { + int stream_id; + + max_id_ += 1; + stream_id = max_id_; + + output_streams_[stream_id] = + std::make_shared(stream_id, name); + stream_id_list_.push_back(stream_id); + + return stream_id; +} + +void OutputStreamManager::remove_stream(int stream_id, int mirror_id) { + int pos = -1; + for (int i = 0; i < output_streams_[stream_id]->mirror_streams_.size(); + i++) { + auto &mirror_stream = output_streams_[stream_id]->mirror_streams_[i]; + if (mirror_id == -1 || + mirror_stream.stream_id_ == + mirror_id) { //-1 means all the mirror will be removed + pos = i; + mirror_stream.input_stream_manager_->remove_stream( + mirror_stream.stream_id_); + break; + } } - int OutputStreamManager::add_stream(std::string name) { - int stream_id; - - max_id_ += 1; - stream_id = max_id_; - - output_streams_[stream_id] = std::make_shared(stream_id, name); - stream_id_list_.push_back(stream_id); + auto &mirror_s = output_streams_[stream_id]->mirror_streams_; - return stream_id; + if (mirror_id != -1 && pos != -1) { + mirror_s.erase(mirror_s.begin() + pos); + BMFLOG(BMF_INFO) << "output stream manager erase mirror id: " + << mirror_id << " in stream: " << stream_id; } - - void OutputStreamManager::remove_stream(int stream_id, int mirror_id) { - int pos = -1; - for (int i = 0; i < output_streams_[stream_id]->mirror_streams_.size(); i++) { - auto &mirror_stream = output_streams_[stream_id]->mirror_streams_[i]; - if (mirror_id == -1 || mirror_stream.stream_id_ == mirror_id) {//-1 means all the mirror will be removed - pos = i; - mirror_stream.input_stream_manager_->remove_stream(mirror_stream.stream_id_); + if (mirror_id == -1 || mirror_s.size() == 0) { + output_streams_.erase(stream_id); + int i; + for (i = 0; i < stream_id_list_.size(); i++) { + if (stream_id_list_[i] == stream_id) break; - } - } - - auto &mirror_s = output_streams_[stream_id]->mirror_streams_; - - if (mirror_id != -1 && pos != -1) { - mirror_s.erase(mirror_s.begin() + pos); - BMFLOG(BMF_INFO) << "output stream manager erase mirror id: " << mirror_id << " in stream: " - << stream_id; - } - if (mirror_id == -1 || mirror_s.size() == 0) { - output_streams_.erase(stream_id); - int i; - for (i = 0; i < stream_id_list_.size(); i++) { - if (stream_id_list_[i] == stream_id) - break; - } - stream_id_list_.erase(stream_id_list_.begin() + i); } - return; + stream_id_list_.erase(stream_id_list_.begin() + i); } - - void OutputStreamManager::wait_on_stream_empty(int stream_id) { - for (auto mirror_stream:output_streams_[stream_id]->mirror_streams_) - mirror_stream.input_stream_manager_->wait_on_stream_empty(mirror_stream.stream_id_); - } - - void OutputStreamManager::probe_eof() { - for (auto output_stream_iter = output_streams_.begin(); - output_stream_iter != output_streams_.end(); output_stream_iter++) { - for (auto mirror_stream:(output_stream_iter->second->mirror_streams_)) { - std::shared_ptr downstream; - mirror_stream.input_stream_manager_->get_stream(mirror_stream.stream_id_, downstream); - downstream->probe_eof(true); - } + return; +} + +void OutputStreamManager::wait_on_stream_empty(int stream_id) { + for (auto mirror_stream : output_streams_[stream_id]->mirror_streams_) + mirror_stream.input_stream_manager_->wait_on_stream_empty( + mirror_stream.stream_id_); +} + +void OutputStreamManager::probe_eof() { + for (auto output_stream_iter = output_streams_.begin(); + output_stream_iter != output_streams_.end(); output_stream_iter++) { + for (auto mirror_stream : + (output_stream_iter->second->mirror_streams_)) { + std::shared_ptr downstream; + mirror_stream.input_stream_manager_->get_stream( + mirror_stream.stream_id_, downstream); + downstream->probe_eof(true); } - return; } - - int OutputStreamManager::get_outlink_nodes_id(std::vector &nodes_id) { - std::map outlink_id; - for (auto output_stream_iter = output_streams_.begin(); - output_stream_iter != output_streams_.end(); output_stream_iter++) { - for (auto mirror_stream:(output_stream_iter->second->mirror_streams_)) - outlink_id[mirror_stream.input_stream_manager_->node_id_] = true; - } - for (auto it:outlink_id) - nodes_id.push_back(it.first); - return 0; + return; +} + +int OutputStreamManager::get_outlink_nodes_id(std::vector &nodes_id) { + std::map outlink_id; + for (auto output_stream_iter = output_streams_.begin(); + output_stream_iter != output_streams_.end(); output_stream_iter++) { + for (auto mirror_stream : (output_stream_iter->second->mirror_streams_)) + outlink_id[mirror_stream.input_stream_manager_->node_id_] = true; } + for (auto it : outlink_id) + nodes_id.push_back(it.first); + return 0; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/running_info_collector.cpp b/bmf/engine/c_engine/src/running_info_collector.cpp index ed89a538..4182bab8 100644 --- a/bmf/engine/c_engine/src/running_info_collector.cpp +++ b/bmf/engine/c_engine/src/running_info_collector.cpp @@ -22,263 +22,272 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - - bmf::GraphRunningInfo RunningInfoCollector::collect_graph_info(Graph *graph) { - //graph->pause_running(); - bmf::GraphRunningInfo graph_info; - // TODO: Not implemented. - graph_info.id = 0; - graph_info.mode = [](bmf_sdk::BmfMode mode) -> std::string { - switch (mode) { - case bmf_sdk::BmfMode::NORMAL_MODE: - return "Normal"; - case bmf_sdk::BmfMode::SERVER_MODE: - return "Server"; - case bmf_sdk::BmfMode::GENERATOR_MODE: - return "Generator"; - default: - return "UNKNOWN"; - } - }(graph->graph_config_.get_mode()); - // TODO: Not implemented. - graph_info.state = "UNKNOWN"; - graph_info.scheduler = collect_scheduler_info(graph->scheduler_.get()); - - for (auto &s:graph->input_streams_) { - std::vector tmp; - for (auto &os:s.second->manager_->output_streams_) - tmp.push_back(collect_output_stream_info(os.second.get())); - graph_info.input_streams.push_back(tmp); +USE_BMF_SDK_NS + +bmf::GraphRunningInfo RunningInfoCollector::collect_graph_info(Graph *graph) { + // graph->pause_running(); + bmf::GraphRunningInfo graph_info; + // TODO: Not implemented. + graph_info.id = 0; + graph_info.mode = [](bmf_sdk::BmfMode mode) -> std::string { + switch (mode) { + case bmf_sdk::BmfMode::NORMAL_MODE: + return "Normal"; + case bmf_sdk::BmfMode::SERVER_MODE: + return "Server"; + case bmf_sdk::BmfMode::GENERATOR_MODE: + return "Generator"; + default: + return "UNKNOWN"; } - - for (auto &s:graph->output_streams_) { - std::vector tmp; - for (auto &s:s.second->input_manager_->input_streams_) - tmp.push_back(collect_input_stream_info(s.second.get())); - graph_info.output_streams.push_back(tmp); - } - - for (auto &nd:graph->nodes_) - graph_info.nodes.push_back(collect_node_info(nd.second.get(), graph)); - - graph->resume_running(); - return graph_info; + }(graph->graph_config_.get_mode()); + // TODO: Not implemented. + graph_info.state = "UNKNOWN"; + graph_info.scheduler = collect_scheduler_info(graph->scheduler_.get()); + + for (auto &s : graph->input_streams_) { + std::vector tmp; + for (auto &os : s.second->manager_->output_streams_) + tmp.push_back(collect_output_stream_info(os.second.get())); + graph_info.input_streams.push_back(tmp); } - bmf::SchedulerInfo RunningInfoCollector::collect_scheduler_info(Scheduler *scheduler) { - bmf::SchedulerInfo scheduler_info; - scheduler_info.last_schedule_success_time = scheduler->last_schedule_success_time_; + for (auto &s : graph->output_streams_) { + std::vector tmp; + for (auto &s : s.second->input_manager_->input_streams_) + tmp.push_back(collect_input_stream_info(s.second.get())); + graph_info.output_streams.push_back(tmp); + } - for (auto &nd:scheduler->nodes_to_schedule_) { - bmf::SchedulerNodeInfo tmp; - tmp.id = uint64_t(nd.second.node_->id_); - tmp.last_scheduled_time = uint64_t(nd.second.last_scheduled_time_); - tmp.ref_count = uint64_t(nd.second.nodes_ref_cnt_); + for (auto &nd : graph->nodes_) + graph_info.nodes.push_back(collect_node_info(nd.second.get(), graph)); - scheduler_info.scheduler_nodes.push_back(tmp); - } - for (auto &q:scheduler->scheduler_queues_) - scheduler_info.scheduler_queues.push_back(collect_scheduler_queue_info(q.get())); + graph->resume_running(); + return graph_info; +} - return scheduler_info; - } +bmf::SchedulerInfo +RunningInfoCollector::collect_scheduler_info(Scheduler *scheduler) { + bmf::SchedulerInfo scheduler_info; + scheduler_info.last_schedule_success_time = + scheduler->last_schedule_success_time_; - bmf::SchedulerQueueInfo RunningInfoCollector::collect_scheduler_queue_info(SchedulerQueue *scheduler_q) { - bmf::SchedulerQueueInfo sq_info; - sq_info.id = scheduler_q->id_; - sq_info.queue_size = scheduler_q->queue_.size(); - // TODO: Not implemented. - sq_info.started_at = scheduler_q->start_time_; - - switch (scheduler_q->paused_state_) { - case State::INITED: - sq_info.state = "INITED"; - break; - case State::PAUSED: - sq_info.state = "PAUSED"; - break; - case State::RUNNING: - sq_info.state = "RUNNING"; - break; - case State::TERMINATED: - sq_info.state = "TERMINATED"; - break; - case State::TERMINATING: - sq_info.state = "TERMINATING"; - break; - default: - sq_info.state = std::to_string(int64_t(scheduler_q->paused_state_)) + " -> UNKNOWN"; - } - // PriorityQueue need buffer to store and push back later. - auto siz = scheduler_q->queue_.size(); - std::queue buf; - while (siz--) { - auto t = scheduler_q->pop_task(); - auto tmp = collect_task_info(&t.task); - tmp.priority = t.priority; - buf.push(t); - sq_info.tasks.push_back(tmp); - } - while (!buf.empty()) { - scheduler_q->add_task(buf.front().task, buf.front().priority); - buf.pop(); - } + for (auto &nd : scheduler->nodes_to_schedule_) { + bmf::SchedulerNodeInfo tmp; + tmp.id = uint64_t(nd.second.node_->id_); + tmp.last_scheduled_time = uint64_t(nd.second.last_scheduled_time_); + tmp.ref_count = uint64_t(nd.second.nodes_ref_cnt_); - return sq_info; + scheduler_info.scheduler_nodes.push_back(tmp); + } + for (auto &q : scheduler->scheduler_queues_) + scheduler_info.scheduler_queues.push_back( + collect_scheduler_queue_info(q.get())); + + return scheduler_info; +} + +bmf::SchedulerQueueInfo RunningInfoCollector::collect_scheduler_queue_info( + SchedulerQueue *scheduler_q) { + bmf::SchedulerQueueInfo sq_info; + sq_info.id = scheduler_q->id_; + sq_info.queue_size = scheduler_q->queue_.size(); + // TODO: Not implemented. + sq_info.started_at = scheduler_q->start_time_; + + switch (scheduler_q->paused_state_) { + case State::INITED: + sq_info.state = "INITED"; + break; + case State::PAUSED: + sq_info.state = "PAUSED"; + break; + case State::RUNNING: + sq_info.state = "RUNNING"; + break; + case State::TERMINATED: + sq_info.state = "TERMINATED"; + break; + case State::TERMINATING: + sq_info.state = "TERMINATING"; + break; + default: + sq_info.state = + std::to_string(int64_t(scheduler_q->paused_state_)) + " -> UNKNOWN"; + } + // PriorityQueue need buffer to store and push back later. + auto siz = scheduler_q->queue_.size(); + std::queue buf; + while (siz--) { + auto t = scheduler_q->pop_task(); + auto tmp = collect_task_info(&t.task); + tmp.priority = t.priority; + buf.push(t); + sq_info.tasks.push_back(tmp); + } + while (!buf.empty()) { + scheduler_q->add_task(buf.front().task, buf.front().priority); + buf.pop(); } - bmf::NodeRunningInfo RunningInfoCollector::collect_node_info(Node *node, Graph *graph) { - bmf::NodeRunningInfo node_info; - node_info.id = uint64_t(node->id_); - node_info.type = node->type_; - node_info.is_source = node->is_source_; - node_info.is_infinity = node->infinity_node_; - bmf::NodeModuleInfo module_info; - module_info.module_name = node->module_info_.module_name; - module_info.module_path = node->module_info_.module_path; - module_info.module_entry = node->module_info_.module_entry; - module_info.module_type = node->module_info_.module_type; - node_info.module_info = module_info; - node_info.max_pending_task = uint64_t(node->max_pending_tasks_); - node_info.pending_task = uint64_t(node->pending_tasks_); - node_info.task_processed = uint64_t(node->task_processed_cnt_); - node_info.input_manager_type = node->node_config_.get_input_manager() + " -> " + - node->input_stream_manager_->type(); - node_info.scheduler_queue = uint64_t(node->scheduler_queue_id_); - node_info.schedule_count = uint64_t(node->schedule_node_cnt_); - node_info.schedule_success_count = uint64_t(node->schedule_node_success_cnt_); - - switch (node->state_) { - case NodeState::NOT_INITED: - node_info.state = "NOT_INITED"; - break; - case NodeState::RUNNING: - node_info.state = "RUNNING"; - break; - case NodeState::PENDING: - node_info.state = "PENDING"; - break; - case NodeState::CLOSED: - node_info.state = "CLOSED"; - break; - default: - node_info.state = std::to_string(int64_t(node->state_)) + " -> UNKNOWN"; - } + return sq_info; +} + +bmf::NodeRunningInfo RunningInfoCollector::collect_node_info(Node *node, + Graph *graph) { + bmf::NodeRunningInfo node_info; + node_info.id = uint64_t(node->id_); + node_info.type = node->type_; + node_info.is_source = node->is_source_; + node_info.is_infinity = node->infinity_node_; + bmf::NodeModuleInfo module_info; + module_info.module_name = node->module_info_.module_name; + module_info.module_path = node->module_info_.module_path; + module_info.module_entry = node->module_info_.module_entry; + module_info.module_type = node->module_info_.module_type; + node_info.module_info = module_info; + node_info.max_pending_task = uint64_t(node->max_pending_tasks_); + node_info.pending_task = uint64_t(node->pending_tasks_); + node_info.task_processed = uint64_t(node->task_processed_cnt_); + node_info.input_manager_type = node->node_config_.get_input_manager() + + " -> " + node->input_stream_manager_->type(); + node_info.scheduler_queue = uint64_t(node->scheduler_queue_id_); + node_info.schedule_count = uint64_t(node->schedule_node_cnt_); + node_info.schedule_success_count = + uint64_t(node->schedule_node_success_cnt_); + + switch (node->state_) { + case NodeState::NOT_INITED: + node_info.state = "NOT_INITED"; + break; + case NodeState::RUNNING: + node_info.state = "RUNNING"; + break; + case NodeState::PENDING: + node_info.state = "PENDING"; + break; + case NodeState::CLOSED: + node_info.state = "CLOSED"; + break; + default: + node_info.state = std::to_string(int64_t(node->state_)) + " -> UNKNOWN"; + } - auto f = [](Graph *graph, uint64_t node_id, uint32_t stream_id) -> uint64_t { - if (graph == nullptr) - return INT_MAX; - for (auto &nd:graph->nodes_) - for (auto &os:nd.second->output_stream_manager_->output_streams_) - for (auto &is:os.second->mirror_streams_) - if (is.input_stream_manager_->node_id_ == node_id && is.stream_id_ == stream_id) - return nd.second->id_; + auto f = [](Graph *graph, uint64_t node_id, + uint32_t stream_id) -> uint64_t { + if (graph == nullptr) return INT_MAX; - }; - for (auto &s:node->input_stream_manager_->input_streams_) { - auto tmp = collect_input_stream_info(s.second.get()); - tmp.prev_id = f(graph, node->id_, s.first); - node_info.input_streams.push_back(tmp); - } - for (auto &s:node->output_stream_manager_->output_streams_) { - auto tmp = collect_output_stream_info(s.second.get()); - tmp.prev_id = node->id_; - for (auto &s:tmp.down_streams) - s.prev_id = node->id_; - node_info.output_streams.push_back(tmp); - } - - return node_info; + for (auto &nd : graph->nodes_) + for (auto &os : nd.second->output_stream_manager_->output_streams_) + for (auto &is : os.second->mirror_streams_) + if (is.input_stream_manager_->node_id_ == node_id && + is.stream_id_ == stream_id) + return nd.second->id_; + return INT_MAX; + }; + for (auto &s : node->input_stream_manager_->input_streams_) { + auto tmp = collect_input_stream_info(s.second.get()); + tmp.prev_id = f(graph, node->id_, s.first); + node_info.input_streams.push_back(tmp); } - - bmf::InputStreamInfo RunningInfoCollector::collect_input_stream_info(InputStream *stream) { - bmf::InputStreamInfo s_info; - s_info.id = uint64_t(stream->stream_id_); - s_info.prev_id = INT_MAX; - s_info.nex_id = uint64_t(stream->node_id_); - s_info.name = stream->identifier_; - s_info.max_size = uint64_t(stream->max_queue_size_); - s_info.size = uint64_t(stream->queue_->size()); - - auto siz = stream->queue_->size(); - while (siz--) { - Packet tmp; - stream->queue_->pop(tmp); - s_info.packets.push_back(collect_packet_info(&tmp)); - stream->queue_->push(tmp); - } - - return s_info; + for (auto &s : node->output_stream_manager_->output_streams_) { + auto tmp = collect_output_stream_info(s.second.get()); + tmp.prev_id = node->id_; + for (auto &s : tmp.down_streams) + s.prev_id = node->id_; + node_info.output_streams.push_back(tmp); } - bmf::OutputStreamInfo RunningInfoCollector::collect_output_stream_info(OutputStream *stream) { - bmf::OutputStreamInfo s_info; - s_info.id = uint64_t(stream->stream_id_); - s_info.name = stream->identifier_; - - for (auto &s:stream->mirror_streams_) - s_info.down_streams.push_back( - collect_input_stream_info(s.input_stream_manager_->input_streams_[s.stream_id_].get())); - - return s_info; + return node_info; +} + +bmf::InputStreamInfo +RunningInfoCollector::collect_input_stream_info(InputStream *stream) { + bmf::InputStreamInfo s_info; + s_info.id = uint64_t(stream->stream_id_); + s_info.prev_id = INT_MAX; + s_info.nex_id = uint64_t(stream->node_id_); + s_info.name = stream->identifier_; + s_info.max_size = uint64_t(stream->max_queue_size_); + s_info.size = uint64_t(stream->queue_->size()); + + auto siz = stream->queue_->size(); + while (siz--) { + Packet tmp; + stream->queue_->pop(tmp); + s_info.packets.push_back(collect_packet_info(&tmp)); + stream->queue_->push(tmp); } - bmf::TaskInfo RunningInfoCollector::collect_task_info(Task *task) { - bmf::TaskInfo task_info; - task_info.node_id = uint64_t(task->node_id_); - task_info.priority = 0; - - switch (int64_t(task->timestamp_)) { - case -1: - task_info.timestamp = "UNSET"; - break; - case 9223372036854775802: - task_info.timestamp = "BMF_PAUSE"; - break; - case 9223372036854775804: - task_info.timestamp = "BMF_EOF"; - break; - case 9223372036854775805: - task_info.timestamp = "EOS"; - break; - case 9223372036854775806: - task_info.timestamp = "INF_SRC"; - break; - case 9223372036854775807: - task_info.timestamp = "DONE"; - break; - default: - task_info.timestamp = std::to_string(int64_t(task->timestamp_)); - } + return s_info; +} + +bmf::OutputStreamInfo +RunningInfoCollector::collect_output_stream_info(OutputStream *stream) { + bmf::OutputStreamInfo s_info; + s_info.id = uint64_t(stream->stream_id_); + s_info.name = stream->identifier_; + + for (auto &s : stream->mirror_streams_) + s_info.down_streams.push_back(collect_input_stream_info( + s.input_stream_manager_->input_streams_[s.stream_id_].get())); + + return s_info; +} + +bmf::TaskInfo RunningInfoCollector::collect_task_info(Task *task) { + bmf::TaskInfo task_info; + task_info.node_id = uint64_t(task->node_id_); + task_info.priority = 0; + + switch (int64_t(task->timestamp_)) { + case -1: + task_info.timestamp = "UNSET"; + break; + case 9223372036854775802: + task_info.timestamp = "BMF_PAUSE"; + break; + case 9223372036854775804: + task_info.timestamp = "BMF_EOF"; + break; + case 9223372036854775805: + task_info.timestamp = "EOS"; + break; + case 9223372036854775806: + task_info.timestamp = "INF_SRC"; + break; + case 9223372036854775807: + task_info.timestamp = "DONE"; + break; + default: + task_info.timestamp = std::to_string(int64_t(task->timestamp_)); + } - for (auto &s:task->outputs_queue_) - task_info.output_streams.push_back(s.first); - for (auto &s:task->inputs_queue_) { - bmf::TaskStreamInfo ts_info = { - .id=uint64_t(s.first) - }; - auto siz = s.second->size(); - while (siz--) { - auto tmp = s.second->front(); - s.second->pop(); - ts_info.packets.push_back(collect_packet_info(&tmp)); - s.second->push(tmp); - } - task_info.input_streams.push_back(ts_info); + for (auto &s : task->outputs_queue_) + task_info.output_streams.push_back(s.first); + for (auto &s : task->inputs_queue_) { + bmf::TaskStreamInfo ts_info = {.id = uint64_t(s.first)}; + auto siz = s.second->size(); + while (siz--) { + auto tmp = s.second->front(); + s.second->pop(); + ts_info.packets.push_back(collect_packet_info(&tmp)); + s.second->push(tmp); } - - return task_info; + task_info.input_streams.push_back(ts_info); } - bmf::PacketInfo RunningInfoCollector::collect_packet_info(Packet *packet) { - bmf::PacketInfo packet_info; - packet_info.timestamp = packet->timestamp(); - packet_info.class_name = packet->type_info().name; - packet_info.class_type = packet->type_info().name; - packet_info.data_type = "UNSET"; + return task_info; +} - return packet_info; - } +bmf::PacketInfo RunningInfoCollector::collect_packet_info(Packet *packet) { + bmf::PacketInfo packet_info; + packet_info.timestamp = packet->timestamp(); + packet_info.class_name = packet->type_info().name; + packet_info.class_type = packet->type_info().name; + packet_info.data_type = "UNSET"; + + return packet_info; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/scheduler.cpp b/bmf/engine/c_engine/src/scheduler.cpp index 61e23939..77fb09ce 100644 --- a/bmf/engine/c_engine/src/scheduler.cpp +++ b/bmf/engine/c_engine/src/scheduler.cpp @@ -22,266 +22,289 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS +USE_BMF_SDK_NS - NodeItem::NodeItem(std::shared_ptr node) : node_(node) { - last_scheduled_time_ = 0; - nodes_ref_cnt_ = 0; - } +NodeItem::NodeItem(std::shared_ptr node) : node_(node) { + last_scheduled_time_ = 0; + nodes_ref_cnt_ = 0; +} - Scheduler::Scheduler(SchedulerCallBack callback, int scheduler_cnt, double time_out) { - thread_quit_ = false; - callback_ = callback; - SchedulerQueueCallBack scheduler_queue_callback; - scheduler_queue_callback.get_node_ = callback.get_node_; - scheduler_queue_callback.exception_ = [this](int node_id) -> int { - int scheduler_queue_id; - std::shared_ptr node = NULL; - std::shared_ptr scheduler_queue; - this->callback_.get_node_(node_id, node); - if (!node) { - BMFLOG(BMF_ERROR) << "node id incorrect in schedule:" << node_id; - return -1; - } - scheduler_queue_id = node->get_scheduler_queue_id(); - scheduler_queue = this->scheduler_queues_[scheduler_queue_id]; - if (scheduler_queue->exception_catch_flag_) { - exception_flag_ = true; - eptr_ = scheduler_queue->eptr_; - } - for (int i = 0; i < this->scheduler_queues_.size(); i++) - this->scheduler_queues_[i]->exception_catch_flag_ = true; - - this->callback_.close_report_(node_id, true); - return 0; - }; - for (int i = 0; i < scheduler_cnt; i++) { - std::shared_ptr scheduler_queue = std::make_shared( - i, scheduler_queue_callback); - scheduler_queues_.push_back(scheduler_queue); +Scheduler::Scheduler(SchedulerCallBack callback, int scheduler_cnt, + double time_out) { + thread_quit_ = false; + callback_ = callback; + SchedulerQueueCallBack scheduler_queue_callback; + scheduler_queue_callback.get_node_ = callback.get_node_; + scheduler_queue_callback.exception_ = [this](int node_id) -> int { + int scheduler_queue_id; + std::shared_ptr node = NULL; + std::shared_ptr scheduler_queue; + this->callback_.get_node_(node_id, node); + if (!node) { + BMFLOG(BMF_ERROR) << "node id incorrect in schedule:" << node_id; + return -1; } - time_out_ = time_out; - } - - int Scheduler::start() { - for (int i = 0; i < scheduler_queues_.size(); i++) { - scheduler_queues_[i]->start(); + scheduler_queue_id = node->get_scheduler_queue_id(); + scheduler_queue = this->scheduler_queues_[scheduler_queue_id]; + if (scheduler_queue->exception_catch_flag_) { + exception_flag_ = true; + eptr_ = scheduler_queue->eptr_; } - if (time_out_ > 0) - guard_thread_ = std::thread(&Scheduler::alive_watch, this); + for (int i = 0; i < this->scheduler_queues_.size(); i++) + this->scheduler_queues_[i]->exception_catch_flag_ = true; + this->callback_.close_report_(node_id, true); return 0; + }; + for (int i = 0; i < scheduler_cnt; i++) { + std::shared_ptr scheduler_queue = + std::make_shared(i, scheduler_queue_callback); + scheduler_queues_.push_back(scheduler_queue); } + time_out_ = time_out; +} - int Scheduler::close() { - for (int i = 0; i < scheduler_queues_.size(); i++) { - scheduler_queues_[i]->close(); - } - if (time_out_ > 0) { - thread_quit_ = true; - guard_thread_.join(); - } - - BMFLOG(BMF_INFO) << "all scheduling threads were joint"; - return 0; +int Scheduler::start() { + for (int i = 0; i < scheduler_queues_.size(); i++) { + scheduler_queues_[i]->start(); } + if (time_out_ > 0) + guard_thread_ = std::thread(&Scheduler::alive_watch, this); - void Scheduler::pause() { - paused_ = true; - for (auto &q: scheduler_queues_) - q->pause(); - } + return 0; +} - void Scheduler::resume() { - for (auto &q: scheduler_queues_) - q->resume(); - paused_ = false; +int Scheduler::close() { + for (int i = 0; i < scheduler_queues_.size(); i++) { + scheduler_queues_[i]->close(); + } + if (time_out_ > 0) { + thread_quit_ = true; + guard_thread_.join(); } - int Scheduler::add_or_remove_node(int node_id, bool is_add) { - node_mutex_.lock(); - bool notify_needed = false; - if (nodes_to_schedule_.size() == 0) - notify_needed = true; -// BMFLOG(BMF_INFO)<<"add or remove node :"< node = NULL; - callback_.get_node_(node_id, node); - if (node != NULL) { - if (is_add) { - if (nodes_to_schedule_.count(node_id) > 0) { - nodes_to_schedule_[node_id].nodes_ref_cnt_++; - } else { - nodes_to_schedule_[node_id] = NodeItem(node); - nodes_to_schedule_[node_id].nodes_ref_cnt_++; - } - //printf("DEBUG, node %d refcnt is: %d\n", node_id, nodes_to_schedule_[node_id].nodes_ref_cnt_); + BMFLOG(BMF_INFO) << "all scheduling threads were joint"; + return 0; +} + +void Scheduler::pause() { + paused_ = true; + for (auto &q : scheduler_queues_) + q->pause(); +} + +void Scheduler::resume() { + for (auto &q : scheduler_queues_) + q->resume(); + paused_ = false; +} + +int Scheduler::add_or_remove_node(int node_id, bool is_add) { + node_mutex_.lock(); + bool notify_needed = false; + if (nodes_to_schedule_.size() == 0) + notify_needed = true; + // BMFLOG(BMF_INFO)<<"add or remove node :"< node = NULL; + callback_.get_node_(node_id, node); + if (node != NULL) { + if (is_add) { + if (nodes_to_schedule_.count(node_id) > 0) { + nodes_to_schedule_[node_id].nodes_ref_cnt_++; } else { - if (nodes_to_schedule_.count(node_id) > 0) { - if (nodes_to_schedule_[node_id].nodes_ref_cnt_ > 0) { - nodes_to_schedule_[node_id].nodes_ref_cnt_--; - } - //printf("DEBUG, node %d refcnt is: %d\n", node_id, nodes_to_schedule_[node_id].nodes_ref_cnt_); - if (nodes_to_schedule_[node_id].nodes_ref_cnt_ == 0) { - nodes_to_schedule_.erase(node_id); - } + nodes_to_schedule_[node_id] = NodeItem(node); + nodes_to_schedule_[node_id].nodes_ref_cnt_++; + } + // printf("DEBUG, node %d refcnt is: %d\n", node_id, + // nodes_to_schedule_[node_id].nodes_ref_cnt_); + } else { + if (nodes_to_schedule_.count(node_id) > 0) { + if (nodes_to_schedule_[node_id].nodes_ref_cnt_ > 0) { + nodes_to_schedule_[node_id].nodes_ref_cnt_--; + } + // printf("DEBUG, node %d refcnt is: %d\n", node_id, + // nodes_to_schedule_[node_id].nodes_ref_cnt_); + if (nodes_to_schedule_[node_id].nodes_ref_cnt_ == 0) { + nodes_to_schedule_.erase(node_id); } } } - //printf("DEBUG: nodes to scheduler size: %d\n", nodes_to_schedule_.size()); + } + // printf("DEBUG: nodes to scheduler size: %d\n", + // nodes_to_schedule_.size()); - if (is_add) { - int64_t start_time = clock(); - std::shared_ptr sched_node = NULL; - choose_node_schedule(start_time, sched_node); - if (sched_node && - ((sched_node->is_source() && !sched_node->any_of_downstream_full()) || - (!sched_node->is_source() && !sched_node->too_many_tasks_pending()))) { - //if (nodes_to_schedule_.size() > 0 && notify_needed) { - //printf("DEBUG: add node %d and notify all, sched list size: %d\n", sched_node->get_id(), nodes_to_schedule_.size()); - sched_node->pre_sched_num_++; - //sched_nodes_.push(sched_node); - to_schedule_queue(sched_node); - //std::lock_guard lk(sched_mutex_); - //sched_needed_.notify_one(); - //} - } + if (is_add) { + int64_t start_time = clock(); + std::shared_ptr sched_node = NULL; + choose_node_schedule(start_time, sched_node); + if (sched_node && ((sched_node->is_source() && + !sched_node->any_of_downstream_full()) || + (!sched_node->is_source() && + !sched_node->too_many_tasks_pending()))) { + // if (nodes_to_schedule_.size() > 0 && notify_needed) { + // printf("DEBUG: add node %d and notify all, sched list size: + // %d\n", sched_node->get_id(), nodes_to_schedule_.size()); + sched_node->pre_sched_num_++; + // sched_nodes_.push(sched_node); + to_schedule_queue(sched_node); + // std::lock_guard lk(sched_mutex_); + // sched_needed_.notify_one(); + //} } - node_mutex_.unlock(); - return 0; } + node_mutex_.unlock(); + return 0; +} - int Scheduler::sched_required(int node_id, bool is_closed) { - NodeItem final_node_item = NodeItem(); - bool got_node = false; - int scheduler_queue_id; - std::shared_ptr node = NULL; - std::shared_ptr scheduler_queue; +int Scheduler::sched_required(int node_id, bool is_closed) { + NodeItem final_node_item = NodeItem(); + bool got_node = false; + int scheduler_queue_id; + std::shared_ptr node = NULL; + std::shared_ptr scheduler_queue; - callback_.get_node_(node_id, node); - if (!node) { - BMFLOG(BMF_ERROR) << "node id incorrect in schedule:" << node_id; - return -1; - } - if (exception_flag_) - return 0; - if (is_closed) { - callback_.close_report_(node_id, false); - } else { - std::shared_ptr input_stream_manager; - node->get_input_stream_manager(input_stream_manager); - for (auto &node_id:input_stream_manager->upstream_nodes_) - sched_required(node_id, false); + callback_.get_node_(node_id, node); + if (!node) { + BMFLOG(BMF_ERROR) << "node id incorrect in schedule:" << node_id; + return -1; + } + if (exception_flag_) + return 0; + if (is_closed) { + callback_.close_report_(node_id, false); + } else { + std::shared_ptr input_stream_manager; + node->get_input_stream_manager(input_stream_manager); + for (auto &node_id : input_stream_manager->upstream_nodes_) + sched_required(node_id, false); - std::lock_guard lk(node->sched_mutex_); - if ((!node->too_many_tasks_pending() && !node->any_of_downstream_full())) { - node->pre_sched_num_++; - to_schedule_queue(node); - } + std::lock_guard lk(node->sched_mutex_); + if ((!node->too_many_tasks_pending() && + !node->any_of_downstream_full())) { + node->pre_sched_num_++; + to_schedule_queue(node); } - return 0; } + return 0; +} - bool Scheduler::choose_node_schedule(int64_t start_time, std::shared_ptr &node) { - node_mutex_.lock(); - NodeItem final_node_item = NodeItem(); - int node_id = -1; - for (auto node_item:nodes_to_schedule_) { - //if (node_item.second.node_->pre_sched_num_ <= 4) { - if (node_item.second.node_->is_source() && node_item.second.node_->any_of_downstream_full() && node_item.second.node_->too_many_tasks_pending()) { - if (node_item.second.node_->any_of_downstream_full()) - printf("DEBUG, node %d, choose the source node which is downstream full\n", node_item.first); - if (node_item.second.node_->too_many_tasks_pending()) - printf("DEBUG, node %d, choose the source node which is pending full\n", node_item.first); - node_id = -1; - continue; - } - if (!node_item.second.node_->is_source() && node_item.second.node_->too_many_tasks_pending() && node_item.second.node_->all_input_queue_empty()) { - node_id = -1; - continue; - } - //} else { - // printf("DEBUG, node %d pre sched number is full\n", node_item.first); - // continue; - //} - if (node_item.second.last_scheduled_time_ <= start_time) { - if (final_node_item.node_ == NULL) { +bool Scheduler::choose_node_schedule(int64_t start_time, + std::shared_ptr &node) { + node_mutex_.lock(); + NodeItem final_node_item = NodeItem(); + int node_id = -1; + for (auto node_item : nodes_to_schedule_) { + // if (node_item.second.node_->pre_sched_num_ <= 4) { + if (node_item.second.node_->is_source() && + node_item.second.node_->any_of_downstream_full() && + node_item.second.node_->too_many_tasks_pending()) { + if (node_item.second.node_->any_of_downstream_full()) + printf("DEBUG, node %d, choose the source node which is " + "downstream full\n", + node_item.first); + if (node_item.second.node_->too_many_tasks_pending()) + printf("DEBUG, node %d, choose the source node which is " + "pending full\n", + node_item.first); + node_id = -1; + continue; + } + if (!node_item.second.node_->is_source() && + node_item.second.node_->too_many_tasks_pending() && + node_item.second.node_->all_input_queue_empty()) { + node_id = -1; + continue; + } + //} else { + // printf("DEBUG, node %d pre sched number is full\n", + // node_item.first); + // continue; + //} + if (node_item.second.last_scheduled_time_ <= start_time) { + if (final_node_item.node_ == NULL) { + final_node_item = node_item.second; + node_id = node_item.second.node_->get_id(); + } else { + if (node_item.second.last_scheduled_time_ < + final_node_item.last_scheduled_time_) { final_node_item = node_item.second; node_id = node_item.second.node_->get_id(); - } else { - if (node_item.second.last_scheduled_time_ < final_node_item.last_scheduled_time_) { - final_node_item = node_item.second; - node_id = node_item.second.node_->get_id(); - } } } } + } - if (node_id != -1) { - nodes_to_schedule_[node_id].last_scheduled_time_ = clock(); - final_node_item.last_scheduled_time_ = clock(); - node = final_node_item.node_; - node_mutex_.unlock(); - return true; - } + if (node_id != -1) { + nodes_to_schedule_[node_id].last_scheduled_time_ = clock(); + final_node_item.last_scheduled_time_ = clock(); + node = final_node_item.node_; node_mutex_.unlock(); - return false; + return true; } + node_mutex_.unlock(); + return false; +} - int Scheduler::to_schedule_queue(std::shared_ptr node) { +int Scheduler::to_schedule_queue(std::shared_ptr node) { - if (node && node->wait_pause_) { - //break; - return 0; - } - if (node) { - node->pre_sched_num_--; - if (node->schedule_node()) { - last_schedule_success_time_ = clock(); - last_schedule_clk_ = std::chrono::steady_clock::now(); - } - } + if (node && node->wait_pause_) { + // break; return 0; } - - int Scheduler::schedule_node(Task &task) { - int node_id = task.node_id_; - std::shared_ptr node; - callback_.get_node_(node_id, node); - node->inc_pending_task(); - std::shared_ptr scheduler_queue; - int scheduler_queue_id = node->get_scheduler_queue_id(); - scheduler_queue = scheduler_queues_[scheduler_queue_id]; - // TODO: ??? Useless priority - scheduler_queue->add_task(task, 1); - return 0; + if (node) { + node->pre_sched_num_--; + if (node->schedule_node()) { + last_schedule_success_time_ = clock(); + last_schedule_clk_ = std::chrono::steady_clock::now(); + } } + return 0; +} - int Scheduler::clear_task(int node_id, int scheduler_queue_id) { - std::shared_ptr scheduler_queue = scheduler_queues_[scheduler_queue_id]; - scheduler_queue->remove_node_task(node_id); - return 0; - } +int Scheduler::schedule_node(Task &task) { + int node_id = task.node_id_; + std::shared_ptr node; + callback_.get_node_(node_id, node); + node->inc_pending_task(); + std::shared_ptr scheduler_queue; + int scheduler_queue_id = node->get_scheduler_queue_id(); + scheduler_queue = scheduler_queues_[scheduler_queue_id]; + // TODO: ??? Useless priority + scheduler_queue->add_task(task, 1); + return 0; +} - int Scheduler::alive_watch() { - std::chrono::duration time_span; - while (1) { - if (!thread_quit_) { - time_span = std::chrono::duration_cast>(std::chrono::steady_clock::now() - last_schedule_clk_); - if (time_span.count() >= time_out_) { - try { - BMF_Error(BMF_StsTimeOut, "No more task to be scheduled during 5 seconds"); - } catch (...) { - eptr_ = std::current_exception(); - for (int i = 0; i < scheduler_queues_.size(); i++) - scheduler_queues_[i]->exception_catch_flag_ = true; - callback_.close_report_(-1, true); - break; - } +int Scheduler::clear_task(int node_id, int scheduler_queue_id) { + std::shared_ptr scheduler_queue = + scheduler_queues_[scheduler_queue_id]; + scheduler_queue->remove_node_task(node_id); + return 0; +} + +int Scheduler::alive_watch() { + std::chrono::duration time_span; + while (1) { + if (!thread_quit_) { + time_span = + std::chrono::duration_cast>( + std::chrono::steady_clock::now() - last_schedule_clk_); + if (time_span.count() >= time_out_) { + try { + BMF_Error(BMF_StsTimeOut, + "No more task to be scheduled during 5 seconds"); + } catch (...) { + eptr_ = std::current_exception(); + for (int i = 0; i < scheduler_queues_.size(); i++) + scheduler_queues_[i]->exception_catch_flag_ = true; + callback_.close_report_(-1, true); + break; } - usleep(100000); - } else - break; - } - return 0; + } + usleep(100000); + } else + break; } + return 0; +} END_BMF_ENGINE_NS diff --git a/bmf/engine/c_engine/src/scheduler_queue.cpp b/bmf/engine/c_engine/src/scheduler_queue.cpp index d18f9e19..c0d356d1 100644 --- a/bmf/engine/c_engine/src/scheduler_queue.cpp +++ b/bmf/engine/c_engine/src/scheduler_queue.cpp @@ -21,161 +21,173 @@ #include BEGIN_BMF_ENGINE_NS - USE_BMF_SDK_NS - +USE_BMF_SDK_NS // TODO: Unused Item.priority - bool operator<(const Item &lhs, const Item &rhs) { - if (lhs.task.timestamp() > rhs.task.timestamp()) { +bool operator<(const Item &lhs, const Item &rhs) { + if (lhs.task.timestamp() > rhs.task.timestamp()) { + return true; + } else if (lhs.task.timestamp() == rhs.task.timestamp()) { + if (lhs.task.node_id_ > rhs.task.node_id_) return true; - } else if (lhs.task.timestamp() == rhs.task.timestamp()) { - if (lhs.task.node_id_ > rhs.task.node_id_) - return true; - } - return false; } + return false; +} - SchedulerQueue::SchedulerQueue(int id, SchedulerQueueCallBack callback) - : id_(id), callback_(callback), start_time_(0), state_(State::INITED) {} +SchedulerQueue::SchedulerQueue(int id, SchedulerQueueCallBack callback) + : id_(id), callback_(callback), start_time_(0), state_(State::INITED) {} - Item SchedulerQueue::pop_task() { - Item item; - queue_.pop(item); - return item; - } +Item SchedulerQueue::pop_task() { + Item item; + queue_.pop(item); + return item; +} - int SchedulerQueue::add_task(Task &task, int priority) { - if (state_ == State::TERMINATED) - return false; - if (task.timestamp_ != UNSET) { - std::lock_guard guard(con_var_mutex_); - Item item = Item(priority, task); - queue_.push(item); - con_var_.notify_one(); - return true; - } +int SchedulerQueue::add_task(Task &task, int priority) { + if (state_ == State::TERMINATED) return false; + if (task.timestamp_ != UNSET) { + std::lock_guard guard(con_var_mutex_); + Item item = Item(priority, task); + queue_.push(item); + con_var_.notify_one(); + return true; } + return false; +} - int SchedulerQueue::remove_node_task(int node_id){ - std::lock_guard guard(con_var_mutex_); - SafePriorityQueue temp_queue; - while (!queue_.empty()){ - Item item; - queue_.pop(item); - if (item.task.node_id_ != node_id){ - temp_queue.push(item); - } - } - while (!temp_queue.empty()){ - Item item; - temp_queue.pop(item); - queue_.push(item); +int SchedulerQueue::remove_node_task(int node_id) { + std::lock_guard guard(con_var_mutex_); + SafePriorityQueue temp_queue; + while (!queue_.empty()) { + Item item; + queue_.pop(item); + if (item.task.node_id_ != node_id) { + temp_queue.push(item); } - return 0; } - - int SchedulerQueue::exec_loop() { - while (true) { - if (paused_) - internal_pause(); - if (state_ == State::TERMINATING and queue_.empty() || exception_catch_flag_) { - break; - } - { - std::unique_lock lk(con_var_mutex_); - if (queue_.empty() and state_ != State::TERMINATING) { - wait_cnt_++; - int64_t startts; - BMF_TRACE(SCHEDULE, ("THREAD_" + std::to_string(id_) + "_WAIT" + "_" + std::to_string(wait_cnt_)).c_str(), START); - startts = clock(); - con_var_.wait(lk, [this] { return this->state_ == State::TERMINATING || !this->queue_.empty(); }); - wait_duration_ += (clock() - startts); - BMF_TRACE(SCHEDULE, ("THREAD_" + std::to_string(id_) + "_WAIT"+ "_" + std::to_string(wait_cnt_)).c_str(), END); - } + while (!temp_queue.empty()) { + Item item; + temp_queue.pop(item); + queue_.push(item); + } + return 0; +} + +int SchedulerQueue::exec_loop() { + while (true) { + if (paused_) + internal_pause(); + if (state_ == State::TERMINATING and queue_.empty() || + exception_catch_flag_) { + break; + } + { + std::unique_lock lk(con_var_mutex_); + if (queue_.empty() and state_ != State::TERMINATING) { + wait_cnt_++; + int64_t startts; + BMF_TRACE(SCHEDULE, ("THREAD_" + std::to_string(id_) + "_WAIT" + + "_" + std::to_string(wait_cnt_)) + .c_str(), + START); + startts = clock(); + con_var_.wait(lk, [this] { + return this->state_ == State::TERMINATING || + !this->queue_.empty(); + }); + wait_duration_ += (clock() - startts); + BMF_TRACE(SCHEDULE, ("THREAD_" + std::to_string(id_) + "_WAIT" + + "_" + std::to_string(wait_cnt_)) + .c_str(), + END); } - Item item; - while (queue_.pop(item)) { - try { - exec(item.task); - } catch(...) { - exception_catch_flag_ = true; - this->eptr_ = std::current_exception(); - callback_.exception_(item.task.node_id_); - } - if (paused_) - internal_pause(); + } + Item item; + while (queue_.pop(item)) { + try { + exec(item.task); + } catch (...) { + exception_catch_flag_ = true; + this->eptr_ = std::current_exception(); + callback_.exception_(item.task.node_id_); } + if (paused_) + internal_pause(); } - BMFLOG(BMF_INFO) << "schedule queue " << id_ << " thread quit"; - return 0; } - - void SchedulerQueue::internal_pause() { - paused_state_ = state_; - state_ = State::PAUSED; - while (paused_) + BMFLOG(BMF_INFO) << "schedule queue " << id_ << " thread quit"; + return 0; +} + +void SchedulerQueue::internal_pause() { + paused_state_ = state_; + state_ = State::PAUSED; + while (paused_) + usleep(1000); +} + +void SchedulerQueue::pause() { + paused_ = true; + if (state_ == State::RUNNING) + while (state_ != State::PAUSED) usleep(1000); - } - - void SchedulerQueue::pause() { - paused_ = true; - if (state_ == State::RUNNING) - while (state_ != State::PAUSED) - usleep(1000); - } - - void SchedulerQueue::resume() { - if (state_ == State::PAUSED) - state_ = paused_state_; - paused_ = false; - } - - int SchedulerQueue::exec(Task &task) { - std::shared_ptr node; - callback_.get_node_(task.node_id_, node); -// std::cout << "Working on " << task.node_id_ << std::endl; -// for (const auto &it:task.get_inputs()) -// std::cout << "input queue id=" << it.first << " task packet count " << it.second->size() << std::endl; - auto st = TIMENOW(); - node->process_node(task); - node->dur += DURATION(TIMENOW() - st); -// std::cout << "Work done for" << task.node_id_ << std::endl; -// for (const auto &it:task.get_outputs()) -// std::cout << "output queue id=" << it.first << " task packet count " << it.second->size() << std::endl; - return 0; - } - - int SchedulerQueue::start() { - state_ = State::RUNNING; - exec_thread_ = std::thread(&SchedulerQueue::exec_loop, this); - auto handle = exec_thread_.native_handle(); - std::string thread_name = "schedule_queue"+std::to_string(id_); +} + +void SchedulerQueue::resume() { + if (state_ == State::PAUSED) + state_ = paused_state_; + paused_ = false; +} + +int SchedulerQueue::exec(Task &task) { + std::shared_ptr node; + callback_.get_node_(task.node_id_, node); + // std::cout << "Working on " << task.node_id_ << std::endl; + // for (const auto &it:task.get_inputs()) + // std::cout << "input queue id=" << it.first << " task packet + // count " << it.second->size() << std::endl; + auto st = TIMENOW(); + node->process_node(task); + node->dur += DURATION(TIMENOW() - st); + // std::cout << "Work done for" << task.node_id_ << std::endl; + // for (const auto &it:task.get_outputs()) + // std::cout << "output queue id=" << it.first << " task packet + // count " << it.second->size() << std::endl; + return 0; +} + +int SchedulerQueue::start() { + state_ = State::RUNNING; + exec_thread_ = std::thread(&SchedulerQueue::exec_loop, this); + auto handle = exec_thread_.native_handle(); + std::string thread_name = "schedule_queue" + std::to_string(id_); #if __APPLE__ - pthread_setname_np(thread_name.c_str()); + pthread_setname_np(thread_name.c_str()); #else - pthread_setname_np(handle,thread_name.c_str()); + pthread_setname_np(handle, thread_name.c_str()); #endif - return 0; - } + return 0; +} - int SchedulerQueue::close() { - BMFLOG(BMF_INFO) << "schedule queue " << id_ << " start to join thread"; - if (state_ != State::TERMINATED and exec_thread_.joinable()) { - { - std::lock_guard guard(con_var_mutex_); - state_ = State::TERMINATING; - //con_var_ should notify ,otherwise it will block in con_var_.wait() - con_var_.notify_one(); - } - exec_thread_.join(); - state_ = State::TERMINATED; +int SchedulerQueue::close() { + BMFLOG(BMF_INFO) << "schedule queue " << id_ << " start to join thread"; + if (state_ != State::TERMINATED and exec_thread_.joinable()) { + { + std::lock_guard guard(con_var_mutex_); + state_ = State::TERMINATING; + // con_var_ should notify ,otherwise it will block in + // con_var_.wait() + con_var_.notify_one(); } - double duration = (double) wait_duration_ / CLOCKS_PER_SEC; - //BMFLOG(BMF_INFO) << "DEBUG, scheduler queue " << id_ << " wait time " << duration << ", wait cnt " << wait_cnt_; - BMFLOG(BMF_INFO) << "schedule queue " << id_ << " closed"; - return 0; + exec_thread_.join(); + state_ = State::TERMINATED; } + double duration = (double)wait_duration_ / CLOCKS_PER_SEC; + // BMFLOG(BMF_INFO) << "DEBUG, scheduler queue " << id_ << " wait time " << + // duration << ", wait cnt " << wait_cnt_; + BMFLOG(BMF_INFO) << "schedule queue " << id_ << " closed"; + return 0; +} END_BMF_ENGINE_NS - diff --git a/bmf/engine/c_engine/test/call_back_for_test.cpp b/bmf/engine/c_engine/test/call_back_for_test.cpp index fa477edc..34e7977a 100644 --- a/bmf/engine/c_engine/test/call_back_for_test.cpp +++ b/bmf/engine/c_engine/test/call_back_for_test.cpp @@ -17,12 +17,16 @@ #include "call_back_for_test.h" CallBackForTest::CallBackForTest() { - callback_add_or_remove_node_ = std::bind(&CallBackForTest::add_or_remove_node, this, std::placeholders::_1, - std::placeholders::_2); - callback_node_to_schedule_node_ = std::bind(&CallBackForTest::node_to_schedule_node, this); - callback_scheduler_to_schedule_node_ = std::bind(&CallBackForTest::scheduler_to_schedule_node, this, - std::placeholders::_1); - callback_node_is_closed_cb_ = std::bind(&CallBackForTest::node_is_closed_cb, this); + callback_add_or_remove_node_ = + std::bind(&CallBackForTest::add_or_remove_node, this, + std::placeholders::_1, std::placeholders::_2); + callback_node_to_schedule_node_ = + std::bind(&CallBackForTest::node_to_schedule_node, this); + callback_scheduler_to_schedule_node_ = + std::bind(&CallBackForTest::scheduler_to_schedule_node, this, + std::placeholders::_1); + callback_node_is_closed_cb_ = + std::bind(&CallBackForTest::node_is_closed_cb, this); } void CallBackForTest::add_or_remove_node(int node_id, bool is_add) { @@ -39,6 +43,4 @@ bool CallBackForTest::node_to_schedule_node() { return true; } -bool CallBackForTest::node_is_closed_cb() { - return false; -} \ No newline at end of file +bool CallBackForTest::node_is_closed_cb() { return false; } \ No newline at end of file diff --git a/bmf/engine/c_engine/test/test_builder.cpp b/bmf/engine/c_engine/test/test_builder.cpp index 20ab2e21..368052e1 100644 --- a/bmf/engine/c_engine/test/test_builder.cpp +++ b/bmf/engine/c_engine/test/test_builder.cpp @@ -40,10 +40,12 @@ TEST(builder, decode_encode) { encoder_para["video_params"] = video_para; encoder_para["audio_params"] = audio_para; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); + auto graph = + bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); auto video = graph.Decode(bmf_sdk::JsonParam(decoder_para)); - graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encoder_para)); + graph.Encode(video["video"], video["audio"], + bmf_sdk::JsonParam(encoder_para)); std::cout << graph.Dump() << std::endl; graph.Run(); @@ -70,11 +72,13 @@ TEST(builder, decode_passthrough_encode) { encoder_para["video_params"] = video_para; encoder_para["audio_params"] = audio_para; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); + auto graph = + bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); auto video = graph.Decode(bmf_sdk::JsonParam(decoder_para)); - graph.Encode(video["video"].CppModule({}, "pass_through", bmf_sdk::JsonParam()), video["audio"], - bmf_sdk::JsonParam(encoder_para)); + graph.Encode( + video["video"].CppModule({}, "pass_through", bmf_sdk::JsonParam()), + video["audio"], bmf_sdk::JsonParam(encoder_para)); std::cout << graph.Dump() << std::endl; graph.Run(); @@ -100,7 +104,8 @@ TEST(builder, decode_filter_encode) { encoder_para["video_params"] = video_para; encoder_para["audio_params"] = audio_para; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); + auto graph = + bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam()); auto video = graph.Decode(bmf_sdk::JsonParam(decoder_para)); auto audio = video["audio"].Atrim("start=0:end=6"); @@ -109,10 +114,9 @@ TEST(builder, decode_filter_encode) { std::cout << graph.Dump() << std::endl; graph.Run(); - } -#if 0 //FIXME: need go module sdk support +#if 0 // FIXME: need go module sdk support TEST(builder, custom_module) { google::InitGoogleLogging("main"); google::SetStderrLogging(google::INFO); diff --git a/bmf/engine/c_engine/test/test_c_module.cpp b/bmf/engine/c_engine/test/test_c_module.cpp index 4dbaa8e1..c8a01ba1 100644 --- a/bmf/engine/c_engine/test/test_c_module.cpp +++ b/bmf/engine/c_engine/test/test_c_module.cpp @@ -1 +1 @@ -//TBD - remove it from v2.0 \ No newline at end of file +// TBD - remove it from v2.0 \ No newline at end of file diff --git a/bmf/engine/c_engine/test/test_go_module_loader.cpp b/bmf/engine/c_engine/test/test_go_module_loader.cpp index 6e1c5f09..339049e8 100644 --- a/bmf/engine/c_engine/test/test_go_module_loader.cpp +++ b/bmf/engine/c_engine/test/test_go_module_loader.cpp @@ -3,23 +3,21 @@ #include "module_factory.h" #include - #ifndef BMF_ENABLE_MOBILE using namespace bmf_engine; using namespace bmf_sdk; -TEST(go_module, module_loader) -{ +TEST(go_module, module_loader) { std::string module_name = "test_go_module"; - int node_id=42; + int node_id = 42; JsonParam option; std::string module_type; std::string module_path; std::string module_entry; std::shared_ptr module; - ModuleFactory::create_module(module_name,node_id,option,module_type,module_path,module_entry,module); + ModuleFactory::create_module(module_name, node_id, option, module_type, module_path, module_entry, module); EXPECT_EQ(module == nullptr, 0); // get module info @@ -36,12 +34,12 @@ TEST(go_module, module_loader) // EXPECT_THROW(module->reset(), std::runtime_error); - //process - std::vector iids{1, 2}, oids{2,3}; + // process + std::vector iids{1, 2}, oids{2, 3}; Task task(42, iids, oids); - //fill inputs - for(int i = 0; i < 10; ++i){ + // fill inputs + for (int i = 0; i < 10; ++i) { auto rgb = hmp::PixelInfo(hmp::PF_RGB24); auto vf0 = VideoFrame::make(1920, 1080, rgb); auto vf1 = VideoFrame::make(1280, 720, rgb); @@ -60,7 +58,7 @@ TEST(go_module, module_loader) EXPECT_EQ(task.timestamp(), Timestamp::DONE); - for(int i = 0; i < 10; ++i){ + for (int i = 0; i < 10; ++i) { Packet pkt; EXPECT_TRUE(task.pop_packet_from_out_queue(2, pkt)); auto vf0 = pkt.get(); @@ -74,4 +72,4 @@ TEST(go_module, module_loader) } } -#endif //BMF_ENABLE_MOBILE +#endif // BMF_ENABLE_MOBILE diff --git a/bmf/engine/c_engine/test/test_graph.cpp b/bmf/engine/c_engine/test/test_graph.cpp index 0ce08b5b..2c430e17 100644 --- a/bmf/engine/c_engine/test/test_graph.cpp +++ b/bmf/engine/c_engine/test/test_graph.cpp @@ -29,12 +29,12 @@ TEST(graph, start) { std::ifstream gs(config_file); gs >> graph_json; GraphConfig graph_config(graph_json); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules,callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); graph->start(); graph->close(); - } void SignalHandle2(const char *data, int size) { @@ -42,10 +42,10 @@ void SignalHandle2(const char *data, int size) { std::string str = std::string(data, size); fs << str; fs.close(); - + BMFLOG(BMF_ERROR) << str; } -//TEST(graph, decode){ +// TEST(graph, decode){ //// google::InitGoogleLogging("main"); // google::SetStderrLogging(google::INFO); // google::InstallFailureSignalHandler(); @@ -60,7 +60,8 @@ void SignalHandle2(const char *data, int size) { // std::string config_file = "../../files/decode_graph.json"; // GraphConfig graph_config(config_file); // std::map > pre_modules; -// std::shared_ptr graph = std::make_shared(graph_config, pre_modules); +// std::shared_ptr graph = std::make_shared(graph_config, +// pre_modules); // std::cout<<"init graph success"<> graph_json; GraphConfig graph_config(graph_json); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules,callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); std::cout << "init graph success" << std::endl; graph->start(); graph->close(); time_t time2 = clock(); std::cout << "time:" << time2 - time1 << std::endl; - } TEST(graph, c_decode_encode) { @@ -100,17 +101,17 @@ TEST(graph, c_decode_encode) { std::ifstream gs(config_file); gs >> graph_json; GraphConfig graph_config(graph_json); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules,callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); std::cout << "init graph success" << std::endl; -// PyEval_ReleaseThread(PyThreadState_Get()); + // PyEval_ReleaseThread(PyThreadState_Get()); graph->start(); graph->close(); time_t time2 = clock(); std::cout << "time:" << time2 - time1 << std::endl; - } TEST(graph, dynamic_add) { @@ -121,9 +122,10 @@ TEST(graph, dynamic_add) { std::string dyn_config_file = "../../files/dynamic_add.json"; GraphConfig graph_config(config_file); GraphConfig dyn_config(dyn_config_file); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules, callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); std::cout << "init graph success" << std::endl; graph->start(); @@ -135,7 +137,6 @@ TEST(graph, dynamic_add) { graph->close(); time_t time2 = clock(); std::cout << "time:" << time2 - time1 << std::endl; - } TEST(graph, dynamic_remove) { @@ -148,9 +149,10 @@ TEST(graph, dynamic_remove) { GraphConfig graph_config(config_file); GraphConfig dyn_add_config(dyn_add_config_file); GraphConfig dyn_remove_config(dyn_remove_config_file); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules, callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); std::cout << "init graph success" << std::endl; graph->start(); @@ -164,10 +166,9 @@ TEST(graph, dynamic_remove) { graph->update(dyn_remove_config); sleep(2); - graph->force_close();//here only the pass_through_module lefted + graph->force_close(); // here only the pass_through_module lefted time_t time2 = clock(); std::cout << "time:" << time2 - time1 << std::endl; - } TEST(graph, decode_filter_encode) { @@ -177,9 +178,10 @@ TEST(graph, decode_filter_encode) { std::ifstream gs(config_file); gs >> graph_json; GraphConfig graph_config(graph_json); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules,callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); graph->start(); graph->close(); } @@ -192,14 +194,15 @@ TEST(graph, c_decode_filter_encode) { std::ifstream gs(config_file); gs >> graph_json; GraphConfig graph_config(graph_json); - std::map > pre_modules; - std::map > callback_bindings; - std::shared_ptr graph = std::make_shared(graph_config, pre_modules,callback_bindings); + std::map> pre_modules; + std::map> callback_bindings; + std::shared_ptr graph = + std::make_shared(graph_config, pre_modules, callback_bindings); graph->start(); graph->close(); } -//TEST(graph, multi_process) { +// TEST(graph, multi_process) { // google::InitGoogleLogging("main"); // google::SetStderrLogging(google::INFO); // google::InstallFailureSignalHandler(); @@ -211,7 +214,8 @@ TEST(graph, c_decode_filter_encode) { // std::string config_file = "../../files/multi.json"; // GraphConfig graph_config(config_file); // std::map > pre_modules; -// std::shared_ptr graph = std::make_shared(graph_config, pre_modules); +// std::shared_ptr graph = std::make_shared(graph_config, +// pre_modules); // graph->start(); // graph->close(); // std::cout<<"close graph*******"<> graph_json; GraphConfig graph_config(graph_json); - EXPECT_EQ(graph_config.get_nodes()[0].get_module_info().module_name, "c_ffmpeg_decoder"); -} + EXPECT_EQ(graph_config.get_nodes()[0].get_module_info().module_name, + "c_ffmpeg_decoder"); +} \ No newline at end of file diff --git a/bmf/engine/c_engine/test/test_input_stream.cpp b/bmf/engine/c_engine/test/test_input_stream.cpp index d243cafd..a4c29247 100644 --- a/bmf/engine/c_engine/test/test_input_stream.cpp +++ b/bmf/engine/c_engine/test/test_input_stream.cpp @@ -14,10 +14,13 @@ TEST(input_stream, add_normal_packets) { int max_queue_size = 5; int node_id = 1; CallBackForTest call_back; - std::function throttled_cb = call_back.callback_add_or_remove_node_; - InputStream input_stream = InputStream(stream_id, name, "", "", node_id, throttled_cb, max_queue_size); -// SafeQueue packets; - std::shared_ptr > packets = std::make_shared >(); + std::function throttled_cb = + call_back.callback_add_or_remove_node_; + InputStream input_stream = InputStream(stream_id, name, "", "", node_id, + throttled_cb, max_queue_size); + // SafeQueue packets; + std::shared_ptr> packets = + std::make_shared>(); Packet pkt(0); pkt.set_timestamp(10); packets->push(pkt); @@ -28,16 +31,19 @@ TEST(input_stream, add_normal_packets) { } // no need run this test for new engine -//TEST(input_stream, add_eof_packets) { +// TEST(input_stream, add_eof_packets) { // // int stream_id = 1; // std::string name = "video"; // int max_queue_size = 5; // int node_id = 1; // CallBackForTest call_back; -// std::function throttled_cb = call_back.callback_add_or_remove_node_; -// InputStream input_stream = InputStream(stream_id, name, "", "", node_id, throttled_cb, max_queue_size); -// std::shared_ptr > packets = std::make_shared >(); +// std::function throttled_cb = +// call_back.callback_add_or_remove_node_; +// InputStream input_stream = InputStream(stream_id, name, "", "", node_id, +// throttled_cb, max_queue_size); +// std::shared_ptr > packets = +// std::make_shared >(); // Packet pkt; // pkt.set_timestamp(10); // packets->push(pkt); @@ -49,19 +55,20 @@ TEST(input_stream, add_normal_packets) { // EXPECT_EQ(call_back.is_add_, 1); //} -TEST(input_stream, pop_packet_at_timestamp) { +TEST(input_stream, pop_packet_at_timestamp) {} -} - -//TEST(input_stream, pop_next_packet) { +// TEST(input_stream, pop_next_packet) { // int stream_id = 1; // std::string name = "video"; // int max_queue_size = 5; // int node_id = 1; // CallBackForTest call_back; -// std::function throttled_cb = call_back.callback_add_or_remove_node_; -// InputStream input_stream = InputStream(stream_id, name, "", "", node_id, throttled_cb, max_queue_size); -// std::shared_ptr > packets = std::make_shared >(); +// std::function throttled_cb = +// call_back.callback_add_or_remove_node_; +// InputStream input_stream = InputStream(stream_id, name, "", "", node_id, +// throttled_cb, max_queue_size); +// std::shared_ptr > packets = +// std::make_shared >(); // Packet pkt; // pkt.set_timestamp(10); // packets->push(pkt); diff --git a/bmf/engine/c_engine/test/test_input_stream_manager.cpp b/bmf/engine/c_engine/test/test_input_stream_manager.cpp index 1b46c6f9..a2dc49bd 100644 --- a/bmf/engine/c_engine/test/test_input_stream_manager.cpp +++ b/bmf/engine/c_engine/test/test_input_stream_manager.cpp @@ -5,15 +5,15 @@ #include "../include/input_stream_manager.h" #include "gtest/gtest.h" -//void scheduler_node(Task task){ +// void scheduler_node(Task task){ // std::cout<<"scheduler node task:"< output_stream_names; -// output_stream_names.push_back("encode"); + // std::vector output_stream_names; + // output_stream_names.push_back("encode"); std::vector output_stream_id_list; output_stream_id_list.push_back(0); CallBackForTest call_back; - std::function throttled_cb = call_back.callback_add_or_remove_node_; - std::function sched_required = call_back.callback_add_or_remove_node_; - std::function scheduler_cb = call_back.callback_scheduler_to_schedule_node_; + std::function throttled_cb = + call_back.callback_add_or_remove_node_; + std::function sched_required = + call_back.callback_add_or_remove_node_; + std::function scheduler_cb = + call_back.callback_scheduler_to_schedule_node_; std::function notify_cb = call_back.callback_node_to_schedule_node_; - std::function node_is_closed_cb = call_back.callback_node_is_closed_cb_; + std::function node_is_closed_cb = + call_back.callback_node_is_closed_cb_; InputStreamManagerCallBack callback; callback.scheduler_cb = scheduler_cb; callback.notify_cb = notify_cb; callback.throttled_cb = throttled_cb; callback.sched_required = sched_required; callback.node_is_closed_cb = node_is_closed_cb; - ImmediateInputStreamManager immediate_input_stream_manager(node_id, input_stream_names, output_stream_id_list, - 5, callback); + ImmediateInputStreamManager immediate_input_stream_manager( + node_id, input_stream_names, output_stream_id_list, 5, callback); int stream_id = 1; - std::shared_ptr > packets = std::make_shared >(); + std::shared_ptr> packets = + std::make_shared>(); Packet packet(0); packet.set_timestamp(10); packets->push(packet); diff --git a/bmf/engine/c_engine/test/test_module_factory.cpp b/bmf/engine/c_engine/test/test_module_factory.cpp index e2726908..086ac716 100644 --- a/bmf/engine/c_engine/test/test_module_factory.cpp +++ b/bmf/engine/c_engine/test/test_module_factory.cpp @@ -29,22 +29,21 @@ USE_BMF_ENGINE_NS USE_BMF_SDK_NS TEST(module_factory, cpp_module) { std::string module_name = "test_cpp_module"; - - int node_id=1; + int node_id = 1; JsonParam option; std::string module_type; std::string module_path; std::string module_entry; std::shared_ptr module; - ModuleInfo module_info = ModuleFactory::create_module(module_name,node_id,option,module_type,module_path,module_entry,module); + ModuleInfo module_info = + ModuleFactory::create_module(module_name, node_id, option, module_type, + module_path, module_entry, module); EXPECT_EQ(module == nullptr, 0); - } TEST(module_factory, python_module) { std::string module_name = "test_python_module"; - - int node_id=0; + int node_id = 0; JsonParam option; std::string option_str = "{\"hello\":1}"; option.parse(option_str); @@ -52,9 +51,10 @@ TEST(module_factory, python_module) { std::string module_path; std::string module_entry; std::shared_ptr module; - ModuleInfo module_info = ModuleFactory::create_module(module_name,node_id,option,module_type,module_path,module_entry,module); + ModuleInfo module_info = + ModuleFactory::create_module(module_name, node_id, option, module_type, + module_path, module_entry, module); EXPECT_EQ(module == nullptr, 0); - } -#endif //BMF_ENABLE_MOBILE +#endif // BMF_ENABLE_MOBILE \ No newline at end of file diff --git a/bmf/engine/c_engine/test/test_node.cpp b/bmf/engine/c_engine/test/test_node.cpp index 21747cd7..e3f3a8d4 100644 --- a/bmf/engine/c_engine/test/test_node.cpp +++ b/bmf/engine/c_engine/test/test_node.cpp @@ -31,19 +31,21 @@ int init_node(std::shared_ptr &node) { NodeConfig node_config = NodeConfig(json_param); CallBackForTest callback_for_test; NodeCallBack callback; - callback.scheduler_cb = callback_for_test.callback_scheduler_to_schedule_node_; + callback.scheduler_cb = + callback_for_test.callback_scheduler_to_schedule_node_; callback.throttled_cb = callback_for_test.callback_add_or_remove_node_; callback.sched_required = callback_for_test.callback_add_or_remove_node_; std::shared_ptr pre_allocated_modules = NULL; BmfMode mode = BmfMode::NORMAL_MODE; - node = std::make_shared(node_id, node_config, callback, pre_allocated_modules, mode, nullptr); + node = std::make_shared(node_id, node_config, callback, + pre_allocated_modules, mode, nullptr); return 0; } TEST(node, schedule_node) { std::shared_ptr node; init_node(node); -// node->schedule_node(); + // node->schedule_node(); } TEST(node, process_node) { diff --git a/bmf/engine/c_engine/test/test_output_stream.cpp b/bmf/engine/c_engine/test/test_output_stream.cpp index e22096f2..65dd0834 100644 --- a/bmf/engine/c_engine/test/test_output_stream.cpp +++ b/bmf/engine/c_engine/test/test_output_stream.cpp @@ -24,7 +24,8 @@ USE_BMF_ENGINE_NS USE_BMF_SDK_NS -std::shared_ptr initInputStreamManager(std::shared_ptr &input_stream_manager) { +std::shared_ptr initInputStreamManager( + std::shared_ptr &input_stream_manager) { int node_id = 1; std::vector input_stream_names; StreamConfig v, a; @@ -35,19 +36,24 @@ std::shared_ptr initInputStreamManager(std::shared_ptr output_stream_id_list; output_stream_id_list.push_back(0); auto call_back = std::make_shared(); - std::function throttled_cb = call_back->callback_add_or_remove_node_; - std::function scheduler_cb = call_back->callback_scheduler_to_schedule_node_; - std::function sched_required = call_back->callback_add_or_remove_node_; - std::function notify_cb = call_back->callback_node_to_schedule_node_; - std::function node_is_closed_cb = call_back->callback_node_is_closed_cb_; + std::function throttled_cb = + call_back->callback_add_or_remove_node_; + std::function scheduler_cb = + call_back->callback_scheduler_to_schedule_node_; + std::function sched_required = + call_back->callback_add_or_remove_node_; + std::function notify_cb = + call_back->callback_node_to_schedule_node_; + std::function node_is_closed_cb = + call_back->callback_node_is_closed_cb_; InputStreamManagerCallBack callback; callback.scheduler_cb = scheduler_cb; callback.notify_cb = notify_cb; callback.throttled_cb = throttled_cb; callback.sched_required = sched_required; callback.node_is_closed_cb = node_is_closed_cb; - input_stream_manager = std::make_shared(node_id, input_stream_names, - output_stream_id_list, 5, callback); + input_stream_manager = std::make_shared( + node_id, input_stream_names, output_stream_id_list, 5, callback); return call_back; } @@ -62,10 +68,10 @@ TEST(output_stream, add_mirror_stream) { } TEST(output_stream, propagate_packets) { -// google::InitGoogleLogging("main"); -// google::SetStderrLogging(google::INFO); -// google::InstallFailureSignalHandler(); -// google::InstallFailureWriter(&SignalHandle); + // google::InitGoogleLogging("main"); + // google::SetStderrLogging(google::INFO); + // google::InstallFailureSignalHandler(); + // google::InstallFailureWriter(&SignalHandle); int stream_id = 1; std::string name = "audio"; OutputStream output_stream(stream_id, name); @@ -73,7 +79,8 @@ TEST(output_stream, propagate_packets) { std::shared_ptr input_stream_manager; auto cb_p = initInputStreamManager(input_stream_manager); output_stream.add_mirror_stream(input_stream_manager, stream_id); - std::shared_ptr > packets = std::make_shared >(); + std::shared_ptr> packets = + std::make_shared>(); Packet packet(0); packet.set_timestamp(10); packets->push(packet); diff --git a/bmf/engine/c_engine/test/test_output_stream_manager.cpp b/bmf/engine/c_engine/test/test_output_stream_manager.cpp index c1399b13..200134ea 100644 --- a/bmf/engine/c_engine/test/test_output_stream_manager.cpp +++ b/bmf/engine/c_engine/test/test_output_stream_manager.cpp @@ -30,8 +30,10 @@ TEST(output_stream_manager, propagate_packets) { StreamConfig a; a.identifier = "audio"; output_stream_names.push_back(a); - OutputStreamManager output_stream_manager = OutputStreamManager(output_stream_names); - std::shared_ptr > packets = std::make_shared >(); + OutputStreamManager output_stream_manager = + OutputStreamManager(output_stream_names); + std::shared_ptr> packets = + std::make_shared>(); Packet packet(0); packet.set_timestamp(10); packets->push(packet); diff --git a/bmf/engine/c_engine/test/test_safe_queue.cpp b/bmf/engine/c_engine/test/test_safe_queue.cpp index 4e816b90..0f9593b2 100644 --- a/bmf/engine/c_engine/test/test_safe_queue.cpp +++ b/bmf/engine/c_engine/test/test_safe_queue.cpp @@ -29,5 +29,4 @@ TEST(safe_queue, single_thread) { int item; safe_queue.pop(item); EXPECT_EQ(item, 1); - } \ No newline at end of file diff --git a/bmf/engine/c_engine/test/test_scheduler.cpp b/bmf/engine/c_engine/test/test_scheduler.cpp index f22785bb..5b2ba3b1 100644 --- a/bmf/engine/c_engine/test/test_scheduler.cpp +++ b/bmf/engine/c_engine/test/test_scheduler.cpp @@ -21,6 +21,7 @@ USE_BMF_ENGINE_NS USE_BMF_SDK_NS TEST(scheduler, start) { SchedulerCallBack callback; - std::shared_ptr scheduler = std::make_shared(callback, 1); -// scheduler->start(); + std::shared_ptr scheduler = + std::make_shared(callback, 1); + // scheduler->start(); } diff --git a/bmf/engine/c_engine/test/test_scheduler_queue.cpp b/bmf/engine/c_engine/test/test_scheduler_queue.cpp index 7f085489..a0e97919 100644 --- a/bmf/engine/c_engine/test/test_scheduler_queue.cpp +++ b/bmf/engine/c_engine/test/test_scheduler_queue.cpp @@ -18,7 +18,7 @@ #include "../include/scheduler_queue.h" #include "gtest/gtest.h" -//bool operator<(const Item &lhs, const Item &rhs) { +// bool operator<(const Item &lhs, const Item &rhs) { // if (lhs.task.get_timestamp()>rhs.task.get_timestamp()) // { // return true; @@ -36,10 +36,11 @@ USE_BMF_ENGINE_NS USE_BMF_SDK_NS TEST(scheduler_queue, start) { SchedulerQueueCallBack callback; - std::shared_ptr scheduler_queue = std::make_shared(0, callback); -// scheduler_queue->start(); + std::shared_ptr scheduler_queue = + std::make_shared(0, callback); + // scheduler_queue->start(); } -//TEST(scheduler_queue,item){ +// TEST(scheduler_queue,item){ // SafePriorityQueue queue; // for (int i=0;i<100;i++){ // Task task = Task(0,1,1); diff --git a/bmf/engine/connector/include/builder.hpp b/bmf/engine/connector/include/builder.hpp index 4f6144fc..d8566efd 100644 --- a/bmf/engine/connector/include/builder.hpp +++ b/bmf/engine/connector/include/builder.hpp @@ -31,687 +31,766 @@ #include "connector.hpp" #ifndef BMF_MAX_CAPACITY -#define BMF_MAX_CAPACITY (1<<10) +#define BMF_MAX_CAPACITY (1 << 10) #endif namespace bmf::builder { - class Graph; +class Graph; - class Node; +class Node; - class Stream; +class Stream; - class SyncModule; +class SyncModule; - class SyncPackets; +class SyncPackets; - // enum constants - enum GraphMode { - NormalMode, - ServerMode, - GeneratorMode, - SubGraphMode, - UpdateMode, - }; - enum InputManagerType { - Immediate, - Default, - Server, - FrameSync, - ClockSync - }; - enum ModuleType { - CPP, - C, - Python, - Go - }; - namespace internal { - // Forward declaration - class RealGraph; - - class RealNode; - - class RealStream; - - class RealStream : public std::enable_shared_from_this { - public: - RealStream(const std::shared_ptr& node, std::string name, std::string notify, - std::string alias); - - RealStream() = delete; - - RealStream(RealStream const &) = delete; - - RealStream(RealStream &&) = default; - - void SetNotify(std::string const ¬ify); - - void SetAlias(std::string const &alias); - void Start(); - - nlohmann::json Dump(); - - std::shared_ptr - AddModule(std::string const &alias, const bmf_sdk::JsonParam& option, - std::vector > inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); - - private: - friend bmf::builder::Graph; - friend bmf::builder::Node; - friend bmf::builder::Stream; - friend RealGraph; - friend RealNode; - - std::weak_ptr node_; - std::string name_; - std::string notify_; - std::string alias_; - }; +// enum constants +enum GraphMode { + NormalMode, + ServerMode, + GeneratorMode, + SubGraphMode, + UpdateMode, +}; +enum InputManagerType { Immediate, Default, Server, FrameSync, ClockSync }; +enum ModuleType { CPP, C, Python, Go }; +namespace internal { +// Forward declaration +class RealGraph; - class RealNode : public std::enable_shared_from_this { - public: - RealNode(const std::shared_ptr& graph, int id, std::string alias, const bmf_sdk::JsonParam& option, - std::vector > inputStreams, std::string const &moduleName, - ModuleType mduleType, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler); +class RealNode; - RealNode() = delete; +class RealStream; - RealNode(RealNode const &) = delete; +class RealStream : public std::enable_shared_from_this { + public: + RealStream(const std::shared_ptr &node, std::string name, + std::string notify, std::string alias); - RealNode(RealNode &&) = default; + RealStream() = delete; - std::shared_ptr Stream(int idx); + RealStream(RealStream const &) = delete; - std::shared_ptr Stream(std::string const &name); + RealStream(RealStream &&) = default; - void GiveStreamNotify(int idx, std::string const ¬ify); + void SetNotify(std::string const ¬ify); - void GiveStreamAlias(int idx, std::string const &alias); + void SetAlias(std::string const &alias); + void Start(); - void SetAlias(std::string const &alias); + nlohmann::json Dump(); - void SetInputManager(InputManagerType inputStreamManager); + std::shared_ptr + AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); - void SetScheduler(int scheduler); + private: + friend bmf::builder::Graph; + friend bmf::builder::Node; + friend bmf::builder::Stream; + friend RealGraph; + friend RealNode; - void SetPreModule(bmf::BMFModule preModuleInstance); + std::weak_ptr node_; + std::string name_; + std::string notify_; + std::string alias_; +}; - void AddCallback(long long key, bmf::BMFCallback callbackInstance); +class RealNode : public std::enable_shared_from_this { + public: + RealNode(const std::shared_ptr &graph, int id, std::string alias, + const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType mduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); - nlohmann::json Dump(); + RealNode() = delete; - std::shared_ptr - AddModule(std::string const &alias, const bmf_sdk::JsonParam& option, - std::vector > inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); + RealNode(RealNode const &) = delete; - private: - friend bmf::builder::Graph; - friend bmf::builder::Node; - friend bmf::builder::Stream; - friend RealGraph; - friend RealStream; + RealNode(RealNode &&) = default; - class ModuleMetaInfo { - public: - ModuleMetaInfo(std::string moduleName, ModuleType moduleType, std::string modulePath, - std::string moduleEntry); + std::shared_ptr Stream(int idx); - nlohmann::json Dump(); + std::shared_ptr Stream(std::string const &name); - std::string moduleName_; - ModuleType moduleType_; - std::string modulePath_; - std::string moduleEntry_; - }; + void GiveStreamNotify(int idx, std::string const ¬ify); - class NodeMetaInfo { - public: - NodeMetaInfo() = default; + void GiveStreamAlias(int idx, std::string const &alias); - nlohmann::json Dump(); + void SetAlias(std::string const &alias); - unsigned int preModuleUID_ = 0; - std::map callbackBinding_; - std::shared_ptr preModuleInstance_ = nullptr; - std::map > callbackInstances_; - }; + void SetInputManager(InputManagerType inputStreamManager); + void SetScheduler(int scheduler); - std::weak_ptr graph_; - int id_; - std::string alias_; - bmf_sdk::JsonParam option_; - std::vector > inputStreams_; - std::vector > outputStreams_; - ModuleMetaInfo moduleInfo_; - NodeMetaInfo metaInfo_; - InputManagerType inputManager_; - int scheduler_; + void SetPreModule(bmf::BMFModule preModuleInstance); - std::map> existedStreamNotify_; - }; + void AddCallback(long long key, bmf::BMFCallback callbackInstance); - class RealGraph : public std::enable_shared_from_this { - public: - RealGraph(GraphMode runMode, const bmf_sdk::JsonParam& graphOption); + nlohmann::json Dump(); - RealGraph() = delete; + std::shared_ptr + AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); - RealGraph(RealGraph const &) = delete; + private: + friend bmf::builder::Graph; + friend bmf::builder::Node; + friend bmf::builder::Stream; + friend RealGraph; + friend RealStream; - RealGraph(RealGraph &&) = default; + class ModuleMetaInfo { + public: + ModuleMetaInfo(std::string moduleName, ModuleType moduleType, + std::string modulePath, std::string moduleEntry); - void GiveStreamAlias(std::shared_ptr stream, std::string const &alias); + nlohmann::json Dump(); - void GiveNodeAlias(std::shared_ptr node, std::string const &alias); - - nlohmann::json Dump(); - - std::shared_ptr - AddModule(std::string const &alias, const bmf_sdk::JsonParam& option, - const std::vector >& inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); - - std::shared_ptr GetAliasedNode(std::string const &alias); - - std::shared_ptr GetAliasedStream(std::string const &alias); - - std::shared_ptr NewPlaceholderStream(); - - void SetOption(const bmf_sdk::JsonParam& optionPatch); - bmf::BMFGraph Instantiate(bool dumpGraph, bool needMerge); - bmf::BMFGraph Instance(); - void Start(bool dumpGraph, bool needMerge); - void Start(const std::shared_ptr& stream, bool dumpGraph, bool needMerge); - int Run(bool dumpGraph, bool needMerge); - Packet Generate(); - private: - friend bmf::builder::Graph; - friend bmf::builder::Node; - friend bmf::builder::Stream; - friend RealNode; - friend RealStream; - - GraphMode mode_; - std::vector > inputStreams_; - std::vector > outputStreams_; - std::vector > nodes_; - bmf_sdk::JsonParam graphOption_; - - std::shared_ptr placeholderNode_; - std::shared_ptr graphInstance_ = nullptr; - std::string generatorStreamName; - std::map > existedStreamAlias_; - std::map > existedNodeAlias_; - }; - } - - std::string GetVersion(); - - std::string GetCommit(); - - void ChangeDmpPath(std::string path); - - bmf::BMFModule - GetModuleInstance(std::string const &moduleName, std::string const &option, ModuleType moduleType = Python, - std::string const &modulePath = "", std::string const &moduleEntry = ""); + std::string moduleName_; + ModuleType moduleType_; + std::string modulePath_; + std::string moduleEntry_; + }; - bmf::BMFCallback GetCallbackInstance(std::function callback); + class NodeMetaInfo { + public: + NodeMetaInfo() = default; - class Stream { - public: - BMF_FUNC_VIS Stream() = delete; + nlohmann::json Dump(); - BMF_FUNC_VIS Stream(Stream const &) = default; + unsigned int preModuleUID_ = 0; + std::map callbackBinding_; + std::shared_ptr preModuleInstance_ = nullptr; + std::map> + callbackInstances_; + }; - BMF_FUNC_VIS Stream(Stream &&) = default; + std::weak_ptr graph_; + int id_; + std::string alias_; + bmf_sdk::JsonParam option_; + std::vector> inputStreams_; + std::vector> outputStreams_; + ModuleMetaInfo moduleInfo_; + NodeMetaInfo metaInfo_; + InputManagerType inputManager_; + int scheduler_; + + std::map> existedStreamNotify_; +}; + +class RealGraph : public std::enable_shared_from_this { + public: + RealGraph(GraphMode runMode, const bmf_sdk::JsonParam &graphOption); + + RealGraph() = delete; + + RealGraph(RealGraph const &) = delete; + + RealGraph(RealGraph &&) = default; + + void GiveStreamAlias(std::shared_ptr stream, + std::string const &alias); + + void GiveNodeAlias(std::shared_ptr node, + std::string const &alias); + + nlohmann::json Dump(); + + std::shared_ptr + AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector> &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); + + std::shared_ptr GetAliasedNode(std::string const &alias); + + std::shared_ptr GetAliasedStream(std::string const &alias); + + std::shared_ptr NewPlaceholderStream(); + + void SetOption(const bmf_sdk::JsonParam &optionPatch); + bmf::BMFGraph Instantiate(bool dumpGraph, bool needMerge); + bmf::BMFGraph Instance(); + void Start(bool dumpGraph, bool needMerge); + void Start(const std::shared_ptr &stream, + bool dumpGraph, bool needMerge); + int Run(bool dumpGraph, bool needMerge); + Packet Generate(); + + private: + friend bmf::builder::Graph; + friend bmf::builder::Node; + friend bmf::builder::Stream; + friend RealNode; + friend RealStream; + + GraphMode mode_; + std::vector> inputStreams_; + std::vector> outputStreams_; + std::vector> nodes_; + bmf_sdk::JsonParam graphOption_; + + std::shared_ptr placeholderNode_; + std::shared_ptr graphInstance_ = nullptr; + std::string generatorStreamName; + std::map> existedStreamAlias_; + std::map> existedNodeAlias_; +}; +} - private: - friend Node; - friend Graph; +std::string GetVersion(); - BMF_FUNC_VIS explicit Stream(std::shared_ptr baseP); - std::shared_ptr baseP_; - public: - BMF_FUNC_VIS void SetNotify(std::string const ¬ify); +std::string GetCommit(); - BMF_FUNC_VIS void SetAlias(std::string const &alias); - BMF_FUNC_VIS void Start(); +void ChangeDmpPath(std::string path); - BMF_FUNC_VIS Node Module(const std::vector& inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam& option, std::string const &alias = "", +bmf::BMFModule GetModuleInstance(std::string const &moduleName, + std::string const &option, + ModuleType moduleType = Python, std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); - - BMF_FUNC_VIS Node - CppModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); - - BMF_FUNC_VIS Node - PythonModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); - - BMF_FUNC_VIS Node - GoModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + std::string const &moduleEntry = ""); - BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam& decodePara, std::string const &alias = ""); +bmf::BMFCallback +GetCallbackInstance(std::function callback); - BMF_FUNC_VIS Node - EncodeAsVideo(const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); +class Stream { + public: + BMF_FUNC_VIS Stream() = delete; - BMF_FUNC_VIS Node - EncodeAsVideo(Stream audioStream, const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS Stream(Stream const &) = default; - BMF_FUNC_VIS Node - FFMpegFilter(const std::vector& inStreams, std::string const &filterName, bmf_sdk::JsonParam filterPara, - std::string const &alias = ""); + BMF_FUNC_VIS Stream(Stream &&) = default; - template{} || std::is_floating_point{} || - std::is_convertible{} || - std::is_convertible{}, bool>::type = true> - BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, std::string const &filterName, T filterPara, - std::string const &alias = ""); + private: + friend Node; + friend Graph; - template - BMF_FUNC_VIS Node Vflip(T para, std::string const &alias = ""); + BMF_FUNC_VIS explicit Stream(std::shared_ptr baseP); + std::shared_ptr baseP_; - template - BMF_FUNC_VIS Node Scale(T para, std::string const &alias = ""); + public: + BMF_FUNC_VIS void SetNotify(std::string const ¬ify); - template - BMF_FUNC_VIS Node Setsar(T para, std::string const &alias = ""); + BMF_FUNC_VIS void SetAlias(std::string const &alias); + BMF_FUNC_VIS void Start(); - template - BMF_FUNC_VIS Node Pad(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node + Module(const std::vector &inStreams, std::string const &moduleName, + ModuleType moduleType, const bmf_sdk::JsonParam &option, + std::string const &alias = "", std::string const &modulePath = "", + std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Trim(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node CppModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Setpts(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node PythonModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Loop(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node GoModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Split(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Adelay(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Atrim(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node EncodeAsVideo(Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Afade(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + bmf_sdk::JsonParam filterPara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Asetpts(T para, std::string const &alias = ""); + template {} || std::is_floating_point{} || + std::is_convertible{} || + std::is_convertible{}, + bool>::type = true> + BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, + std::string const &filterName, T filterPara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Vflip(T para, std::string const &alias = ""); - template - BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Scale(T para, std::string const &alias = ""); - template - BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Setsar(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node Fps(int fps, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Pad(T para, std::string const &alias = ""); - private: - BMF_FUNC_VIS Node - ConnectNewModule(std::string const &alias, const bmf_sdk::JsonParam& option, const std::vector& inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); + template + BMF_FUNC_VIS Node Trim(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node InternalFFMpegFilter(const std::vector& inStreams, std::string const &filterName, - const bmf_sdk::JsonParam& filterPara, std::string const &alias = ""); - }; + template + BMF_FUNC_VIS Node Setpts(T para, std::string const &alias = ""); - class Node { - public: - BMF_FUNC_VIS Node() = delete; + template + BMF_FUNC_VIS Node Loop(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node(Node const &) = default; + template + BMF_FUNC_VIS Node Split(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node(Node &&) = default; + template + BMF_FUNC_VIS Node Adelay(T para, std::string const &alias = ""); - private: - friend class Stream; + template + BMF_FUNC_VIS Node Atrim(T para, std::string const &alias = ""); - friend Graph; + template + BMF_FUNC_VIS Node Afade(T para, std::string const &alias = ""); - BMF_FUNC_VIS explicit Node(std::shared_ptr baseP); - std::shared_ptr baseP_; - public: - BMF_FUNC_VIS class Stream operator[](int index); + template + BMF_FUNC_VIS Node Asetpts(T para, std::string const &alias = ""); - BMF_FUNC_VIS class Stream operator[](std::string const ¬ifyOrAlias); + template + BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, + std::string const &alias = ""); - BMF_FUNC_VIS class Stream Stream(int index); + template + BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, + std::string const &alias = ""); - BMF_FUNC_VIS class Stream Stream(std::string const ¬ifyOrAlias); + template + BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, + std::string const &alias = ""); - BMF_FUNC_VIS operator class Stream(); + BMF_FUNC_VIS Node Fps(int fps, std::string const &alias = ""); - BMF_FUNC_VIS void SetAlias(std::string const &alias); + private: + BMF_FUNC_VIS Node ConnectNewModule( + std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, std::string const &moduleName, + ModuleType moduleType, std::string const &modulePath, + std::string const &moduleEntry, InputManagerType inputStreamManager, + int scheduler); - BMF_FUNC_VIS void SetInputStreamManager(InputManagerType inputStreamManager); + BMF_FUNC_VIS Node InternalFFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias = ""); +}; - BMF_FUNC_VIS void SetThread(int threadNum); +class Node { + public: + BMF_FUNC_VIS Node() = delete; - BMF_FUNC_VIS void SetPreModule(const bmf::BMFModule& preModuleInstance); + BMF_FUNC_VIS Node(Node const &) = default; - BMF_FUNC_VIS void AddCallback(long long key, const bmf::BMFCallback& callbackInstance); + BMF_FUNC_VIS Node(Node &&) = default; - BMF_FUNC_VIS void Start(); + private: + friend class Stream; - BMF_FUNC_VIS Node - Module(const std::vector& inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam& option, std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + friend Graph; - BMF_FUNC_VIS Node - CppModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + BMF_FUNC_VIS explicit Node(std::shared_ptr baseP); + std::shared_ptr baseP_; - BMF_FUNC_VIS Node - PythonModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + public: + BMF_FUNC_VIS class Stream operator[](int index); - BMF_FUNC_VIS Node - GoModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + BMF_FUNC_VIS class Stream operator[](std::string const ¬ifyOrAlias); - BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam& decodePara, std::string const &alias = ""); + BMF_FUNC_VIS class Stream Stream(int index); - BMF_FUNC_VIS Node - EncodeAsVideo(const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS class Stream Stream(std::string const ¬ifyOrAlias); - BMF_FUNC_VIS Node - EncodeAsVideo(class Stream audioStream, const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS operator class Stream(); - BMF_FUNC_VIS Node - FFMpegFilter(const std::vector& inStreams, std::string const &filterName, bmf_sdk::JsonParam filterPara, - std::string const &alias = ""); + BMF_FUNC_VIS void SetAlias(std::string const &alias); - template{} || std::is_floating_point{} || - std::is_convertible{} || - std::is_convertible{}, bool>::type = true> - BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, std::string const &filterName, T filterPara, - std::string const &alias = ""); + BMF_FUNC_VIS void + SetInputStreamManager(InputManagerType inputStreamManager); - template - BMF_FUNC_VIS Node Vflip(T para, std::string const &alias = ""); + BMF_FUNC_VIS void SetThread(int threadNum); - template - BMF_FUNC_VIS Node Scale(T para, std::string const &alias = ""); + BMF_FUNC_VIS void SetPreModule(const bmf::BMFModule &preModuleInstance); - template - BMF_FUNC_VIS Node Setsar(T para, std::string const &alias = ""); + BMF_FUNC_VIS void AddCallback(long long key, + const bmf::BMFCallback &callbackInstance); - template - BMF_FUNC_VIS Node Pad(T para, std::string const &alias = ""); + BMF_FUNC_VIS void Start(); - template - BMF_FUNC_VIS Node Trim(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node Module( + const std::vector &inStreams, + std::string const &moduleName, ModuleType moduleType, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Setpts(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node CppModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, + std::string const &alias = "", + std::string const &modulePath = "", + std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, + int scheduler = 0); - template - BMF_FUNC_VIS Node Loop(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node PythonModule( + const std::vector &inStreams, + std::string const &moduleName, const bmf_sdk::JsonParam &option, + std::string const &alias = "", std::string const &modulePath = "", + std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); - template - BMF_FUNC_VIS Node Split(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node GoModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, + std::string const &alias = "", + std::string const &modulePath = "", + std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, + int scheduler = 0); - template - BMF_FUNC_VIS Node Adelay(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Atrim(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Afade(T para, std::string const &alias = ""); + BMF_FUNC_VIS Node EncodeAsVideo(class Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); + + BMF_FUNC_VIS Node FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + bmf_sdk::JsonParam filterPara, + std::string const &alias = ""); + + template {} || std::is_floating_point{} || + std::is_convertible{} || + std::is_convertible{}, + bool>::type = true> + BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, + std::string const &filterName, T filterPara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Asetpts(T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Vflip(T para, std::string const &alias = ""); - template - BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Scale(T para, std::string const &alias = ""); - template - BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Setsar(T para, std::string const &alias = ""); - template - BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Pad(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node Fps(int fps, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Trim(T para, std::string const &alias = ""); - private: - BMF_FUNC_VIS Node - ConnectNewModule(std::string const &alias, const bmf_sdk::JsonParam& option, const std::vector& inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); + template + BMF_FUNC_VIS Node Setpts(T para, std::string const &alias = ""); - BMF_FUNC_VIS Node InternalFFMpegFilter(const std::vector& inStreams, std::string const &filterName, - const bmf_sdk::JsonParam& filterPara, std::string const &alias = ""); - }; + template + BMF_FUNC_VIS Node Loop(T para, std::string const &alias = ""); - class SyncPackets { - public: - BMF_FUNC_VIS SyncPackets() = default; - BMF_FUNC_VIS void Insert(int streamId, std::vector frames); - BMF_FUNC_VIS std::vector operator[](int); - std::map > packets; - }; + template + BMF_FUNC_VIS Node Split(T para, std::string const &alias = ""); - class SyncModule { - public: - BMF_FUNC_VIS SyncModule() = default; - std::vector inputStreams; - std::vector outputStreams; - std::shared_ptr moduleInstance = nullptr; - BMF_FUNC_VIS std::map > ProcessPkts(std::map > inputPackets); - BMF_FUNC_VIS SyncPackets ProcessPkts(SyncPackets pkts = SyncPackets()); - BMF_FUNC_VIS void Process(bmf_sdk::Task task); - BMF_FUNC_VIS void SendEOF(); - BMF_FUNC_VIS void Init(); - BMF_FUNC_VIS void Close(); - }; + template + BMF_FUNC_VIS Node Adelay(T para, std::string const &alias = ""); - class Graph { - public: - BMF_FUNC_VIS explicit Graph(GraphMode runMode, bmf_sdk::JsonParam graphOption); + template + BMF_FUNC_VIS Node Atrim(T para, std::string const &alias = ""); - BMF_FUNC_VIS explicit Graph(GraphMode runMode, nlohmann::json graphOption = {}); + template + BMF_FUNC_VIS Node Afade(T para, std::string const &alias = ""); - BMF_FUNC_VIS Graph() = delete; + template + BMF_FUNC_VIS Node Asetpts(T para, std::string const &alias = ""); - BMF_FUNC_VIS Graph(Graph const &rhs) = default; + template + BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Fps(int fps, std::string const &alias = ""); + + private: + BMF_FUNC_VIS Node ConnectNewModule( + std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); - BMF_FUNC_VIS Graph(Graph &&rhs) = default; + BMF_FUNC_VIS Node InternalFFMpegFilter( + const std::vector &inStreams, + std::string const &filterName, const bmf_sdk::JsonParam &filterPara, + std::string const &alias = ""); +}; - private: - friend class Stream; +class SyncPackets { + public: + BMF_FUNC_VIS SyncPackets() = default; + BMF_FUNC_VIS void Insert(int streamId, std::vector frames); + BMF_FUNC_VIS std::vector operator[](int); + std::map> packets; +}; - friend Node; +class SyncModule { + public: + BMF_FUNC_VIS SyncModule() = default; + std::vector inputStreams; + std::vector outputStreams; + std::shared_ptr moduleInstance = nullptr; + BMF_FUNC_VIS std::map> + ProcessPkts(std::map> inputPackets); + BMF_FUNC_VIS SyncPackets ProcessPkts(SyncPackets pkts = SyncPackets()); + BMF_FUNC_VIS void Process(bmf_sdk::Task task); + BMF_FUNC_VIS void SendEOF(); + BMF_FUNC_VIS void Init(); + BMF_FUNC_VIS void Close(); +}; - std::shared_ptr graph_; +class Graph { + public: + BMF_FUNC_VIS explicit Graph(GraphMode runMode, + bmf_sdk::JsonParam graphOption); - public: - BMF_FUNC_VIS void SetTotalThreadNum(int num); + BMF_FUNC_VIS explicit Graph(GraphMode runMode, + nlohmann::json graphOption = {}); - BMF_FUNC_VIS Stream NewPlaceholderStream(); + BMF_FUNC_VIS Graph() = delete; - BMF_FUNC_VIS Node GetAliasedNode(std::string const &alias); + BMF_FUNC_VIS Graph(Graph const &rhs) = default; - BMF_FUNC_VIS Stream GetAliasedStream(std::string const &alias); - - BMF_FUNC_VIS bmf::BMFGraph Instantiate(bool dumpGraph = true, bool needMerge = true); - - BMF_FUNC_VIS bmf::BMFGraph Instance(); - - BMF_FUNC_VIS int Run(bool dumpGraph = true, bool needMerge = true); - - BMF_FUNC_VIS void Start(bool dumpGraph = true, bool needMerge = true); - - BMF_FUNC_VIS std::string Dump(); - - BMF_FUNC_VIS Node Module(const std::vector& inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam& option, std::string const &alias = "", - std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + BMF_FUNC_VIS Graph(Graph &&rhs) = default; - BMF_FUNC_VIS Node - CppModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + private: + friend class Stream; - BMF_FUNC_VIS Node - PythonModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + friend Node; - BMF_FUNC_VIS Node - GoModule(const std::vector& inStreams, std::string const &moduleName, const bmf_sdk::JsonParam& option, - std::string const &alias = "", std::string const &modulePath = "", - std::string const &moduleEntry = "", InputManagerType inputStreamManager = Immediate, - int scheduler = 0); + std::shared_ptr graph_; - BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam& decodePara, std::string const &alias = ""); + public: + BMF_FUNC_VIS void SetTotalThreadNum(int num); - BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam& decodePara, Stream controlStream, std::string const &alias = ""); + BMF_FUNC_VIS Stream NewPlaceholderStream(); - BMF_FUNC_VIS Node - Encode(Stream videoStream, Stream audioStream, const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS Node GetAliasedNode(std::string const &alias); - BMF_FUNC_VIS Node - Encode(Stream videoStream, const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS Stream GetAliasedStream(std::string const &alias); - BMF_FUNC_VIS Node - Encode(const bmf_sdk::JsonParam& encodePara, std::string const &alias = ""); + BMF_FUNC_VIS bmf::BMFGraph Instantiate(bool dumpGraph = true, + bool needMerge = true); - BMF_FUNC_VIS Node - FFMpegFilter(const std::vector& inStreams, std::string const &filterName, const bmf_sdk::JsonParam& filterPara, - std::string const &alias = ""); + BMF_FUNC_VIS bmf::BMFGraph Instance(); - template{} || std::is_floating_point{} || - std::is_convertible{} || - std::is_convertible{}, bool>::type = true> - BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, std::string const &filterName, T filterPara, - std::string const &alias = ""); + BMF_FUNC_VIS int Run(bool dumpGraph = true, bool needMerge = true); - template - BMF_FUNC_VIS Node Vflip(Stream inStream, T para, std::string const &alias = ""); + BMF_FUNC_VIS void Start(bool dumpGraph = true, bool needMerge = true); - template - BMF_FUNC_VIS Node Scale(Stream inStream, T para, std::string const &alias = ""); + BMF_FUNC_VIS std::string Dump(); + + BMF_FUNC_VIS Node + Module(const std::vector &inStreams, std::string const &moduleName, + ModuleType moduleType, const bmf_sdk::JsonParam &option, + std::string const &alias = "", std::string const &modulePath = "", + std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS Node CppModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS Node PythonModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS Node GoModule( + const std::vector &inStreams, std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias = "", + std::string const &modulePath = "", std::string const &moduleEntry = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Decode(const bmf_sdk::JsonParam &decodePara, + Stream controlStream, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Encode(Stream videoStream, Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Encode(Stream videoStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Encode(const bmf_sdk::JsonParam &encodePara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Setsar(Stream inStream, T para, std::string const &alias = ""); + BMF_FUNC_VIS Node FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Pad(Stream inStream, T para, std::string const &alias = ""); + template {} || std::is_floating_point{} || + std::is_convertible{} || + std::is_convertible{}, + bool>::type = true> + BMF_FUNC_VIS Node FFMpegFilter(std::vector inStreams, + std::string const &filterName, T filterPara, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Trim(Stream inStream, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Vflip(Stream inStream, T para, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Setpts(Stream inStream, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Scale(Stream inStream, T para, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Loop(Stream inStream, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Setsar(Stream inStream, T para, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Split(Stream inStream, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Pad(Stream inStream, T para, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Adelay(Stream inStream, T para, std::string const &alias = ""); + template + BMF_FUNC_VIS Node Trim(Stream inStream, T para, + std::string const &alias = ""); - template - BMF_FUNC_VIS Node Atrim(Stream inStream, T para, std::string const &alias = ""); - - template - BMF_FUNC_VIS Node Afade(Stream inStream, T para, std::string const &alias = ""); - - template - BMF_FUNC_VIS Node Asetpts(Stream inStream, T para, std::string const &alias = ""); - - template - BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, std::string const &alias = ""); - - template - BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, std::string const &alias = ""); - - template - BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, std::string const &alias = ""); - - BMF_FUNC_VIS Node Fps(Stream inStream, int fps, std::string const &alias = ""); - - BMF_FUNC_VIS SyncModule Sync(const std::vector inStreams, const std::vector outStreams, - bmf_sdk::JsonParam moduleOption, std::string const &moduleName, - ModuleType moduleType = CPP, std::string const &modulePath = "", - std::string const &moduleEntry = "", std::string const &alias = "", - InputManagerType inputStreamManager = Immediate, int scheduler = 0); - - BMF_FUNC_VIS SyncModule Sync(const std::vector inStreams, const std::vector outStreams, - nlohmann::json moduleOption, std::string const &moduleName, - ModuleType moduleType = CPP, std::string const &modulePath = "", - std::string const &moduleEntry = "", std::string const &alias = "", - InputManagerType inputStreamManager = Immediate, int scheduler = 0); - - BMF_FUNC_VIS std::map > Process(SyncModule module, - std::map > inputPackets); - - BMF_FUNC_VIS SyncPackets Process(SyncModule module, SyncPackets pkts = SyncPackets()); - - BMF_FUNC_VIS void Init(SyncModule module); - - BMF_FUNC_VIS void Close(SyncModule module); - - BMF_FUNC_VIS void SendEOF(SyncModule module); - - BMF_FUNC_VIS void SetOption(const bmf_sdk::JsonParam& optionPatch); - BMF_FUNC_VIS Packet Generate(); - private: - BMF_FUNC_VIS Node NewNode(std::string const &alias, const bmf_sdk::JsonParam& option, const std::vector& inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler); - BMF_FUNC_VIS Node InternalFFMpegFilter(const std::vector& inStreams, std::string const &filterName, - const bmf_sdk::JsonParam& filterPara, std::string const &alias = ""); - }; + template + BMF_FUNC_VIS Node Setpts(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Loop(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Split(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Adelay(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Atrim(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Afade(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Asetpts(Stream inStream, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Amix(std::vector inStreams, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Overlay(std::vector inStreams, T para, + std::string const &alias = ""); + + template + BMF_FUNC_VIS Node Concat(std::vector inStreams, T para, + std::string const &alias = ""); + + BMF_FUNC_VIS Node Fps(Stream inStream, int fps, + std::string const &alias = ""); + + BMF_FUNC_VIS SyncModule + Sync(const std::vector inStreams, const std::vector outStreams, + bmf_sdk::JsonParam moduleOption, std::string const &moduleName, + ModuleType moduleType = CPP, std::string const &modulePath = "", + std::string const &moduleEntry = "", std::string const &alias = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS SyncModule + Sync(const std::vector inStreams, const std::vector outStreams, + nlohmann::json moduleOption, std::string const &moduleName, + ModuleType moduleType = CPP, std::string const &modulePath = "", + std::string const &moduleEntry = "", std::string const &alias = "", + InputManagerType inputStreamManager = Immediate, int scheduler = 0); + + BMF_FUNC_VIS std::map> + Process(SyncModule module, std::map> inputPackets); + + BMF_FUNC_VIS SyncPackets Process(SyncModule module, + SyncPackets pkts = SyncPackets()); + + BMF_FUNC_VIS void Init(SyncModule module); + + BMF_FUNC_VIS void Close(SyncModule module); + + BMF_FUNC_VIS void SendEOF(SyncModule module); + + BMF_FUNC_VIS void SetOption(const bmf_sdk::JsonParam &optionPatch); + BMF_FUNC_VIS Packet Generate(); + + private: + BMF_FUNC_VIS Node + NewNode(std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler); + BMF_FUNC_VIS Node InternalFFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias = ""); +}; } #include "builder.ipp" -#endif //BMF_ENGINE_BUILDER_HPP +#endif // BMF_ENGINE_BUILDER_HPP diff --git a/bmf/engine/connector/include/connector.hpp b/bmf/engine/connector/include/connector.hpp index fe2f00be..398697e7 100644 --- a/bmf/engine/connector/include/connector.hpp +++ b/bmf/engine/connector/include/connector.hpp @@ -20,9 +20,9 @@ #include "running_info.h" #if defined(__clang__) -#define BMF_FUNC_VIS __attribute__ ((__visibility__("default"))) +#define BMF_FUNC_VIS __attribute__((__visibility__("default"))) #elif defined(__GNUC__) -#define BMF_FUNC_VIS __attribute__ ((visibility("default"))) +#define BMF_FUNC_VIS __attribute__((visibility("default"))) #else #define BMF_FUNC_VIS #endif @@ -37,173 +37,183 @@ #include namespace bmf { +/* + * @brief Interface of a runnable BMF Graph instance. + */ +class BMFGraph { + public: + /* + * @brief Create a BMF Graph instance from provided graph_config. + * @param [in] graph_config Config string in serialized json style. + * @param [in] is_path When set to true, 'graph_config' means a path to json + * file containing graph config. + * This param is set to False by default. + * @param [in] need_merge When set to true, BMF will preprocess graph to + * merge ffmpeg_filter nodes into groups if possible. + * A merge operation can make graph running faster, but may also + * introduce some stability issue. + * This param is set to true by default. + */ + BMF_FUNC_VIS BMFGraph(std::string const &graph_config, bool is_path = false, + bool need_merge = true); + + BMF_FUNC_VIS BMFGraph(BMFGraph const &graph); + + BMF_FUNC_VIS ~BMFGraph(); + + BMF_FUNC_VIS BMFGraph &operator=(BMFGraph const &graph); + + BMF_FUNC_VIS uint32_t uid(); + + /* + * @brief Start running a BMF Graph instance. + */ + BMF_FUNC_VIS void start(); + + /* + * @brief Update a dynamical BMF Graph instance. + */ + BMF_FUNC_VIS void update(const std::string &config, bool is_path); + + /* + * @brief Wait a running BMF Graph instance stopping. + * It may be stuck if the instance has not been 'start'ed. + */ + BMF_FUNC_VIS int close(); + + BMF_FUNC_VIS int force_close(); + + /* + * @brief + * @param stream_name [in] + * @param packet [in] + * + * @return + */ + BMF_FUNC_VIS int add_input_stream_packet(std::string const &stream_name, + bmf_sdk::Packet &packet, + bool block = false); + + /* + * @brief + * @param stream_name [in] + * @param block [in] + * + * @return + */ + BMF_FUNC_VIS bmf_sdk::Packet + poll_output_stream_packet(std::string const &stream_name, + bool block = true); + /* - * @brief Interface of a runnable BMF Graph instance. - */ - class BMFGraph { - public: - /* - * @brief Create a BMF Graph instance from provided graph_config. - * @param [in] graph_config Config string in serialized json style. - * @param [in] is_path When set to true, 'graph_config' means a path to json file containing graph config. - * This param is set to False by default. - * @param [in] need_merge When set to true, BMF will preprocess graph to merge ffmpeg_filter nodes into groups if possible. - * A merge operation can make graph running faster, but may also introduce some stability issue. - * This param is set to true by default. - */ - BMF_FUNC_VIS BMFGraph(std::string const &graph_config, bool is_path = false, bool need_merge = true); - - BMF_FUNC_VIS BMFGraph(BMFGraph const &graph); - - BMF_FUNC_VIS ~BMFGraph(); - - BMF_FUNC_VIS BMFGraph &operator=(BMFGraph const &graph); - - BMF_FUNC_VIS uint32_t uid(); - - /* - * @brief Start running a BMF Graph instance. - */ - BMF_FUNC_VIS void start(); - - /* - * @brief Update a dynamical BMF Graph instance. - */ - BMF_FUNC_VIS void update(const std::string &config, bool is_path); - - /* - * @brief Wait a running BMF Graph instance stopping. - * It may be stuck if the instance has not been 'start'ed. - */ - BMF_FUNC_VIS int close(); - - BMF_FUNC_VIS int force_close(); - - /* - * @brief - * @param stream_name [in] - * @param packet [in] - * - * @return - */ - BMF_FUNC_VIS int add_input_stream_packet(std::string const &stream_name, bmf_sdk::Packet &packet, bool block = false); - - /* - * @brief - * @param stream_name [in] - * @param block [in] - * - * @return - */ - BMF_FUNC_VIS bmf_sdk::Packet poll_output_stream_packet(std::string const &stream_name, bool block = true); - - /* - * @brief - * @return - */ - BMF_FUNC_VIS GraphRunningInfo status(); - - private: - uint32_t graph_uid_; - }; - - - /* - * @brief Interface of a Module instance. - */ - class BMFModule { - public: - /* - * @brief - * @param [in] module_name - * @param [in] option - * @param [in] module_type - * @param [in] module_path - * @param [in] module_entry - */ - BMF_FUNC_VIS BMFModule(std::string const &module_name, std::string const &option, std::string const &module_type = "", - std::string const &module_path = "", std::string const &module_entry = ""); - - /* - * @brief - * @param [in] module_p - */ - BMF_FUNC_VIS BMFModule(std::shared_ptr module_p); - - BMF_FUNC_VIS BMFModule(BMFModule const &mod); - - BMF_FUNC_VIS ~BMFModule(); - - BMF_FUNC_VIS BMFModule &operator=(BMFModule const &mod); - - /* - * @brief - * @return - */ - BMF_FUNC_VIS uint32_t uid(); - - /* - * @brief - * @return - */ - BMF_FUNC_VIS int32_t process(bmf_sdk::Task &task); - - /* - * @brief - * @return - */ - BMF_FUNC_VIS int32_t reset(); + * @brief + * @return + */ + BMF_FUNC_VIS GraphRunningInfo status(); - /* - * @brief - * @return - */ - BMF_FUNC_VIS int32_t init(); - - /* - * @brief - * @return - */ - BMF_FUNC_VIS int32_t close(); - - private: - friend BMFGraph; - - uint32_t module_uid_; - std::string module_name_; - }; - - - /* - * @brief Interface of a registered callback. - */ - class BMFCallback { - public: - /* - * @brief - * @param [in] callback - */ - BMF_FUNC_VIS BMFCallback(std::function callback); - - BMF_FUNC_VIS BMFCallback(BMFCallback const &cb); + private: + uint32_t graph_uid_; +}; - BMF_FUNC_VIS ~BMFCallback(); - - BMF_FUNC_VIS BMFCallback &operator=(BMFCallback const &cb); +/* + * @brief Interface of a Module instance. + */ +class BMFModule { + public: + /* + * @brief + * @param [in] module_name + * @param [in] option + * @param [in] module_type + * @param [in] module_path + * @param [in] module_entry + */ + BMF_FUNC_VIS BMFModule(std::string const &module_name, + std::string const &option, + std::string const &module_type = "", + std::string const &module_path = "", + std::string const &module_entry = ""); - /* - * @brief - * @return - */ - BMF_FUNC_VIS uint32_t uid(); + /* + * @brief + * @param [in] module_p + */ + BMF_FUNC_VIS BMFModule(std::shared_ptr module_p); + + BMF_FUNC_VIS BMFModule(BMFModule const &mod); + + BMF_FUNC_VIS ~BMFModule(); + + BMF_FUNC_VIS BMFModule &operator=(BMFModule const &mod); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS uint32_t uid(); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS int32_t process(bmf_sdk::Task &task); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS int32_t reset(); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS int32_t init(); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS int32_t close(); + + private: + friend BMFGraph; + + uint32_t module_uid_; + std::string module_name_; +}; + +/* + * @brief Interface of a registered callback. + */ +class BMFCallback { + public: + /* + * @brief + * @param [in] callback + */ + BMF_FUNC_VIS + BMFCallback(std::function callback); + + BMF_FUNC_VIS BMFCallback(BMFCallback const &cb); + + BMF_FUNC_VIS ~BMFCallback(); + + BMF_FUNC_VIS BMFCallback &operator=(BMFCallback const &cb); + + /* + * @brief + * @return + */ + BMF_FUNC_VIS uint32_t uid(); - private: - friend BMFGraph; + private: + friend BMFGraph; - uint32_t callback_uid_; - }; + uint32_t callback_uid_; +}; - void ChangeDmpPath(std::string path); +void ChangeDmpPath(std::string path); } -#endif //CONNECTOR_CONNECTOR_HPP +#endif // CONNECTOR_CONNECTOR_HPP diff --git a/bmf/engine/connector/internal/env_init.cpp b/bmf/engine/connector/internal/env_init.cpp index 64c93e51..3fceab42 100644 --- a/bmf/engine/connector/internal/env_init.cpp +++ b/bmf/engine/connector/internal/env_init.cpp @@ -9,32 +9,32 @@ #ifdef BMF_ENABLE_BREAKPAD #define __STDC_FORMAT_MACROS #include "client/linux/handler/exception_handler.h" -static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, - void* context, bool succeeded) { - printf("Dump path: %s\n", descriptor.path()); - return succeeded; +static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, + void *context, bool succeeded) { + printf("Dump path: %s\n", descriptor.path()); + return succeeded; } #endif namespace bmf::internal { - EnvInit::EnvInit() { +EnvInit::EnvInit() { #ifdef BMF_ENABLE_GLOG - google::InstallFailureSignalHandler(); + google::InstallFailureSignalHandler(); #endif #ifdef BMF_ENABLE_BREAKPAD - std::string path("./"); - if (getenv("BMF_BREADKPAD_PATH")) - path = getenv("BMF_BREADKPAD_PATH"); - static google_breakpad::MinidumpDescriptor descriptor(path); - handler = new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1); + std::string path("./"); + if (getenv("BMF_BREADKPAD_PATH")) + path = getenv("BMF_BREADKPAD_PATH"); + static google_breakpad::MinidumpDescriptor descriptor(path); + handler = new google_breakpad::ExceptionHandler( + descriptor, NULL, dumpCallback, NULL, true, -1); #endif - } +} - void EnvInit::ChangeDmpPath(std::string path) { +void EnvInit::ChangeDmpPath(std::string path) { #ifdef BMF_ENABLE_BREAKPAD - google_breakpad::MinidumpDescriptor descriptor(path); - handler->set_minidump_descriptor(descriptor); + google_breakpad::MinidumpDescriptor descriptor(path); + handler->set_minidump_descriptor(descriptor); #endif - } - +} } \ No newline at end of file diff --git a/bmf/engine/connector/internal/instance_mapping.hpp b/bmf/engine/connector/internal/instance_mapping.hpp index 85ab48fe..21611cef 100644 --- a/bmf/engine/connector/internal/instance_mapping.hpp +++ b/bmf/engine/connector/internal/instance_mapping.hpp @@ -10,60 +10,58 @@ #include namespace bmf::internal { - template - class InstanceMapping { - public: - InstanceMapping(); +template class InstanceMapping { + public: + InstanceMapping(); - uint32_t insert(std::shared_ptr instance) { - //std::lock_guard _(lk_); - ++counting_; - mapping_[counting_] = instance; - ref_cnt_[counting_] = 1; - return counting_; - } + uint32_t insert(std::shared_ptr instance) { + // std::lock_guard _(lk_); + ++counting_; + mapping_[counting_] = instance; + ref_cnt_[counting_] = 1; + return counting_; + } - bool ref(uint32_t idx) { - //std::lock_guard _(lk_); - if (mapping_.count(idx) == 0) - return false; - ++ref_cnt_[idx]; - return true; - } + bool ref(uint32_t idx) { + // std::lock_guard _(lk_); + if (mapping_.count(idx) == 0) + return false; + ++ref_cnt_[idx]; + return true; + } - std::shared_ptr get(uint32_t idx) { - //std::lock_guard _(lk_); - if (mapping_.count(idx) == 0) - throw std::range_error("Instance not existed."); - return mapping_[idx]; - } + std::shared_ptr get(uint32_t idx) { + // std::lock_guard _(lk_); + if (mapping_.count(idx) == 0) + throw std::range_error("Instance not existed."); + return mapping_[idx]; + } - bool exist(uint32_t idx) { - //std::lock_guard _(lk_); - return mapping_.count(idx) != 0; - } + bool exist(uint32_t idx) { + // std::lock_guard _(lk_); + return mapping_.count(idx) != 0; + } - bool remove(uint32_t idx) { - //std::lock_guard _(lk_); - if (mapping_.count(idx) == 0) - return false; - --ref_cnt_[idx]; - if (ref_cnt_[idx] == 0) { - mapping_.erase(idx); - ref_cnt_.erase(idx); - } - return true; - } + bool remove(uint32_t idx) { + // std::lock_guard _(lk_); + if (mapping_.count(idx) == 0) + return false; + --ref_cnt_[idx]; + if (ref_cnt_[idx] == 0) { + mapping_.erase(idx); + ref_cnt_.erase(idx); + } + return true; + } - private: - uint32_t counting_; - std::mutex lk_; - std::map > mapping_; - std::map ref_cnt_; - }; + private: + uint32_t counting_; + std::mutex lk_; + std::map> mapping_; + std::map ref_cnt_; +}; - template - InstanceMapping::InstanceMapping() :counting_(0) {} - } +template InstanceMapping::InstanceMapping() : counting_(0) {} +} -#endif //CONNECTOR_INSTANCE_MAPPING_HPP +#endif // CONNECTOR_INSTANCE_MAPPING_HPP diff --git a/bmf/engine/connector/internal/mapping.cpp b/bmf/engine/connector/internal/mapping.cpp index 3bbf67af..2a1bfe06 100644 --- a/bmf/engine/connector/internal/mapping.cpp +++ b/bmf/engine/connector/internal/mapping.cpp @@ -17,21 +17,22 @@ #include "mapping.h" namespace bmf::internal { - InstanceMapping &ConnectorMapping::GraphInstanceMapping() { - static auto *graph_instance_mapping = new InstanceMapping(); - return *graph_instance_mapping; - } +InstanceMapping &ConnectorMapping::GraphInstanceMapping() { + static auto *graph_instance_mapping = + new InstanceMapping(); + return *graph_instance_mapping; +} - InstanceMapping &ConnectorMapping::ModuleInstanceMapping() { - static auto *module_instance_mapping = new InstanceMapping(); - return *module_instance_mapping; - } - - InstanceMapping > & - ConnectorMapping::ModuleCallbackInstanceMapping() { - static auto *module_callback_instance_mapping = - new InstanceMapping >(); - return *module_callback_instance_mapping; - } +InstanceMapping &ConnectorMapping::ModuleInstanceMapping() { + static auto *module_instance_mapping = + new InstanceMapping(); + return *module_instance_mapping; +} +InstanceMapping> & +ConnectorMapping::ModuleCallbackInstanceMapping() { + static auto *module_callback_instance_mapping = + new InstanceMapping>(); + return *module_callback_instance_mapping; +} } \ No newline at end of file diff --git a/bmf/engine/connector/src/builder.cpp b/bmf/engine/connector/src/builder.cpp index b94d43fb..da51f447 100644 --- a/bmf/engine/connector/src/builder.cpp +++ b/bmf/engine/connector/src/builder.cpp @@ -28,970 +28,1038 @@ #include "../include/connector.hpp" namespace bmf::builder { - namespace internal { - RealStream::RealStream(const std::shared_ptr &node, std::string name, std::string notify, - std::string alias) - : node_(node), name_(std::move(name)), notify_(std::move(notify)), alias_(std::move(alias)) {} - - void RealStream::SetNotify(std::string const ¬ify) { - auto node = node_.lock(); - int idx = -1; - for (idx = 0; idx < node->outputStreams_.size(); ++idx) - if (node->outputStreams_[idx]->name_ == name_) - break; - if (idx < 0) - throw std::logic_error("Internal error."); - node->GiveStreamNotify(idx, notify); - - } +namespace internal { +RealStream::RealStream(const std::shared_ptr &node, std::string name, + std::string notify, std::string alias) + : node_(node), name_(std::move(name)), notify_(std::move(notify)), + alias_(std::move(alias)) {} + +void RealStream::SetNotify(std::string const ¬ify) { + auto node = node_.lock(); + int idx = -1; + for (idx = 0; idx < node->outputStreams_.size(); ++idx) + if (node->outputStreams_[idx]->name_ == name_) + break; + if (idx < 0) + throw std::logic_error("Internal error."); + node->GiveStreamNotify(idx, notify); +} - void RealStream::SetAlias(std::string const &alias) { - auto node = node_.lock(); - int idx = -1; - for (idx = 0; idx < node->outputStreams_.size(); ++idx) - if (node->outputStreams_[idx]->name_ == name_) - break; - if (idx < 0) - throw std::logic_error("Internal error."); - node->GiveStreamAlias(idx, alias); +void RealStream::SetAlias(std::string const &alias) { + auto node = node_.lock(); + int idx = -1; + for (idx = 0; idx < node->outputStreams_.size(); ++idx) + if (node->outputStreams_[idx]->name_ == name_) + break; + if (idx < 0) + throw std::logic_error("Internal error."); + node->GiveStreamAlias(idx, alias); +} - } +std::shared_ptr RealStream::AddModule( + std::string const &alias, const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + inputStreams.insert(inputStreams.begin(), shared_from_this()); + return node_.lock()->graph_.lock()->AddModule( + alias, option, inputStreams, moduleName, moduleType, modulePath, + moduleEntry, inputStreamManager, scheduler); +} - std::shared_ptr RealStream::AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, - std::vector > inputStreams, - std::string const &moduleName, - ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, - InputManagerType inputStreamManager, - int scheduler) { - inputStreams.insert(inputStreams.begin(), shared_from_this()); - return node_.lock()->graph_.lock()->AddModule(alias, option, inputStreams, moduleName, moduleType, - modulePath, - moduleEntry, inputStreamManager, scheduler); - } +nlohmann::json RealStream::Dump() { + nlohmann::json info; - nlohmann::json RealStream::Dump() { - nlohmann::json info; + info["identifier"] = (notify_.empty() ? "" : (notify_ + ":")) + name_; + info["alias"] = alias_; - info["identifier"] = (notify_.empty() ? "" : (notify_ + ":")) + name_; - info["alias"] = alias_; + return info; +} - return info; - } +void RealStream::Start() { + auto node = node_.lock(); + node->graph_.lock()->Start(shared_from_this(), false, true); +} - void RealStream::Start() { - auto node = node_.lock(); - node->graph_.lock()->Start(shared_from_this(), false, true); - } +RealNode::ModuleMetaInfo::ModuleMetaInfo(std::string moduleName, + ModuleType moduleType, + std::string modulePath, + std::string moduleEntry) + : moduleName_(std::move(moduleName)), moduleType_(moduleType), + modulePath_(std::move(modulePath)), moduleEntry_(std::move(moduleEntry)) { +} - RealNode::ModuleMetaInfo::ModuleMetaInfo(std::string moduleName, ModuleType moduleType, - std::string modulePath, std::string moduleEntry) - : moduleName_(std::move(moduleName)), moduleType_(moduleType), modulePath_(std::move(modulePath)), - moduleEntry_(std::move(moduleEntry)) {} - - nlohmann::json RealNode::ModuleMetaInfo::Dump() { - nlohmann::json info; - - switch (moduleType_) { - case C: - info["type"] = "c"; - break; - case CPP: - info["type"] = "c++"; - break; - case Python: - info["type"] = "python"; - break; - case Go: - info["type"] = "go"; - break; - } - info["name"] = moduleName_; - info["path"] = modulePath_; - info["entry"] = moduleEntry_; - - return info; - } +nlohmann::json RealNode::ModuleMetaInfo::Dump() { + nlohmann::json info; + + switch (moduleType_) { + case C: + info["type"] = "c"; + break; + case CPP: + info["type"] = "c++"; + break; + case Python: + info["type"] = "python"; + break; + case Go: + info["type"] = "go"; + break; + } + info["name"] = moduleName_; + info["path"] = modulePath_; + info["entry"] = moduleEntry_; + + return info; +} - nlohmann::json RealNode::NodeMetaInfo::Dump() { - nlohmann::json info; +nlohmann::json RealNode::NodeMetaInfo::Dump() { + nlohmann::json info; - info["premodule_id"] = preModuleUID_; - info["callback_bindings"] = nlohmann::json::object(); - for (auto &kv:callbackBinding_) - { - info["callback_bindings"][kv.first] = kv.second; - } + info["premodule_id"] = preModuleUID_; + info["callback_bindings"] = nlohmann::json::object(); + for (auto &kv : callbackBinding_) { + info["callback_bindings"][kv.first] = kv.second; + } - return info; - } + return info; +} - RealNode::RealNode(const std::shared_ptr &graph, int id, std::string alias, - const bmf_sdk::JsonParam &option, - std::vector > inputStreams, std::string const &moduleName, - ModuleType moduleType, - std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) - : graph_(graph), id_(id), alias_(std::move(alias)), option_(option), - moduleInfo_({moduleName, moduleType, modulePath, moduleEntry}), - metaInfo_(), inputStreams_(std::move(inputStreams)), inputManager_(inputStreamManager), - scheduler_(scheduler) { -// outputStreams_.reserve(BMF_MAX_CAPACITY); - } +RealNode::RealNode(const std::shared_ptr &graph, int id, + std::string alias, const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) + : graph_(graph), id_(id), alias_(std::move(alias)), option_(option), + moduleInfo_({moduleName, moduleType, modulePath, moduleEntry}), + metaInfo_(), inputStreams_(std::move(inputStreams)), + inputManager_(inputStreamManager), scheduler_(scheduler) { + // outputStreams_.reserve(BMF_MAX_CAPACITY); +} - std::shared_ptr RealNode::Stream(int idx) { - if (idx < 0) - throw std::overflow_error("Requesting unexisted stream using index."); -// if (idx >= BMF_MAX_CAPACITY) -// throw std::overflow_error("Stream index bigger than max capacity (1024 by default)."); - for (auto i = outputStreams_.size(); i <= idx; ++i) { - auto buf = new char[255]; - std::sprintf(buf, "%s_%d_%lu", moduleInfo_.moduleName_.c_str(), id_, i); - outputStreams_.emplace_back( - std::move(std::make_shared(shared_from_this(), std::string(buf), "", ""))); - delete[] buf; - } - return outputStreams_[idx]; - } +std::shared_ptr RealNode::Stream(int idx) { + if (idx < 0) + throw std::overflow_error("Requesting unexisted stream using index."); + // if (idx >= BMF_MAX_CAPACITY) + // throw std::overflow_error("Stream index bigger than max + // capacity (1024 by default)."); + for (auto i = outputStreams_.size(); i <= idx; ++i) { + auto buf = new char[255]; + std::sprintf(buf, "%s_%d_%lu", moduleInfo_.moduleName_.c_str(), id_, i); + outputStreams_.emplace_back(std::move(std::make_shared( + shared_from_this(), std::string(buf), "", ""))); + delete[] buf; + } + return outputStreams_[idx]; +} - std::shared_ptr RealNode::Stream(std::string const &name) { - auto graph = graph_.lock(); - if (graph->existedStreamAlias_.count(name) && graph->existedStreamAlias_[name]->node_.lock().get() == this) - return graph->existedStreamAlias_[name]; - if (existedStreamNotify_.count(name)) - return existedStreamNotify_[name]; - - throw std::logic_error("Requesting unexisted stream using name. (Not an alias nor notify.)"); - } +std::shared_ptr RealNode::Stream(std::string const &name) { + auto graph = graph_.lock(); + if (graph->existedStreamAlias_.count(name) && + graph->existedStreamAlias_[name]->node_.lock().get() == this) + return graph->existedStreamAlias_[name]; + if (existedStreamNotify_.count(name)) + return existedStreamNotify_[name]; - void RealNode::SetAlias(std::string const &alias) { - graph_.lock()->GiveNodeAlias(shared_from_this(), alias); - } + throw std::logic_error( + "Requesting unexisted stream using name. (Not an alias nor notify.)"); +} - void RealNode::GiveStreamNotify(int idx, std::string const ¬ify) { - auto graph = graph_.lock(); - if (graph->existedNodeAlias_.count(notify)) - throw std::logic_error("Duplicated stream notify with existing node alias."); - if (graph->existedStreamAlias_.count(notify)) - throw std::logic_error("Duplicated stream notify with existing stream alias."); - if (existedStreamNotify_.count(notify)) - throw std::logic_error("Duplicated stream notify with existing stream notify."); - existedStreamNotify_[notify] = outputStreams_[idx]; - outputStreams_[idx]->notify_ = notify; - } +void RealNode::SetAlias(std::string const &alias) { + graph_.lock()->GiveNodeAlias(shared_from_this(), alias); +} - void RealNode::GiveStreamAlias(int idx, std::string const &alias) { - graph_.lock()->GiveStreamAlias(outputStreams_[idx], alias); - } +void RealNode::GiveStreamNotify(int idx, std::string const ¬ify) { + auto graph = graph_.lock(); + if (graph->existedNodeAlias_.count(notify)) + throw std::logic_error( + "Duplicated stream notify with existing node alias."); + if (graph->existedStreamAlias_.count(notify)) + throw std::logic_error( + "Duplicated stream notify with existing stream alias."); + if (existedStreamNotify_.count(notify)) + throw std::logic_error( + "Duplicated stream notify with existing stream notify."); + existedStreamNotify_[notify] = outputStreams_[idx]; + outputStreams_[idx]->notify_ = notify; +} - void RealNode::SetInputManager(InputManagerType inputStreamManager) { - if (graph_.lock()->mode_ == ServerMode) { - if (inputStreamManager != Server) - throw std::logic_error( - "cannot set input_manager other than Server to node in graph set to ServerMode"); - } - inputManager_ = inputStreamManager; - } +void RealNode::GiveStreamAlias(int idx, std::string const &alias) { + graph_.lock()->GiveStreamAlias(outputStreams_[idx], alias); +} - void RealNode::SetScheduler(int scheduler) { - scheduler_ = scheduler; - } +void RealNode::SetInputManager(InputManagerType inputStreamManager) { + if (graph_.lock()->mode_ == ServerMode) { + if (inputStreamManager != Server) + throw std::logic_error("cannot set input_manager other than Server " + "to node in graph set to ServerMode"); + } + inputManager_ = inputStreamManager; +} - void RealNode::SetPreModule(bmf::BMFModule preModuleInstance) { - metaInfo_.preModuleInstance_ = std::make_shared(preModuleInstance); - metaInfo_.preModuleUID_ = preModuleInstance.uid(); - } +void RealNode::SetScheduler(int scheduler) { scheduler_ = scheduler; } - void RealNode::AddCallback(long long key, bmf::BMFCallback callbackInstance) { - metaInfo_.callbackInstances_[key] = std::make_shared(callbackInstance); - metaInfo_.callbackBinding_[key] = callbackInstance.uid(); - } +void RealNode::SetPreModule(bmf::BMFModule preModuleInstance) { + metaInfo_.preModuleInstance_ = + std::make_shared(preModuleInstance); + metaInfo_.preModuleUID_ = preModuleInstance.uid(); +} - std::shared_ptr - RealNode::AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, - std::vector > inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - inputStreams.insert(inputStreams.begin(), Stream(0)); - return graph_.lock()->AddModule(alias, option, inputStreams, moduleName, moduleType, modulePath, - moduleEntry, inputStreamManager, scheduler); - } +void RealNode::AddCallback(long long key, bmf::BMFCallback callbackInstance) { + metaInfo_.callbackInstances_[key] = + std::make_shared(callbackInstance); + metaInfo_.callbackBinding_[key] = callbackInstance.uid(); +} - nlohmann::json RealNode::Dump() { - nlohmann::json info; - - info["id"] = id_; - info["alias"] = alias_; - info["module_info"] = moduleInfo_.Dump(); - info["meta_info"] = metaInfo_.Dump(); - info["input_streams"] = nlohmann::json::array(); - for (auto &s:inputStreams_) - info["input_streams"].push_back(s->Dump()); - info["output_streams"] = nlohmann::json::array(); - for (auto &s:outputStreams_) - info["output_streams"].push_back(s->Dump()); - info["option"] = option_.json_value_; - info["scheduler"] = scheduler_; - switch (inputManager_) { - case Default: - info["input_manager"] = "default"; - break; - case Immediate: - info["input_manager"] = "immediate"; - break; - case Server: - info["input_manager"] = "server"; - break; - case FrameSync: - info["input_manager"] = "framesync"; - break; - case ClockSync: - info["input_manager"] = "clocksync"; - break; - default: - info["input_manager"] = "default"; - } - - return info; - } +std::shared_ptr +RealNode::AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, + std::vector> inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + inputStreams.insert(inputStreams.begin(), Stream(0)); + return graph_.lock()->AddModule(alias, option, inputStreams, moduleName, + moduleType, modulePath, moduleEntry, + inputStreamManager, scheduler); +} - RealGraph::RealGraph(GraphMode runMode, const bmf_sdk::JsonParam &graphOption) - : mode_(runMode), graphOption_(graphOption), - placeholderNode_(nullptr) {} - - void RealGraph::GiveStreamAlias(std::shared_ptr stream, std::string const &alias) { - if (existedNodeAlias_.count(alias)) - throw std::logic_error("Duplicated stream alias with existing node alias."); - if (existedStreamAlias_.count(alias)) - throw std::logic_error("Duplicated stream alias with existing stream alias."); - for (auto &nd:nodes_) - if (nd->existedStreamNotify_.count(alias)) - throw std::logic_error("Duplicated stream alias with existing stream notify."); - existedStreamAlias_[alias] = std::move(stream); - existedStreamAlias_[alias]->alias_ = alias; - } +nlohmann::json RealNode::Dump() { + nlohmann::json info; + + info["id"] = id_; + info["alias"] = alias_; + info["module_info"] = moduleInfo_.Dump(); + info["meta_info"] = metaInfo_.Dump(); + info["input_streams"] = nlohmann::json::array(); + for (auto &s : inputStreams_) + info["input_streams"].push_back(s->Dump()); + info["output_streams"] = nlohmann::json::array(); + for (auto &s : outputStreams_) + info["output_streams"].push_back(s->Dump()); + info["option"] = option_.json_value_; + info["scheduler"] = scheduler_; + switch (inputManager_) { + case Default: + info["input_manager"] = "default"; + break; + case Immediate: + info["input_manager"] = "immediate"; + break; + case Server: + info["input_manager"] = "server"; + break; + case FrameSync: + info["input_manager"] = "framesync"; + break; + case ClockSync: + info["input_manager"] = "clocksync"; + break; + default: + info["input_manager"] = "default"; + } + + return info; +} - void RealGraph::GiveNodeAlias(std::shared_ptr node, std::string const &alias) { - if (existedNodeAlias_.count(alias)) - throw std::logic_error("Duplicated node alias with existing node alias."); - if (existedStreamAlias_.count(alias)) - throw std::logic_error("Duplicated node alias with existing stream alias."); - for (auto &nd:nodes_) - if (nd->existedStreamNotify_.count(alias)) - throw std::logic_error("Duplicated node alias with existing stream notify."); - existedNodeAlias_[alias] = std::move(node); - existedNodeAlias_[alias]->alias_ = alias; - } +RealGraph::RealGraph(GraphMode runMode, const bmf_sdk::JsonParam &graphOption) + : mode_(runMode), graphOption_(graphOption), placeholderNode_(nullptr) {} + +void RealGraph::GiveStreamAlias(std::shared_ptr stream, + std::string const &alias) { + if (existedNodeAlias_.count(alias)) + throw std::logic_error( + "Duplicated stream alias with existing node alias."); + if (existedStreamAlias_.count(alias)) + throw std::logic_error( + "Duplicated stream alias with existing stream alias."); + for (auto &nd : nodes_) + if (nd->existedStreamNotify_.count(alias)) + throw std::logic_error( + "Duplicated stream alias with existing stream notify."); + existedStreamAlias_[alias] = std::move(stream); + existedStreamAlias_[alias]->alias_ = alias; +} - std::shared_ptr RealGraph::AddModule(std::string const &alias, const bmf_sdk::JsonParam &option, - const std::vector > &inputStreams, - std::string const &moduleName, - ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, - InputManagerType inputStreamManager, - int scheduler) { -// if (nodes_.size() + 1 >= BMF_MAX_CAPACITY) -// throw std::overflow_error("Node number bigger than max capacity (1024 by default)."); - if (mode_ == ServerMode) - inputStreamManager = Server; - int node_id = nodes_.size(); - nodes_.emplace_back(std::move( - std::make_shared(shared_from_this(), node_id, alias, option, inputStreams, - moduleName, moduleType, modulePath, moduleEntry, inputStreamManager, - scheduler))); - return nodes_[node_id]; - } +void RealGraph::GiveNodeAlias(std::shared_ptr node, + std::string const &alias) { + if (existedNodeAlias_.count(alias)) + throw std::logic_error( + "Duplicated node alias with existing node alias."); + if (existedStreamAlias_.count(alias)) + throw std::logic_error( + "Duplicated node alias with existing stream alias."); + for (auto &nd : nodes_) + if (nd->existedStreamNotify_.count(alias)) + throw std::logic_error( + "Duplicated node alias with existing stream notify."); + existedNodeAlias_[alias] = std::move(node); + existedNodeAlias_[alias]->alias_ = alias; +} - std::shared_ptr RealGraph::GetAliasedNode(std::string const &alias) { - if (!existedNodeAlias_.count(alias)) - throw std::logic_error("Unexisted aliased node."); - return existedNodeAlias_[alias]; - } +std::shared_ptr RealGraph::AddModule( + std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector> &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + // if (nodes_.size() + 1 >= BMF_MAX_CAPACITY) + // throw std::overflow_error("Node number bigger than max + // capacity (1024 by default)."); + if (mode_ == ServerMode) + inputStreamManager = Server; + int node_id = nodes_.size(); + nodes_.emplace_back(std::move(std::make_shared( + shared_from_this(), node_id, alias, option, inputStreams, moduleName, + moduleType, modulePath, moduleEntry, inputStreamManager, scheduler))); + return nodes_[node_id]; +} - std::shared_ptr RealGraph::GetAliasedStream(std::string const &alias) { - if (!existedStreamAlias_.count(alias)) - throw std::logic_error("Unexisted aliased stream."); - return existedStreamAlias_[alias]; - } +std::shared_ptr RealGraph::GetAliasedNode(std::string const &alias) { + if (!existedNodeAlias_.count(alias)) + throw std::logic_error("Unexisted aliased node."); + return existedNodeAlias_[alias]; +} - std::shared_ptr RealGraph::NewPlaceholderStream() { - if (placeholderNode_ == nullptr) - placeholderNode_ = std::move( - std::make_shared(shared_from_this(), std::numeric_limits::max(), "", bmf_sdk::JsonParam(), - std::vector >(), "BMFPlaceholderNode", - CPP, "", "", Immediate, 0)); +std::shared_ptr +RealGraph::GetAliasedStream(std::string const &alias) { + if (!existedStreamAlias_.count(alias)) + throw std::logic_error("Unexisted aliased stream."); + return existedStreamAlias_[alias]; +} - return placeholderNode_->Stream(placeholderNode_->outputStreams_.size()); - } +std::shared_ptr RealGraph::NewPlaceholderStream() { + if (placeholderNode_ == nullptr) + placeholderNode_ = std::move(std::make_shared( + shared_from_this(), std::numeric_limits::max(), "", + bmf_sdk::JsonParam(), std::vector>(), + "BMFPlaceholderNode", CPP, "", "", Immediate, 0)); - nlohmann::json RealGraph::Dump() { - nlohmann::json info; - - info["input_streams"] = nlohmann::json::array(); - info["output_streams"] = nlohmann::json::array(); - info["nodes"] = nlohmann::json::array(); - info["option"] = graphOption_.json_value_; - switch (mode_) { - case NormalMode: - info["mode"] = "Normal"; - break; - case ServerMode: - info["mode"] = "Server"; - break; - case GeneratorMode: - info["mode"] = "Generator"; - break; - case SubGraphMode: - info["mode"] = "Subgraph"; - break; - case UpdateMode: - info["mode"] = "Update"; - break; - } - for (auto &nd:nodes_) - info["nodes"].push_back(nd->Dump()); - for (auto &s:inputStreams_) - info["input_streams"].push_back(s->Dump()); - for (auto &s:outputStreams_) - info["output_streams"].push_back(s->Dump()); - - return info; - } + return placeholderNode_->Stream(placeholderNode_->outputStreams_.size()); +} - void RealGraph::SetOption(const bmf_sdk::JsonParam& optionPatch) { - graphOption_.merge_patch(optionPatch); - } +nlohmann::json RealGraph::Dump() { + nlohmann::json info; + + info["input_streams"] = nlohmann::json::array(); + info["output_streams"] = nlohmann::json::array(); + info["nodes"] = nlohmann::json::array(); + info["option"] = graphOption_.json_value_; + switch (mode_) { + case NormalMode: + info["mode"] = "Normal"; + break; + case ServerMode: + info["mode"] = "Server"; + break; + case GeneratorMode: + info["mode"] = "Generator"; + break; + case SubGraphMode: + info["mode"] = "Subgraph"; + break; + case UpdateMode: + info["mode"] = "Update"; + break; + } + for (auto &nd : nodes_) + info["nodes"].push_back(nd->Dump()); + for (auto &s : inputStreams_) + info["input_streams"].push_back(s->Dump()); + for (auto &s : outputStreams_) + info["output_streams"].push_back(s->Dump()); + + return info; +} - void RealGraph::Start(bool dumpGraph, bool needMerge) { - auto graph_config = Dump().dump(4); - BMFLOG(BMF_INFO) << graph_config << std::endl; - if (dumpGraph || - (graphOption_.json_value_.count("dump_graph") && graphOption_.json_value_["dump_graph"] == 1)) { - BMFLOG(BMF_INFO) << "graph_config dump" << std::endl; - std::ofstream graph_file("graph.json", std::ios::app); - BMFLOG(BMF_INFO) << graph_config << std::endl; - graph_file << graph_config; - graph_file.close(); - } - if (graphInstance_ == nullptr) - graphInstance_ = std::make_shared(graph_config, false, needMerge); - graphInstance_->start(); - } +void RealGraph::SetOption(const bmf_sdk::JsonParam &optionPatch) { + graphOption_.merge_patch(optionPatch); +} - int RealGraph::Run(bool dumpGraph, bool needMerge) { - auto graph_config = Dump().dump(4); - if (dumpGraph || - (graphOption_.json_value_.count("dump_graph") && graphOption_.json_value_["dump_graph"] == 1)) { - std::ofstream graph_file("graph.json", std::ios::app); - graph_file << graph_config; - graph_file.close(); - } - if (graphInstance_ == nullptr) - graphInstance_ = std::make_shared(graph_config, false, needMerge); - graphInstance_->start(); - return graphInstance_->close(); - } +void RealGraph::Start(bool dumpGraph, bool needMerge) { + auto graph_config = Dump().dump(4); + BMFLOG(BMF_INFO) << graph_config << std::endl; + if (dumpGraph || (graphOption_.json_value_.count("dump_graph") && + graphOption_.json_value_["dump_graph"] == 1)) { + BMFLOG(BMF_INFO) << "graph_config dump" << std::endl; + std::ofstream graph_file("graph.json", std::ios::app); + BMFLOG(BMF_INFO) << graph_config << std::endl; + graph_file << graph_config; + graph_file.close(); + } + if (graphInstance_ == nullptr) + graphInstance_ = + std::make_shared(graph_config, false, needMerge); + graphInstance_->start(); +} - void RealGraph::Start(const std::shared_ptr& stream, bool dumpGraph, bool needMerge) { - outputStreams_.emplace_back(stream); - generatorStreamName = stream->name_; - Start(dumpGraph, needMerge); - } - - bmf::BMFGraph RealGraph::Instantiate(bool dumpGraph, bool needMerge) { - auto graph_config = Dump().dump(4); - if (dumpGraph || - (graphOption_.json_value_.count("dump_graph") && graphOption_.json_value_["dump_graph"] == 1)) { - std::ofstream graph_file("graph.json", std::ios::app); - graph_file << graph_config; - graph_file.close(); - } - if (graphInstance_ == nullptr) - graphInstance_ = std::make_shared(graph_config, false, needMerge); - return *graphInstance_; - } +int RealGraph::Run(bool dumpGraph, bool needMerge) { + auto graph_config = Dump().dump(4); + if (dumpGraph || (graphOption_.json_value_.count("dump_graph") && + graphOption_.json_value_["dump_graph"] == 1)) { + std::ofstream graph_file("graph.json", std::ios::app); + graph_file << graph_config; + graph_file.close(); + } + if (graphInstance_ == nullptr) + graphInstance_ = + std::make_shared(graph_config, false, needMerge); + graphInstance_->start(); + return graphInstance_->close(); +} - bmf::BMFGraph RealGraph::Instance() { - if (graphInstance_ == nullptr) - throw std::logic_error("trying to get graph instance before instantiated."); - return *graphInstance_; - } +void RealGraph::Start(const std::shared_ptr &stream, + bool dumpGraph, bool needMerge) { + outputStreams_.emplace_back(stream); + generatorStreamName = stream->name_; + Start(dumpGraph, needMerge); +} - Packet RealGraph::Generate() { - Packet pkt = graphInstance_->poll_output_stream_packet(generatorStreamName, true); - return pkt; - } +bmf::BMFGraph RealGraph::Instantiate(bool dumpGraph, bool needMerge) { + auto graph_config = Dump().dump(4); + if (dumpGraph || (graphOption_.json_value_.count("dump_graph") && + graphOption_.json_value_["dump_graph"] == 1)) { + std::ofstream graph_file("graph.json", std::ios::app); + graph_file << graph_config; + graph_file.close(); + } + if (graphInstance_ == nullptr) + graphInstance_ = + std::make_shared(graph_config, false, needMerge); + return *graphInstance_; +} - } +bmf::BMFGraph RealGraph::Instance() { + if (graphInstance_ == nullptr) + throw std::logic_error( + "trying to get graph instance before instantiated."); + return *graphInstance_; +} - std::string GetVersion() { - return BMF_VERSION; - } +Packet RealGraph::Generate() { + Packet pkt = + graphInstance_->poll_output_stream_packet(generatorStreamName, true); + return pkt; +} +} - std::string GetCommit() { - return BMF_COMMIT; - } +std::string GetVersion() { return BMF_VERSION; } + +std::string GetCommit() { return BMF_COMMIT; } + +void ChangeDmpPath(std::string path) { bmf::ChangeDmpPath(path); } + +bmf::BMFModule GetModuleInstance(std::string const &moduleName, + std::string const &option, + ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry) { + std::string type_; + switch (moduleType) { + case C: + type_ = "c"; + break; + case CPP: + type_ = "c++"; + break; + case Python: + type_ = "python"; + break; + case Go: + type_ = "go"; + break; + } + return bmf::BMFModule(moduleName, option, type_, modulePath, moduleEntry); +} - void ChangeDmpPath(std::string path) { - bmf::ChangeDmpPath(path); - } +bmf::BMFCallback +GetCallbackInstance(std::function callback) { + return bmf::BMFCallback(std::move(callback)); +} - bmf::BMFModule GetModuleInstance(std::string const &moduleName, std::string const &option, ModuleType moduleType, - std::string const &modulePath, std::string const &moduleEntry) { - std::string type_; - switch (moduleType) { - case C: - type_ = "c"; - break; - case CPP: - type_ = "c++"; - break; - case Python: - type_ = "python"; - break; - case Go: - type_ = "go"; - break; - } - return bmf::BMFModule(moduleName, option, type_, modulePath, moduleEntry); - } +Stream::Stream(std::shared_ptr baseP) + : baseP_(std::move(baseP)) {} - bmf::BMFCallback GetCallbackInstance(std::function callback) { - return bmf::BMFCallback(std::move(callback)); - } +void Stream::SetNotify(std::string const ¬ify) { baseP_->SetNotify(notify); } - Stream::Stream(std::shared_ptr baseP) : baseP_(std::move(baseP)) {} +void Stream::SetAlias(std::string const &alias) { baseP_->SetAlias(alias); } - void Stream::SetNotify(std::string const ¬ify) { - baseP_->SetNotify(notify); - } +void Stream::Start() { baseP_->Start(); } - void Stream::SetAlias(std::string const &alias) { - baseP_->SetAlias(alias); - } +Node Stream::Module(const std::vector &inStreams, + std::string const &moduleName, ModuleType moduleType, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, moduleType, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - void Stream::Start() { - baseP_->Start(); - } +Node Stream::CppModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, + std::string const &alias, std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, CPP, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node Stream::Module(const std::vector &inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam &option, std::string const &alias, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, moduleType, modulePath, moduleEntry, - inputStreamManager, scheduler); - } +Node Stream::PythonModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, + std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, Python, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node - Stream::CppModule(const std::vector &inStreams, std::string const &moduleName, +Node Stream::GoModule(const std::vector &inStreams, + std::string const &moduleName, const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, + std::string const &alias, std::string const &modulePath, + std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, CPP, modulePath, moduleEntry, - inputStreamManager, scheduler); - } - - Node - Stream::PythonModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, Python, modulePath, moduleEntry, - inputStreamManager, scheduler); - } - - Node - Stream::GoModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, Go, modulePath, moduleEntry, - inputStreamManager, scheduler); - } + return ConnectNewModule(alias, option, inStreams, moduleName, Go, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node Stream::Decode(const bmf_sdk::JsonParam &decodePara, std::string const &alias) { - auto nd = ConnectNewModule(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, "", "", Immediate, 0); - nd[0].SetNotify("video"); - nd[1].SetNotify("audio"); - return nd; - } +Node Stream::Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias) { + auto nd = ConnectNewModule(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, + "", "", Immediate, 0); + nd[0].SetNotify("video"); + nd[1].SetNotify("audio"); + return nd; +} - Node Stream::EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, std::string const &alias) { - return ConnectNewModule(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", "", Immediate, 1); - } +Node Stream::EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return ConnectNewModule(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", + "", Immediate, 1); +} - Node Stream::EncodeAsVideo(Stream audioStream, const bmf_sdk::JsonParam &encodePara, std::string const &alias) { - return ConnectNewModule(alias, encodePara, {std::move(audioStream)}, "c_ffmpeg_encoder", CPP, "", "", Immediate, - 1); - } +Node Stream::EncodeAsVideo(Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return ConnectNewModule(alias, encodePara, {std::move(audioStream)}, + "c_ffmpeg_encoder", CPP, "", "", Immediate, 1); +} - Node Stream::FFMpegFilter(const std::vector &inStreams, std::string const &filterName, - bmf_sdk::JsonParam filterPara, std::string const &alias) { - nlohmann::json realPara; - realPara["name"] = filterName; - realPara["para"] = filterPara.json_value_; - filterPara = bmf_sdk::JsonParam(realPara); - return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, 0); - } +Node Stream::FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + bmf_sdk::JsonParam filterPara, + std::string const &alias) { + nlohmann::json realPara; + realPara["name"] = filterName; + realPara["para"] = filterPara.json_value_; + filterPara = bmf_sdk::JsonParam(realPara); + return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", + CPP, "", "", Immediate, 0); +} - Node Stream::Fps(int fps, std::string const &alias) { - bmf_sdk::JsonParam para; - para.json_value_["fps"] = fps; - return FFMpegFilter({}, "fps", para, alias); - } +Node Stream::Fps(int fps, std::string const &alias) { + bmf_sdk::JsonParam para; + para.json_value_["fps"] = fps; + return FFMpegFilter({}, "fps", para, alias); +} - Node Stream::InternalFFMpegFilter(const std::vector &inStreams, std::string const &filterName, - const bmf_sdk::JsonParam &filterPara, std::string const &alias) { - return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, 0); - } +Node Stream::InternalFFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias) { + return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", + CPP, "", "", Immediate, 0); +} - Node Stream::ConnectNewModule(const std::string &alias, const bmf_sdk::JsonParam &option, - const std::vector &inputStreams, - const std::string &moduleName, ModuleType moduleType, const std::string &modulePath, - const std::string &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - std::vector > inRealStreams; - inRealStreams.reserve(inputStreams.size()); - for (auto &s:inputStreams) - inRealStreams.emplace_back(s.baseP_); - return Node(baseP_->AddModule(alias, option, inRealStreams, moduleName, moduleType, modulePath, moduleEntry, - inputStreamManager, scheduler)); - } +Node Stream::ConnectNewModule( + const std::string &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, const std::string &moduleName, + ModuleType moduleType, const std::string &modulePath, + const std::string &moduleEntry, InputManagerType inputStreamManager, + int scheduler) { + std::vector> inRealStreams; + inRealStreams.reserve(inputStreams.size()); + for (auto &s : inputStreams) + inRealStreams.emplace_back(s.baseP_); + return Node(baseP_->AddModule(alias, option, inRealStreams, moduleName, + moduleType, modulePath, moduleEntry, + inputStreamManager, scheduler)); +} - Node::Node(std::shared_ptr baseP) : baseP_(std::move(baseP)) {} - - class Stream Node::operator[](int index) { - return Stream(index); - } +Node::Node(std::shared_ptr baseP) + : baseP_(std::move(baseP)) {} - class Stream Node::operator[](std::string const ¬ifyOrAlias) { - return Stream(notifyOrAlias); - } +class Stream Node::operator[](int index) { + return Stream(index); +} - class Stream Node::Stream(int index) { - return (class Stream) (baseP_->Stream(index)); - } +class Stream Node::operator[](std::string const ¬ifyOrAlias) { + return Stream(notifyOrAlias); +} - class Stream Node::Stream(std::string const ¬ifyOrAlias) { - return (class Stream) (baseP_->Stream(notifyOrAlias)); - } +class Stream Node::Stream(int index) { + return (class Stream)(baseP_->Stream(index)); +} - Node::operator class Stream() { - return Stream(0); - } +class Stream Node::Stream(std::string const ¬ifyOrAlias) { + return (class Stream)(baseP_->Stream(notifyOrAlias)); +} - void Node::SetAlias(std::string const &alias) { - baseP_->SetAlias(alias); - } +Node::operator class Stream() { return Stream(0); } - void Node::SetInputStreamManager(InputManagerType inputStreamManager) { - baseP_->SetInputManager(inputStreamManager); - } +void Node::SetAlias(std::string const &alias) { baseP_->SetAlias(alias); } - void Node::SetThread(int threadNum) { - baseP_->SetScheduler(threadNum); - } +void Node::SetInputStreamManager(InputManagerType inputStreamManager) { + baseP_->SetInputManager(inputStreamManager); +} - void Node::SetPreModule(const bmf::BMFModule &preModuleInstance) { - baseP_->SetPreModule(preModuleInstance); - } +void Node::SetThread(int threadNum) { baseP_->SetScheduler(threadNum); } - void Node::AddCallback(long long key, const bmf::BMFCallback &callbackInstance) { - baseP_->AddCallback(key, callbackInstance); - } +void Node::SetPreModule(const bmf::BMFModule &preModuleInstance) { + baseP_->SetPreModule(preModuleInstance); +} - void Node::Start() { - Stream(0).Start(); - } +void Node::AddCallback(long long key, + const bmf::BMFCallback &callbackInstance) { + baseP_->AddCallback(key, callbackInstance); +} - Node Node::Module(const std::vector &inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam &option, std::string const &alias, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, moduleType, modulePath, moduleEntry, - inputStreamManager, scheduler); - } +void Node::Start() { Stream(0).Start(); } - Node Node::CppModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, CPP, modulePath, moduleEntry, inputStreamManager, - scheduler); - } +Node Node::Module(const std::vector &inStreams, + std::string const &moduleName, ModuleType moduleType, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, moduleType, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node - Node::PythonModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, Python, modulePath, moduleEntry, - inputStreamManager, scheduler); - } +Node Node::CppModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, CPP, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node Node::GoModule(const std::vector &inStreams, std::string const &moduleName, +Node Node::PythonModule(const std::vector &inStreams, + std::string const &moduleName, const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, + std::string const &alias, std::string const &modulePath, + std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return ConnectNewModule(alias, option, inStreams, moduleName, Go, modulePath, moduleEntry, inputStreamManager, - scheduler); - } + return ConnectNewModule(alias, option, inStreams, moduleName, Python, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node Node::Decode(const bmf_sdk::JsonParam &decodePara, std::string const &alias) { - auto nd = ConnectNewModule(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, "", "", Immediate, 0); - nd[0].SetNotify("video"); - nd[1].SetNotify("audio"); - return nd; - } +Node Node::GoModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return ConnectNewModule(alias, option, inStreams, moduleName, Go, + modulePath, moduleEntry, inputStreamManager, + scheduler); +} - Node Node::EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, std::string const &alias) { - return ConnectNewModule(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", "", Immediate, - 1); - } +Node Node::Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias) { + auto nd = ConnectNewModule(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, + "", "", Immediate, 0); + nd[0].SetNotify("video"); + nd[1].SetNotify("audio"); + return nd; +} - Node Node::EncodeAsVideo(class Stream audioStream, const bmf_sdk::JsonParam &encodePara, std::string const &alias) { - return ConnectNewModule(alias, encodePara, {std::move(audioStream)}, "c_ffmpeg_encoder", CPP, "", "", Immediate, - 1); - } +Node Node::EncodeAsVideo(const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return ConnectNewModule(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", + "", Immediate, 1); +} - Node Node::FFMpegFilter(const std::vector &inStreams, std::string const &filterName, - bmf_sdk::JsonParam filterPara, std::string const &alias) { - nlohmann::json realPara; - realPara["name"] = filterName; - realPara["para"] = filterPara.json_value_; - filterPara = bmf_sdk::JsonParam(realPara); - return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, 0); - } +Node Node::EncodeAsVideo(class Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return ConnectNewModule(alias, encodePara, {std::move(audioStream)}, + "c_ffmpeg_encoder", CPP, "", "", Immediate, 1); +} - Node Node::Fps(int fps, std::string const &alias) { - bmf_sdk::JsonParam para; - para.json_value_["fps"] = fps; - return FFMpegFilter({}, "fps", para, alias); - } +Node Node::FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + bmf_sdk::JsonParam filterPara, + std::string const &alias) { + nlohmann::json realPara; + realPara["name"] = filterName; + realPara["para"] = filterPara.json_value_; + filterPara = bmf_sdk::JsonParam(realPara); + return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", + CPP, "", "", Immediate, 0); +} - Node Node::InternalFFMpegFilter(const std::vector &inStreams, std::string const &filterName, - const bmf_sdk::JsonParam &filterPara, std::string const &alias) { - return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, 0); - } +Node Node::Fps(int fps, std::string const &alias) { + bmf_sdk::JsonParam para; + para.json_value_["fps"] = fps; + return FFMpegFilter({}, "fps", para, alias); +} - Node - Node::ConnectNewModule(std::string const &alias, const bmf_sdk::JsonParam &option, - const std::vector &inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - std::vector > inRealStreams; - inRealStreams.reserve(inputStreams.size()); - for (auto &s:inputStreams) - inRealStreams.emplace_back(s.baseP_); - return Node(baseP_->AddModule(alias, option, inRealStreams, moduleName, moduleType, modulePath, moduleEntry, - inputStreamManager, scheduler)); - } +Node Node::InternalFFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias) { + return ConnectNewModule(alias, filterPara, inStreams, "c_ffmpeg_filter", + CPP, "", "", Immediate, 0); +} - Graph::Graph(GraphMode runMode, bmf_sdk::JsonParam graphOption) - : graph_(std::make_shared(runMode, graphOption)) {} +Node Node::ConnectNewModule( + std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + std::vector> inRealStreams; + inRealStreams.reserve(inputStreams.size()); + for (auto &s : inputStreams) + inRealStreams.emplace_back(s.baseP_); + return Node(baseP_->AddModule(alias, option, inRealStreams, moduleName, + moduleType, modulePath, moduleEntry, + inputStreamManager, scheduler)); +} - Graph::Graph(GraphMode runMode, nlohmann::json graphOption) - : graph_(std::make_shared(runMode, bmf_sdk::JsonParam(graphOption))) {} +Graph::Graph(GraphMode runMode, bmf_sdk::JsonParam graphOption) + : graph_(std::make_shared(runMode, graphOption)) {} - bmf::BMFGraph Graph::Instantiate(bool dumpGraph, bool needMerge) { - return graph_->Instantiate(dumpGraph, needMerge); - } +Graph::Graph(GraphMode runMode, nlohmann::json graphOption) + : graph_(std::make_shared( + runMode, bmf_sdk::JsonParam(graphOption))) {} - bmf::BMFGraph Graph::Instance() { - return graph_->Instance(); - } +bmf::BMFGraph Graph::Instantiate(bool dumpGraph, bool needMerge) { + return graph_->Instantiate(dumpGraph, needMerge); +} - int Graph::Run(bool dumpGraph, bool needMerge) { - return graph_->Run(dumpGraph, needMerge); - } +bmf::BMFGraph Graph::Instance() { return graph_->Instance(); } - void Graph::Start(bool dumpGraph, bool needMerge) { - graph_->Start(dumpGraph, needMerge); - } +int Graph::Run(bool dumpGraph, bool needMerge) { + return graph_->Run(dumpGraph, needMerge); +} - Packet Graph::Generate() { - return graph_->Generate(); - } +void Graph::Start(bool dumpGraph, bool needMerge) { + graph_->Start(dumpGraph, needMerge); +} - void Graph::SetTotalThreadNum(int num) { - graph_->graphOption_.json_value_["scheduler_count"] = num; - } +Packet Graph::Generate() { return graph_->Generate(); } - Stream Graph::NewPlaceholderStream() { - return Stream(graph_->NewPlaceholderStream()); - } +void Graph::SetTotalThreadNum(int num) { + graph_->graphOption_.json_value_["scheduler_count"] = num; +} - Node Graph::GetAliasedNode(std::string const &alias) { - return Node(graph_->GetAliasedNode(alias)); - } +Stream Graph::NewPlaceholderStream() { + return Stream(graph_->NewPlaceholderStream()); +} - Stream Graph::GetAliasedStream(std::string const &alias) { - return Stream(graph_->GetAliasedStream(alias)); - } +Node Graph::GetAliasedNode(std::string const &alias) { + return Node(graph_->GetAliasedNode(alias)); +} - std::string Graph::Dump() { - return graph_->Dump().dump(4); - } +Stream Graph::GetAliasedStream(std::string const &alias) { + return Stream(graph_->GetAliasedStream(alias)); +} - Node Graph::Module(const std::vector &inStreams, std::string const &moduleName, ModuleType moduleType, - const bmf_sdk::JsonParam &option, std::string const &alias, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return NewNode(alias, option, inStreams, moduleName, moduleType, modulePath, moduleEntry, inputStreamManager, - scheduler); - } +std::string Graph::Dump() { return graph_->Dump().dump(4); } - Node Graph::CppModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return NewNode(alias, option, inStreams, moduleName, CPP, modulePath, moduleEntry, inputStreamManager, - scheduler); - } +Node Graph::Module(const std::vector &inStreams, + std::string const &moduleName, ModuleType moduleType, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return NewNode(alias, option, inStreams, moduleName, moduleType, modulePath, + moduleEntry, inputStreamManager, scheduler); +} - Node Graph::PythonModule(const std::vector &inStreams, std::string const &moduleName, - const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, - InputManagerType inputStreamManager, int scheduler) { - return NewNode(alias, option, inStreams, moduleName, Python, modulePath, moduleEntry, inputStreamManager, - scheduler); - } +Node Graph::CppModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, + std::string const &alias, std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return NewNode(alias, option, inStreams, moduleName, CPP, modulePath, + moduleEntry, inputStreamManager, scheduler); +} - Node Graph::GoModule(const std::vector &inStreams, std::string const &moduleName, +Node Graph::PythonModule(const std::vector &inStreams, + std::string const &moduleName, const bmf_sdk::JsonParam &option, - std::string const &alias, std::string const &modulePath, std::string const &moduleEntry, + std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - return NewNode(alias, option, inStreams, moduleName, Go, modulePath, moduleEntry, inputStreamManager, - scheduler); - } + return NewNode(alias, option, inStreams, moduleName, Python, modulePath, + moduleEntry, inputStreamManager, scheduler); +} - Node Graph::Decode(const bmf_sdk::JsonParam &decodePara, std::string const &alias) { - auto nd = NewNode(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, "", "", Immediate, 0); - nd[0].SetNotify("video"); - nd[1].SetNotify("audio"); - return nd; - } +Node Graph::GoModule(const std::vector &inStreams, + std::string const &moduleName, + const bmf_sdk::JsonParam &option, std::string const &alias, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + return NewNode(alias, option, inStreams, moduleName, Go, modulePath, + moduleEntry, inputStreamManager, scheduler); +} - Node Graph::Decode(const bmf_sdk::JsonParam &decodePara, Stream controlStream, std::string const &alias) { - return NewNode(alias, decodePara, {std::move(controlStream)}, "c_ffmpeg_decoder", CPP, "", "", Immediate, 0); - } +Node Graph::Decode(const bmf_sdk::JsonParam &decodePara, + std::string const &alias) { + auto nd = NewNode(alias, decodePara, {}, "c_ffmpeg_decoder", CPP, "", "", + Immediate, 0); + nd[0].SetNotify("video"); + nd[1].SetNotify("audio"); + return nd; +} - Node - Graph::Encode(Stream videoStream, Stream audioStream, const bmf_sdk::JsonParam &encodePara, - std::string const &alias) { - return NewNode(alias, encodePara, {std::move(videoStream), std::move(audioStream)}, "c_ffmpeg_encoder", CPP, "", - "", Immediate, 1); +Node Graph::Decode(const bmf_sdk::JsonParam &decodePara, Stream controlStream, + std::string const &alias) { + return NewNode(alias, decodePara, {std::move(controlStream)}, + "c_ffmpeg_decoder", CPP, "", "", Immediate, 0); +} - } +Node Graph::Encode(Stream videoStream, Stream audioStream, + const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return NewNode(alias, encodePara, + {std::move(videoStream), std::move(audioStream)}, + "c_ffmpeg_encoder", CPP, "", "", Immediate, 1); +} - Node - Graph::Encode(Stream videoStream, const bmf_sdk::JsonParam &encodePara, - std::string const &alias) { - return NewNode(alias, encodePara, {std::move(videoStream)}, "c_ffmpeg_encoder", CPP, "", - "", Immediate, 1); - } +Node Graph::Encode(Stream videoStream, const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return NewNode(alias, encodePara, {std::move(videoStream)}, + "c_ffmpeg_encoder", CPP, "", "", Immediate, 1); +} - Node - Graph::Encode(const bmf_sdk::JsonParam &encodePara, - std::string const &alias) { - return NewNode(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", - "", Immediate, 1); - } +Node Graph::Encode(const bmf_sdk::JsonParam &encodePara, + std::string const &alias) { + return NewNode(alias, encodePara, {}, "c_ffmpeg_encoder", CPP, "", "", + Immediate, 1); +} - Node - Graph::FFMpegFilter(const std::vector &inStreams, std::string const &filterName, - const bmf_sdk::JsonParam &filterPara, - std::string const &alias) { - nlohmann::json realPara; - realPara["name"] = filterName; - realPara["para"] = filterPara.json_value_; - return NewNode(alias, bmf_sdk::JsonParam(realPara), inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, - 0); - } +Node Graph::FFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias) { + nlohmann::json realPara; + realPara["name"] = filterName; + realPara["para"] = filterPara.json_value_; + return NewNode(alias, bmf_sdk::JsonParam(realPara), inStreams, + "c_ffmpeg_filter", CPP, "", "", Immediate, 0); +} - Node Graph::Fps(Stream inStream, int fps, std::string const &alias) { - bmf_sdk::JsonParam para; - para.json_value_["fps"] = fps; - return FFMpegFilter({std::move(inStream)}, "fps", para, alias); - } +Node Graph::Fps(Stream inStream, int fps, std::string const &alias) { + bmf_sdk::JsonParam para; + para.json_value_["fps"] = fps; + return FFMpegFilter({std::move(inStream)}, "fps", para, alias); +} - Node Graph::InternalFFMpegFilter(const std::vector &inStreams, std::string const &filterName, - const bmf_sdk::JsonParam &filterPara, std::string const &alias) { - return NewNode(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", Immediate, 0); - } +Node Graph::InternalFFMpegFilter(const std::vector &inStreams, + std::string const &filterName, + const bmf_sdk::JsonParam &filterPara, + std::string const &alias) { + return NewNode(alias, filterPara, inStreams, "c_ffmpeg_filter", CPP, "", "", + Immediate, 0); +} - Node - Graph::NewNode(std::string const &alias, const bmf_sdk::JsonParam &option, const std::vector &inputStreams, - std::string const &moduleName, ModuleType moduleType, std::string const &modulePath, - std::string const &moduleEntry, InputManagerType inputStreamManager, int scheduler) { - std::vector > inRealStreams; - inRealStreams.reserve(inputStreams.size()); - for (auto &s:inputStreams) - inRealStreams.emplace_back(s.baseP_); - return Node(graph_->AddModule(alias, option, inRealStreams, moduleName, moduleType, modulePath, moduleEntry, - inputStreamManager, scheduler)); - } +Node Graph::NewNode(std::string const &alias, const bmf_sdk::JsonParam &option, + const std::vector &inputStreams, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry, + InputManagerType inputStreamManager, int scheduler) { + std::vector> inRealStreams; + inRealStreams.reserve(inputStreams.size()); + for (auto &s : inputStreams) + inRealStreams.emplace_back(s.baseP_); + return Node(graph_->AddModule(alias, option, inRealStreams, moduleName, + moduleType, modulePath, moduleEntry, + inputStreamManager, scheduler)); +} - SyncModule - Graph::Sync(const std::vector inStreams, const std::vector outStreams, - bmf_sdk::JsonParam moduleOption, std::string const &moduleName, ModuleType moduleType, - std::string const &modulePath, std::string const &moduleEntry, std::string const &alias, - InputManagerType inputStreamManager, int scheduler) { - auto sync_m = SyncModule(); - std::string module_type; - switch (moduleType) { - case C: - module_type = "c"; - break; - case Python: - module_type = "python"; - break; - case Go: - module_type = "go"; - break; - default: - module_type = "c++"; +SyncModule Graph::Sync(const std::vector inStreams, + const std::vector outStreams, + bmf_sdk::JsonParam moduleOption, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry, std::string const &alias, + InputManagerType inputStreamManager, int scheduler) { + auto sync_m = SyncModule(); + std::string module_type; + switch (moduleType) { + case C: + module_type = "c"; + break; + case Python: + module_type = "python"; + break; + case Go: + module_type = "go"; + break; + default: + module_type = "c++"; + } + if (moduleName.compare("c_ffmpeg_filter") == 0) { + nlohmann::json inputOption; + nlohmann::json outputOption; + for (auto id : inStreams) { + nlohmann::json stream = { + {"identifier", moduleName + std::to_string(id)}}; + inputOption.push_back(stream); } - if (moduleName.compare("c_ffmpeg_filter") == 0) { - nlohmann::json inputOption; - nlohmann::json outputOption; - for (auto id : inStreams) { - nlohmann::json stream = { - {"identifier", moduleName + std::to_string(id)} - }; - inputOption.push_back(stream); - } - for (auto id : outStreams) { - nlohmann::json stream = { - {"identifier", moduleName + std::to_string(id)} - }; - outputOption.push_back(stream); - } - nlohmann::json option = { - {"option", moduleOption.json_value_}, - {"input_streams", inputOption}, - {"output_streams", outputOption}, - }; - auto config = bmf_engine::NodeConfig(option); - bmf_engine::Optimizer::convert_filter_para(config); - bmf_engine::Optimizer::replace_stream_name_with_id(config); - moduleOption = config.get_option(); + for (auto id : outStreams) { + nlohmann::json stream = { + {"identifier", moduleName + std::to_string(id)}}; + outputOption.push_back(stream); } - bmf_engine::ModuleFactory::create_module(moduleName, -1, moduleOption, module_type, modulePath, moduleEntry, - sync_m.moduleInstance); - sync_m.inputStreams = inStreams; - sync_m.outputStreams = outStreams; - sync_m.moduleInstance->init(); - return sync_m; - } + nlohmann::json option = { + {"option", moduleOption.json_value_}, + {"input_streams", inputOption}, + {"output_streams", outputOption}, + }; + auto config = bmf_engine::NodeConfig(option); + bmf_engine::Optimizer::convert_filter_para(config); + bmf_engine::Optimizer::replace_stream_name_with_id(config); + moduleOption = config.get_option(); + } + bmf_engine::ModuleFactory::create_module( + moduleName, -1, moduleOption, module_type, modulePath, moduleEntry, + sync_m.moduleInstance); + sync_m.inputStreams = inStreams; + sync_m.outputStreams = outStreams; + sync_m.moduleInstance->init(); + return sync_m; +} - SyncModule - Graph::Sync(const std::vector inStreams, const std::vector outStreams, - nlohmann::json moduleOption, std::string const &moduleName, ModuleType moduleType, - std::string const &modulePath, std::string const &moduleEntry, std::string const &alias, - InputManagerType inputStreamManager, int scheduler) { - return Sync(inStreams, outStreams, bmf_sdk::JsonParam(moduleOption), moduleName, moduleType, - modulePath, moduleEntry, alias, inputStreamManager, scheduler); - } +SyncModule Graph::Sync(const std::vector inStreams, + const std::vector outStreams, + nlohmann::json moduleOption, + std::string const &moduleName, ModuleType moduleType, + std::string const &modulePath, + std::string const &moduleEntry, std::string const &alias, + InputManagerType inputStreamManager, int scheduler) { + return Sync(inStreams, outStreams, bmf_sdk::JsonParam(moduleOption), + moduleName, moduleType, modulePath, moduleEntry, alias, + inputStreamManager, scheduler); +} - std::map > - Graph::Process(SyncModule module, std::map > inputPackets) { - auto task = bmf_sdk::Task(0, module.inputStreams, module.outputStreams); - for (auto const &pkts : inputPackets) { - for (auto const &pkt : pkts.second) { - task.fill_input_packet(pkts.first, pkt); - } +std::map> +Graph::Process(SyncModule module, + std::map> inputPackets) { + auto task = bmf_sdk::Task(0, module.inputStreams, module.outputStreams); + for (auto const &pkts : inputPackets) { + for (auto const &pkt : pkts.second) { + task.fill_input_packet(pkts.first, pkt); } - module.moduleInstance->process(task); - std::map > returnMap; - for (auto id : module.outputStreams) { - auto it = task.outputs_queue_.find(id); - if (it == task.outputs_queue_.end()) continue; - while (!it->second->empty()) { - Packet pkt; - task.pop_packet_from_out_queue(id, pkt); - returnMap[id].push_back(pkt); - } + } + module.moduleInstance->process(task); + std::map> returnMap; + for (auto id : module.outputStreams) { + auto it = task.outputs_queue_.find(id); + if (it == task.outputs_queue_.end()) + continue; + while (!it->second->empty()) { + Packet pkt; + task.pop_packet_from_out_queue(id, pkt); + returnMap[id].push_back(pkt); } - return returnMap; } + return returnMap; +} - SyncPackets - Graph::Process(SyncModule module, SyncPackets pkts) { - SyncPackets returnPkts; - returnPkts.packets = Process(module, pkts.packets); - return returnPkts; - } +SyncPackets Graph::Process(SyncModule module, SyncPackets pkts) { + SyncPackets returnPkts; + returnPkts.packets = Process(module, pkts.packets); + return returnPkts; +} - void Graph::Init(SyncModule module) { - module.moduleInstance->init(); - } +void Graph::Init(SyncModule module) { module.moduleInstance->init(); } - void Graph::Close(SyncModule module) { - module.moduleInstance->close(); - } +void Graph::Close(SyncModule module) { module.moduleInstance->close(); } - void Graph::SendEOF(SyncModule module) { - auto task = bmf_sdk::Task(0, module.inputStreams, module.outputStreams); - for (auto id : module.inputStreams) { - task.fill_input_packet(id, Packet::generate_eof_packet()); - } - module.moduleInstance->process(task); +void Graph::SendEOF(SyncModule module) { + auto task = bmf_sdk::Task(0, module.inputStreams, module.outputStreams); + for (auto id : module.inputStreams) { + task.fill_input_packet(id, Packet::generate_eof_packet()); } + module.moduleInstance->process(task); +} - void Graph::SetOption(const bmf_sdk::JsonParam& optionPatch) { - graph_->SetOption(optionPatch); - } +void Graph::SetOption(const bmf_sdk::JsonParam &optionPatch) { + graph_->SetOption(optionPatch); +} - void SyncPackets::Insert(int streamId, std::vector frames) { - packets.insert(std::make_pair(streamId, frames)); - } +void SyncPackets::Insert(int streamId, std::vector frames) { + packets.insert(std::make_pair(streamId, frames)); +} - std::vector SyncPackets::operator[](int index) { - return packets[index]; - } +std::vector SyncPackets::operator[](int index) { + return packets[index]; +} - std::map > - SyncModule::ProcessPkts(std::map > inputPackets) { - auto task = bmf_sdk::Task(0, inputStreams, outputStreams); - for (auto const &pkts : inputPackets) { - for (auto const &pkt : pkts.second) { - task.fill_input_packet(pkts.first, pkt); - } +std::map> +SyncModule::ProcessPkts(std::map> inputPackets) { + auto task = bmf_sdk::Task(0, inputStreams, outputStreams); + for (auto const &pkts : inputPackets) { + for (auto const &pkt : pkts.second) { + task.fill_input_packet(pkts.first, pkt); } - moduleInstance->process(task); - std::map > returnMap; - for (auto id : outputStreams) { - auto it = task.outputs_queue_.find(id); - if (it == task.outputs_queue_.end()) continue; - while (!it->second->empty()) { - Packet pkt; - task.pop_packet_from_out_queue(id, pkt); - returnMap[id].push_back(pkt); - } + } + moduleInstance->process(task); + std::map> returnMap; + for (auto id : outputStreams) { + auto it = task.outputs_queue_.find(id); + if (it == task.outputs_queue_.end()) + continue; + while (!it->second->empty()) { + Packet pkt; + task.pop_packet_from_out_queue(id, pkt); + returnMap[id].push_back(pkt); } - return returnMap; } + return returnMap; +} - SyncPackets SyncModule::ProcessPkts(SyncPackets pkts) { - SyncPackets returnPkts; - returnPkts.packets = ProcessPkts(pkts.packets); - return returnPkts; - } +SyncPackets SyncModule::ProcessPkts(SyncPackets pkts) { + SyncPackets returnPkts; + returnPkts.packets = ProcessPkts(pkts.packets); + return returnPkts; +} - void SyncModule::Process(bmf_sdk::Task task) { - moduleInstance->process(task); - } +void SyncModule::Process(bmf_sdk::Task task) { moduleInstance->process(task); } - void SyncModule::SendEOF() { - auto task = bmf_sdk::Task(0, inputStreams, outputStreams); - for (auto id : inputStreams) { - task.fill_input_packet(id, Packet::generate_eof_packet()); - } - moduleInstance->process(task); +void SyncModule::SendEOF() { + auto task = bmf_sdk::Task(0, inputStreams, outputStreams); + for (auto id : inputStreams) { + task.fill_input_packet(id, Packet::generate_eof_packet()); } + moduleInstance->process(task); +} - void SyncModule::Init() { - moduleInstance->init(); - } +void SyncModule::Init() { moduleInstance->init(); } - void SyncModule::Close() { - moduleInstance->close(); - } +void SyncModule::Close() { moduleInstance->close(); } } diff --git a/bmf/engine/connector/src/connector.cpp b/bmf/engine/connector/src/connector.cpp index e6c899c5..15c176ab 100644 --- a/bmf/engine/connector/src/connector.cpp +++ b/bmf/engine/connector/src/connector.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include "../internal/env_init.h" #include "../internal/mapping.h" @@ -29,7 +28,6 @@ #include #include "../include/connector.hpp" - #include #include @@ -38,230 +36,266 @@ using json_t = nlohmann::json; namespace bmf { - BMFGraph::BMFGraph(const std::string &graph_config, bool is_path, bool need_merge) { - - json_t graph_json; - if (is_path) { - if (!fs::exists(graph_config)) - throw std::logic_error("Graph config file not exists."); - std::ifstream gs(graph_config); - gs >> graph_json; - } else { - graph_json = json_t::parse(graph_config); - } +BMFGraph::BMFGraph(const std::string &graph_config, bool is_path, + bool need_merge) { + + json_t graph_json; + if (is_path) { + if (!fs::exists(graph_config)) + throw std::logic_error("Graph config file not exists."); + std::ifstream gs(graph_config); + gs >> graph_json; + } else { + graph_json = json_t::parse(graph_config); + } - auto g_config = bmf_engine::GraphConfig(graph_json); - std::map > created_modules; - std::map > callback_bindings; + auto g_config = bmf_engine::GraphConfig(graph_json); + std::map> created_modules; + std::map> + callback_bindings; - // find subgraph and merge into while graph - bmf_engine::Optimizer::subgraph_preprocess(g_config, created_modules); + // find subgraph and merge into while graph + bmf_engine::Optimizer::subgraph_preprocess(g_config, created_modules); - // catch graph config at this time for further comparison. - auto ori_g_config = g_config; + // catch graph config at this time for further comparison. + auto ori_g_config = g_config; - // dump unmerged graph - bmf_engine::Optimizer::dump_graph(g_config, false); + // dump unmerged graph + bmf_engine::Optimizer::dump_graph(g_config, false); - // convert filter para to new format - bmf_engine::Optimizer::convert_filter_para_for_graph(g_config.nodes); + // convert filter para to new format + bmf_engine::Optimizer::convert_filter_para_for_graph(g_config.nodes); - // do optimize for filter nodes - if (need_merge) { - bmf_engine::Optimizer::optimize(g_config.nodes); - } + // do optimize for filter nodes + if (need_merge) { + bmf_engine::Optimizer::optimize(g_config.nodes); + } - // replace stream name with stream id in filter option - bmf_engine::Optimizer::replace_stream_name_for_graph(g_config.nodes); - - // dump merged graph - bmf_engine::Optimizer::dump_graph(g_config, true); - - for (auto &nd:g_config.nodes) { - auto meta = nd.meta; - callback_bindings[nd.id] = std::make_shared(); - if (meta.get_premodule_id() > 0) { - if (!internal::ConnectorMapping::ModuleInstanceMapping().exist(meta.get_premodule_id())) - throw std::logic_error("Trying to use an unexisted premodule."); - created_modules[nd.id] = internal::ConnectorMapping::ModuleInstanceMapping().get(meta.get_premodule_id()); - } - - for (auto cb: meta.get_callback_binding()) { - if (!internal::ConnectorMapping::ModuleCallbackInstanceMapping().exist(cb.second)) - throw std::logic_error("Trying to bind an unexisted callback."); - callback_bindings[nd.id]->add_callback( - cb.first, *internal::ConnectorMapping::ModuleCallbackInstanceMapping().get(cb.second)); - } + // replace stream name with stream id in filter option + bmf_engine::Optimizer::replace_stream_name_for_graph(g_config.nodes); + + // dump merged graph + bmf_engine::Optimizer::dump_graph(g_config, true); + + for (auto &nd : g_config.nodes) { + auto meta = nd.meta; + callback_bindings[nd.id] = + std::make_shared(); + if (meta.get_premodule_id() > 0) { + if (!internal::ConnectorMapping::ModuleInstanceMapping().exist( + meta.get_premodule_id())) + throw std::logic_error("Trying to use an unexisted premodule."); + created_modules[nd.id] = + internal::ConnectorMapping::ModuleInstanceMapping().get( + meta.get_premodule_id()); } - // Clean up pre-modules. - std::map > all_created_modules; - std::map node_ori_opts; - for (auto nd:ori_g_config.get_nodes()) - node_ori_opts[nd.id] = nd.option.dump(); - for (auto nd:g_config.get_nodes()) { - if (node_ori_opts.count(nd.id) && node_ori_opts[nd.id] != nd.option.dump()) - continue; - if (created_modules.count(nd.id)) - all_created_modules[nd.id] = created_modules[nd.id]; + for (auto cb : meta.get_callback_binding()) { + if (!internal::ConnectorMapping::ModuleCallbackInstanceMapping() + .exist(cb.second)) + throw std::logic_error("Trying to bind an unexisted callback."); + callback_bindings[nd.id]->add_callback( + cb.first, + *internal::ConnectorMapping::ModuleCallbackInstanceMapping() + .get(cb.second)); } - created_modules.clear(); - - auto g_instance = std::make_shared(g_config, all_created_modules, callback_bindings); - - graph_uid_ = internal::ConnectorMapping::GraphInstanceMapping().insert(g_instance); } - BMFGraph::BMFGraph(BMFGraph const &graph) { - graph_uid_ = graph.graph_uid_; - internal::ConnectorMapping::GraphInstanceMapping().ref(graph_uid_); + // Clean up pre-modules. + std::map> all_created_modules; + std::map node_ori_opts; + for (auto nd : ori_g_config.get_nodes()) + node_ori_opts[nd.id] = nd.option.dump(); + for (auto nd : g_config.get_nodes()) { + if (node_ori_opts.count(nd.id) && + node_ori_opts[nd.id] != nd.option.dump()) + continue; + if (created_modules.count(nd.id)) + all_created_modules[nd.id] = created_modules[nd.id]; } + created_modules.clear(); - BMFGraph::~BMFGraph() { - internal::ConnectorMapping::GraphInstanceMapping().remove(graph_uid_); - } + auto g_instance = std::make_shared( + g_config, all_created_modules, callback_bindings); - BMFGraph &BMFGraph::operator=(BMFGraph const &graph) { - internal::ConnectorMapping::GraphInstanceMapping().ref(graph.graph_uid_); - internal::ConnectorMapping::GraphInstanceMapping().remove(graph_uid_); - graph_uid_ = graph.graph_uid_; + graph_uid_ = + internal::ConnectorMapping::GraphInstanceMapping().insert(g_instance); +} - return *this; - } +BMFGraph::BMFGraph(BMFGraph const &graph) { + graph_uid_ = graph.graph_uid_; + internal::ConnectorMapping::GraphInstanceMapping().ref(graph_uid_); +} - uint32_t BMFGraph::uid() { - return graph_uid_; - } +BMFGraph::~BMFGraph() { + internal::ConnectorMapping::GraphInstanceMapping().remove(graph_uid_); +} - void BMFGraph::start() { - internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->start(); - } +BMFGraph &BMFGraph::operator=(BMFGraph const &graph) { + internal::ConnectorMapping::GraphInstanceMapping().ref(graph.graph_uid_); + internal::ConnectorMapping::GraphInstanceMapping().remove(graph_uid_); + graph_uid_ = graph.graph_uid_; - void BMFGraph::update(const std::string &graph_config, bool is_path) { - json_t graph_json; - if (is_path) { - if (!fs::exists(graph_config)) - throw std::logic_error("Graph config file not exists."); - std::ifstream gs(graph_config); - gs >> graph_json; - } else { - graph_json = json_t::parse(graph_config); - } - auto g_config = bmf_engine::GraphConfig(graph_json); - - internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->update(g_config); - } + return *this; +} - int BMFGraph::close() { - return internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->close(); - } +uint32_t BMFGraph::uid() { return graph_uid_; } - int BMFGraph::force_close() { - return internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->force_close(); - } +void BMFGraph::start() { + internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->start(); +} - int BMFGraph::add_input_stream_packet(const std::string &stream_name, bmf_sdk::Packet &packet, bool block) { - return internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->add_input_stream_packet(stream_name, - packet, block); +void BMFGraph::update(const std::string &graph_config, bool is_path) { + json_t graph_json; + if (is_path) { + if (!fs::exists(graph_config)) + throw std::logic_error("Graph config file not exists."); + std::ifstream gs(graph_config); + gs >> graph_json; + } else { + graph_json = json_t::parse(graph_config); } + auto g_config = bmf_engine::GraphConfig(graph_json); - bmf_sdk::Packet BMFGraph::poll_output_stream_packet(const std::string &stream_name, bool block) { - return internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->poll_output_stream_packet( - stream_name, block); - } + internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->update(g_config); +} - GraphRunningInfo BMFGraph::status() { - return internal::ConnectorMapping::GraphInstanceMapping().get(graph_uid_)->status(); - } +int BMFGraph::close() { + return internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->close(); +} - BMFModule::BMFModule(const std::string &module_name, const std::string &option, const std::string &module_type, - const std::string &module_path, const std::string &module_entry) { - std::shared_ptr mod; - auto opt = bmf_sdk::JsonParam(option); - module_name_ = module_name; - auto m = bmf_engine::ModuleFactory::create_module(module_name, -1, opt, module_type, module_path, module_entry, - mod); - if(!mod){ - throw std::runtime_error("Load module " + module_name + " failed"); - } - auto cb = std::make_shared(); - mod->set_callback([cb](int64_t key, CBytes para) -> CBytes { - return cb->call(key, para); - }); - module_uid_ = internal::ConnectorMapping::ModuleInstanceMapping().insert(mod); - } +int BMFGraph::force_close() { + return internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->force_close(); +} - BMFModule::BMFModule(std::shared_ptr module_p) { - module_uid_ = internal::ConnectorMapping::ModuleInstanceMapping().insert(module_p); - } +int BMFGraph::add_input_stream_packet(const std::string &stream_name, + bmf_sdk::Packet &packet, bool block) { + return internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->add_input_stream_packet(stream_name, packet, block); +} - BMFModule::BMFModule(BMFModule const &mod) { - module_uid_ = mod.module_uid_; - internal::ConnectorMapping::ModuleInstanceMapping().ref(module_uid_); - } +bmf_sdk::Packet +BMFGraph::poll_output_stream_packet(const std::string &stream_name, + bool block) { + return internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->poll_output_stream_packet(stream_name, block); +} + +GraphRunningInfo BMFGraph::status() { + return internal::ConnectorMapping::GraphInstanceMapping() + .get(graph_uid_) + ->status(); +} - BMFModule::~BMFModule() { - internal::ConnectorMapping::ModuleInstanceMapping().remove(module_uid_); +BMFModule::BMFModule(const std::string &module_name, const std::string &option, + const std::string &module_type, + const std::string &module_path, + const std::string &module_entry) { + std::shared_ptr mod; + auto opt = bmf_sdk::JsonParam(option); + module_name_ = module_name; + auto m = bmf_engine::ModuleFactory::create_module( + module_name, -1, opt, module_type, module_path, module_entry, mod); + if (!mod) { + throw std::runtime_error("Load module " + module_name + " failed"); } + auto cb = std::make_shared(); + mod->set_callback([cb](int64_t key, CBytes para) -> CBytes { + return cb->call(key, para); + }); + module_uid_ = + internal::ConnectorMapping::ModuleInstanceMapping().insert(mod); +} - BMFModule &BMFModule::operator=(BMFModule const &mod) { - internal::ConnectorMapping::ModuleInstanceMapping().ref(mod.module_uid_); - internal::ConnectorMapping::ModuleInstanceMapping().remove(module_uid_); - module_uid_ = mod.module_uid_; +BMFModule::BMFModule(std::shared_ptr module_p) { + module_uid_ = + internal::ConnectorMapping::ModuleInstanceMapping().insert(module_p); +} - return *this; - } +BMFModule::BMFModule(BMFModule const &mod) { + module_uid_ = mod.module_uid_; + internal::ConnectorMapping::ModuleInstanceMapping().ref(module_uid_); +} - uint32_t BMFModule::uid() { - return module_uid_; - } +BMFModule::~BMFModule() { + internal::ConnectorMapping::ModuleInstanceMapping().remove(module_uid_); +} - int32_t BMFModule::process(bmf_sdk::Task &task) { - BMF_TRACE(PROCESSING, module_name_.c_str(), START); - int32_t status = internal::ConnectorMapping::ModuleInstanceMapping().get(module_uid_)->process(task); - BMF_TRACE(PROCESSING, module_name_.c_str(), END); - return status; - } +BMFModule &BMFModule::operator=(BMFModule const &mod) { + internal::ConnectorMapping::ModuleInstanceMapping().ref(mod.module_uid_); + internal::ConnectorMapping::ModuleInstanceMapping().remove(module_uid_); + module_uid_ = mod.module_uid_; - int32_t BMFModule::init() { - return internal::ConnectorMapping::ModuleInstanceMapping().get(module_uid_)->init(); - } + return *this; +} - int32_t BMFModule::reset() { - return internal::ConnectorMapping::ModuleInstanceMapping().get(module_uid_)->reset(); - } +uint32_t BMFModule::uid() { return module_uid_; } - int32_t BMFModule::close() { - return internal::ConnectorMapping::ModuleInstanceMapping().get(module_uid_)->close(); - } +int32_t BMFModule::process(bmf_sdk::Task &task) { + BMF_TRACE(PROCESSING, module_name_.c_str(), START); + int32_t status = internal::ConnectorMapping::ModuleInstanceMapping() + .get(module_uid_) + ->process(task); + BMF_TRACE(PROCESSING, module_name_.c_str(), END); + return status; +} - BMFCallback::BMFCallback(std::function callback) { - callback_uid_ = internal::ConnectorMapping::ModuleCallbackInstanceMapping().insert( - std::make_shared >(callback)); - } +int32_t BMFModule::init() { + return internal::ConnectorMapping::ModuleInstanceMapping() + .get(module_uid_) + ->init(); +} - BMFCallback::BMFCallback(BMFCallback const &cb) { - callback_uid_ = cb.callback_uid_; - internal::ConnectorMapping::ModuleCallbackInstanceMapping().ref(callback_uid_); - } +int32_t BMFModule::reset() { + return internal::ConnectorMapping::ModuleInstanceMapping() + .get(module_uid_) + ->reset(); +} - BMFCallback::~BMFCallback() { - internal::ConnectorMapping::ModuleCallbackInstanceMapping().remove(callback_uid_); - } +int32_t BMFModule::close() { + return internal::ConnectorMapping::ModuleInstanceMapping() + .get(module_uid_) + ->close(); +} - BMFCallback &BMFCallback::operator=(BMFCallback const &cb) { - internal::ConnectorMapping::ModuleCallbackInstanceMapping().ref(cb.callback_uid_); - internal::ConnectorMapping::ModuleCallbackInstanceMapping().remove(callback_uid_); - callback_uid_ = cb.callback_uid_; +BMFCallback::BMFCallback( + std::function callback) { + callback_uid_ = + internal::ConnectorMapping::ModuleCallbackInstanceMapping().insert( + std::make_shared>( + callback)); +} - return *this; - } +BMFCallback::BMFCallback(BMFCallback const &cb) { + callback_uid_ = cb.callback_uid_; + internal::ConnectorMapping::ModuleCallbackInstanceMapping().ref( + callback_uid_); +} - uint32_t BMFCallback::uid() { - return callback_uid_; - } +BMFCallback::~BMFCallback() { + internal::ConnectorMapping::ModuleCallbackInstanceMapping().remove( + callback_uid_); +} - void ChangeDmpPath(std::string path) { - internal::env_init.ChangeDmpPath(path); - } +BMFCallback &BMFCallback::operator=(BMFCallback const &cb) { + internal::ConnectorMapping::ModuleCallbackInstanceMapping().ref( + cb.callback_uid_); + internal::ConnectorMapping::ModuleCallbackInstanceMapping().remove( + callback_uid_); + callback_uid_ = cb.callback_uid_; + + return *this; +} + +uint32_t BMFCallback::uid() { return callback_uid_; } + +void ChangeDmpPath(std::string path) { internal::env_init.ChangeDmpPath(path); } } diff --git a/bmf/engine/connector/src/connector_capi.cpp b/bmf/engine/connector/src/connector_capi.cpp index 16c832e1..8cd58182 100644 --- a/bmf/engine/connector/src/connector_capi.cpp +++ b/bmf/engine/connector/src/connector_capi.cpp @@ -1,154 +1,101 @@ #include "connector_capi.h" - -#define BMF_PROTECT(...) \ - try{ \ - __VA_ARGS__ \ - } catch(const std::exception &e){ \ - s_bmf_last_error = e.what(); \ +#define BMF_PROTECT(...) \ + try { \ + __VA_ARGS__ \ + } catch (const std::exception &e) { \ + s_bmf_last_error = e.what(); \ } - using namespace bmf_sdk; - thread_local std::string s_bmf_last_error; -const char *bmf_engine_last_error() -{ - return s_bmf_last_error.c_str(); -} - +const char *bmf_engine_last_error() { return s_bmf_last_error.c_str(); } -bmf_BMFGraph bmf_make_graph(char const *graph_json, bool is_path, bool need_merge) -{ - BMF_PROTECT( - return new bmf::BMFGraph(graph_json, is_path, need_merge); - ) +bmf_BMFGraph bmf_make_graph(char const *graph_json, bool is_path, + bool need_merge) { + BMF_PROTECT(return new bmf::BMFGraph(graph_json, is_path, need_merge);) return nullptr; } -void bmf_graph_free(bmf_BMFGraph graph) -{ - BMF_PROTECT( - if(graph){ - delete graph; - } - ) +void bmf_graph_free(bmf_BMFGraph graph) { + BMF_PROTECT(if (graph) { delete graph; }) } -uint32_t bmf_graph_uid(bmf_BMFGraph graph) -{ - return graph->uid(); -} +uint32_t bmf_graph_uid(bmf_BMFGraph graph) { return graph->uid(); } -int bmf_graph_start(bmf_BMFGraph graph) -{ - BMF_PROTECT( - graph->start(); - return 0; - ) +int bmf_graph_start(bmf_BMFGraph graph) { + BMF_PROTECT(graph->start(); return 0;) return -1; } -int bmf_graph_close(bmf_BMFGraph graph) -{ - BMF_PROTECT( - graph->close(); - return 0; - ) +int bmf_graph_close(bmf_BMFGraph graph) { + BMF_PROTECT(graph->close(); return 0;) return -1; } -int -bmf_graph_add_input_stream_packet(bmf_BMFGraph graph, char const *stream_name, bmf_Packet packet, bool block) -{ +int bmf_graph_add_input_stream_packet(bmf_BMFGraph graph, + char const *stream_name, + bmf_Packet packet, bool block) { BMF_PROTECT( - return graph->add_input_stream_packet(stream_name, *packet, block); - ) + return graph->add_input_stream_packet(stream_name, *packet, block);) return -1; } -bmf_Packet -bmf_graph_poll_output_stream_packet(bmf_BMFGraph graph, char const *stream_name) -{ - BMF_PROTECT( - return new bmf_sdk::Packet(graph->poll_output_stream_packet(stream_name)); - ) +bmf_Packet bmf_graph_poll_output_stream_packet(bmf_BMFGraph graph, + char const *stream_name) { + BMF_PROTECT(return new bmf_sdk::Packet( + graph->poll_output_stream_packet(stream_name));) return 0; } int bmf_graph_update(bmf_BMFGraph graph, char const *config, bool is_path) { - BMF_PROTECT( - graph->update(config, is_path); - return 0; - ) + BMF_PROTECT(graph->update(config, is_path); return 0;) return -1; } int bmf_graph_force_close(bmf_BMFGraph graph) { - BMF_PROTECT( - graph->force_close(); - return 0; - ) + BMF_PROTECT(graph->force_close(); return 0;) return -1; } -char* bmf_graph_status(bmf_BMFGraph graph) -{ - BMF_PROTECT( - return bmf_strdup(graph->status().jsonify().dump().c_str()); - ) +char *bmf_graph_status(bmf_BMFGraph graph) { + BMF_PROTECT(return bmf_strdup(graph->status().jsonify().dump().c_str());) return 0; } - -bmf_BMFModule -bmf_make_module(char const *module_name, char const *option, char const *module_type, char const *module_path, - char const *module_entry) { - return new bmf::BMFModule(module_name, option, module_type, module_path, module_entry); +bmf_BMFModule bmf_make_module(char const *module_name, char const *option, + char const *module_type, char const *module_path, + char const *module_entry) { + return new bmf::BMFModule(module_name, option, module_type, module_path, + module_entry); } -void bmf_module_free(bmf_BMFModule module) -{ - if(module){ +void bmf_module_free(bmf_BMFModule module) { + if (module) { delete module; } } -int bmf_module_uid(bmf_BMFModule module) -{ - return module->uid(); -} +int bmf_module_uid(bmf_BMFModule module) { return module->uid(); } -int bmf_module_process(bmf_BMFModule module, bmf_Task task) -{ - BMF_PROTECT( - return module->process(*task); - ) +int bmf_module_process(bmf_BMFModule module, bmf_Task task) { + BMF_PROTECT(return module->process(*task);) return -1; } -int bmf_module_init(bmf_BMFModule module) -{ - BMF_PROTECT( - return module->init(); - ) +int bmf_module_init(bmf_BMFModule module) { + BMF_PROTECT(return module->init();) return -1; } -int bmf_module_reset(bmf_BMFModule module) -{ - BMF_PROTECT( - return module->reset(); - ) +int bmf_module_reset(bmf_BMFModule module) { + BMF_PROTECT(return module->reset();) return -1; } -int bmf_module_close(bmf_BMFModule module) -{ - BMF_PROTECT( - return module->close(); - ) +int bmf_module_close(bmf_BMFModule module) { + BMF_PROTECT(return module->close();) return -1; } diff --git a/bmf/hml/include/hmp/core/details/optional.hpp b/bmf/hml/include/hmp/core/details/optional.hpp index ba7cbbca..2859f2ab 100644 --- a/bmf/hml/include/hmp/core/details/optional.hpp +++ b/bmf/hml/include/hmp/core/details/optional.hpp @@ -7,1060 +7,1033 @@ // The idea and interface is based on Boost.Optional library // authored by Fernando Luis Cacciola Carballal -# ifndef ___OPTIONAL_HPP___ -# define ___OPTIONAL_HPP___ - -# include -# include -# include -# include -# include -# include -# include - -# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false - -# if defined __GNUC__ // NOTE: GNUC is also defined for Clang -# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) -# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ -# elif (__GNUC__ > 4) -# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ -# endif - -# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) -# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ -# elif (__GNUC__ > 4) -# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ -# endif - -# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) -# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ -# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) -# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ -# elif (__GNUC__ > 4) -# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ -# endif -# endif - -# if defined __clang_major__ -# if (__clang_major__ == 3 && __clang_minor__ >= 5) -# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ -# elif (__clang_major__ > 3) -# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ -# endif -# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ -# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ -# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2) -# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ -# endif -# endif - -# if defined _MSC_VER -# if (_MSC_VER >= 1900) -# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ -# endif -# endif - -# if defined __clang__ -# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) -# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 -# else -# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 -# endif -# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ -# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 -# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ -# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 -# else -# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 -# endif - - -# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ -# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 -# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr -# else -# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 -# define OPTIONAL_CONSTEXPR_INIT_LIST -# endif - -# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L) -# define OPTIONAL_HAS_MOVE_ACCESSORS 1 -# else -# define OPTIONAL_HAS_MOVE_ACCESSORS 0 -# endif - -// In C++11 constexpr implies const, so we need to make non-const members also non-constexpr -# if (defined __cplusplus) && (__cplusplus == 201103L) -# define OPTIONAL_MUTABLE_CONSTEXPR -# else -# define OPTIONAL_MUTABLE_CONSTEXPR constexpr -# endif - -namespace std{ - -namespace experimental{ +#ifndef ___OPTIONAL_HPP___ +#define ___OPTIONAL_HPP___ + +#include +#include +#include +#include +#include +#include +#include + +#define TR2_OPTIONAL_REQUIRES(...) \ + typename enable_if<__VA_ARGS__::value, bool>::type = false + +#if defined __GNUC__ // NOTE: GNUC is also defined for Clang +#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) +#define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +#elif (__GNUC__ > 4) +#define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +#endif -// BEGIN workaround for missing is_trivially_destructible -# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ - // leave it: it is already there -# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ - // leave it: it is already there -# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ - // leave it: it is already there -# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS - // leave it: the user doesn't want it -# else - template - using is_trivially_destructible = std::has_trivial_destructor; -# endif -// END workaround for missing is_trivially_destructible +#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) +#define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +#elif (__GNUC__ > 4) +#define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +#endif -# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) - // leave it; our metafunctions are already defined. -# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ - // leave it; our metafunctions are already defined. -# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ - // leave it: it is already there -# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS - // leave it: the user doesn't want it -# else +#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) +#define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +#elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) +#define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +#elif (__GNUC__ > 4) +#define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +#endif +#endif +#if defined __clang_major__ +#if (__clang_major__ == 3 && __clang_minor__ >= 5) +#define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +#elif (__clang_major__ > 3) +#define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +#endif +#if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +#define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +#elif (__clang_major__ == 3 && __clang_minor__ == 4 && \ + __clang_patchlevel__ >= 2) +#define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +#endif +#endif -// workaround for missing traits in GCC and CLANG -template -struct is_nothrow_move_constructible -{ - constexpr static bool value = std::is_nothrow_constructible::value; -}; +#if defined _MSC_VER +#if (_MSC_VER >= 1900) +#define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +#endif +#endif +#if defined __clang__ +#if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) +#define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +#else +#define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +#endif +#elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +#define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +#elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +#define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +#else +#define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +#endif + +#if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +#define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 +#define OPTIONAL_CONSTEXPR_INIT_LIST constexpr +#else +#define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 +#define OPTIONAL_CONSTEXPR_INIT_LIST +#endif + +#if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && \ + (__cplusplus != 201103L) +#define OPTIONAL_HAS_MOVE_ACCESSORS 1 +#else +#define OPTIONAL_HAS_MOVE_ACCESSORS 0 +#endif -template -struct is_assignable -{ - template - constexpr static bool has_assign(...) { return false; } +// In C++11 constexpr implies const, so we need to make non-const members also +// non-constexpr +#if (defined __cplusplus) && (__cplusplus == 201103L) +#define OPTIONAL_MUTABLE_CONSTEXPR +#else +#define OPTIONAL_MUTABLE_CONSTEXPR constexpr +#endif + +namespace std { + +namespace experimental { + +// BEGIN workaround for missing is_trivially_destructible +#if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +// leave it: it is already there +#elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +// leave it: it is already there +#elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +// leave it: it is already there +#elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS +// leave it: the user doesn't want it +#else +template +using is_trivially_destructible = std::has_trivial_destructor; +#endif +// END workaround for missing is_trivially_destructible - template () = std::declval(), true)) > - // the comma operator is necessary for the cases where operator= returns void - constexpr static bool has_assign(bool) { return true; } +#if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) +// leave it; our metafunctions are already defined. +#elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +// leave it; our metafunctions are already defined. +#elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +// leave it: it is already there +#elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS +// leave it: the user doesn't want it +#else - constexpr static bool value = has_assign(true); +// workaround for missing traits in GCC and CLANG +template struct is_nothrow_move_constructible { + constexpr static bool value = std::is_nothrow_constructible::value; }; +template struct is_assignable { + template constexpr static bool has_assign(...) { + return false; + } -template -struct is_nothrow_move_assignable -{ - template - struct has_nothrow_move_assign { - constexpr static bool value = false; - }; - - template - struct has_nothrow_move_assign { - constexpr static bool value = noexcept( std::declval() = std::declval() ); - }; - - constexpr static bool value = has_nothrow_move_assign::value>::value; + template () = std::declval(), true))> + // the comma operator is necessary for the cases where operator= returns + // void + constexpr static bool has_assign(bool) { + return true; + } + + constexpr static bool value = has_assign(true); }; -// end workaround +template struct is_nothrow_move_assignable { + template + struct has_nothrow_move_assign { + constexpr static bool value = false; + }; -# endif + template struct has_nothrow_move_assign { + constexpr static bool value = + noexcept(std::declval() = std::declval()); + }; + constexpr static bool value = + has_nothrow_move_assign::value>::value; +}; +// end workaround +#endif // 20.5.4, optional for object types template class optional; // 20.5.5, optional for lvalue reference types -template class optional; - +template class optional; // workaround: std utility functions aren't constexpr yet -template inline constexpr T&& constexpr_forward(typename std::remove_reference::type& t) noexcept -{ - return static_cast(t); +template +inline constexpr T && +constexpr_forward(typename std::remove_reference::type &t) noexcept { + return static_cast(t); } -template inline constexpr T&& constexpr_forward(typename std::remove_reference::type&& t) noexcept -{ +template +inline constexpr T && +constexpr_forward(typename std::remove_reference::type &&t) noexcept { static_assert(!std::is_lvalue_reference::value, "!!"); - return static_cast(t); + return static_cast(t); } -template inline constexpr typename std::remove_reference::type&& constexpr_move(T&& t) noexcept -{ - return static_cast::type&&>(t); +template +inline constexpr typename std::remove_reference::type && +constexpr_move(T &&t) noexcept { + return static_cast::type &&>(t); } - #if defined NDEBUG -# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) +#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) #else -# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR))) +#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) \ + ((CHECK) ? (EXPR) : ([] { assert(!#CHECK); }(), (EXPR))) #endif - -namespace detail_ -{ +namespace detail_ { // static_addressof: a constexpr version of addressof -template -struct has_overloaded_addressof -{ - template - constexpr static bool has_overload(...) { return false; } - - template ().operator&()) > - constexpr static bool has_overload(bool) { return true; } - - constexpr static bool value = has_overload(true); +template struct has_overloaded_addressof { + template constexpr static bool has_overload(...) { return false; } + + template ().operator&())> + constexpr static bool has_overload(bool) { + return true; + } + + constexpr static bool value = has_overload(true); }; template )> -constexpr T* static_addressof(T& ref) -{ - return &ref; +constexpr T *static_addressof(T &ref) { + return &ref; } template )> -T* static_addressof(T& ref) -{ - return std::addressof(ref); +T *static_addressof(T &ref) { + return std::addressof(ref); } +// the call to convert(b) has return type A and converts b to type A iff b +// decltype(b) is implicitly convertible to A +template constexpr U convert(U v) { return v; } -// the call to convert(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A -template -constexpr U convert(U v) { return v; } - +namespace swap_ns { +using std::swap; -namespace swap_ns -{ - using std::swap; - - template - void adl_swap(T& t, T& u) noexcept(noexcept(swap(t, u))) - { +template void adl_swap(T &t, T &u) noexcept(noexcept(swap(t, u))) { swap(t, u); - } +} } // namespace swap_ns } // namespace detail - -constexpr struct trivial_init_t{} trivial_init{}; - +constexpr struct trivial_init_t { +} trivial_init{}; // 20.5.6, In-place construction -constexpr struct in_place_t{} in_place{}; - +constexpr struct in_place_t { +} in_place{}; // 20.5.7, Disengaged state indicator -struct nullopt_t -{ - struct init{}; - constexpr explicit nullopt_t(init){} +struct nullopt_t { + struct init {}; + constexpr explicit nullopt_t(init) {} }; constexpr nullopt_t nullopt{nullopt_t::init()}; - // 20.5.8, class bad_optional_access class bad_optional_access : public logic_error { -public: - explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {} - explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {} + public: + explicit bad_optional_access(const string &what_arg) + : logic_error{what_arg} {} + explicit bad_optional_access(const char *what_arg) + : logic_error{what_arg} {} }; +template union storage_t { + unsigned char dummy_; + T value_; -template -union storage_t -{ - unsigned char dummy_; - T value_; - - constexpr storage_t( trivial_init_t ) noexcept : dummy_() {}; + constexpr storage_t(trivial_init_t) noexcept : dummy_(){}; - template - constexpr storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + template + constexpr storage_t(Args &&... args) + : value_(constexpr_forward(args)...) {} - ~storage_t(){} + ~storage_t() {} }; - -template -union constexpr_storage_t -{ +template union constexpr_storage_t { unsigned char dummy_; T value_; - constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {}; + constexpr constexpr_storage_t(trivial_init_t) noexcept : dummy_(){}; template - constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + constexpr constexpr_storage_t(Args &&... args) + : value_(constexpr_forward(args)...) {} ~constexpr_storage_t() = default; }; - -template -struct optional_base -{ +template struct optional_base { bool init_; storage_t storage_; - constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {}; + constexpr optional_base() noexcept : init_(false), storage_(trivial_init){}; - explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {} + explicit constexpr optional_base(const T &v) : init_(true), storage_(v) {} - explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + explicit constexpr optional_base(T &&v) + : init_(true), storage_(constexpr_move(v)) {} - template explicit optional_base(in_place_t, Args&&... args) + template + explicit optional_base(in_place_t, Args &&... args) : init_(true), storage_(constexpr_forward(args)...) {} - template >)> - explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) + template < + class U, class... Args, + TR2_OPTIONAL_REQUIRES(is_constructible>)> + explicit optional_base(in_place_t, std::initializer_list il, + Args &&... args) : init_(true), storage_(il, std::forward(args)...) {} - ~optional_base() { if (init_) storage_.value_.T::~T(); } + ~optional_base() { + if (init_) + storage_.value_.T::~T(); + } }; - -template -struct constexpr_optional_base -{ +template struct constexpr_optional_base { bool init_; constexpr_storage_t storage_; - constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {}; + constexpr constexpr_optional_base() noexcept : init_(false), + storage_(trivial_init){}; - explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {} + explicit constexpr constexpr_optional_base(const T &v) + : init_(true), storage_(v) {} - explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + explicit constexpr constexpr_optional_base(T &&v) + : init_(true), storage_(constexpr_move(v)) {} - template explicit constexpr constexpr_optional_base(in_place_t, Args&&... args) - : init_(true), storage_(constexpr_forward(args)...) {} + template + explicit constexpr constexpr_optional_base(in_place_t, Args &&... args) + : init_(true), storage_(constexpr_forward(args)...) {} - template >)> - OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list il, Args&&... args) - : init_(true), storage_(il, std::forward(args)...) {} + template < + class U, class... Args, + TR2_OPTIONAL_REQUIRES(is_constructible>)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base( + in_place_t, std::initializer_list il, Args &&... args) + : init_(true), storage_(il, std::forward(args)...) {} ~constexpr_optional_base() = default; }; template using OptionalBase = typename std::conditional< - is_trivially_destructible::value, // if possible - constexpr_optional_base::type>, // use base with trivial destructor - optional_base::type> ->::type; + is_trivially_destructible::value, // if possible + constexpr_optional_base::type>, // use base with trivial destructor + optional_base::type>>::type; + +template class optional : private OptionalBase { + static_assert(!std::is_same::type, nullopt_t>::value, + "bad T"); + static_assert( + !std::is_same::type, in_place_t>::value, + "bad T"); + + constexpr bool initialized() const noexcept { + return OptionalBase::init_; + } + typename std::remove_const::type *dataptr() { + return std::addressof(OptionalBase::storage_.value_); + } + constexpr const T *dataptr() const { + return detail_::static_addressof(OptionalBase::storage_.value_); + } +#if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + constexpr const T &contained_val() const & { + return OptionalBase::storage_.value_; + } +#if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + OPTIONAL_MUTABLE_CONSTEXPR T &&contained_val() && { + return std::move(OptionalBase::storage_.value_); + } + OPTIONAL_MUTABLE_CONSTEXPR T &contained_val() & { + return OptionalBase::storage_.value_; + } +#else + T &contained_val() & { return OptionalBase::storage_.value_; } + T &&contained_val() && { + return std::move(OptionalBase::storage_.value_); + } +#endif +#else + constexpr const T &contained_val() const { + return OptionalBase::storage_.value_; + } + T &contained_val() { return OptionalBase::storage_.value_; } +#endif + void clear() noexcept { + if (initialized()) + dataptr()->T::~T(); + OptionalBase::init_ = false; + } -template -class optional : private OptionalBase -{ - static_assert( !std::is_same::type, nullopt_t>::value, "bad T" ); - static_assert( !std::is_same::type, in_place_t>::value, "bad T" ); - - - constexpr bool initialized() const noexcept { return OptionalBase::init_; } - typename std::remove_const::type* dataptr() { return std::addressof(OptionalBase::storage_.value_); } - constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase::storage_.value_); } - -# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 - constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; } -# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 - OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } - OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase::storage_.value_; } -# else - T& contained_val() & { return OptionalBase::storage_.value_; } - T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } -# endif -# else - constexpr const T& contained_val() const { return OptionalBase::storage_.value_; } - T& contained_val() { return OptionalBase::storage_.value_; } -# endif - - void clear() noexcept { - if (initialized()) dataptr()->T::~T(); - OptionalBase::init_ = false; - } - - template - void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) - { - assert(!OptionalBase::init_); - ::new (static_cast(dataptr())) T(std::forward(args)...); - OptionalBase::init_ = true; - } - - template - void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...))) - { - assert(!OptionalBase::init_); - ::new (static_cast(dataptr())) T(il, std::forward(args)...); - OptionalBase::init_ = true; - } - -public: - typedef T value_type; - - // 20.5.5.1, constructors - constexpr optional() noexcept : OptionalBase() {}; - constexpr optional(nullopt_t) noexcept : OptionalBase() {}; - - optional(const optional& rhs) - : OptionalBase() - { - if (rhs.initialized()) { - ::new (static_cast(dataptr())) T(*rhs); + template + void initialize(Args &&... args) noexcept( + noexcept(T(std::forward(args)...))) { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(std::forward(args)...); OptionalBase::init_ = true; } - } - optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value) - : OptionalBase() - { - if (rhs.initialized()) { - ::new (static_cast(dataptr())) T(std::move(*rhs)); + template + void initialize(std::initializer_list il, Args &&... args) noexcept( + noexcept(T(il, std::forward(args)...))) { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) + T(il, std::forward(args)...); OptionalBase::init_ = true; } - } - - constexpr optional(const T& v) : OptionalBase(v) {} - - constexpr optional(T&& v) : OptionalBase(constexpr_move(v)) {} - - template - explicit constexpr optional(in_place_t, Args&&... args) - : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} - - template >)> - OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list il, Args&&... args) - : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} - - // 20.5.4.2, Destructor - ~optional() = default; - - // 20.5.4.3, assignment - optional& operator=(nullopt_t) noexcept - { - clear(); - return *this; - } - - optional& operator=(const optional& rhs) - { - if (initialized() == true && rhs.initialized() == false) clear(); - else if (initialized() == false && rhs.initialized() == true) initialize(*rhs); - else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs; - return *this; - } - - optional& operator=(optional&& rhs) - noexcept(is_nothrow_move_assignable::value && is_nothrow_move_constructible::value) - { - if (initialized() == true && rhs.initialized() == false) clear(); - else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs)); - else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs); - return *this; - } - - template - auto operator=(U&& v) - -> typename enable_if - < - is_same::type, T>::value, - optional& - >::type - { - if (initialized()) { contained_val() = std::forward(v); } - else { initialize(std::forward(v)); } - return *this; - } - - - template - void emplace(Args&&... args) - { - clear(); - initialize(std::forward(args)...); - } - - template - void emplace(initializer_list il, Args&&... args) - { - clear(); - initialize(il, std::forward(args)...); - } - - // 20.5.4.4, Swap - void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value - && noexcept(detail_::swap_ns::adl_swap(declval(), declval()))) - { - if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); } - else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); } - else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); } - } - - // 20.5.4.5, Observers - - explicit constexpr operator bool() const noexcept { return initialized(); } - constexpr bool has_value() const noexcept { return initialized(); } - - constexpr T const* operator ->() const { - return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr()); - } - -# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 - - OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() { - assert (initialized()); - return dataptr(); - } - - constexpr T const& operator *() const& { - return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); - } - - OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & { - assert (initialized()); - return contained_val(); - } - - OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && { - assert (initialized()); - return constexpr_move(contained_val()); - } - - constexpr T const& value() const& { - return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); - } - - OPTIONAL_MUTABLE_CONSTEXPR T& value() & { - return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); - } - - OPTIONAL_MUTABLE_CONSTEXPR T&& value() && { - if (!initialized()) throw bad_optional_access("bad optional access"); - return std::move(contained_val()); - } - -# else - - T* operator ->() { - assert (initialized()); - return dataptr(); - } - - constexpr T const& operator *() const { - return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); - } - - T& operator *() { - assert (initialized()); - return contained_val(); - } - - constexpr T const& value() const { - return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); - } - - T& value() { - return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); - } - -# endif - -# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 - - template - constexpr T value_or(V&& v) const& - { - return *this ? **this : detail_::convert(constexpr_forward(v)); - } - -# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 - - template - OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) && - { - return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); - } - -# else - - template - T value_or(V&& v) && - { - return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); - } - -# endif - -# else - - template - constexpr T value_or(V&& v) const - { - return *this ? **this : detail_::convert(constexpr_forward(v)); - } - -# endif - - // 20.6.3.6, modifiers - void reset() noexcept { clear(); } + + public: + typedef T value_type; + + // 20.5.5.1, constructors + constexpr optional() noexcept : OptionalBase(){}; + constexpr optional(nullopt_t) noexcept : OptionalBase(){}; + + optional(const optional &rhs) : OptionalBase() { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(*rhs); + OptionalBase::init_ = true; + } + } + + optional(optional &&rhs) noexcept(is_nothrow_move_constructible::value) + : OptionalBase() { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(std::move(*rhs)); + OptionalBase::init_ = true; + } + } + + constexpr optional(const T &v) : OptionalBase(v) {} + + constexpr optional(T &&v) : OptionalBase(constexpr_move(v)) {} + + template + explicit constexpr optional(in_place_t, Args &&... args) + : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} + + template < + class U, class... Args, + TR2_OPTIONAL_REQUIRES(is_constructible>)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, + std::initializer_list il, + Args &&... args) + : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} + + // 20.5.4.2, Destructor + ~optional() = default; + + // 20.5.4.3, assignment + optional &operator=(nullopt_t) noexcept { + clear(); + return *this; + } + + optional &operator=(const optional &rhs) { + if (initialized() == true && rhs.initialized() == false) + clear(); + else if (initialized() == false && rhs.initialized() == true) + initialize(*rhs); + else if (initialized() == true && rhs.initialized() == true) + contained_val() = *rhs; + return *this; + } + + optional &operator=(optional &&rhs) noexcept( + is_nothrow_move_assignable::value + &&is_nothrow_move_constructible::value) { + if (initialized() == true && rhs.initialized() == false) + clear(); + else if (initialized() == false && rhs.initialized() == true) + initialize(std::move(*rhs)); + else if (initialized() == true && rhs.initialized() == true) + contained_val() = std::move(*rhs); + return *this; + } + + template + auto operator=(U &&v) -> + typename enable_if::type, T>::value, + optional &>::type { + if (initialized()) { + contained_val() = std::forward(v); + } else { + initialize(std::forward(v)); + } + return *this; + } + + template void emplace(Args &&... args) { + clear(); + initialize(std::forward(args)...); + } + + template + void emplace(initializer_list il, Args &&... args) { + clear(); + initialize(il, std::forward(args)...); + } + + // 20.5.4.4, Swap + void swap(optional &rhs) noexcept( + is_nothrow_move_constructible::value &&noexcept( + detail_::swap_ns::adl_swap(declval(), declval()))) { + if (initialized() == true && rhs.initialized() == false) { + rhs.initialize(std::move(**this)); + clear(); + } else if (initialized() == false && rhs.initialized() == true) { + initialize(std::move(*rhs)); + rhs.clear(); + } else if (initialized() == true && rhs.initialized() == true) { + using std::swap; + swap(**this, *rhs); + } + } + + // 20.5.4.5, Observers + + explicit constexpr operator bool() const noexcept { return initialized(); } + constexpr bool has_value() const noexcept { return initialized(); } + + constexpr T const *operator->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr()); + } + +#if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + OPTIONAL_MUTABLE_CONSTEXPR T *operator->() { + assert(initialized()); + return dataptr(); + } + + constexpr T const &operator*() const & { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T &operator*() & { + assert(initialized()); + return contained_val(); + } + + OPTIONAL_MUTABLE_CONSTEXPR T &&operator*() && { + assert(initialized()); + return constexpr_move(contained_val()); + } + + constexpr T const &value() const & { + return initialized() + ? contained_val() + : (throw bad_optional_access("bad optional access"), + contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T &value() & { + return initialized() + ? contained_val() + : (throw bad_optional_access("bad optional access"), + contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T &&value() && { + if (!initialized()) + throw bad_optional_access("bad optional access"); + return std::move(contained_val()); + } + +#else + + T *operator->() { + assert(initialized()); + return dataptr(); + } + + constexpr T const &operator*() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + T &operator*() { + assert(initialized()); + return contained_val(); + } + + constexpr T const &value() const { + return initialized() + ? contained_val() + : (throw bad_optional_access("bad optional access"), + contained_val()); + } + + T &value() { + return initialized() + ? contained_val() + : (throw bad_optional_access("bad optional access"), + contained_val()); + } + +#endif + +#if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + + template constexpr T value_or(V &&v) const & { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +#if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + template OPTIONAL_MUTABLE_CONSTEXPR T value_or(V &&v) && { + return *this ? constexpr_move( + const_cast &>(*this).contained_val()) + : detail_::convert(constexpr_forward(v)); + } + +#else + + template T value_or(V &&v) && { + return *this ? constexpr_move( + const_cast &>(*this).contained_val()) + : detail_::convert(constexpr_forward(v)); + } + +#endif + +#else + + template constexpr T value_or(V &&v) const { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +#endif + + // 20.6.3.6, modifiers + void reset() noexcept { clear(); } }; +template class optional { + static_assert(!std::is_same::value, "bad T"); + static_assert(!std::is_same::value, "bad T"); + T *ref; -template -class optional -{ - static_assert( !std::is_same::value, "bad T" ); - static_assert( !std::is_same::value, "bad T" ); - T* ref; - -public: - - // 20.5.5.1, construction/destruction - constexpr optional() noexcept : ref(nullptr) {} - - constexpr optional(nullopt_t) noexcept : ref(nullptr) {} - - constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {} - - optional(T&&) = delete; - - constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {} - - explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {} - - explicit optional(in_place_t, T&&) = delete; - - ~optional() = default; - - // 20.5.5.2, mutation - optional& operator=(nullopt_t) noexcept { - ref = nullptr; - return *this; - } - - // optional& operator=(const optional& rhs) noexcept { + public: + // 20.5.5.1, construction/destruction + constexpr optional() noexcept : ref(nullptr) {} + + constexpr optional(nullopt_t) noexcept : ref(nullptr) {} + + constexpr optional(T &v) noexcept : ref(detail_::static_addressof(v)) {} + + optional(T &&) = delete; + + constexpr optional(const optional &rhs) noexcept : ref(rhs.ref) {} + + explicit constexpr optional(in_place_t, T &v) noexcept + : ref(detail_::static_addressof(v)) {} + + explicit optional(in_place_t, T &&) = delete; + + ~optional() = default; + + // 20.5.5.2, mutation + optional &operator=(nullopt_t) noexcept { + ref = nullptr; + return *this; + } + + // optional& operator=(const optional& rhs) noexcept { // ref = rhs.ref; // return *this; - // } - - // optional& operator=(optional&& rhs) noexcept { + // } + + // optional& operator=(optional&& rhs) noexcept { // ref = rhs.ref; // return *this; - // } - - template - auto operator=(U&& rhs) noexcept - -> typename enable_if - < - is_same::type, optional>::value, - optional& - >::type - { - ref = rhs.ref; - return *this; - } - - template - auto operator=(U&& rhs) noexcept - -> typename enable_if - < - !is_same::type, optional>::value, - optional& - >::type - = delete; - - void emplace(T& v) noexcept { - ref = detail_::static_addressof(v); - } - - void emplace(T&&) = delete; - - - void swap(optional& rhs) noexcept - { - std::swap(ref, rhs.ref); - } - - // 20.5.5.3, observers - constexpr T* operator->() const { - return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref); - } - - constexpr T& operator*() const { - return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref); - } - - constexpr T& value() const { - return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); - } - - explicit constexpr operator bool() const noexcept { - return ref != nullptr; - } - - constexpr bool has_value() const noexcept { - return ref != nullptr; - } - - template - constexpr typename decay::type value_or(V&& v) const - { - return *this ? **this : detail_::convert::type>(constexpr_forward(v)); - } - - // x.x.x.x, modifiers - void reset() noexcept { ref = nullptr; } -}; + // } + + template + auto operator=(U &&rhs) noexcept -> typename enable_if< + is_same::type, optional>::value, + optional &>::type { + ref = rhs.ref; + return *this; + } + template + auto operator=(U &&rhs) noexcept -> typename enable_if< + !is_same::type, optional>::value, + optional &>::type = delete; -template -class optional -{ - static_assert( sizeof(T) == 0, "optional rvalue references disallowed" ); + void emplace(T &v) noexcept { ref = detail_::static_addressof(v); } + + void emplace(T &&) = delete; + + void swap(optional &rhs) noexcept { std::swap(ref, rhs.ref); } + + // 20.5.5.3, observers + constexpr T *operator->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref); + } + + constexpr T &operator*() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref); + } + + constexpr T &value() const { + return ref ? *ref + : (throw bad_optional_access("bad optional access"), *ref); + } + + explicit constexpr operator bool() const noexcept { return ref != nullptr; } + + constexpr bool has_value() const noexcept { return ref != nullptr; } + + template constexpr typename decay::type value_or(V &&v) const { + return *this ? **this : detail_::convert::type>( + constexpr_forward(v)); + } + + // x.x.x.x, modifiers + void reset() noexcept { ref = nullptr; } }; +template class optional { + static_assert(sizeof(T) == 0, "optional rvalue references disallowed"); +}; // 20.5.8, Relational operators -template constexpr bool operator==(const optional& x, const optional& y) -{ - return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; +template +constexpr bool operator==(const optional &x, const optional &y) { + return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; } -template constexpr bool operator!=(const optional& x, const optional& y) -{ - return !(x == y); +template +constexpr bool operator!=(const optional &x, const optional &y) { + return !(x == y); } -template constexpr bool operator<(const optional& x, const optional& y) -{ - return (!y) ? false : (!x) ? true : *x < *y; +template +constexpr bool operator<(const optional &x, const optional &y) { + return (!y) ? false : (!x) ? true : *x < *y; } -template constexpr bool operator>(const optional& x, const optional& y) -{ - return (y < x); +template +constexpr bool operator>(const optional &x, const optional &y) { + return (y < x); } -template constexpr bool operator<=(const optional& x, const optional& y) -{ - return !(y < x); +template +constexpr bool operator<=(const optional &x, const optional &y) { + return !(y < x); } -template constexpr bool operator>=(const optional& x, const optional& y) -{ - return !(x < y); +template +constexpr bool operator>=(const optional &x, const optional &y) { + return !(x < y); } - // 20.5.9, Comparison with nullopt -template constexpr bool operator==(const optional& x, nullopt_t) noexcept -{ - return (!x); +template +constexpr bool operator==(const optional &x, nullopt_t) noexcept { + return (!x); } -template constexpr bool operator==(nullopt_t, const optional& x) noexcept -{ - return (!x); +template +constexpr bool operator==(nullopt_t, const optional &x) noexcept { + return (!x); } -template constexpr bool operator!=(const optional& x, nullopt_t) noexcept -{ - return bool(x); +template +constexpr bool operator!=(const optional &x, nullopt_t) noexcept { + return bool(x); } -template constexpr bool operator!=(nullopt_t, const optional& x) noexcept -{ - return bool(x); +template +constexpr bool operator!=(nullopt_t, const optional &x) noexcept { + return bool(x); } -template constexpr bool operator<(const optional&, nullopt_t) noexcept -{ - return false; +template +constexpr bool operator<(const optional &, nullopt_t) noexcept { + return false; } -template constexpr bool operator<(nullopt_t, const optional& x) noexcept -{ - return bool(x); +template +constexpr bool operator<(nullopt_t, const optional &x) noexcept { + return bool(x); } -template constexpr bool operator<=(const optional& x, nullopt_t) noexcept -{ - return (!x); +template +constexpr bool operator<=(const optional &x, nullopt_t) noexcept { + return (!x); } -template constexpr bool operator<=(nullopt_t, const optional&) noexcept -{ - return true; +template +constexpr bool operator<=(nullopt_t, const optional &) noexcept { + return true; } -template constexpr bool operator>(const optional& x, nullopt_t) noexcept -{ - return bool(x); +template +constexpr bool operator>(const optional &x, nullopt_t) noexcept { + return bool(x); } -template constexpr bool operator>(nullopt_t, const optional&) noexcept -{ - return false; +template +constexpr bool operator>(nullopt_t, const optional &) noexcept { + return false; } -template constexpr bool operator>=(const optional&, nullopt_t) noexcept -{ - return true; +template +constexpr bool operator>=(const optional &, nullopt_t) noexcept { + return true; } -template constexpr bool operator>=(nullopt_t, const optional& x) noexcept -{ - return (!x); +template +constexpr bool operator>=(nullopt_t, const optional &x) noexcept { + return (!x); } - - // 20.5.10, Comparison with T -template constexpr bool operator==(const optional& x, const T& v) -{ - return bool(x) ? *x == v : false; +template constexpr bool operator==(const optional &x, const T &v) { + return bool(x) ? *x == v : false; } -template constexpr bool operator==(const T& v, const optional& x) -{ - return bool(x) ? v == *x : false; +template constexpr bool operator==(const T &v, const optional &x) { + return bool(x) ? v == *x : false; } -template constexpr bool operator!=(const optional& x, const T& v) -{ - return bool(x) ? *x != v : true; +template constexpr bool operator!=(const optional &x, const T &v) { + return bool(x) ? *x != v : true; } -template constexpr bool operator!=(const T& v, const optional& x) -{ - return bool(x) ? v != *x : true; +template constexpr bool operator!=(const T &v, const optional &x) { + return bool(x) ? v != *x : true; } -template constexpr bool operator<(const optional& x, const T& v) -{ - return bool(x) ? *x < v : true; +template constexpr bool operator<(const optional &x, const T &v) { + return bool(x) ? *x < v : true; } -template constexpr bool operator>(const T& v, const optional& x) -{ - return bool(x) ? v > *x : true; +template constexpr bool operator>(const T &v, const optional &x) { + return bool(x) ? v > *x : true; } -template constexpr bool operator>(const optional& x, const T& v) -{ - return bool(x) ? *x > v : false; +template constexpr bool operator>(const optional &x, const T &v) { + return bool(x) ? *x > v : false; } -template constexpr bool operator<(const T& v, const optional& x) -{ - return bool(x) ? v < *x : false; +template constexpr bool operator<(const T &v, const optional &x) { + return bool(x) ? v < *x : false; } -template constexpr bool operator>=(const optional& x, const T& v) -{ - return bool(x) ? *x >= v : false; +template constexpr bool operator>=(const optional &x, const T &v) { + return bool(x) ? *x >= v : false; } -template constexpr bool operator<=(const T& v, const optional& x) -{ - return bool(x) ? v <= *x : false; +template constexpr bool operator<=(const T &v, const optional &x) { + return bool(x) ? v <= *x : false; } -template constexpr bool operator<=(const optional& x, const T& v) -{ - return bool(x) ? *x <= v : true; +template constexpr bool operator<=(const optional &x, const T &v) { + return bool(x) ? *x <= v : true; } -template constexpr bool operator>=(const T& v, const optional& x) -{ - return bool(x) ? v >= *x : true; +template constexpr bool operator>=(const T &v, const optional &x) { + return bool(x) ? v >= *x : true; } - // Comparison of optional with T -template constexpr bool operator==(const optional& x, const T& v) -{ - return bool(x) ? *x == v : false; +template +constexpr bool operator==(const optional &x, const T &v) { + return bool(x) ? *x == v : false; } -template constexpr bool operator==(const T& v, const optional& x) -{ - return bool(x) ? v == *x : false; +template +constexpr bool operator==(const T &v, const optional &x) { + return bool(x) ? v == *x : false; } -template constexpr bool operator!=(const optional& x, const T& v) -{ - return bool(x) ? *x != v : true; +template +constexpr bool operator!=(const optional &x, const T &v) { + return bool(x) ? *x != v : true; } -template constexpr bool operator!=(const T& v, const optional& x) -{ - return bool(x) ? v != *x : true; +template +constexpr bool operator!=(const T &v, const optional &x) { + return bool(x) ? v != *x : true; } -template constexpr bool operator<(const optional& x, const T& v) -{ - return bool(x) ? *x < v : true; +template +constexpr bool operator<(const optional &x, const T &v) { + return bool(x) ? *x < v : true; } -template constexpr bool operator>(const T& v, const optional& x) -{ - return bool(x) ? v > *x : true; +template +constexpr bool operator>(const T &v, const optional &x) { + return bool(x) ? v > *x : true; } -template constexpr bool operator>(const optional& x, const T& v) -{ - return bool(x) ? *x > v : false; +template +constexpr bool operator>(const optional &x, const T &v) { + return bool(x) ? *x > v : false; } -template constexpr bool operator<(const T& v, const optional& x) -{ - return bool(x) ? v < *x : false; +template +constexpr bool operator<(const T &v, const optional &x) { + return bool(x) ? v < *x : false; } -template constexpr bool operator>=(const optional& x, const T& v) -{ - return bool(x) ? *x >= v : false; +template +constexpr bool operator>=(const optional &x, const T &v) { + return bool(x) ? *x >= v : false; } -template constexpr bool operator<=(const T& v, const optional& x) -{ - return bool(x) ? v <= *x : false; +template +constexpr bool operator<=(const T &v, const optional &x) { + return bool(x) ? v <= *x : false; } -template constexpr bool operator<=(const optional& x, const T& v) -{ - return bool(x) ? *x <= v : true; +template +constexpr bool operator<=(const optional &x, const T &v) { + return bool(x) ? *x <= v : true; } -template constexpr bool operator>=(const T& v, const optional& x) -{ - return bool(x) ? v >= *x : true; +template +constexpr bool operator>=(const T &v, const optional &x) { + return bool(x) ? v >= *x : true; } // Comparison of optional with T -template constexpr bool operator==(const optional& x, const T& v) -{ - return bool(x) ? *x == v : false; +template +constexpr bool operator==(const optional &x, const T &v) { + return bool(x) ? *x == v : false; } -template constexpr bool operator==(const T& v, const optional& x) -{ - return bool(x) ? v == *x : false; +template +constexpr bool operator==(const T &v, const optional &x) { + return bool(x) ? v == *x : false; } -template constexpr bool operator!=(const optional& x, const T& v) -{ - return bool(x) ? *x != v : true; +template +constexpr bool operator!=(const optional &x, const T &v) { + return bool(x) ? *x != v : true; } -template constexpr bool operator!=(const T& v, const optional& x) -{ - return bool(x) ? v != *x : true; +template +constexpr bool operator!=(const T &v, const optional &x) { + return bool(x) ? v != *x : true; } -template constexpr bool operator<(const optional& x, const T& v) -{ - return bool(x) ? *x < v : true; +template +constexpr bool operator<(const optional &x, const T &v) { + return bool(x) ? *x < v : true; } -template constexpr bool operator>(const T& v, const optional& x) -{ - return bool(x) ? v > *x : true; +template +constexpr bool operator>(const T &v, const optional &x) { + return bool(x) ? v > *x : true; } -template constexpr bool operator>(const optional& x, const T& v) -{ - return bool(x) ? *x > v : false; +template +constexpr bool operator>(const optional &x, const T &v) { + return bool(x) ? *x > v : false; } -template constexpr bool operator<(const T& v, const optional& x) -{ - return bool(x) ? v < *x : false; +template +constexpr bool operator<(const T &v, const optional &x) { + return bool(x) ? v < *x : false; } -template constexpr bool operator>=(const optional& x, const T& v) -{ - return bool(x) ? *x >= v : false; +template +constexpr bool operator>=(const optional &x, const T &v) { + return bool(x) ? *x >= v : false; } -template constexpr bool operator<=(const T& v, const optional& x) -{ - return bool(x) ? v <= *x : false; +template +constexpr bool operator<=(const T &v, const optional &x) { + return bool(x) ? v <= *x : false; } -template constexpr bool operator<=(const optional& x, const T& v) -{ - return bool(x) ? *x <= v : true; +template +constexpr bool operator<=(const optional &x, const T &v) { + return bool(x) ? *x <= v : true; } -template constexpr bool operator>=(const T& v, const optional& x) -{ - return bool(x) ? v >= *x : true; +template +constexpr bool operator>=(const T &v, const optional &x) { + return bool(x) ? v >= *x : true; } - // 20.5.12, Specialized algorithms template -void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))) -{ - x.swap(y); +void swap(optional &x, optional &y) noexcept(noexcept(x.swap(y))) { + x.swap(y); } - template -constexpr optional::type> make_optional(T&& v) -{ - return optional::type>(constexpr_forward(v)); +constexpr optional::type> make_optional(T &&v) { + return optional::type>(constexpr_forward(v)); } template -constexpr optional make_optional(reference_wrapper v) -{ - return optional(v.get()); +constexpr optional make_optional(reference_wrapper v) { + return optional(v.get()); } - } // namespace experimental } // namespace std -namespace std -{ - template - struct hash> - { +namespace std { +template struct hash> { typedef typename hash::result_type result_type; typedef std::experimental::optional argument_type; - - constexpr result_type operator()(argument_type const& arg) const { - return arg ? std::hash{}(*arg) : result_type{}; + + constexpr result_type operator()(argument_type const &arg) const { + return arg ? std::hash{}(*arg) : result_type{}; } - }; - - template - struct hash> - { +}; + +template struct hash> { typedef typename hash::result_type result_type; - typedef std::experimental::optional argument_type; - - constexpr result_type operator()(argument_type const& arg) const { - return arg ? std::hash{}(*arg) : result_type{}; + typedef std::experimental::optional argument_type; + + constexpr result_type operator()(argument_type const &arg) const { + return arg ? std::hash{}(*arg) : result_type{}; } - }; +}; } -# undef TR2_OPTIONAL_REQUIRES -# undef TR2_OPTIONAL_ASSERTED_EXPRESSION +#undef TR2_OPTIONAL_REQUIRES +#undef TR2_OPTIONAL_ASSERTED_EXPRESSION -# endif //___OPTIONAL_HPP___ \ No newline at end of file +#endif //___OPTIONAL_HPP___ \ No newline at end of file diff --git a/bmf/hml/include/hmp/dataexport/data_export.h b/bmf/hml/include/hmp/dataexport/data_export.h index 1da44ac1..488ece0f 100644 --- a/bmf/hml/include/hmp/dataexport/data_export.h +++ b/bmf/hml/include/hmp/dataexport/data_export.h @@ -5,5 +5,5 @@ namespace hmp { HMP_API DLManagedTensor *to_dlpack(const Tensor &src); -HMP_API Tensor from_dlpack(const DLManagedTensor* src); +HMP_API Tensor from_dlpack(const DLManagedTensor *src); } // namespace hmp \ No newline at end of file diff --git a/bmf/hml/include/hmp_capi.h b/bmf/hml/include/hmp_capi.h index a28d7690..e59d0c12 100644 --- a/bmf/hml/include/hmp_capi.h +++ b/bmf/hml/include/hmp_capi.h @@ -178,7 +178,7 @@ HMP_API hmp_Frame hmp_frame_clone(const hmp_Frame frame); HMP_API hmp_Frame hmp_frame_crop(const hmp_Frame frame, int left, int top, int width, int height); HMP_API hmp_Frame hmp_frame_reformat(const hmp_Frame frame, - const hmp_PixelInfo pix_info); + const hmp_PixelInfo pix_info); HMP_API const char *hmp_frame_stringfy(const hmp_Frame frame, int *size); #ifdef __cplusplus diff --git a/bmf/hml/java/hmp_japi.cpp b/bmf/hml/java/hmp_japi.cpp index 2db6edda..074b4c07 100644 --- a/bmf/hml/java/hmp_japi.cpp +++ b/bmf/hml/java/hmp_japi.cpp @@ -21,23 +21,18 @@ #include #include - using namespace hmp; - - ////////////////////// Scalar ////////////////////////// /* * Class: com_bytedance_hmp_Api * Method: scalar * Signature: (D)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__D - (JNIEnv *env, jclass, jdouble value) -{ - JNI_PROTECT( - return jni::makePtr(value); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__D(JNIEnv *env, + jclass, + jdouble value) { + JNI_PROTECT(return jni::makePtr(value);) return 0; } @@ -47,12 +42,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__D * Method: scalar * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__J - (JNIEnv *env, jclass, jlong value) -{ - JNI_PROTECT( - return jni::makePtr(value); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__J(JNIEnv *env, + jclass, + jlong value) { + JNI_PROTECT(return jni::makePtr(value);) return 0; } @@ -62,12 +55,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__J * Method: scalar * Signature: (Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__Z - (JNIEnv *env, jclass, jboolean value) -{ - JNI_PROTECT( - return jni::makePtr((bool)value); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__Z(JNIEnv *env, + jclass, + jboolean value) { + JNI_PROTECT(return jni::makePtr((bool)value);) return 0; } @@ -77,15 +68,12 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_scalar__Z * Method: scalar_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_scalar_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_scalar_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } - ////////////////////// Device ////////////////////////////////////// /* @@ -93,12 +81,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_scalar_1free * Method: device_count * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1count - (JNIEnv *env, jclass, jint device_type) -{ - JNI_PROTECT( - return device_count((DeviceType)device_type); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1count( + JNIEnv *env, jclass, jint device_type) { + JNI_PROTECT(return device_count((DeviceType)device_type);) return 0; } @@ -108,33 +93,24 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1count * Method: device_make * Signature: (Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1make__Ljava_lang_String_2 - (JNIEnv *env, jclass, jstring dstr) -{ - JNI_PROTECT( - auto str = jni::fromJString(env, dstr); - if(str.size()){ - return jni::makePtr(str); - } - else{ - return jni::makePtr(); - } - ) +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_device_1make__Ljava_lang_String_2(JNIEnv *env, + jclass, + jstring dstr) { + JNI_PROTECT(auto str = jni::fromJString(env, dstr); if (str.size()) { + return jni::makePtr(str); + } else { return jni::makePtr(); }) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: device_make * Signature: (II)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1make__II - (JNIEnv *env, jclass, jint device_type, jint index) -{ - JNI_PROTECT( - return jni::makePtr((DeviceType)device_type, index); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1make__II( + JNIEnv *env, jclass, jint device_type, jint index) { + JNI_PROTECT(return jni::makePtr((DeviceType)device_type, index);) return 0; } @@ -143,12 +119,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1make__II * Method: device_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_device_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_device_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -156,11 +130,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_device_1free * Method: device_type * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1type - (JNIEnv *env, jclass, jlong ptr) -{ +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1type(JNIEnv *env, + jclass, + jlong ptr) { return (jint)jni::ptr(ptr)->type(); - } /* @@ -168,40 +141,32 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1type * Method: device_index * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1index - (JNIEnv *, jclass, jlong ptr) -{ +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_device_1index(JNIEnv *, + jclass, + jlong ptr) { return (jint)jni::ptr(ptr)->index(); } - /* * Class: com_bytedance_hmp_Api * Method: device_stringfy * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_device_1stringfy - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - auto str = stringfy(*jni::ptr(ptr)); - return jni::toJString(env, str); - ) +JNIEXPORT jstring JNICALL +Java_com_bytedance_hmp_Api_device_1stringfy(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(auto str = stringfy(*jni::ptr(ptr)); + return jni::toJString(env, str);) return jni::toJString(env, ""); } - /* * Class: com_bytedance_hmp_Api * Method: device_guard_make * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1guard_1make - (JNIEnv *env, jclass, jlong device) -{ - JNI_PROTECT( - return jni::makePtr(*jni::ptr(device)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1guard_1make( + JNIEnv *env, jclass, jlong device) { + JNI_PROTECT(return jni::makePtr(*jni::ptr(device));) return 0; } @@ -210,27 +175,21 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_device_1guard_1make * Method: device_guard_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_device_1guard_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL +Java_com_bytedance_hmp_Api_device_1guard_1free(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } - ///////////////////// Stream & StreamGuard //////////////// /* * Class: com_bytedance_hmp_Api * Method: stream_make * Signature: (IJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1make - (JNIEnv *env, jclass, jint device_type, jlong flags) -{ - JNI_PROTECT( - return jni::makePtr(create_stream((DeviceType)device_type, flags)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1make( + JNIEnv *env, jclass, jint device_type, jlong flags) { + JNI_PROTECT(return jni::makePtr( + create_stream((DeviceType)device_type, flags));) return 0; } @@ -239,12 +198,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1make * Method: stream_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -252,12 +209,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1free * Method: stream_query * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_stream_1query - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->query(); - ) +JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_stream_1query(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->query();) return false; } @@ -266,12 +221,9 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_stream_1query * Method: stream_synchronize * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1synchronize - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::ptr(ptr)->synchronize(); - ) +JNIEXPORT void JNICALL +Java_com_bytedance_hmp_Api_stream_1synchronize(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(jni::ptr(ptr)->synchronize();) } /* @@ -279,12 +231,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1synchronize * Method: stream_handle * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1handle - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->handle(); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1handle(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->handle();) return 0; } @@ -293,12 +243,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1handle * Method: stream_device_type * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1type - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().type(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1type( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().type();) return 0; } @@ -307,12 +254,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1type * Method: stream_device_index * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1index - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().index(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1index( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().index();) return 0; } @@ -321,12 +265,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_stream_1device_1index * Method: stream_set_current * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1set_1current - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - set_current_stream(*jni::ptr(ptr)); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1set_1current( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(set_current_stream(*jni::ptr(ptr));) } /* @@ -334,12 +275,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1set_1current * Method: stream_current * Signature: (I)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1current - (JNIEnv *env, jclass, jint device_type) -{ - JNI_PROTECT( - return jni::makePtr(current_stream((DeviceType)device_type).value()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1current( + JNIEnv *env, jclass, jint device_type) { + JNI_PROTECT(return jni::makePtr( + current_stream((DeviceType)device_type).value());) return 0; } @@ -348,12 +287,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1current * Method: stream_guard_create * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1guard_1create - (JNIEnv *env, jclass, jlong stream) -{ - JNI_PROTECT( - return jni::makePtr(*jni::ptr(stream)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1guard_1create( + JNIEnv *env, jclass, jlong stream) { + JNI_PROTECT(return jni::makePtr(*jni::ptr(stream));) return 0; } @@ -362,30 +298,25 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_stream_1guard_1create * Method: stream_guard_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_stream_1guard_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL +Java_com_bytedance_hmp_Api_stream_1guard_1free(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } - /////////////////////// Tensor ///////////////////////////// /* * Class: com_bytedance_hmp_Api * Method: tensor_empty * Signature: ([JILjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1empty - (JNIEnv *env, jclass, jlongArray shape, jint dtype, jstring device, jboolean pinned_memory) -{ - JNI_PROTECT( - auto vshape = jni::fromJArray(env, shape); - return jni::makePtr(empty(vshape, TensorOptions(jni::fromJString(env, device)) - .dtype((ScalarType)dtype) - .pinned_memory(pinned_memory))); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1empty( + JNIEnv *env, jclass, jlongArray shape, jint dtype, jstring device, + jboolean pinned_memory) { + JNI_PROTECT(auto vshape = jni::fromJArray(env, shape); + return jni::makePtr( + empty(vshape, TensorOptions(jni::fromJString(env, device)) + .dtype((ScalarType)dtype) + .pinned_memory(pinned_memory)));) return 0; } @@ -394,15 +325,13 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1empty * Method: tensor_arange * Signature: (JJJILjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1arange - (JNIEnv *env, jclass, jlong start, jlong end, jlong step, jint dtype, jstring device, jboolean pinned_memory) -{ - JNI_PROTECT( - return jni::makePtr(arange(start, end, step, - TensorOptions(jni::fromJString(env, device)) - .dtype((ScalarType)dtype) - .pinned_memory(pinned_memory))); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1arange( + JNIEnv *env, jclass, jlong start, jlong end, jlong step, jint dtype, + jstring device, jboolean pinned_memory) { + JNI_PROTECT(return jni::makePtr(arange( + start, end, step, TensorOptions(jni::fromJString(env, device)) + .dtype((ScalarType)dtype) + .pinned_memory(pinned_memory)));) return 0; } @@ -411,12 +340,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1arange * Method: tensor_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -424,13 +351,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1free * Method: tensor_stringfy * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_tensor_1stringfy - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - auto str = stringfy(*jni::ptr(ptr)); - return jni::toJString(env, str); - ) +JNIEXPORT jstring JNICALL +Java_com_bytedance_hmp_Api_tensor_1stringfy(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(auto str = stringfy(*jni::ptr(ptr)); + return jni::toJString(env, str);) return jni::toJString(env, ""); } @@ -440,12 +364,11 @@ JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_tensor_1stringfy * Method: tensor_fill * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1fill - (JNIEnv *env, jclass, jlong ptr, jlong scalar) -{ - JNI_PROTECT( - jni::ptr(ptr)->fill_(*jni::ptr(scalar)); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1fill(JNIEnv *env, + jclass, + jlong ptr, + jlong scalar) { + JNI_PROTECT(jni::ptr(ptr)->fill_(*jni::ptr(scalar));) } /* @@ -453,12 +376,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1fill * Method: tensor_defined * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_tensor_1defined - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->defined(); - ) +JNIEXPORT jboolean JNICALL +Java_com_bytedance_hmp_Api_tensor_1defined(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->defined();) return false; } @@ -467,12 +387,10 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_tensor_1defined * Method: tensor_dim * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1dim - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->dim(); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1dim(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->dim();) return 0; } @@ -481,12 +399,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1dim * Method: tensor_size * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1size - (JNIEnv *env, jclass, jlong ptr, jlong dim) -{ - JNI_PROTECT( - return jni::ptr(ptr)->size(dim); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1size(JNIEnv *env, + jclass, + jlong ptr, + jlong dim) { + JNI_PROTECT(return jni::ptr(ptr)->size(dim);) return 0; } @@ -495,12 +412,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1size * Method: tensor_stride * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1stride - (JNIEnv *env, jclass, jlong ptr, jlong dim) -{ - JNI_PROTECT( - return jni::ptr(ptr)->stride(dim); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1stride(JNIEnv *env, + jclass, + jlong ptr, + jlong dim) { + JNI_PROTECT(return jni::ptr(ptr)->stride(dim);) return 0; } @@ -509,31 +425,25 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1stride * Method: tensor_nitems * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1nitems - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->nitems(); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1nitems(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->nitems();) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: tensor_from_file * Signature: (Ljava/lang/String;IJJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1from_1file - (JNIEnv *env, jclass, jstring fn, jint dtype, jlong count, jlong offset) -{ - JNI_PROTECT( - auto sfn = jni::fromJString(env, fn); - return jni::makePtr( - hmp::fromfile(sfn, (ScalarType)dtype, count, offset)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1from_1file( + JNIEnv *env, jclass, jstring fn, jint dtype, jlong count, jlong offset) { + JNI_PROTECT(auto sfn = jni::fromJString(env, fn); + return jni::makePtr( + hmp::fromfile(sfn, (ScalarType)dtype, count, offset));) - return 0; + return 0; } /* @@ -541,27 +451,23 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1from_1file * Method: tensor_to_file * Signature: (JLjava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1file - (JNIEnv *env, jclass, jlong data, jstring fn) -{ - JNI_PROTECT( - auto sfn = jni::fromJString(env, fn); - hmp::tofile(*jni::ptr(data), sfn); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1file(JNIEnv *env, + jclass, + jlong data, + jstring fn) { + JNI_PROTECT(auto sfn = jni::fromJString(env, fn); + hmp::tofile(*jni::ptr(data), sfn);) } - /* * Class: com_bytedance_hmp_Api * Method: tensor_itemsize * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1itemsize - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->itemsize(); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1itemsize(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->itemsize();) return 0; } @@ -570,12 +476,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1itemsize * Method: tensor_nbytes * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1nbytes - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->nbytes(); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1nbytes(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->nbytes();) return 0; } @@ -584,12 +488,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1nbytes * Method: tensor_dtype * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1dtype - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->dtype(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1dtype(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->dtype();) return 0; } @@ -598,12 +500,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1dtype * Method: tensor_is_contiguous * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_tensor_1is_1contiguous - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->is_contiguous(); - ) +JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_tensor_1is_1contiguous( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->is_contiguous();) return 0; } @@ -612,12 +511,9 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_tensor_1is_1contiguous * Method: tensor_device_type * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1type - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device_type(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1type( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device_type();) return 0; } @@ -626,12 +522,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1type * Method: tensor_device_index * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1index - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->device_index(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1index( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->device_index();) return 0; } @@ -640,27 +533,21 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_tensor_1device_1index * Method: tensor_data_ptr * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1data_1ptr - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jlong)jni::ptr(ptr)->unsafe_data(); - ) +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_tensor_1data_1ptr(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jlong)jni::ptr(ptr)->unsafe_data();) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: tensor_clone * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1clone - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->clone()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1clone(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->clone());) return 0; } @@ -669,28 +556,23 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1clone * Method: tensor_alias * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1alias - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->alias()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1alias(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->alias());) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: tensor_view * Signature: (J[J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1view - (JNIEnv *env, jclass, jlong ptr, jlongArray shape) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1view( + JNIEnv *env, jclass, jlong ptr, jlongArray shape) { JNI_PROTECT( auto vshape = jni::fromJArray(env, shape); - return jni::makePtr(jni::ptr(ptr)->view(vshape)); - ) + return jni::makePtr(jni::ptr(ptr)->view(vshape));) return 0; } @@ -699,13 +581,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1view * Method: tensor_reshape * Signature: (J[J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1reshape - (JNIEnv *env, jclass, jlong ptr, jlongArray shape) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1reshape( + JNIEnv *env, jclass, jlong ptr, jlongArray shape) { JNI_PROTECT( auto vshape = jni::fromJArray(env, shape); - return jni::makePtr(jni::ptr(ptr)->reshape(vshape)); - ) + return jni::makePtr(jni::ptr(ptr)->reshape(vshape));) return 0; } @@ -714,12 +594,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1reshape * Method: tensor_slice * Signature: (JJJJJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1slice - (JNIEnv *env, jclass, jlong ptr, jlong dim, jlong start, jlong end, jlong step) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->slice(dim, start, end, step)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1slice( + JNIEnv *env, jclass, jlong ptr, jlong dim, jlong start, jlong end, + jlong step) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->slice( + dim, start, end, step));) return 0; } @@ -728,12 +607,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1slice * Method: tensor_select * Signature: (JJJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1select - (JNIEnv *env, jclass, jlong ptr, jlong dim, jlong index) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1select( + JNIEnv *env, jclass, jlong ptr, jlong dim, jlong index) { JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->select(dim, index)); - ) + return jni::makePtr(jni::ptr(ptr)->select(dim, index));) return 0; } @@ -742,13 +619,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1select * Method: tensor_permute * Signature: (J[J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1permute - (JNIEnv *env, jclass, jlong ptr, jlongArray dims) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1permute( + JNIEnv *env, jclass, jlong ptr, jlongArray dims) { JNI_PROTECT( auto vdims = jni::fromJArray(env, dims); - return jni::makePtr(jni::ptr(ptr)->permute(vdims)); - ) + return jni::makePtr(jni::ptr(ptr)->permute(vdims));) return 0; } @@ -757,12 +632,12 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1permute * Method: tensor_squeeze * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1squeeze - (JNIEnv *env, jclass, jlong ptr, jlong dim) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1squeeze(JNIEnv *env, + jclass, + jlong ptr, + jlong dim) { JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->squeeze(dim)); - ) + return jni::makePtr(jni::ptr(ptr)->squeeze(dim));) return 0; } @@ -771,12 +646,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1squeeze * Method: tensor_unsqueeze * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1unsqueeze - (JNIEnv *env, jclass, jlong ptr, jlong dim) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1unsqueeze( + JNIEnv *env, jclass, jlong ptr, jlong dim) { JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->unsqueeze(dim)); - ) + return jni::makePtr(jni::ptr(ptr)->unsqueeze(dim));) return 0; } @@ -785,13 +658,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1unsqueeze * Method: tensor_to_device * Signature: (JLjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1device - (JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->to( - Device(jni::fromJString(env, device)), non_blocking)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1device( + JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->to( + Device(jni::fromJString(env, device)), non_blocking));) return 0; } @@ -800,13 +670,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1device * Method: tensor_to_dtype * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1dtype - (JNIEnv *env, jclass, jlong ptr, jint dtype) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->to( - ScalarType(dtype))); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1dtype( + JNIEnv *env, jclass, jlong ptr, jint dtype) { + JNI_PROTECT(return jni::makePtr( + jni::ptr(ptr)->to(ScalarType(dtype)));) return 0; } @@ -815,29 +682,21 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_tensor_1to_1dtype * Method: tensor_copy_from * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1copy_1from - (JNIEnv *env, jclass, jlong ptr, jlong from) -{ - JNI_PROTECT( - jni::ptr(ptr)->copy_(*jni::ptr(from)); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_tensor_1copy_1from( + JNIEnv *env, jclass, jlong ptr, jlong from) { + JNI_PROTECT(jni::ptr(ptr)->copy_(*jni::ptr(from));) } - /* * Class: com_bytedance_hmp_Api * Method: color_model_make * Signature: (IIII)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_color_1model_1make - (JNIEnv *env, jclass, jint cs, jint cr, jint cp, jint ctc) -{ - JNI_PROTECT( - return jni::makePtr((ColorSpace)cs, - (ColorRange)cr, - (ColorPrimaries)cp, - (ColorTransferCharacteristic)ctc); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_color_1model_1make( + JNIEnv *env, jclass, jint cs, jint cr, jint cp, jint ctc) { + JNI_PROTECT(return jni::makePtr( + (ColorSpace)cs, (ColorRange)cr, (ColorPrimaries)cp, + (ColorTransferCharacteristic)ctc);) return 0; } @@ -847,12 +706,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_color_1model_1make * Method: color_model_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_color_1model_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL +Java_com_bytedance_hmp_Api_color_1model_1free(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -860,12 +716,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_color_1model_1free * Method: color_model_space * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1space - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->space(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_color_1model_1space(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->space();) return 0; } @@ -874,12 +727,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1space * Method: color_model_range * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1range - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->range(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_color_1model_1range(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->range();) return 0; } @@ -888,12 +738,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1range * Method: color_model_primaries * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1primaries - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->primaries(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1primaries( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->primaries();) return 0; } @@ -902,12 +749,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1primaries * Method: color_model_ctc * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1ctc - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->transfer_characteristic(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1ctc(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->transfer_characteristic();) return 0; } @@ -916,12 +761,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_color_1model_1ctc * Method: pixel_info_make * Signature: (IJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__IJ - (JNIEnv *env, jclass, jint format, jlong cm) -{ - JNI_PROTECT( - return jni::makePtr((PixelFormat)format, *jni::ptr(cm)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__IJ( + JNIEnv *env, jclass, jint format, jlong cm) { + JNI_PROTECT(return jni::makePtr((PixelFormat)format, + *jni::ptr(cm));) return 0; } @@ -930,14 +773,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__IJ * Method: pixel_info_make * Signature: (III)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__III - (JNIEnv *env, jclass, jint format, jint cs, jint cr) -{ - JNI_PROTECT( - return jni::makePtr((PixelFormat)format, - (ColorSpace)cs, - (ColorRange)cr); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__III( + JNIEnv *env, jclass, jint format, jint cs, jint cr) { + JNI_PROTECT(return jni::makePtr((PixelFormat)format, + (ColorSpace)cs, (ColorRange)cr);) return 0; } @@ -946,12 +785,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1make__III * Method: pixel_info_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -959,12 +796,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1free * Method: pixel_info_format * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1format - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->format(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1info_1format(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->format();) return 0; } @@ -973,12 +807,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1format * Method: pixel_info_space * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1space - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->space(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1info_1space(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->space();) return 0; } @@ -987,12 +818,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1space * Method: pixel_info_range * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1range - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->range(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1info_1range(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->range();) return 0; } @@ -1001,12 +829,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1range * Method: pixel_info_primaries * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1primaries - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->primaries(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1primaries( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->primaries();) return 0; } @@ -1015,12 +840,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1primaries * Method: pixel_info_ctc * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1ctc - (JNIEnv *env, jclass, jlong ptr) -{ +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1ctc(JNIEnv *env, + jclass, + jlong ptr) { JNI_PROTECT( - return (jint)jni::ptr(ptr)->transfer_characteristic(); - ) + return (jint)jni::ptr(ptr)->transfer_characteristic();) return 0; } @@ -1029,12 +853,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1ctc * Method: pixel_info_infer_space * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1infer_1space - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->infer_space(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1infer_1space( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->infer_space();) return 0; } @@ -1043,12 +864,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1infer_1space * Method: pixel_info_color_model * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1color_1model - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jlong)(&jni::ptr(ptr)->color_model()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1color_1model( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jlong)(&jni::ptr(ptr)->color_model());) return 0; } @@ -1057,12 +875,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1color_1model * Method: pixel_info_is_rgbx * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1is_1rgbx - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->is_rgbx(); - ) +JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1is_1rgbx( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->is_rgbx();) return 0; } @@ -1071,13 +886,10 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1is_1rgbx * Method: pixel_info_stringfy * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1stringfy - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - auto str = stringfy(*jni::ptr(ptr)); - return jni::toJString(env, str); - ) +JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1stringfy( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(auto str = stringfy(*jni::ptr(ptr)); + return jni::toJString(env, str);) return jni::toJString(env, ""); } @@ -1086,12 +898,9 @@ JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_pixel_1info_1stringfy * Method: pixel_format_desc_make * Signature: (I)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1make - (JNIEnv *env, jclass obj, jint format) -{ - JNI_PROTECT( - return jni::makePtr(format); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1make( + JNIEnv *env, jclass obj, jint format) { + JNI_PROTECT(return jni::makePtr(format);) return 0; } @@ -1100,12 +909,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1make * Method: pixel_format_desc_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1free - (JNIEnv *env, jclass obj, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1free( + JNIEnv *env, jclass obj, jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -1113,12 +919,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1free * Method: pixel_format_desc_nplanes * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1nplanes - (JNIEnv *env, jclass obj, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->nplanes(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1nplanes( + JNIEnv *env, jclass obj, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->nplanes();) return 0; } @@ -1127,12 +930,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1nplanes * Method: pixel_format_desc_dtype * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1dtype - (JNIEnv *env, jclass obj, jlong ptr) -{ - JNI_PROTECT( - return (int)jni::ptr(ptr)->dtype(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1dtype( + JNIEnv *env, jclass obj, jlong ptr) { + JNI_PROTECT(return (int)jni::ptr(ptr)->dtype();) return 0; } @@ -1141,12 +941,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1dtype * Method: pixel_format_desc_format * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1format - (JNIEnv *env, jclass obj, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->format(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1format( + JNIEnv *env, jclass obj, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->format();) return 0; } @@ -1155,12 +952,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1format * Method: pixel_format_desc_channels * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1channels - (JNIEnv *env, jclass obj, jlong ptr, jint plane) -{ - JNI_PROTECT( - return jni::ptr(ptr)->channels(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1channels( + JNIEnv *env, jclass obj, jlong ptr, jint plane) { + JNI_PROTECT(return jni::ptr(ptr)->channels();) return 0; } @@ -1169,12 +963,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1channels * Method: pixel_format_desc_infer_width * Signature: (JII)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1width - (JNIEnv *env, jclass obj, jlong ptr, jint width, jint plane) -{ +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1width( + JNIEnv *env, jclass obj, jlong ptr, jint width, jint plane) { JNI_PROTECT( - return jni::ptr(ptr)->infer_width(width, plane); - ) + return jni::ptr(ptr)->infer_width(width, plane);) return 0; } @@ -1183,12 +976,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1wi * Method: pixel_format_desc_infer_height * Signature: (JII)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1height - (JNIEnv *env, jclass obj, jlong ptr, jint height, jint plane) -{ +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1height( + JNIEnv *env, jclass obj, jlong ptr, jint height, jint plane) { JNI_PROTECT( - return jni::ptr(ptr)->infer_height(height, plane); - ) + return jni::ptr(ptr)->infer_height(height, plane);) return 0; } @@ -1197,12 +989,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1he * Method: pixel_format_desc_infer_nitems * Signature: (JII)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1nitems__JII - (JNIEnv *env, jclass obj, jlong ptr, jint width, jint height) -{ +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1nitems__JII( + JNIEnv *env, jclass obj, jlong ptr, jint width, jint height) { JNI_PROTECT( - return jni::ptr(ptr)->infer_nitems(width, height); - ) + return jni::ptr(ptr)->infer_nitems(width, height);) return 0; } @@ -1211,12 +1002,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1ni * Method: pixel_format_desc_infer_nitems * Signature: (JIII)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1nitems__JIII - (JNIEnv *env, jclass obj, jlong ptr, jint width, jint height, jint plane) -{ - JNI_PROTECT( - return jni::ptr(ptr)->infer_nitems(width, height, plane); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1nitems__JIII( + JNIEnv *env, jclass obj, jlong ptr, jint width, jint height, jint plane) { + JNI_PROTECT(return jni::ptr(ptr)->infer_nitems( + width, height, plane);) return 0; } @@ -1225,33 +1015,30 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_pixel_1format_1desc_1infer_1ni * Method: frame_make * Signature: (IIJLjava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make__IIJLjava_lang_String_2 - (JNIEnv *env, jclass, jint width, jint height, jlong pix_info, jstring device) -{ - JNI_PROTECT( - auto dstr = jni::fromJString(env, device); - return jni::makePtr(width, height, *jni::ptr(pix_info), dstr); - ) +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_frame_1make__IIJLjava_lang_String_2( + JNIEnv *env, jclass, jint width, jint height, jlong pix_info, + jstring device) { + JNI_PROTECT(auto dstr = jni::fromJString(env, device); + return jni::makePtr( + width, height, *jni::ptr(pix_info), dstr);) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: frame_make * Signature: ([JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JJ - (JNIEnv *env, jclass, jlongArray data, jlong pix_info) -{ +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JJ( + JNIEnv *env, jclass, jlongArray data, jlong pix_info) { JNI_PROTECT( - TensorList vdata; - for(auto p : jni::fromJArray(env, data)){ + TensorList vdata; for (auto p + : jni::fromJArray(env, data)) { vdata.push_back(*jni::ptr(p)); } - return jni::makePtr(vdata, *jni::ptr(pix_info)); - ) + return jni::makePtr(vdata, *jni::ptr(pix_info));) return 0; } @@ -1261,17 +1048,16 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JJ * Method: frame_make * Signature: ([JIIJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JIIJ - (JNIEnv *env, jclass, jlongArray data, jint width, jint height, jlong pix_info) -{ - JNI_PROTECT( - TensorList vdata; - for(auto p : jni::fromJArray(env, data)){ - vdata.push_back(*jni::ptr(p)); - } +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JIIJ( + JNIEnv *env, jclass, jlongArray data, jint width, jint height, + jlong pix_info) { + JNI_PROTECT(TensorList vdata; for (auto p + : jni::fromJArray(env, data)) { + vdata.push_back(*jni::ptr(p)); + } - return jni::makePtr(vdata, width, height, *jni::ptr(pix_info)); - ) + return jni::makePtr(vdata, width, height, + *jni::ptr(pix_info));) return 0; } @@ -1281,29 +1067,27 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make___3JIIJ * Method: frame_make * Signature: (Landroid/graphics/Bitmap;)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make__Landroid_graphics_Bitmap_2 - (JNIEnv *env, jclass, jobject bitmap) -{ - JNI_PROTECT( - AndroidBitmapInfo bitmapInfo; - int ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo); - HMP_REQUIRE(ret >= 0, "Get Bitmap info failed, ret={}", ret); - HMP_REQUIRE(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888, - "Only RGBA_8888 format is supported"); +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_frame_1make__Landroid_graphics_Bitmap_2( + JNIEnv *env, jclass, jobject bitmap) { + JNI_PROTECT( + AndroidBitmapInfo bitmapInfo; + int ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo); + HMP_REQUIRE(ret >= 0, "Get Bitmap info failed, ret={}", ret); + HMP_REQUIRE(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888, + "Only RGBA_8888 format is supported"); - void *ptr; - ret = AndroidBitmap_lockPixels(env, bitmap, &ptr); - HMP_REQUIRE(ret >= 0, "Lock Bitmap pixels failed, ret={}", ret); - auto data_ptr = DataPtr(ptr, - [=](void*){ AndroidBitmap_unlockPixels(env, bitmap); }, - Device("cpu")); - SizeArray shape{bitmapInfo.height, bitmapInfo.width, 4}; - SizeArray strides{bitmapInfo.stride, 4, 1}; - Tensor data = from_buffer(std::move(data_ptr), kUInt8, shape, strides); - return jni::makePtr(TensorList{data}, PixelInfo(PF_RGBA32)); - ) + void *ptr; ret = AndroidBitmap_lockPixels(env, bitmap, &ptr); + HMP_REQUIRE(ret >= 0, "Lock Bitmap pixels failed, ret={}", ret); + auto data_ptr = DataPtr( + ptr, [=](void *) { AndroidBitmap_unlockPixels(env, bitmap); }, + Device("cpu")); + SizeArray shape{bitmapInfo.height, bitmapInfo.width, 4}; + SizeArray strides{bitmapInfo.stride, 4, 1}; + Tensor data = from_buffer(std::move(data_ptr), kUInt8, shape, strides); + return jni::makePtr(TensorList{data}, PixelInfo(PF_RGBA32));) - return 0; + return 0; } /* @@ -1311,12 +1095,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1make__Landroid_graphic * Method: frame_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -1324,12 +1106,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1free * Method: frame_defined * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_frame_1defined - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->operator bool(); - ) +JNIEXPORT jboolean JNICALL +Java_com_bytedance_hmp_Api_frame_1defined(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->operator bool();) return false; } @@ -1338,12 +1117,10 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_frame_1defined * Method: frame_pix_info * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1pix_1info - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jlong)(&jni::ptr(ptr)->pix_info()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1pix_1info(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jlong)(&jni::ptr(ptr)->pix_info());) return 0; } @@ -1352,12 +1129,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1pix_1info * Method: frame_format * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1format - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->format(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1format(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->format();) return 0; } @@ -1366,12 +1141,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1format * Method: frame_width * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1width - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->width(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1width(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->width();) return 0; } @@ -1380,12 +1153,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1width * Method: frame_height * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1height - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->height(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1height(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->height();) return 0; } @@ -1394,14 +1165,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1height * Method: frame_dtype * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1dtype - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->dtype(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1dtype(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->dtype();) return 0; - } /* @@ -1409,12 +1177,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1dtype * Method: frame_device_type * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1device_1type - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().type(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_frame_1device_1type(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().type();) return 0; } @@ -1423,27 +1188,21 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1device_1type * Method: frame_device_index * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1device_1index - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().index(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1device_1index( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().index();) return 0; } - /* * Class: com_bytedance_hmp_Api * Method: frame_nplanes * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1nplanes - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->nplanes(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1nplanes(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->nplanes();) return 0; } @@ -1452,12 +1211,11 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_frame_1nplanes * Method: frame_plane * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1plane - (JNIEnv *env, jclass, jlong ptr, jint p) -{ - JNI_PROTECT( - return jlong(&jni::ptr(ptr)->plane(p)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1plane(JNIEnv *env, + jclass, + jlong ptr, + jint p) { + JNI_PROTECT(return jlong(&jni::ptr(ptr)->plane(p));) return 0; } @@ -1466,13 +1224,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1plane * Method: frame_to_device * Signature: (JLjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1device - (JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) -{ - JNI_PROTECT( - auto dstr = jni::fromJString(env, device); - return jni::makePtr(jni::ptr(ptr)->to(Device(dstr), non_blocking)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1device( + JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) { + JNI_PROTECT(auto dstr = jni::fromJString(env, device); + return jni::makePtr( + jni::ptr(ptr)->to(Device(dstr), non_blocking));) return 0; } @@ -1481,12 +1237,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1device * Method: frame_copy_from * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1copy_1from - (JNIEnv *env, jclass, jlong ptr, jlong from) -{ - JNI_PROTECT( - jni::ptr(ptr)->copy_(*jni::ptr(from)); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1copy_1from( + JNIEnv *env, jclass, jlong ptr, jlong from) { + JNI_PROTECT(jni::ptr(ptr)->copy_(*jni::ptr(from));) } /* @@ -1494,12 +1247,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_frame_1copy_1from * Method: frame_clone * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1clone - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->clone()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1clone(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->clone());) return 0; } @@ -1508,12 +1259,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1clone * Method: frame_crop * Signature: (JIIII)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1crop - (JNIEnv *env, jclass, jlong ptr, jint left, jint top, jint width, jint height) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->crop(left, top, width, height)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1crop( + JNIEnv *env, jclass, jlong ptr, jint left, jint top, jint width, + jint height) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->crop( + left, top, width, height));) return 0; } @@ -1522,12 +1272,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1crop * Method: frame_to_image * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1image - (JNIEnv *env, jclass, jlong ptr, jint cformat) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->to_image((ChannelFormat)cformat)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1image( + JNIEnv *env, jclass, jlong ptr, jint cformat) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->to_image( + (ChannelFormat)cformat));) return 0; } @@ -1536,14 +1284,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1to_1image * Method: frame_from_image * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1from_1image - (JNIEnv *env, jclass, jlong image, jlong pix_info) -{ - JNI_PROTECT( - return jni::makePtr( - Frame::from_image(*jni::ptr(image), - *jni::ptr(pix_info))); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1from_1image( + JNIEnv *env, jclass, jlong image, jlong pix_info) { + JNI_PROTECT(return jni::makePtr(Frame::from_image( + *jni::ptr(image), *jni::ptr(pix_info)));) return 0; } @@ -1552,35 +1296,28 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_frame_1from_1image * Method: frame_stringfy * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_frame_1stringfy - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - auto str = stringfy(*jni::ptr(ptr)); - return jni::toJString(env, str); - ) +JNIEXPORT jstring JNICALL +Java_com_bytedance_hmp_Api_frame_1stringfy(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(auto str = stringfy(*jni::ptr(ptr)); + return jni::toJString(env, str);) return jni::toJString(env, ""); } - /* * Class: com_bytedance_hmp_Api * Method: image_make * Signature: (IIIIILjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__IIIIILjava_lang_String_2Z - (JNIEnv *env, jclass, jint width, jint height, jint channels, jint cformat, - jint dtype, jstring device, jboolean pinned_memory) -{ - JNI_PROTECT( - auto options = TensorOptions(jni::fromJString(env, device)) - .dtype((ScalarType)dtype) - .pinned_memory(pinned_memory); +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_image_1make__IIIIILjava_lang_String_2Z( + JNIEnv *env, jclass, jint width, jint height, jint channels, jint cformat, + jint dtype, jstring device, jboolean pinned_memory) { + JNI_PROTECT(auto options = TensorOptions(jni::fromJString(env, device)) + .dtype((ScalarType)dtype) + .pinned_memory(pinned_memory); - return jni::makePtr(width, height, channels, - (ChannelFormat)cformat, - options); - ) + return jni::makePtr(width, height, channels, + (ChannelFormat)cformat, options);) return 0; } @@ -1589,12 +1326,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__IIIIILjava_lang_ * Method: image_make * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JI - (JNIEnv *env, jclass, jlong data, jint cformat) -{ - JNI_PROTECT( - return jni::makePtr(*jni::ptr(data), (ChannelFormat)cformat); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JI( + JNIEnv *env, jclass, jlong data, jint cformat) { + JNI_PROTECT(return jni::makePtr(*jni::ptr(data), + (ChannelFormat)cformat);) return 0; } @@ -1603,14 +1338,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JI * Method: image_make * Signature: (JIJ)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JIJ - (JNIEnv *env, jclass, jlong data, jint cformat, jlong cm) -{ - JNI_PROTECT( - return jni::makePtr(*jni::ptr(data), - (ChannelFormat)cformat, - *jni::ptr(cm)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JIJ( + JNIEnv *env, jclass, jlong data, jint cformat, jlong cm) { + JNI_PROTECT(return jni::makePtr(*jni::ptr(data), + (ChannelFormat)cformat, + *jni::ptr(cm));) return 0; } @@ -1619,12 +1351,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1make__JIJ * Method: image_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1free - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - jni::freePtr(ptr); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1free(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(jni::freePtr(ptr);) } /* @@ -1632,12 +1362,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1free * Method: image_defined * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_image_1defined - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->operator bool(); - ) +JNIEXPORT jboolean JNICALL +Java_com_bytedance_hmp_Api_image_1defined(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->operator bool();) return false; } @@ -1646,12 +1373,10 @@ JNIEXPORT jboolean JNICALL Java_com_bytedance_hmp_Api_image_1defined * Method: image_format * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1format - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->format(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1format(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->format();) return false; } @@ -1660,12 +1385,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1format * Method: image_set_color_model * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1set_1color_1model - (JNIEnv *env, jclass, jlong ptr, jlong cm) -{ +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1set_1color_1model( + JNIEnv *env, jclass, jlong ptr, jlong cm) { JNI_PROTECT( - jni::ptr(ptr)->set_color_model(*jni::ptr(cm)); - ) + jni::ptr(ptr)->set_color_model(*jni::ptr(cm));) } /* @@ -1673,12 +1396,9 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1set_1color_1model * Method: image_color_model * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1color_1model - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jlong)(&jni::ptr(ptr)->color_model()); - ) +JNIEXPORT jlong JNICALL +Java_com_bytedance_hmp_Api_image_1color_1model(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jlong)(&jni::ptr(ptr)->color_model());) return 0; } @@ -1687,12 +1407,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1color_1model * Method: image_wdim * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1wdim - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->wdim(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1wdim(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->wdim();) return 0; } @@ -1701,12 +1419,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1wdim * Method: image_hdim * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1hdim - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->hdim(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1hdim(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->hdim();) return 0; } @@ -1715,12 +1431,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1hdim * Method: image_cdim * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1cdim - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->cdim(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1cdim(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->cdim();) return 0; } @@ -1729,12 +1443,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1cdim * Method: image_width * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1width - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->width(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1width(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->width();) return 0; } @@ -1743,12 +1455,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1width * Method: image_height * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1height - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->height(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1height(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->height();) return 0; } @@ -1757,12 +1467,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1height * Method: image_nchannels * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1nchannels - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::ptr(ptr)->nchannels(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1nchannels(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::ptr(ptr)->nchannels();) return 0; } @@ -1771,12 +1479,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1nchannels * Method: image_dtype * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1dtype - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->dtype(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1dtype(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->dtype();) return 0; } @@ -1785,12 +1491,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1dtype * Method: image_device_type * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1device_1type - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().type(); - ) +JNIEXPORT jint JNICALL +Java_com_bytedance_hmp_Api_image_1device_1type(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().type();) return 0; } @@ -1799,12 +1502,9 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1device_1type * Method: image_device_index * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1device_1index - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return (jint)jni::ptr(ptr)->device().index(); - ) +JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1device_1index( + JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(return (jint)jni::ptr(ptr)->device().index();) return 0; } @@ -1813,12 +1513,10 @@ JNIEXPORT jint JNICALL Java_com_bytedance_hmp_Api_image_1device_1index * Method: image_data * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1data - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jlong(&jni::ptr(ptr)->data()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1data(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jlong(&jni::ptr(ptr)->data());) return 0; } @@ -1827,13 +1525,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1data * Method: image_to_device * Signature: (JLjava/lang/String;Z)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1device - (JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) -{ - JNI_PROTECT( - auto dstr = jni::fromJString(env, device); - return jni::makePtr(jni::ptr(ptr)->to(dstr, (bool)non_blocking)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1device( + JNIEnv *env, jclass, jlong ptr, jstring device, jboolean non_blocking) { + JNI_PROTECT(auto dstr = jni::fromJString(env, device); + return jni::makePtr( + jni::ptr(ptr)->to(dstr, (bool)non_blocking));) return 0; } @@ -1842,12 +1538,10 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1device * Method: image_to_dtype * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1dtype - (JNIEnv *env, jclass, jlong ptr, jint dtype) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->to((ScalarType)dtype)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1dtype( + JNIEnv *env, jclass, jlong ptr, jint dtype) { + JNI_PROTECT(return jni::makePtr( + jni::ptr(ptr)->to((ScalarType)dtype));) return 0; } @@ -1856,12 +1550,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1to_1dtype * Method: image_copy_from * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1copy_1from - (JNIEnv *env, jclass, jlong ptr, jlong from) -{ - JNI_PROTECT( - jni::ptr(ptr)->copy_(*jni::ptr(from)); - ) +JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1copy_1from( + JNIEnv *env, jclass, jlong ptr, jlong from) { + JNI_PROTECT(jni::ptr(ptr)->copy_(*jni::ptr(from));) } /* @@ -1869,12 +1560,10 @@ JNIEXPORT void JNICALL Java_com_bytedance_hmp_Api_image_1copy_1from * Method: image_clone * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1clone - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->clone()); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1clone(JNIEnv *env, + jclass, + jlong ptr) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->clone());) return 0; } @@ -1883,12 +1572,11 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1clone * Method: image_crop * Signature: (JIIII)J */ -JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1crop - (JNIEnv *env, jclass, jlong ptr, jint left, jint top, jint width, jint height) -{ - JNI_PROTECT( - return jni::makePtr(jni::ptr(ptr)->crop(left, top, width, height)); - ) +JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1crop( + JNIEnv *env, jclass, jlong ptr, jint left, jint top, jint width, + jint height) { + JNI_PROTECT(return jni::makePtr(jni::ptr(ptr)->crop( + left, top, width, height));) return 0; } @@ -1897,12 +1585,9 @@ JNIEXPORT jlong JNICALL Java_com_bytedance_hmp_Api_image_1crop * Method: image_stringfy * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_com_bytedance_hmp_Api_image_1stringfy - (JNIEnv *env, jclass, jlong ptr) -{ - JNI_PROTECT( - auto str = stringfy(*jni::ptr(ptr)); - return jni::toJString(env, str); - ) +JNIEXPORT jstring JNICALL +Java_com_bytedance_hmp_Api_image_1stringfy(JNIEnv *env, jclass, jlong ptr) { + JNI_PROTECT(auto str = stringfy(*jni::ptr(ptr)); + return jni::toJString(env, str);) return jni::toJString(env, ""); } \ No newline at end of file diff --git a/bmf/hml/object-c/include/hmp/oc/Formats.h b/bmf/hml/object-c/include/hmp/oc/Formats.h index 07baafab..1190ac37 100644 --- a/bmf/hml/object-c/include/hmp/oc/Formats.h +++ b/bmf/hml/object-c/include/hmp/oc/Formats.h @@ -32,7 +32,7 @@ typedef enum _HmpColorPrimaries { 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) CP_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R - ///BT1700 625 PAL & SECAM + /// BT1700 625 PAL & SECAM CP_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC CP_SMPTE240M = 7, ///< functionally identical to above @@ -60,7 +60,7 @@ typedef enum _HmpColorTransferCharacteristic { CTC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM CTC_GAMMA28 = 5, ///< also ITU-R BT470BG CTC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or - ///625 / ITU-R BT1700 NTSC + /// 625 / ITU-R BT1700 NTSC CTC_SMPTE240M = 7, CTC_LINEAR = 8, ///< "Linear transfer characteristics" CTC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" @@ -93,7 +93,7 @@ typedef enum _HmpColorSpace { CS_RESERVED = 3, CS_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) CS_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R - ///BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + /// BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 CS_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC CS_SMPTE240M = 7, ///< functionally identical to above @@ -131,8 +131,8 @@ typedef enum _HmpPixelFormat { PF_YUV444P = 5, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) PF_NV12 = 23, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for - ///the UV components, which are interleaved (first byte U and - ///the following byte V) + /// the UV components, which are interleaved (first byte U and + /// the following byte V) PF_NV21 = 24, ///< as above, but U and V bytes are swapped PF_GRAY8 = 8, ///< Y , 8bpp @@ -148,14 +148,14 @@ typedef enum _HmpPixelFormat { PF_YUVA420P = 33, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y ///& A samples) PF_RGB48 = 35, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte - ///value for each R/G/B component is stored as little-endian + /// value for each R/G/B component is stored as little-endian PF_YA8 = 58, ///< 8 bits gray, 8 bits alpha PF_RGBA64 = 107, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, - ///the 2-byte value for each R/G/B/A component is stored as - ///little-endian + /// the 2-byte value for each R/G/B/A component is stored as + /// little-endian PF_P010LE = 161, ///< like NV12, with 10bpp per component, data in the high - ///bits, zeros in the low bits, little-endian + /// bits, zeros in the low bits, little-endian PF_P016LE = 172, ///< like NV12, with 16bpp per component, little-endian } HmpPixelFormat; diff --git a/bmf/hml/perf/perf_allocator.cpp b/bmf/hml/perf/perf_allocator.cpp index 296e9a6d..6a87baf0 100644 --- a/bmf/hml/perf/perf_allocator.cpp +++ b/bmf/hml/perf/perf_allocator.cpp @@ -21,37 +21,38 @@ using namespace hmp; namespace { - -template -void BM_allocator(benchmark::State &state) -{ +template +void BM_allocator(benchmark::State &state) { auto seed = state.range(0); auto max_size = state.range(1); auto options = TensorOptions(kFloat32).device(device).pinned_memory(pinned); std::vector used; - for(auto _ : state){ - auto size = (rand()*long(rand())) % max_size; + for (auto _ : state) { + auto size = (rand() * long(rand())) % max_size; size = std::max(size, 1); auto data = empty({size}, options); - if((size&0x1) ==0x0){ //keep half of the data + if ((size & 0x1) == 0x0) { // keep half of the data used.push_back(data); } } } - BENCHMARK_TEMPLATE(BM_allocator, kCPU, false) - ->Args({42, 4<<20})->Threads(8)->Unit(benchmark::kMicrosecond); + ->Args({42, 4 << 20}) + ->Threads(8) + ->Unit(benchmark::kMicrosecond); #ifdef HMP_ENABLE_CUDA BENCHMARK_TEMPLATE(BM_allocator, kCPU, true) - ->Args({42, 4<<20})->Threads(8)->Unit(benchmark::kMicrosecond); + ->Args({42, 4 << 20}) + ->Threads(8) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_allocator, kCUDA, false) - ->Args({42, 4<<20})->Threads(8)->Unit(benchmark::kMicrosecond); + ->Args({42, 4 << 20}) + ->Threads(8) + ->Unit(benchmark::kMicrosecond); #endif - - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/perf/perf_img_resize.cpp b/bmf/hml/perf/perf_img_resize.cpp index d2eb6e58..90be138b 100644 --- a/bmf/hml/perf/perf_img_resize.cpp +++ b/bmf/hml/perf/perf_img_resize.cpp @@ -34,24 +34,21 @@ using namespace hmp; namespace { - const static int ResizeBatch = 100; - -template -void BM_img_resize(benchmark::State &state) -{ +template +void BM_img_resize(benchmark::State &state) { auto swidth = state.range(0); auto sheight = state.range(1); auto dwidth = state.range(2); auto dheight = state.range(3); auto options = TensorOptions(device).dtype(dtype); SizeArray sshape, dshape; - if(cformat == kNHWC){ + if (cformat == kNHWC) { sshape = {ResizeBatch, sheight, swidth, 3}; dshape = {ResizeBatch, dheight, dwidth, 3}; - } - else{ + } else { sshape = {ResizeBatch, 3, sheight, swidth}; dshape = {ResizeBatch, 3, dheight, dwidth}; } @@ -60,10 +57,9 @@ void BM_img_resize(benchmark::State &state) auto dst = empty(dshape, options); auto timer = create_timer(device); - for(auto _ : state){ + for (auto _ : state) { timer.start(); - benchmark::DoNotOptimize( - img::resize(dst, src, mode, cformat)); + benchmark::DoNotOptimize(img::resize(dst, src, mode, cformat)); timer.stop(); current_stream(device)->synchronize(); @@ -71,33 +67,38 @@ void BM_img_resize(benchmark::State &state) } } - BENCHMARK_TEMPLATE(BM_img_resize, kCPU, kUInt8, kBicubic, kNHWC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCPU, kUInt8, kBicubic, kNCHW) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCPU, kUInt8, kBilinear, kNHWC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCPU, kUInt8, kBilinear, kNCHW) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); #ifdef HMP_ENABLE_CUDA BENCHMARK_TEMPLATE(BM_img_resize, kCUDA, kUInt8, kBicubic, kNCHW) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCUDA, kUInt8, kBicubic, kNHWC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCUDA, kUInt8, kBilinear, kNCHW) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_img_resize, kCUDA, kUInt8, kBilinear, kNHWC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); #endif #ifdef HMP_ENABLE_OPENCV - -template -void BM_cv_resize(benchmark::State &state) -{ +template +void BM_cv_resize(benchmark::State &state) { auto swidth = state.range(0); auto sheight = state.range(1); auto dwidth = state.range(2); @@ -107,25 +108,26 @@ void BM_cv_resize(benchmark::State &state) cv::Mat dst; #ifdef HMP_ENABLE_CUDA - //default stream: call_resize_cubic_glob - // other : call_resize_cubic_tex - auto stream = create_stream(kCUDA); + // default stream: call_resize_cubic_glob + // other : call_resize_cubic_tex + auto stream = create_stream(kCUDA); cv::cuda::GpuMat gpu_src; cv::cuda::GpuMat gpu_dst; - auto cv_stream = cv::cuda::StreamAccessor::wrapStream((cudaStream_t)stream.handle()); + auto cv_stream = + cv::cuda::StreamAccessor::wrapStream((cudaStream_t)stream.handle()); gpu_src.upload(src); #endif auto timer = create_timer(device); - for(auto _ : state){ + for (auto _ : state) { timer.start(); - for(int i = 0; i < ResizeBatch; ++i){ - if(device == kCPU){ + for (int i = 0; i < ResizeBatch; ++i) { + if (device == kCPU) { cv::resize(src, dst, cv::Size(dwidth, dheight), 0, 0, mode); - } - else{ + } else { #ifdef HMP_ENABLE_CUDA - cv::cuda::resize(gpu_src, gpu_dst, cv::Size(dwidth, dheight), 0, 0, mode, cv_stream); + cv::cuda::resize(gpu_src, gpu_dst, cv::Size(dwidth, dheight), 0, + 0, mode, cv_stream); #endif } } @@ -136,21 +138,22 @@ void BM_cv_resize(benchmark::State &state) } } - BENCHMARK_TEMPLATE(BM_cv_resize, kCPU, CV_8UC3, cv::INTER_CUBIC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_cv_resize, kCPU, CV_8UC3, cv::INTER_LINEAR) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); #ifdef HMP_ENABLE_CUDA BENCHMARK_TEMPLATE(BM_cv_resize, kCUDA, CV_8UC3, cv::INTER_CUBIC) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); BENCHMARK_TEMPLATE(BM_cv_resize, kCUDA, CV_8UC3, cv::INTER_LINEAR) - ->Args({1280, 720, 1920, 1080})->Unit(benchmark::kMicrosecond); + ->Args({1280, 720, 1920, 1080}) + ->Unit(benchmark::kMicrosecond); #endif - #endif - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/py/py_core.cpp b/bmf/hml/py/py_core.cpp index 23d4e56f..855025b8 100644 --- a/bmf/hml/py/py_core.cpp +++ b/bmf/hml/py/py_core.cpp @@ -22,28 +22,25 @@ #include #include - namespace py = pybind11; using namespace hmp; -void coreBind(py::module &m) -{ +void coreBind(py::module &m) { py::enum_(m, "ScalarType") - #define DEF_TYPE_ATTR(_, name) \ - .value("k"#name, ::ScalarType::name) +#define DEF_TYPE_ATTR(_, name) .value("k" #name, ::ScalarType::name) HMP_FORALL_SCALAR_TYPES(DEF_TYPE_ATTR) - #undef DEF_TYPE_ATTR - //Numpy like dtype names - .value("uint8", kUInt8) - .value("int8", kInt8) - .value("uint16", kUInt16) - .value("int16", kInt16) - .value("int32", kInt32) - .value("int64", kInt64) - .value("float32", kFloat32) - .value("float64", kFloat64) - .export_values(); +#undef DEF_TYPE_ATTR + // Numpy like dtype names + .value("uint8", kUInt8) + .value("int8", kInt8) + .value("uint16", kUInt16) + .value("int16", kInt16) + .value("int32", kInt32) + .value("int64", kInt64) + .value("float32", kFloat32) + .value("float64", kFloat64) + .export_values(); py::enum_(m, "DeviceType") .value("kCPU", kCPU) @@ -52,45 +49,44 @@ void coreBind(py::module &m) py::class_(m, "Device", py::dynamic_attr()) .def(py::init<>()) - .def(py::init(), py::arg("device_type"), py::arg("index") = 0) + .def(py::init(), py::arg("device_type"), + py::arg("index") = 0) .def(py::init()) .def("__eq__", &Device::operator==) .def("__neq__", &Device::operator!=) .def("__repr__", [](const Device &device) { return stringfy(device); }) .def("type", &Device::type) .def("index", &Device::index) - .def("__enter__", [](py::object &self){ - auto device = self.cast(); - auto guard = DeviceGuard(device); - self.attr("__guard__") = py::cast(std::move(guard)); - return self; - }) - .def("__exit__", [](py::object &self, py::args){ - self.attr("__guard__") = py::none(); - }) - ; + .def("__enter__", + [](py::object &self) { + auto device = self.cast(); + auto guard = DeviceGuard(device); + self.attr("__guard__") = py::cast(std::move(guard)); + return self; + }) + .def("__exit__", [](py::object &self, py::args) { + self.attr("__guard__") = py::none(); + }); py::class_(m, "DeviceGuard"); py::class_(m, "Stream", py::dynamic_attr()) .def("__eq__", &Stream::operator==) .def("__neq__", &Stream::operator!=) - .def("__repr__", [](const Stream &stream){ - return stringfy(stream); - }) + .def("__repr__", [](const Stream &stream) { return stringfy(stream); }) .def("query", &Stream::query) .def("synchronize", &Stream::synchronize) .def("device", &Stream::device) .def("handle", &Stream::handle) - .def("__enter__", [](py::object &self){ - auto stream = self.cast(); - auto guard = StreamGuard(stream); - self.attr("__guard__") = py::cast(std::move(guard)); - return self; - }) - .def("__exit__", [](py::object &self, py::args){ + .def("__enter__", + [](py::object &self) { + auto stream = self.cast(); + auto guard = StreamGuard(stream); + self.attr("__guard__") = py::cast(std::move(guard)); + return self; + }) + .def("__exit__", [](py::object &self, py::args) { self.attr("__guard__") = py::none(); - }) - ; + }); py::class_(m, "StreamGuard"); @@ -98,17 +94,17 @@ void coreBind(py::module &m) m.def("current_device", ¤t_device, py::arg("device_type")); m.def("set_current_device", &set_current_device, py::arg("device")); - m.def("create_stream", &create_stream, py::arg("device_type"), py::arg("flags") = 0); + m.def("create_stream", &create_stream, py::arg("device_type"), + py::arg("flags") = 0); m.def("current_stream", ¤t_stream, py::arg("device_type")); py::class_(m, "Timer") - .def("__repr__", (std::string(*)(const Timer&))&stringfy) + .def("__repr__", (std::string(*)(const Timer &)) & stringfy) .def("start", &Timer::start) .def("stop", &Timer::stop) .def("elapsed", &Timer::elapsed) .def("is_stopped", &Timer::is_stopped) - .def("device", &Timer::device) - ; + .def("device", &Timer::device); - m.def("create_timer", &create_timer, py::arg("device_type")=kCPU); + m.def("create_timer", &create_timer, py::arg("device_type") = kCPU); } \ No newline at end of file diff --git a/bmf/hml/py/py_cuda.cpp b/bmf/hml/py/py_cuda.cpp index 8d20bdf5..5edd8799 100644 --- a/bmf/hml/py/py_cuda.cpp +++ b/bmf/hml/py/py_cuda.cpp @@ -23,22 +23,18 @@ namespace py = pybind11; using namespace hmp; - -void cudaBind(py::module &m) -{ +void cudaBind(py::module &m) { #ifdef HMP_ENABLE_CUDA auto cu = m.def_submodule("cuda"); py::class_(cu, "Event") - .def(py::init(), - py::arg("enable_timing"), py::arg("blocking")=true, py::arg("interprocess")=false) + .def(py::init(), py::arg("enable_timing"), + py::arg("blocking") = true, py::arg("interprocess") = false) .def("is_created", &cuda::Event::is_created) - .def("record", &cuda::Event::record, py::arg("stream")=py::none()) - .def("block", &cuda::Event::block, py::arg("stream")=py::none()) + .def("record", &cuda::Event::record, py::arg("stream") = py::none()) + .def("block", &cuda::Event::block, py::arg("stream") = py::none()) .def("query", &cuda::Event::query) .def("synchronize", &cuda::Event::synchronize) - .def("elapsed", &cuda::Event::elapsed) - ; + .def("elapsed", &cuda::Event::elapsed); #endif - } diff --git a/bmf/hml/py/py_ffmpeg.cpp b/bmf/hml/py/py_ffmpeg.cpp index 2cd2f25f..fc099db0 100644 --- a/bmf/hml/py/py_ffmpeg.cpp +++ b/bmf/hml/py/py_ffmpeg.cpp @@ -25,10 +25,7 @@ namespace py = pybind11; - - -void ffmpegBind(py::module &m) -{ +void ffmpegBind(py::module &m) { #ifdef HMP_ENABLE_FFMPEG using namespace hmp; @@ -39,8 +36,9 @@ void ffmpegBind(py::module &m) .def("read", &ffmpeg::VideoReader::read); py::class_(ff, "VideoWriter") - .def(py::init(), - py::arg("fn"), py::arg("width"), py::arg("height"), py::arg("fps"), py::arg("pix_info"), py::arg("kbs")=2000) + .def(py::init(), + py::arg("fn"), py::arg("width"), py::arg("height"), py::arg("fps"), + py::arg("pix_info"), py::arg("kbs") = 2000) .def("write", &ffmpeg::VideoWriter::write); #endif } diff --git a/bmf/hml/py/py_hmp.cpp b/bmf/hml/py/py_hmp.cpp index e0bcbed4..6586b6d2 100644 --- a/bmf/hml/py/py_hmp.cpp +++ b/bmf/hml/py/py_hmp.cpp @@ -28,7 +28,7 @@ void imageBind(py::module &m); void cudaBind(py::module &m); -static std::map sHMPConfigs{ +static std::map sHMPConfigs{ #define DEF_CONFIG(M, value) std::make_pair(#M, value), #ifdef HMP_ENABLE_CUDA DEF_CONFIG(HMP_ENABLE_CUDA, 1) @@ -37,53 +37,50 @@ static std::map sHMPConfigs{ #endif #ifdef HMP_ENABLE_FFMPEG - DEF_CONFIG(HMP_ENABLE_FFMPEG, 1) + DEF_CONFIG(HMP_ENABLE_FFMPEG, 1) #else - DEF_CONFIG(HMP_ENABLE_FFMPEG, 0) + DEF_CONFIG(HMP_ENABLE_FFMPEG, 0) #endif #ifdef HMP_ENABLE_OPENCV - DEF_CONFIG(HMP_ENABLE_OPENCV, 1) + DEF_CONFIG(HMP_ENABLE_OPENCV, 1) #else - DEF_CONFIG(HMP_ENABLE_OPENCV, 0) + DEF_CONFIG(HMP_ENABLE_OPENCV, 0) #endif #ifdef HMP_ENABLE_NPP - DEF_CONFIG(HMP_ENABLE_NPP, 1) + DEF_CONFIG(HMP_ENABLE_NPP, 1) #else - DEF_CONFIG(HMP_ENABLE_NPP, 0) + DEF_CONFIG(HMP_ENABLE_NPP, 0) #endif #ifdef HMP_ENABLE_OPENMP - DEF_CONFIG(HMP_ENABLE_OPENMP, 1) + DEF_CONFIG(HMP_ENABLE_OPENMP, 1) #else - DEF_CONFIG(HMP_ENABLE_OPENMP, 0) + DEF_CONFIG(HMP_ENABLE_OPENMP, 0) #endif #ifdef HMP_ENABLE_TORCH - DEF_CONFIG(HMP_ENABLE_TORCH, 1) + DEF_CONFIG(HMP_ENABLE_TORCH, 1) #else - DEF_CONFIG(HMP_ENABLE_TORCH, 0) + DEF_CONFIG(HMP_ENABLE_TORCH, 0) #endif #undef DEF_CONFIG }; - - -PYBIND11_MODULE(_hmp, m) -{ +PYBIND11_MODULE(_hmp, m) { m.doc() = "Python binding for hmp library"; m.attr("__version__") = HMP_VERSION_STR(); - + m.attr("__config__") = sHMPConfigs; - //core modules + // core modules coreBind(m); tensorBind(m); - //sub modules + // sub modules imageBind(m); ffmpegBind(m); diff --git a/bmf/hml/py/py_imgproc.cpp b/bmf/hml/py/py_imgproc.cpp index 2a9e2714..0969b19f 100644 --- a/bmf/hml/py/py_imgproc.cpp +++ b/bmf/hml/py/py_imgproc.cpp @@ -25,12 +25,10 @@ namespace py = pybind11; using namespace hmp; -Tensor tensor_from_numpy(const py::array& arr); -py::array tensor_to_numpy(const Tensor& tensor); +Tensor tensor_from_numpy(const py::array &arr); +py::array tensor_to_numpy(const Tensor &tensor); - -void imageBind(py::module &m) -{ +void imageBind(py::module &m) { #define VALUE(C, N) value("k" #N, C::N) py::enum_(m, "ColorPrimaries") @@ -109,8 +107,7 @@ void imageBind(py::module &m) #define DEF_VALUE(N) .VALUE(PixelFormat, N) HMP_FORALL_PIXEL_FORMATS(DEF_VALUE) #undef DEF_VALUE - .export_values(); - + .export_values(); py::enum_(m, "ChannelFormat") .value("kNCHW", kNCHW) @@ -137,62 +134,68 @@ void imageBind(py::module &m) .export_values(); py::class_(m, "PixelColorModel") - .def(py::init()) - .def(py::init(), - py::arg("cs"), py::arg("cr")=CR_UNSPECIFIED) + .def(py::init()) + .def(py::init(), py::arg("cs"), + py::arg("cr") = CR_UNSPECIFIED) .def(py::init(), - py::arg("cp"), py::arg("ctc")=CTC_UNSPECIFIED) + py::arg("cp"), py::arg("ctc") = CTC_UNSPECIFIED) .def_property_readonly("space", &ColorModel::space) .def_property_readonly("range", &ColorModel::range) .def_property_readonly("primaries", &ColorModel::primaries) - .def_property_readonly("transfer_characteristic", &ColorModel::transfer_characteristic) - ; + .def_property_readonly("transfer_characteristic", + &ColorModel::transfer_characteristic); py::class_(m, "PixelInfo") - .def(py::init(), - py::arg("format"), py::arg("color_model")=ColorModel()) - .def(py::init(), - py::arg("format"), py::arg("cs"), py::arg("cr")=CR_UNSPECIFIED) - .def(py::init(), - py::arg("format"), py::arg("cp"), py::arg("ctc")=CTC_UNSPECIFIED) + .def(py::init(), py::arg("format"), + py::arg("color_model") = ColorModel()) + .def(py::init(), py::arg("format"), + py::arg("cs"), py::arg("cr") = CR_UNSPECIFIED) + .def(py::init(), + py::arg("format"), py::arg("cp"), py::arg("ctc") = CTC_UNSPECIFIED) .def_property_readonly("format", &PixelInfo::format) .def_property_readonly("color_model", &PixelInfo::color_model) .def_property_readonly("space", &PixelInfo::space) .def_property_readonly("range", &PixelInfo::range) .def_property_readonly("primaries", &PixelInfo::primaries) - .def_property_readonly("transfer_characteristic", &PixelInfo::transfer_characteristic) - .def("infer_space", &PixelInfo::infer_space) - ; + .def_property_readonly("transfer_characteristic", + &PixelInfo::transfer_characteristic) + .def("infer_space", &PixelInfo::infer_space); py::class_(m, "PixelFormatDesc") .def(py::init()) .def("defined", &PixelFormatDesc::defined) - .def("channels", &PixelFormatDesc::channels, py::arg("plane")=0) - .def("infer_width", &PixelFormatDesc::infer_width, - py::arg("width"), py::arg("plane")=0) - .def("infer_height", &PixelFormatDesc::infer_height, - py::arg("height"), py::arg("plane")=0) - .def("infer_nitems", (int(PixelFormatDesc::*)(int, int) const)&PixelFormatDesc::infer_nitems, - py::arg("width"), py::arg("height")) - .def("infer_nitems", (int(PixelFormatDesc::*)(int, int, int) const)&PixelFormatDesc::infer_nitems, - py::arg("width"), py::arg("height"), py::arg("plane")) + .def("channels", &PixelFormatDesc::channels, py::arg("plane") = 0) + .def("infer_width", &PixelFormatDesc::infer_width, py::arg("width"), + py::arg("plane") = 0) + .def("infer_height", &PixelFormatDesc::infer_height, py::arg("height"), + py::arg("plane") = 0) + .def("infer_nitems", (int (PixelFormatDesc::*)(int, int) const) & + PixelFormatDesc::infer_nitems, + py::arg("width"), py::arg("height")) + .def("infer_nitems", (int (PixelFormatDesc::*)(int, int, int) const) & + PixelFormatDesc::infer_nitems, + py::arg("width"), py::arg("height"), py::arg("plane")) .def_property_readonly("nplanes", &PixelFormatDesc::nplanes) .def_property_readonly("dtype", &PixelFormatDesc::dtype) - .def_property_readonly("format", &PixelFormatDesc::format) - ; - + .def_property_readonly("format", &PixelFormatDesc::format); py::class_(m, "Frame") - .def(py::init(), - py::arg("planes"), py::arg("pix_info")) - .def(py::init(), - py::arg("planes"), py::arg("width"), py::arg("height"), py::arg("pix_info")) - .def(py::init(), - py::arg("plane"), py::arg("pix_info")) - .def(py::init([](int width, int height, const PixelInfo& pix_info, const py::object &obj){ - return Frame(width, height, pix_info, parse_device(obj)); - }), py::arg("width"), py::arg("height"), py::arg("pix_info"), py::arg("device")=kCPU) - .def("__repr__", (std::string(*)(const Frame&))&stringfy) + .def(py::init(), py::arg("planes"), + py::arg("pix_info")) + .def(py::init(), + py::arg("planes"), py::arg("width"), py::arg("height"), + py::arg("pix_info")) + .def(py::init(), py::arg("plane"), + py::arg("pix_info")) + .def(py::init([](int width, int height, const PixelInfo &pix_info, + const py::object &obj) { + return Frame(width, height, pix_info, parse_device(obj)); + }), + py::arg("width"), py::arg("height"), py::arg("pix_info"), + py::arg("device") = kCPU) + .def("__repr__", (std::string(*)(const Frame &)) & stringfy) .def("format", &Frame::format) .def("pix_info", &Frame::pix_info) .def("pix_desc", &Frame::pix_desc) @@ -200,30 +203,32 @@ void imageBind(py::module &m) .def("height", &Frame::height) .def("dtype", &Frame::dtype) .def("device", &Frame::device) - .def("plane", (Tensor&(Frame::*)(int64_t))&Frame::plane) + .def("plane", (Tensor & (Frame::*)(int64_t)) & Frame::plane) .def("nplanes", &Frame::nplanes) - .def("data", (TensorList&(Frame::*)())&Frame::data) - .def("to", (Frame(Frame::*)(const Device&, bool) const)&Frame::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", (Frame(Frame::*)(DeviceType, bool) const)&Frame::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", [](const Frame &self, const std::string &device, bool non_blocking){ - return self.to(device); - }, py::arg("device"), py::arg("non_blocking")=false) + .def("data", (TensorList & (Frame::*)()) & Frame::data) + .def("to", (Frame (Frame::*)(const Device &, bool) const) & Frame::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", (Frame (Frame::*)(DeviceType, bool) const) & Frame::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", [](const Frame &self, const std::string &device, + bool non_blocking) { return self.to(device); }, + py::arg("device"), py::arg("non_blocking") = false) .def("copy_", &Frame::copy_) .def("clone", &Frame::clone) - .def("crop", &Frame::crop, py::arg("left"), py::arg("top"), py::arg("width"), py::arg("height")) + .def("crop", &Frame::crop, py::arg("left"), py::arg("top"), + py::arg("width"), py::arg("height")) .def("reformat", &Frame::reformat, py::arg("pix_info")) - .def("numpy", [](const Frame &frame){ + .def("numpy", [](const Frame &frame) { py::list arr_list; - for(auto &tensor : frame.data()){ - arr_list.append(tensor_to_numpy(tensor)); + for (auto &tensor : frame.data()) { + arr_list.append(tensor_to_numpy(tensor)); } return arr_list; - }) - ; + }); py::class_(m, "FrameSeq") - .def(py::init()) - .def("__repr__", (std::string(*)(const FrameSeq&))&stringfy) + .def(py::init()) + .def("__repr__", (std::string(*)(const FrameSeq &)) & stringfy) .def("format", &FrameSeq::format) .def("pix_info", &FrameSeq::pix_info) .def("pix_desc", &FrameSeq::pix_desc) @@ -235,178 +240,227 @@ void imageBind(py::module &m) .def("data", &FrameSeq::data) .def("dtype", &FrameSeq::dtype) .def("device", &FrameSeq::device) - .def("to", (FrameSeq(FrameSeq::*)(const Device&, bool) const)&FrameSeq::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", (FrameSeq(FrameSeq::*)(DeviceType, bool) const)&FrameSeq::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", [](const FrameSeq &self, const std::string &device, bool non_blocking){ - return self.to(device); - }, py::arg("device"), py::arg("non_blocking")=false) - .def("__getitem__", [](FrameSeq &self, int64_t index){ return self[index]; }) - .def("slice", &FrameSeq::slice, py::arg("start"), py::arg("end")=py::none()) - .def("crop", &FrameSeq::crop, py::arg("left"), py::arg("top"), py::arg("width"), py::arg("height")) + .def("to", (FrameSeq (FrameSeq::*)(const Device &, bool) const) & + FrameSeq::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", + (FrameSeq (FrameSeq::*)(DeviceType, bool) const) & FrameSeq::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", [](const FrameSeq &self, const std::string &device, + bool non_blocking) { return self.to(device); }, + py::arg("device"), py::arg("non_blocking") = false) + .def("__getitem__", + [](FrameSeq &self, int64_t index) { return self[index]; }) + .def("slice", &FrameSeq::slice, py::arg("start"), + py::arg("end") = py::none()) + .def("crop", &FrameSeq::crop, py::arg("left"), py::arg("top"), + py::arg("width"), py::arg("height")) .def("reformat", &FrameSeq::reformat, py::arg("pix_info")) - .def("resize", &FrameSeq::resize, - py::arg("width"), py::arg("height"), py::arg("mode")=ImageFilterMode::Bilinear) + .def("resize", &FrameSeq::resize, py::arg("width"), py::arg("height"), + py::arg("mode") = ImageFilterMode::Bilinear) .def("rotate", &FrameSeq::rotate, py::arg("mode")) - .def("mirror", &FrameSeq::mirror, py::arg("axis")=ImageAxis::Horizontal) - ; - + .def("mirror", &FrameSeq::mirror, + py::arg("axis") = ImageAxis::Horizontal); // - m.def("concat", (FrameSeq(*)(const std::vector&))&concat); - m.def("concat", (FrameSeq(*)(const std::vector&))&concat); + m.def("concat", (FrameSeq(*)(const std::vector &)) & concat); + m.def("concat", (FrameSeq(*)(const std::vector &)) & concat); // auto img = m.def_submodule("img"); - img.def("yuv_to_rgb", - (Tensor&(*)(Tensor&, const TensorList&, const PixelInfo&, ChannelFormat))&img::yuv_to_rgb, - py::arg("dst"), py::arg("src"), py::arg("pix_info"), py::arg("cformat")=kNCHW); - img.def("yuv_to_rgb", - (Tensor(*)(const TensorList&, const PixelInfo&, ChannelFormat))&img::yuv_to_rgb, - py::arg("src"), py::arg("pix_info"), py::arg("cformat")=kNCHW); - - img.def("rgb_to_yuv", - (TensorList&(*)(TensorList&, const Tensor&, const PixelInfo&, ChannelFormat))&img::rgb_to_yuv, - py::arg("dst"), py::arg("src"), py::arg("pix_info"), py::arg("cformat")=kNCHW); + img.def("yuv_to_rgb", (Tensor & (*)(Tensor &, const TensorList &, + const PixelInfo &, ChannelFormat)) & + img::yuv_to_rgb, + py::arg("dst"), py::arg("src"), py::arg("pix_info"), + py::arg("cformat") = kNCHW); + img.def("yuv_to_rgb", + (Tensor(*)(const TensorList &, const PixelInfo &, ChannelFormat)) & + img::yuv_to_rgb, + py::arg("src"), py::arg("pix_info"), py::arg("cformat") = kNCHW); + + img.def("rgb_to_yuv", (TensorList & (*)(TensorList &, const Tensor &, + const PixelInfo &, ChannelFormat)) & + img::rgb_to_yuv, + py::arg("dst"), py::arg("src"), py::arg("pix_info"), + py::arg("cformat") = kNCHW); img.def("rgb_to_yuv", - (TensorList(*)(const Tensor&, const PixelInfo&, ChannelFormat))&img::rgb_to_yuv, - py::arg("src"), py::arg("pix_info"), py::arg("cformat")=kNCHW); + (TensorList(*)(const Tensor &, const PixelInfo &, ChannelFormat)) & + img::rgb_to_yuv, + py::arg("src"), py::arg("pix_info"), py::arg("cformat") = kNCHW); img.def("yuv_to_yuv", - (TensorList&(*)(TensorList&, const TensorList&, const PixelInfo&, const PixelInfo&))&img::yuv_to_yuv, - py::arg("dst"), py::arg("src"), py::arg("dst_pix_info"), py::arg("src_pix_info")); - img.def("yuv_to_yuv", - (TensorList(*)(const TensorList&, const PixelInfo&, const PixelInfo&))&img::yuv_to_yuv, - py::arg("src"), py::arg("dst_pix_info"), py::arg("src_pix_info")); + (TensorList & (*)(TensorList &, const TensorList &, + const PixelInfo &, const PixelInfo &)) & + img::yuv_to_yuv, + py::arg("dst"), py::arg("src"), py::arg("dst_pix_info"), + py::arg("src_pix_info")); + img.def("yuv_to_yuv", (TensorList(*)(const TensorList &, const PixelInfo &, + const PixelInfo &)) & + img::yuv_to_yuv, + py::arg("src"), py::arg("dst_pix_info"), py::arg("src_pix_info")); img.def("yuv_resize", &img::yuv_resize); img.def("yuv_rotate", &img::yuv_rotate); img.def("yuv_mirror", &img::yuv_mirror); - img.def("resize", (Tensor&(*)(Tensor&, const Tensor&, ImageFilterMode, ChannelFormat))&img::resize, - py::arg("dst"), py::arg("src"), - py::arg("mode") = ImageFilterMode::Bilinear, - py::arg("format") = kNCHW - ); - img.def("resize", (Tensor(*)(const Tensor&, int, int, ImageFilterMode, ChannelFormat))&img::resize, + img.def("resize", (Tensor & (*)(Tensor &, const Tensor &, ImageFilterMode, + ChannelFormat)) & + img::resize, + py::arg("dst"), py::arg("src"), + py::arg("mode") = ImageFilterMode::Bilinear, + py::arg("format") = kNCHW); + img.def( + "resize", + (Tensor(*)(const Tensor &, int, int, ImageFilterMode, ChannelFormat)) & + img::resize, py::arg("src"), py::arg("width"), py::arg("height"), - py::arg("mode") = ImageFilterMode::Bilinear, - py::arg("format") = kNCHW - ); - - img.def("rotate", (Tensor&(*)(Tensor&, const Tensor&, ImageRotationMode, ChannelFormat))&img::rotate, - py::arg("dst"), py::arg("src"), - py::arg("mode")=ImageRotationMode::Rotate90, - py::arg("format")=kNCHW - ); - img.def("rotate", (Tensor(*)(const Tensor&, ImageRotationMode, ChannelFormat))&img::rotate, - py::arg("src"), - py::arg("mode")=ImageRotationMode::Rotate90, - py::arg("format")=kNCHW - ); - - img.def("mirror", (Tensor&(*)(Tensor&, const Tensor&, ImageAxis, ChannelFormat))&img::mirror, - py::arg("dst"), py::arg("src"), - py::arg("axis")=ImageAxis::Vertical, py::arg("format")=kNCHW - ); - img.def("mirror", (Tensor(*)(const Tensor&, ImageAxis, ChannelFormat))&img::mirror, - py::arg("src"), - py::arg("axis")=ImageAxis::Vertical, py::arg("format")=kNCHW - ); - - img.def("normalize", (Tensor&(*)(Tensor&, const Tensor&, const Tensor&, const Tensor&, ChannelFormat))&img::normalize, - py::arg("dst"), py::arg("src"), - py::arg("mean"), py::arg("std"), py::arg("format")=kNCHW - ); - img.def("normalize", (Tensor(*)(const Tensor&, const Tensor&, const Tensor&, ChannelFormat))&img::normalize, - py::arg("src"), - py::arg("mean"), py::arg("std"), py::arg("format")=kNCHW - ); - - img.def("erode", - (Tensor&(*)(Tensor&, const Tensor&, const optional&, ChannelFormat))&img::erode, - py::arg("dst"), py::arg("src"), py::arg("kernel")=py::none(), - py::arg("format")=kNCHW); - img.def("erode", (Tensor(*)(const Tensor&, const optional&, ChannelFormat))&img::erode, - py::arg("src"), py::arg("kernel")=py::none(), - py::arg("format")=kNCHW); - - img.def("dilate", - (Tensor&(*)(Tensor&, const Tensor&, const optional&, ChannelFormat))&img::dilate, - py::arg("dst"), py::arg("src"), py::arg("kernel")=py::none(), - py::arg("format")=kNCHW); - img.def("dilate", - (Tensor(*)(const Tensor&, const optional&, ChannelFormat))&img::dilate, - py::arg("src"), py::arg("kernel")=py::none(), - py::arg("format")=kNCHW); - - img.def("sobel", - (Tensor&(*)(Tensor&, const Tensor&, int64_t, int64_t, int64_t, const Scalar&, const Scalar&, ChannelFormat))&img::sobel, - py::arg("dst"), py::arg("src"), py::arg("dx"), py::arg("dy"), - py::arg("ksize")=3, py::arg("scale")=1, py::arg("delta")=0, - py::arg("format")=kNCHW); - img.def("sobel", - (Tensor(*)(const Tensor&, int64_t, int64_t, int64_t, const Scalar&, const Scalar&, ChannelFormat))&img::sobel, - py::arg("src"), py::arg("dx"), py::arg("dy"), - py::arg("ksize")=3, py::arg("scale")=1, py::arg("delta")=0, - py::arg("format")=kNCHW); - - img.def("canny", - (Tensor&(*)(Tensor&, const Tensor&, const Scalar&, const Scalar&, int64_t, bool, ChannelFormat))&img::canny, - py::arg("dst"), py::arg("src"), py::arg("low_thresh"), py::arg("high_thresh"), - py::arg("aperture")=3, py::arg("l2_gradient")=false, - py::arg("format")=kNCHW); - img.def("canny", - (Tensor(*)(const Tensor&, const Scalar&, const Scalar&, int64_t, bool, ChannelFormat))&img::canny, - py::arg("src"), py::arg("low_thresh"), py::arg("high_thresh"), - py::arg("aperture")=3, py::arg("l2_gradient")=false, - py::arg("format")=kNCHW); - - img.def("filter2d", - (Tensor&(*)(Tensor&, const Tensor&, const Tensor&, const Scalar&, ChannelFormat))&img::filter2d, - py::arg("dst"), py::arg("src"), py::arg("kernel"), - py::arg("delta")=0, py::arg("format")=kNCHW); - img.def("filter2d", - (Tensor(*)(const Tensor&, const Tensor&, const Scalar&, ChannelFormat))&img::filter2d, - py::arg("src"), py::arg("kernel"), - py::arg("delta")=0, py::arg("format")=kNCHW); - - img.def("warp_perspective", - (Tensor&(*)(Tensor&, const Tensor&, const Tensor&, ImageFilterMode, ChannelFormat))&img::warp_perspective, - py::arg("dst"), py::arg("src"), py::arg("M"), - py::arg("mode")=kBicubic, py::arg("format")=kNCHW); - img.def("warp_perspective", - (Tensor(*)(const Tensor&, int64_t, int64_t, const Tensor&, ImageFilterMode, ChannelFormat))&img::warp_perspective, - py::arg("src"), py::arg("width"), py::arg("height"), py::arg("M"), - py::arg("mode")=kBicubic, py::arg("format")=kNCHW); + py::arg("mode") = ImageFilterMode::Bilinear, py::arg("format") = kNCHW); + + img.def("rotate", (Tensor & (*)(Tensor &, const Tensor &, ImageRotationMode, + ChannelFormat)) & + img::rotate, + py::arg("dst"), py::arg("src"), + py::arg("mode") = ImageRotationMode::Rotate90, + py::arg("format") = kNCHW); + img.def("rotate", + (Tensor(*)(const Tensor &, ImageRotationMode, ChannelFormat)) & + img::rotate, + py::arg("src"), py::arg("mode") = ImageRotationMode::Rotate90, + py::arg("format") = kNCHW); + + img.def("mirror", + (Tensor & (*)(Tensor &, const Tensor &, ImageAxis, ChannelFormat)) & + img::mirror, + py::arg("dst"), py::arg("src"), + py::arg("axis") = ImageAxis::Vertical, py::arg("format") = kNCHW); + img.def("mirror", + (Tensor(*)(const Tensor &, ImageAxis, ChannelFormat)) & img::mirror, + py::arg("src"), py::arg("axis") = ImageAxis::Vertical, + py::arg("format") = kNCHW); + + img.def("normalize", (Tensor & (*)(Tensor &, const Tensor &, const Tensor &, + const Tensor &, ChannelFormat)) & + img::normalize, + py::arg("dst"), py::arg("src"), py::arg("mean"), py::arg("std"), + py::arg("format") = kNCHW); + img.def("normalize", (Tensor(*)(const Tensor &, const Tensor &, + const Tensor &, ChannelFormat)) & + img::normalize, + py::arg("src"), py::arg("mean"), py::arg("std"), + py::arg("format") = kNCHW); + + img.def("erode", (Tensor & (*)(Tensor &, const Tensor &, + const optional &, ChannelFormat)) & + img::erode, + py::arg("dst"), py::arg("src"), py::arg("kernel") = py::none(), + py::arg("format") = kNCHW); + img.def("erode", (Tensor(*)(const Tensor &, const optional &, + ChannelFormat)) & + img::erode, + py::arg("src"), py::arg("kernel") = py::none(), + py::arg("format") = kNCHW); + + img.def("dilate", (Tensor & (*)(Tensor &, const Tensor &, + const optional &, ChannelFormat)) & + img::dilate, + py::arg("dst"), py::arg("src"), py::arg("kernel") = py::none(), + py::arg("format") = kNCHW); + img.def("dilate", (Tensor(*)(const Tensor &, const optional &, + ChannelFormat)) & + img::dilate, + py::arg("src"), py::arg("kernel") = py::none(), + py::arg("format") = kNCHW); + + img.def("sobel", + (Tensor & (*)(Tensor &, const Tensor &, int64_t, int64_t, int64_t, + const Scalar &, const Scalar &, ChannelFormat)) & + img::sobel, + py::arg("dst"), py::arg("src"), py::arg("dx"), py::arg("dy"), + py::arg("ksize") = 3, py::arg("scale") = 1, py::arg("delta") = 0, + py::arg("format") = kNCHW); + img.def( + "sobel", (Tensor(*)(const Tensor &, int64_t, int64_t, int64_t, + const Scalar &, const Scalar &, ChannelFormat)) & + img::sobel, + py::arg("src"), py::arg("dx"), py::arg("dy"), py::arg("ksize") = 3, + py::arg("scale") = 1, py::arg("delta") = 0, py::arg("format") = kNCHW); + + img.def("canny", + (Tensor & (*)(Tensor &, const Tensor &, const Scalar &, + const Scalar &, int64_t, bool, ChannelFormat)) & + img::canny, + py::arg("dst"), py::arg("src"), py::arg("low_thresh"), + py::arg("high_thresh"), py::arg("aperture") = 3, + py::arg("l2_gradient") = false, py::arg("format") = kNCHW); + img.def("canny", (Tensor(*)(const Tensor &, const Scalar &, const Scalar &, + int64_t, bool, ChannelFormat)) & + img::canny, + py::arg("src"), py::arg("low_thresh"), py::arg("high_thresh"), + py::arg("aperture") = 3, py::arg("l2_gradient") = false, + py::arg("format") = kNCHW); + + img.def("filter2d", (Tensor & (*)(Tensor &, const Tensor &, const Tensor &, + const Scalar &, ChannelFormat)) & + img::filter2d, + py::arg("dst"), py::arg("src"), py::arg("kernel"), + py::arg("delta") = 0, py::arg("format") = kNCHW); + img.def("filter2d", (Tensor(*)(const Tensor &, const Tensor &, + const Scalar &, ChannelFormat)) & + img::filter2d, + py::arg("src"), py::arg("kernel"), py::arg("delta") = 0, + py::arg("format") = kNCHW); + + img.def("warp_perspective", + (Tensor & (*)(Tensor &, const Tensor &, const Tensor &, + ImageFilterMode, ChannelFormat)) & + img::warp_perspective, + py::arg("dst"), py::arg("src"), py::arg("M"), + py::arg("mode") = kBicubic, py::arg("format") = kNCHW); + img.def("warp_perspective", + (Tensor(*)(const Tensor &, int64_t, int64_t, const Tensor &, + ImageFilterMode, ChannelFormat)) & + img::warp_perspective, + py::arg("src"), py::arg("width"), py::arg("height"), py::arg("M"), + py::arg("mode") = kBicubic, py::arg("format") = kNCHW); img.def("bilateral_filter", - (Tensor&(*)(Tensor&, const Tensor&, int, const Scalar&, const Scalar&, ChannelFormat))&img::bilateral_filter, - py::arg("dst"), py::arg("src"), py::arg("d"), - py::arg("sigma_color"), py::arg("sigma_space"), py::arg("format")=kNCHW); - img.def("bilateral_filter", - (Tensor(*)(const Tensor&, int, const Scalar&, const Scalar&, ChannelFormat))&img::bilateral_filter, - py::arg("src"), py::arg("d"), - py::arg("sigma_color"), py::arg("sigma_space"), py::arg("format")=kNCHW); + (Tensor & (*)(Tensor &, const Tensor &, int, const Scalar &, + const Scalar &, ChannelFormat)) & + img::bilateral_filter, + py::arg("dst"), py::arg("src"), py::arg("d"), + py::arg("sigma_color"), py::arg("sigma_space"), + py::arg("format") = kNCHW); + img.def("bilateral_filter", (Tensor(*)(const Tensor &, int, const Scalar &, + const Scalar &, ChannelFormat)) & + img::bilateral_filter, + py::arg("src"), py::arg("d"), py::arg("sigma_color"), + py::arg("sigma_space"), py::arg("format") = kNCHW); img.def("gaussian_blur", - (Tensor&(*)(Tensor&, const Tensor&, int, int, const Scalar&, const Scalar&, ChannelFormat))&img::gaussian_blur, - py::arg("dst"), py::arg("src"), py::arg("kx"), py::arg("ky"), - py::arg("sigma_x"), py::arg("sigma_y")=0, py::arg("format")=kNCHW); + (Tensor & (*)(Tensor &, const Tensor &, int, int, const Scalar &, + const Scalar &, ChannelFormat)) & + img::gaussian_blur, + py::arg("dst"), py::arg("src"), py::arg("kx"), py::arg("ky"), + py::arg("sigma_x"), py::arg("sigma_y") = 0, + py::arg("format") = kNCHW); img.def("gaussian_blur", - (Tensor(*)(const Tensor&, int, int, const Scalar&, const Scalar&, ChannelFormat))&img::gaussian_blur, - py::arg("src"), py::arg("kx"), py::arg("ky"), - py::arg("sigma_x"), py::arg("sigma_y")=0, py::arg("format")=kNCHW); - - img.def("overlay", - (Tensor&(*)(Tensor&, const Tensor&, const Tensor&, const Tensor&))&img::overlay, - py::arg("dst"), py::arg("src0"), py::arg("src1"), py::arg("alpha")); - img.def("overlay", - (Tensor(*)(const Tensor&, const Tensor&, const Tensor&))&img::overlay, - py::arg("src0"), py::arg("src1"), py::arg("alpha")); - - img.def("transfer", - (Tensor(*)(const Tensor&, const ChannelFormat&, const ChannelFormat&))&img::transfer, - py::arg("src"), py::arg("src_format"), py::arg("dst_format")); - + (Tensor(*)(const Tensor &, int, int, const Scalar &, const Scalar &, + ChannelFormat)) & + img::gaussian_blur, + py::arg("src"), py::arg("kx"), py::arg("ky"), py::arg("sigma_x"), + py::arg("sigma_y") = 0, py::arg("format") = kNCHW); + + img.def("overlay", (Tensor & (*)(Tensor &, const Tensor &, const Tensor &, + const Tensor &)) & + img::overlay, + py::arg("dst"), py::arg("src0"), py::arg("src1"), py::arg("alpha")); + img.def("overlay", + (Tensor(*)(const Tensor &, const Tensor &, const Tensor &)) & + img::overlay, + py::arg("src0"), py::arg("src1"), py::arg("alpha")); + + img.def("transfer", (Tensor(*)(const Tensor &, const ChannelFormat &, + const ChannelFormat &)) & + img::transfer, + py::arg("src"), py::arg("src_format"), py::arg("dst_format")); } - diff --git a/bmf/hml/py/py_numpy.cpp b/bmf/hml/py/py_numpy.cpp index 267bae7c..26497875 100644 --- a/bmf/hml/py/py_numpy.cpp +++ b/bmf/hml/py/py_numpy.cpp @@ -19,105 +19,92 @@ #include #include - -namespace pybind11{ -namespace detail{ +namespace pybind11 { +namespace detail { const static int NPY_HALF_ = 23; -template <> -struct npy_format_descriptor { - static pybind11::dtype dtype() { - handle ptr = npy_api::get().PyArray_DescrFromType_(NPY_HALF_); - return reinterpret_borrow(ptr); - } - static std::string format() { - // following: https://docs.python.org/3/library/struct.html#format-characters - return "e"; - } - static constexpr auto name() { - return _("float16"); - } +template <> struct npy_format_descriptor { + static pybind11::dtype dtype() { + handle ptr = npy_api::get().PyArray_DescrFromType_(NPY_HALF_); + return reinterpret_borrow(ptr); + } + static std::string format() { + // following: + // https://docs.python.org/3/library/struct.html#format-characters + return "e"; + } + static constexpr auto name() { return _("float16"); } }; - - -}} // - - +} +} // namespace py = pybind11; using namespace hmp; - -static py::dtype scalarTypeToNumpyDtype(const ScalarType scalar_type) -{ - switch (scalar_type) { -#define TO_FORMAT_STR(scalar_t, scalar_type)\ - case ::hmp::ScalarType::scalar_type: \ +static py::dtype scalarTypeToNumpyDtype(const ScalarType scalar_type) { + switch (scalar_type) { +#define TO_FORMAT_STR(scalar_t, scalar_type) \ + case ::hmp::ScalarType::scalar_type: \ return py::dtype::of(); - HMP_FORALL_SCALAR_TYPES(TO_FORMAT_STR) + HMP_FORALL_SCALAR_TYPES(TO_FORMAT_STR) default: - throw std::runtime_error(std::string("Got unsupported ScalarType ") + stringfy(scalar_type)); - } + throw std::runtime_error(std::string("Got unsupported ScalarType ") + + stringfy(scalar_type)); + } } -static ScalarType numpyDtypeToScalarType(py::dtype dtype) -{ -#define TO_SCALAR_TYPE(scalar_t, scalar_type)\ - if (py::dtype::of().is(dtype)) {\ - return ::hmp::ScalarType::scalar_type;\ - } +static ScalarType numpyDtypeToScalarType(py::dtype dtype) { +#define TO_SCALAR_TYPE(scalar_t, scalar_type) \ + if (py::dtype::of().is(dtype)) { \ + return ::hmp::ScalarType::scalar_type; \ + } HMP_FORALL_SCALAR_TYPES(TO_SCALAR_TYPE) throw std::runtime_error(std::string("Got unsupported numpy dtype")); } - - -Tensor tensor_from_numpy(const py::array& arr) -{ +Tensor tensor_from_numpy(const py::array &arr) { int ndim = arr.ndim(); SizeArray shape, strides; auto itemsize = arr.itemsize(); - for(int i = 0; i < ndim; ++i){ + for (int i = 0; i < ndim; ++i) { auto size = arr.shape()[i]; auto stride = arr.strides()[i]; - HMP_REQUIRE(stride%itemsize == 0 && stride >= 0, - "unsupported numpy stride {} at {}", stride, i); + HMP_REQUIRE(stride % itemsize == 0 && stride >= 0, + "unsupported numpy stride {} at {}", stride, i); shape.push_back(static_cast(size)); - strides.push_back(static_cast(stride/itemsize)); + strides.push_back(static_cast(stride / itemsize)); } auto buf_info = std::make_shared(arr.request()); - auto ptr = DataPtr(buf_info->ptr, [buf_info](void *ptr) mutable { - py::gil_scoped_acquire acquire; - //explict release in gil guard - buf_info.reset(); - }, kCPU); - - return from_buffer( - std::move(ptr), - numpyDtypeToScalarType(arr.dtype()), - shape, - strides); + auto ptr = DataPtr(buf_info->ptr, + [buf_info](void *ptr) mutable { + py::gil_scoped_acquire acquire; + // explict release in gil guard + buf_info.reset(); + }, + kCPU); + + return from_buffer(std::move(ptr), numpyDtypeToScalarType(arr.dtype()), + shape, strides); } -py::array tensor_to_numpy(const Tensor& tensor) -{ +py::array tensor_to_numpy(const Tensor &tensor) { HMP_REQUIRE(tensor.is_cpu(), - "Only support convert cpu tensor to numpy, got {}", tensor.device_type()); + "Only support convert cpu tensor to numpy, got {}", + tensor.device_type()); auto dtype = scalarTypeToNumpyDtype(tensor.scalar_type()); std::vector shape, strides; auto itemsize = tensor.itemsize(); - for(int i = 0; i < tensor.dim(); ++i){ + for (int i = 0; i < tensor.dim(); ++i) { shape.push_back(tensor.size(i)); - strides.push_back(tensor.stride(i)*itemsize); + strides.push_back(tensor.stride(i) * itemsize); } - return py::array(dtype, shape, strides, tensor.unsafe_data(), py::cast(tensor)); + return py::array(dtype, shape, strides, tensor.unsafe_data(), + py::cast(tensor)); } - - diff --git a/bmf/hml/py/py_tensor.cpp b/bmf/hml/py/py_tensor.cpp index e16e3621..5d105339 100644 --- a/bmf/hml/py/py_tensor.cpp +++ b/bmf/hml/py/py_tensor.cpp @@ -14,12 +14,11 @@ * limitations under the License. */ - #include #include #ifdef HMP_ENABLE_TORCH #include -//cast implementation +// cast implementation #include #endif #include @@ -35,13 +34,11 @@ namespace py = pybind11; using namespace hmp; -Tensor tensor_from_numpy(const py::array& arr); -py::array tensor_to_numpy(const Tensor& tensor); +Tensor tensor_from_numpy(const py::array &arr); +py::array tensor_to_numpy(const Tensor &tensor); -static bool is_device_supported(DLDeviceType devType) -{ - switch (devType) - { +static bool is_device_supported(DLDeviceType devType) { + switch (devType) { case kDLCUDAHost: case kDLCUDA: case kDLCUDAManaged: @@ -52,192 +49,197 @@ static bool is_device_supported(DLDeviceType devType) } } -Tensor tensor_from_dlpack(const py::object& o){ +Tensor tensor_from_dlpack(const py::object &o) { py::object tmp = py::reinterpret_borrow(o); Tensor ten; - if (hasattr(tmp, "__dlpack__")) - { + if (hasattr(tmp, "__dlpack__")) { // Quickly check if we support the device - if (hasattr(tmp, "__dlpack_device__")) - { - py::tuple dlpackDevice = tmp.attr("__dlpack_device__")().cast(); - auto devType = static_cast(dlpackDevice[0].cast()); - if (!is_device_supported(devType)) - { - HMP_REQUIRE(false, "Only CPU and CUDA memory buffers can be wrapped"); + if (hasattr(tmp, "__dlpack_device__")) { + py::tuple dlpackDevice = + tmp.attr("__dlpack_device__")().cast(); + auto devType = + static_cast(dlpackDevice[0].cast()); + if (!is_device_supported(devType)) { + HMP_REQUIRE(false, + "Only CPU and CUDA memory buffers can be wrapped"); } } py::capsule cap = tmp.attr("__dlpack__")(1).cast(); - py::handle* hdl = dynamic_cast(&cap); - PyObject* pycap = *(PyObject**)hdl; + py::handle *hdl = dynamic_cast(&cap); + PyObject *pycap = *(PyObject **)hdl; - if (auto* tensor = static_cast(cap.get_pointer())) - { + if (auto *tensor = static_cast(cap.get_pointer())) { // m_dlTensor = DLPackTensor{std::move(*tensor)}; ten = from_dlpack(tensor); // signal that producer don't have to call tensor's deleter, we // (consumer will do it instead. - HMP_REQUIRE(PyCapsule_SetName(pycap, "used_dltensor") == 0, "Failed to rename dltensor capsule"); - } - else - { + HMP_REQUIRE(PyCapsule_SetName(pycap, "used_dltensor") == 0, + "Failed to rename dltensor capsule"); + } else { HMP_REQUIRE(false, "No dlpack tensor found"); } - } - else { + } else { HMP_REQUIRE(false, "dlpack not supported in the src tensor"); } return ten; } -Device parse_device(const py::object &obj, const Device &ref) -{ +Device parse_device(const py::object &obj, const Device &ref) { Device device(ref); - if (PyUnicode_Check(obj.ptr())){ + if (PyUnicode_Check(obj.ptr())) { device = Device(py::cast(obj)); - } - else if (py::isinstance(obj)){ + } else if (py::isinstance(obj)) { device = py::cast(obj); - } - else{ - try{ + } else { + try { device = py::cast(obj); - } - catch(std::bad_cast &){ + } catch (std::bad_cast &) { } } return device; } -TensorOptions parse_tensor_options(const py::kwargs &kwargs, const TensorOptions &ref) -{ +TensorOptions parse_tensor_options(const py::kwargs &kwargs, + const TensorOptions &ref) { TensorOptions opts(ref); - if (kwargs.contains("pinned_memory")){ - opts = opts.pinned_memory(py::cast(kwargs["pinned_memory"])); + if (kwargs.contains("pinned_memory")) { + opts = opts.pinned_memory(py::cast(kwargs["pinned_memory"])); } - if (kwargs.contains("device")){ + if (kwargs.contains("device")) { opts = opts.device(parse_device(kwargs["device"])); } - if (kwargs.contains("dtype")){ - opts = opts.dtype(py::cast(kwargs["dtype"])); + if (kwargs.contains("dtype")) { + opts = opts.dtype(py::cast(kwargs["dtype"])); } return opts; } -void tensorBind(py::module &m) -{ +void tensorBind(py::module &m) { using namespace py::literals; // - m.def("from_numpy", [](const py::array& arr){ - return tensor_from_numpy(arr); - }) - .def("from_numpy", [](const py::list& arr_list){ - py::list tensor_list; - for(auto &arr : arr_list){ - tensor_list.append(py::cast(tensor_from_numpy(py::cast(arr)))); - } - return tensor_list; - }) - .def("to_numpy", [](const Tensor &tensor){ - return tensor_to_numpy(tensor); - }) - .def("to_numpy", [](const TensorList &tensors){ - py::list arr_list; - for(auto &tensor : tensors){ - arr_list.append(tensor_to_numpy(tensor)); - } - return arr_list; - }) - .def("from_dlpack", (Tensor(*)(const py::object&))&tensor_from_dlpack, - py::arg("tensor")) + m.def("from_numpy", + [](const py::array &arr) { return tensor_from_numpy(arr); }) + .def("from_numpy", + [](const py::list &arr_list) { + py::list tensor_list; + for (auto &arr : arr_list) { + tensor_list.append( + py::cast(tensor_from_numpy(py::cast(arr)))); + } + return tensor_list; + }) + .def("to_numpy", + [](const Tensor &tensor) { return tensor_to_numpy(tensor); }) + .def("to_numpy", + [](const TensorList &tensors) { + py::list arr_list; + for (auto &tensor : tensors) { + arr_list.append(tensor_to_numpy(tensor)); + } + return arr_list; + }) + .def("from_dlpack", + (Tensor(*)(const py::object &)) & tensor_from_dlpack, + py::arg("tensor")) #ifdef HMP_ENABLE_TORCH - .def("from_torch", [](const at::Tensor &t){ - return hmp::torch::from_tensor(t); - }) + .def("from_torch", + [](const at::Tensor &t) { return hmp::torch::from_tensor(t); }) #endif - .def("empty", [](const SizeArray &shape, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs); - return empty(shape, options); - }) - .def("empty_like", [](const Tensor &other, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs, other.options()); - return empty_like(other, options); - }) - .def("zeros", [](const SizeArray &shape, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs); - return zeros(shape, options); - }) - .def("zeros_like", [](const Tensor &other, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs, other.options()); - return zeros_like(other, options); - }) - .def("ones", [](const SizeArray &shape, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs); - return ones(shape, options); - }) - .def("ones_like", [](const Tensor &other, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs, other.options()); - return ones_like(other, options); - }) - .def("arange", [](int64_t start, int64_t end, int64_t step, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs); - return arange(start, end, step, options); - }, py::arg("start"), py::arg("end"), py::arg("step")=1) - .def("arange", [](int64_t end, const py::kwargs &kwargs){ - auto options = parse_tensor_options(kwargs); - return arange(0, end, 1, options); - }, py::arg("end")) - .def("copy", ©) + .def("empty", + [](const SizeArray &shape, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs); + return empty(shape, options); + }) + .def("empty_like", + [](const Tensor &other, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs, other.options()); + return empty_like(other, options); + }) + .def("zeros", + [](const SizeArray &shape, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs); + return zeros(shape, options); + }) + .def("zeros_like", + [](const Tensor &other, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs, other.options()); + return zeros_like(other, options); + }) + .def("ones", + [](const SizeArray &shape, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs); + return ones(shape, options); + }) + .def("ones_like", + [](const Tensor &other, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs, other.options()); + return ones_like(other, options); + }) + .def("arange", + [](int64_t start, int64_t end, int64_t step, + const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs); + return arange(start, end, step, options); + }, + py::arg("start"), py::arg("end"), py::arg("step") = 1) + .def("arange", + [](int64_t end, const py::kwargs &kwargs) { + auto options = parse_tensor_options(kwargs); + return arange(0, end, 1, options); + }, + py::arg("end")) + .def("copy", ©) - //shape transformation - .def("concat", (Tensor(*)(const TensorList&, int64_t))&concat, - py::arg("tensors"), py::arg("axis") = 0) - .def("concat", (Tensor&(*)(Tensor&, const TensorList&, int64_t))&concat, - py::arg("out"), py::arg("tensors"), py::arg("axis") = 0) - .def("stack", (Tensor(*)(const TensorList&, int64_t))&stack, - py::arg("tensors"), py::arg("axis") = 0) - .def("stack", (Tensor&(*)(Tensor&, const TensorList&, int64_t))&stack, - py::arg("out"), py::arg("tensors"), py::arg("axis") = 0) - .def("vstack", (Tensor(*)(const TensorList&))&vstack, py::arg("tensors")) - .def("vstack", (Tensor&(*)(Tensor&, const TensorList&))&vstack, - py::arg("out"), py::arg("tensors")) - .def("hstack", (Tensor(*)(const TensorList&))&hstack, py::arg("tensors")) - .def("hstack", (Tensor&(*)(Tensor&, const TensorList&))&hstack, - py::arg("out"), py::arg("tensors")) - - //file io - .def("fromfile", &fromfile, py::arg("fn"), py::arg("dtype"), py::arg("count")=-1, - py::arg("offset")=0) - .def("tofile", &tofile, py::arg("data"), py::arg("fn")) - ; + // shape transformation + .def("concat", (Tensor(*)(const TensorList &, int64_t)) & concat, + py::arg("tensors"), py::arg("axis") = 0) + .def("concat", + (Tensor & (*)(Tensor &, const TensorList &, int64_t)) & concat, + py::arg("out"), py::arg("tensors"), py::arg("axis") = 0) + .def("stack", (Tensor(*)(const TensorList &, int64_t)) & stack, + py::arg("tensors"), py::arg("axis") = 0) + .def("stack", + (Tensor & (*)(Tensor &, const TensorList &, int64_t)) & stack, + py::arg("out"), py::arg("tensors"), py::arg("axis") = 0) + .def("vstack", (Tensor(*)(const TensorList &)) & vstack, + py::arg("tensors")) + .def("vstack", (Tensor & (*)(Tensor &, const TensorList &)) & vstack, + py::arg("out"), py::arg("tensors")) + .def("hstack", (Tensor(*)(const TensorList &)) & hstack, + py::arg("tensors")) + .def("hstack", (Tensor & (*)(Tensor &, const TensorList &)) & hstack, + py::arg("out"), py::arg("tensors")) + + // file io + .def("fromfile", &fromfile, py::arg("fn"), py::arg("dtype"), + py::arg("count") = -1, py::arg("offset") = 0) + .def("tofile", &tofile, py::arg("data"), py::arg("fn")); // py::class_(m, "Tensor") - .def("__str__", [](const Tensor &self){ - return stringfy(self); - }) - .def("__repr__", [](const Tensor &self){ - return self.repr(); - }) + .def("__str__", [](const Tensor &self) { return stringfy(self); }) + .def("__repr__", [](const Tensor &self) { return self.repr(); }) .def_property_readonly("defined", &Tensor::defined) .def_property_readonly("device", &Tensor::device) .def_property_readonly("device_type", &Tensor::device_type) .def_property_readonly("device_index", &Tensor::device_index) .def_property_readonly("dtype", &Tensor::dtype) - .def_property_readonly("shape", [](const Tensor &self){ - py::tuple shape = py::cast(self.shape()); - return shape; - }) - .def_property_readonly("strides", [](const Tensor &self){ - py::tuple shape = py::cast(self.strides()); - return shape; - }) + .def_property_readonly("shape", + [](const Tensor &self) { + py::tuple shape = py::cast(self.shape()); + return shape; + }) + .def_property_readonly("strides", + [](const Tensor &self) { + py::tuple shape = py::cast(self.strides()); + return shape; + }) .def_property_readonly("dim", &Tensor::dim) .def("size", &Tensor::size) .def("stride", &Tensor::stride) @@ -253,76 +255,85 @@ void tensorBind(py::module &m) .def("alias", &Tensor::alias) .def("view", &Tensor::view) .def("clone", &Tensor::clone) - .def("as_strided", &Tensor::as_strided, py::arg("shape"), py::arg("strides"), py::arg("offset")=py::none()) - .def("as_strided_", &Tensor::as_strided_, py::arg("shape"), py::arg("strides"), py::arg("offset")=py::none()) - .def("squeeze", &Tensor::squeeze, py::arg("dim")=py::none()) - .def("squeeze_", &Tensor::squeeze_, py::arg("dim")=py::none()) - .def("unsqueeze", &Tensor::unsqueeze, py::arg("dim")=0) - .def("unsqueeze_", &Tensor::unsqueeze_, py::arg("dim")=0) + .def("as_strided", &Tensor::as_strided, py::arg("shape"), + py::arg("strides"), py::arg("offset") = py::none()) + .def("as_strided_", &Tensor::as_strided_, py::arg("shape"), + py::arg("strides"), py::arg("offset") = py::none()) + .def("squeeze", &Tensor::squeeze, py::arg("dim") = py::none()) + .def("squeeze_", &Tensor::squeeze_, py::arg("dim") = py::none()) + .def("unsqueeze", &Tensor::unsqueeze, py::arg("dim") = 0) + .def("unsqueeze_", &Tensor::unsqueeze_, py::arg("dim") = 0) // .def("reshape", &Tensor::reshape) .def("transpose", &Tensor::transpose) .def("permute", &Tensor::permute) - .def("slice", &Tensor::slice, py::arg("dim"), py::arg("start"), py::arg("end")=py::none(), py::arg("step")=1) + .def("slice", &Tensor::slice, py::arg("dim"), py::arg("start"), + py::arg("end") = py::none(), py::arg("step") = 1) .def("select", &Tensor::select) - .def("to", (Tensor(Tensor::*)(const Device&, bool) const)&Tensor::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", (Tensor(Tensor::*)(DeviceType, bool) const)&Tensor::to, py::arg("device"), py::arg("non_blocking")=false) - .def("to", [](const Tensor &self, const std::string &deviceStr){ - return self.to(Device(deviceStr)); - }, py::arg("device")) - .def("to", (Tensor(Tensor::*)(ScalarType) const)&Tensor::to, py::arg("dtype")) + .def("to", + (Tensor (Tensor::*)(const Device &, bool) const) & Tensor::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", (Tensor (Tensor::*)(DeviceType, bool) const) & Tensor::to, + py::arg("device"), py::arg("non_blocking") = false) + .def("to", + [](const Tensor &self, const std::string &deviceStr) { + return self.to(Device(deviceStr)); + }, + py::arg("device")) + .def("to", (Tensor (Tensor::*)(ScalarType) const) & Tensor::to, + py::arg("dtype")) .def("copy_", &Tensor::copy_, py::arg("src")) .def("contiguous", &Tensor::contiguous) - .def("cpu", &Tensor::cpu, py::arg("non_blocking")=false) + .def("cpu", &Tensor::cpu, py::arg("non_blocking") = false) .def("cuda", &Tensor::cuda) - .def("numpy", [](const Tensor &self){ - return tensor_to_numpy(self); - }) - .def("data_ptr", [](const Tensor &self){ - return reinterpret_cast(self.unsafe_data()); - }) - .def("__dlpack__", [](const Tensor &self, const int stream){ - DLManagedTensor* dlMTensor = to_dlpack(self); - py::capsule cap(dlMTensor, "dltensor", [](PyObject *ptr) - { - if(PyCapsule_IsValid(ptr, "dltensor")) - { - // If consumer didn't delete the tensor, - if(auto *dlTensor = static_cast(PyCapsule_GetPointer(ptr, "dltensor"))) - { - // Delete the tensor. - if(dlTensor->deleter != nullptr) - { - dlTensor->deleter(dlTensor); - } - } - } - }); - return cap; - }, py::arg("stream")=1) - .def("__dlpack_device__", [](const Tensor &self){ - DLDeviceType device_type; - switch (self.device().type()) { - case DeviceType::CPU: - device_type = DLDeviceType::kDLCPU; - break; - case DeviceType::CUDA: - device_type = DLDeviceType::kDLCUDA; - break; - default: - HMP_REQUIRE(false, "Cannot pack tensors on " + stringfy(self.device())); - } - // DLManagedTensor* dlMTensor = to_dlpack(self); - return py::make_tuple(py::int_(static_cast(device_type)), - py::int_(static_cast(self.device().index()))); - }) + .def("numpy", [](const Tensor &self) { return tensor_to_numpy(self); }) + .def("data_ptr", + [](const Tensor &self) { + return reinterpret_cast(self.unsafe_data()); + }) + .def("__dlpack__", + [](const Tensor &self, const int stream) { + DLManagedTensor *dlMTensor = to_dlpack(self); + py::capsule cap(dlMTensor, "dltensor", [](PyObject *ptr) { + if (PyCapsule_IsValid(ptr, "dltensor")) { + // If consumer didn't delete the tensor, + if (auto *dlTensor = static_cast( + PyCapsule_GetPointer(ptr, "dltensor"))) { + // Delete the tensor. + if (dlTensor->deleter != nullptr) { + dlTensor->deleter(dlTensor); + } + } + } + }); + return cap; + }, + py::arg("stream") = 1) + .def("__dlpack_device__", + [](const Tensor &self) { + DLDeviceType device_type; + switch (self.device().type()) { + case DeviceType::CPU: + device_type = DLDeviceType::kDLCPU; + break; + case DeviceType::CUDA: + device_type = DLDeviceType::kDLCUDA; + break; + default: + HMP_REQUIRE(false, "Cannot pack tensors on " + + stringfy(self.device())); + } + // DLManagedTensor* dlMTensor = to_dlpack(self); + return py::make_tuple( + py::int_(static_cast(device_type)), + py::int_(static_cast(self.device().index()))); + }) #ifdef HMP_ENABLE_TORCH - .def("torch", [](const Tensor &self){ - return hmp::torch::tensor(self); - }) + .def("torch", + [](const Tensor &self) { return hmp::torch::tensor(self); }) .def(py::init(&hmp::torch::from_tensor), "tensor"_a) #endif @@ -338,26 +349,27 @@ void tensorBind(py::module &m) .def("clip", &Tensor::clip, py::arg("min"), py::arg("max")) .def("clip_", &Tensor::clip_, py::arg("min"), py::arg("max")) - // Binary ops - #define BIND_TENSOR_BOP(name, op) \ - .def(py::self op py::self) \ - .def(py::self op##= py::self) \ - .def(py::self op Scalar()) \ - .def(py::self op##= Scalar()) \ - .def(Scalar() op py::self) \ - .def(#name, (Tensor(Tensor::*)(const Tensor &b) const)&Tensor::name) \ - .def(#name, (Tensor(Tensor::*)(const Scalar &b) const)&Tensor::name) \ - .def(#name "_", (Tensor&(Tensor::*)(const Tensor &b))&Tensor::name##_) \ - .def(#name "_", (Tensor&(Tensor::*)(const Scalar &b))&Tensor::name##_) +// Binary ops +#define BIND_TENSOR_BOP(name, op) \ + .def(py::self op py::self) \ + .def(py::self op## = py::self) \ + .def(py::self op Scalar()) \ + .def(py::self op## = Scalar()) \ + .def(Scalar() op py::self) \ + .def(#name, \ + (Tensor (Tensor::*)(const Tensor &b) const) & Tensor::name) \ + .def(#name, \ + (Tensor (Tensor::*)(const Scalar &b) const) & Tensor::name) \ + .def(#name "_", \ + (Tensor & (Tensor::*)(const Tensor &b)) & Tensor::name##_) \ + .def(#name "_", \ + (Tensor & (Tensor::*)(const Scalar &b)) & Tensor::name##_) - BIND_TENSOR_BOP(add, +) - BIND_TENSOR_BOP(sub, -) - BIND_TENSOR_BOP(mul, *) - BIND_TENSOR_BOP(div, /) + BIND_TENSOR_BOP(add, +) BIND_TENSOR_BOP(sub, -) + BIND_TENSOR_BOP(mul, *) BIND_TENSOR_BOP(div, /) - //shape transformation + // shape transformation .def("flatten", &Tensor::flatten) - .def("tofile", &Tensor::tofile, py::arg("fn")) - ; + .def("tofile", &Tensor::tofile, py::arg("fn")); } diff --git a/bmf/hml/src/core/allocator.cpp b/bmf/hml/src/core/allocator.cpp index bcc79eb0..1f0db795 100644 --- a/bmf/hml/src/core/allocator.cpp +++ b/bmf/hml/src/core/allocator.cpp @@ -18,22 +18,18 @@ #include #include -namespace hmp{ +namespace hmp { -void dummyDeleter(void*) -{ - //auto v = sizeof_scalar_type(kI8); +void dummyDeleter(void *) { + // auto v = sizeof_scalar_type(kI8); } - namespace { -class CPUAllocator : public Allocator -{ -public: - DataPtr alloc(int64_t size) override - { - //TODO: alignment support +class CPUAllocator : public Allocator { + public: + DataPtr alloc(int64_t size) override { + // TODO: alignment support auto ptr = malloc(size); HMP_REQUIRE(ptr, "CPU out of memory"); return DataPtr(ptr, free, kCPU); @@ -43,8 +39,9 @@ class CPUAllocator : public Allocator static CPUAllocator sDefaultCPUAllocator; //+1(Pinned CPU allocator) -const static int sNumberDeviceTypes = static_cast(DeviceType::NumDeviceTypes); -static Allocator* sAllocators[sNumberDeviceTypes + 1]; +const static int sNumberDeviceTypes = + static_cast(DeviceType::NumDeviceTypes); +static Allocator *sAllocators[sNumberDeviceTypes + 1]; } // namespace @@ -52,19 +49,18 @@ HMP_DECLARE_ALLOCATOR(kCPU, 0); HMP_DECLARE_ALLOCATOR(kCPU, 1); HMP_DECLARE_ALLOCATOR(kCUDA, 0); - -HMP_API void set_allocator(DeviceType device, Allocator *allocator, unsigned flags) -{ - HMP_REQUIRE(device < DeviceType::NumDeviceTypes, "invalid device type {}", device); - if(device == kCPU && (flags & static_cast(AllocatorFlags::Pinned))){ +HMP_API void set_allocator(DeviceType device, Allocator *allocator, + unsigned flags) { + HMP_REQUIRE(device < DeviceType::NumDeviceTypes, "invalid device type {}", + device); + if (device == kCPU && + (flags & static_cast(AllocatorFlags::Pinned))) { sAllocators[sNumberDeviceTypes] = allocator; - } - else{ + } else { sAllocators[static_cast(device)] = allocator; } } -HMP_API Allocator *get_allocator(DeviceType device, unsigned flags) -{ +HMP_API Allocator *get_allocator(DeviceType device, unsigned flags) { #ifndef HMP_BUILD_SHARED HMP_IMPORT_ALLOCATOR(kCPU, 0); #ifdef HMP_ENABLE_CUDA @@ -74,16 +70,16 @@ HMP_API Allocator *get_allocator(DeviceType device, unsigned flags) #endif // - HMP_REQUIRE(device < DeviceType::NumDeviceTypes, "invalid device type {}", device); - if(device == kCPU && (flags & static_cast(AllocatorFlags::Pinned))){ + HMP_REQUIRE(device < DeviceType::NumDeviceTypes, "invalid device type {}", + device); + if (device == kCPU && + (flags & static_cast(AllocatorFlags::Pinned))) { return sAllocators[sNumberDeviceTypes]; - } - else{ + } else { return sAllocators[static_cast(device)]; } } - HMP_REGISTER_ALLOCATOR(kCPU, &sDefaultCPUAllocator, 0); -} //namespace hmp \ No newline at end of file +} // namespace hmp \ No newline at end of file diff --git a/bmf/hml/src/core/device.cpp b/bmf/hml/src/core/device.cpp index 422f6951..3eab3c45 100644 --- a/bmf/hml/src/core/device.cpp +++ b/bmf/hml/src/core/device.cpp @@ -20,17 +20,14 @@ #include #include -namespace hmp{ - +namespace hmp { HMP_DECLARE_DEVICE(kCPU); #ifdef HMP_ENABLE_CUDA HMP_DECLARE_DEVICE(kCUDA); #endif -Device::Device(Type type, Index index) - : type_(type), index_(index) -{ +Device::Device(Type type, Index index) : type_(type), index_(index) { HMP_REQUIRE(index >= 0, "invalid device index {} of {}", index, type); #ifndef HMP_BUILD_SHARED @@ -39,16 +36,13 @@ Device::Device(Type type, Index index) HMP_IMPORT_DEVICE(kCUDA); #endif #endif - } - -Device::Device(const std::string &devstr) -{ +Device::Device(const std::string &devstr) { auto cpos = devstr.find(":"); std::string_view dstr{devstr}; int index = 0; - if(cpos != std::string::npos){ + if (cpos != std::string::npos) { dstr = std::string_view(devstr.c_str(), cpos); const char *start = devstr.c_str() + cpos + 1; char *end = nullptr; @@ -56,132 +50,105 @@ Device::Device(const std::string &devstr) HMP_REQUIRE(start < end, "invalid device index in devstr '{}'", devstr); } - if(dstr == "cpu"){ + if (dstr == "cpu") { type_ = kCPU; - } - else if(dstr == "cuda"){ + } else if (dstr == "cuda") { type_ = kCUDA; - } - else{ + } else { HMP_REQUIRE(false, "invalid device string '{}'", devstr); } // auto count = device_count(type_); - HMP_REQUIRE(index < count, - "device index({}) is out of range({})", index, count); + HMP_REQUIRE(index < count, "device index({}) is out of range({})", index, + count); index_ = index; } -bool Device::operator==(const Device &other) const -{ +bool Device::operator==(const Device &other) const { return type_ == other.type() && index_ == other.index(); } - - -std::string stringfy(const Device &device) -{ - if(device.type() == kCPU){ +std::string stringfy(const Device &device) { + if (device.type() == kCPU) { return "cpu"; - } - else if(device.type() == kCUDA){ + } else if (device.type() == kCUDA) { return fmt::format("cuda:{}", device.index()); - } - else{ + } else { return "InvalidDevice"; } } - ///////// -namespace impl{ +namespace impl { -static DeviceManager *sDeviceManagers[static_cast(DeviceType::NumDeviceTypes)]; +static DeviceManager + *sDeviceManagers[static_cast(DeviceType::NumDeviceTypes)]; -void registerDeviceManager(DeviceType dtype, DeviceManager *dm) -{ - //as it only init before main, so no lock is needed - sDeviceManagers[static_cast(dtype)] = dm; +void registerDeviceManager(DeviceType dtype, DeviceManager *dm) { + // as it only init before main, so no lock is needed + sDeviceManagers[static_cast(dtype)] = dm; } //// -class CPUDeviceManager : public DeviceManager -{ +class CPUDeviceManager : public DeviceManager { static Device cpuDevice_; -public: - void setCurrent(const Device &) override - { - } - optional getCurrent() const override - { - return cpuDevice_; - } - int64_t count() const override - { - return 1; - } + public: + void setCurrent(const Device &) override {} + optional getCurrent() const override { return cpuDevice_; } + + int64_t count() const override { return 1; } }; Device CPUDeviceManager::cpuDevice_{}; static CPUDeviceManager sCPUDeviceManager; HMP_REGISTER_DEVICE_MANAGER(kCPU, &sCPUDeviceManager); -} //namespace impl +} // namespace impl - -optional current_device(DeviceType dtype) -{ +optional current_device(DeviceType dtype) { auto dm = impl::sDeviceManagers[static_cast(dtype)]; HMP_REQUIRE(dm, "Device type {} is not supported", dtype); return dm->getCurrent(); } -void set_current_device(const Device &device) -{ +void set_current_device(const Device &device) { auto dtype = device.type(); auto dm = impl::sDeviceManagers[static_cast(dtype)]; HMP_REQUIRE(dm, "Device type {} is not supported", dtype); dm->setCurrent(device); } -int64_t device_count(DeviceType dtype) -{ +int64_t device_count(DeviceType dtype) { auto dm = impl::sDeviceManagers[static_cast(dtype)]; - if(dm){ + if (dm) { return dm->count(); - } - else{ + } else { return 0; } } -DeviceGuard::DeviceGuard(const Device &device) -{ +DeviceGuard::DeviceGuard(const Device &device) { auto current = current_device(device.type()); - if (current != device){ + if (current != device) { set_current_device(device); origin_ = current; } } -DeviceGuard::DeviceGuard(DeviceGuard &&other) -{ +DeviceGuard::DeviceGuard(DeviceGuard &&other) { origin_ = other.origin_; other.origin_.reset(); } -DeviceGuard::~DeviceGuard() -{ - if(origin_){ +DeviceGuard::~DeviceGuard() { + if (origin_) { set_current_device(origin_.value()); } } // - - -} //namespace hmp \ No newline at end of file +} // namespace hmp \ No newline at end of file diff --git a/bmf/hml/src/core/logging.cpp b/bmf/hml/src/core/logging.cpp index 100d369b..25d13fb2 100644 --- a/bmf/hml/src/core/logging.cpp +++ b/bmf/hml/src/core/logging.cpp @@ -35,71 +35,67 @@ #include #include -#else +#else #include #include #endif //__android__ -namespace hmp { namespace logging{ +namespace hmp { +namespace logging { -class OStreamImpl : public StreamLogger::OStream -{ +class OStreamImpl : public StreamLogger::OStream { std::stringstream ss_; -public: - OStream& operator<<(const std::string &msg) override - { + + public: + OStream &operator<<(const std::string &msg) override { ss_ << msg; return *this; } - std::string str() - { - return ss_.str(); - } - + std::string str() { return ss_.str(); } }; - StreamLogger::StreamLogger(int level, const char *tag) - : level_(level), tag_(tag) -{ + : level_(level), tag_(tag) { os_ = new OStreamImpl(); } -StreamLogger::~StreamLogger() -{ - auto os = static_cast(os_); +StreamLogger::~StreamLogger() { + auto os = static_cast(os_); ::hmp::logging::_log(level_, tag_, os->str().c_str()); delete os_; } -StreamLogger::OStream& StreamLogger::stream() -{ - return *os_; -} +StreamLogger::OStream &StreamLogger::stream() { return *os_; } #ifdef __ANDROID__ -android_LogPriority to_android_priority(int level) -{ +android_LogPriority to_android_priority(int level) { android_LogPriority prio; - switch(level){ - case Level::trace: - prio = ANDROID_LOG_VERBOSE; break; - case Level::debug: - prio = ANDROID_LOG_DEBUG; break; - case Level::info: - prio = ANDROID_LOG_INFO; break; - case Level::warn: - prio = ANDROID_LOG_WARN; break; - case Level::err: - prio = ANDROID_LOG_ERROR; break; - case Level::fatal: - prio = ANDROID_LOG_FATAL; break; - case Level::off: - prio = ANDROID_LOG_SILENT; break; - default: - prio = ANDROID_LOG_UNKNOWN; + switch (level) { + case Level::trace: + prio = ANDROID_LOG_VERBOSE; + break; + case Level::debug: + prio = ANDROID_LOG_DEBUG; + break; + case Level::info: + prio = ANDROID_LOG_INFO; + break; + case Level::warn: + prio = ANDROID_LOG_WARN; + break; + case Level::err: + prio = ANDROID_LOG_ERROR; + break; + case Level::fatal: + prio = ANDROID_LOG_FATAL; + break; + case Level::off: + prio = ANDROID_LOG_SILENT; + break; + default: + prio = ANDROID_LOG_UNKNOWN; } return prio; } @@ -107,8 +103,7 @@ android_LogPriority to_android_priority(int level) #if __ANDROID_API__ < 30 static std::atomic _s_log_prio = ANDROID_LOG_DEFAULT; -int32_t __android_log_set_minimum_priority(android_LogPriority prio) -{ +int32_t __android_log_set_minimum_priority(android_LogPriority prio) { _s_log_prio = prio; return 0; } @@ -118,9 +113,7 @@ int32_t __android_log_set_minimum_priority(android_LogPriority prio) static std::atomic _s_log_prio = Level::info; #endif - -void set_level(int level) -{ +void set_level(int level) { #if defined(__ANDROID__) auto prio = to_android_priority(level); __android_log_set_minimum_priority(prio); @@ -131,46 +124,50 @@ void set_level(int level) #endif } -void set_format(const std::string &fmt) -{ +void set_format(const std::string &fmt) { #if !defined(__ANDROID__) && !defined(__APPLE__) spdlog::set_pattern(fmt); #endif } - -void _log(int level, const char* tag, const char *msg) -{ +void _log(int level, const char *tag, const char *msg) { #if defined(__ANDROID__) auto prio = to_android_priority(level); #if __ANDROID_API__ < 30 - if(prio >= _s_log_prio) + if (prio >= _s_log_prio) #endif - __android_log_write(prio, tag, msg); + __android_log_write(prio, tag, msg); #elif defined(__APPLE__) - if(level < _s_log_prio){ + if (level < _s_log_prio) { return; } const char *level_name = nullptr; - switch(level){ - case Level::trace: - level_name = "TRACE"; break; - case Level::debug: - level_name = "DEBUG"; break; - case Level::info: - level_name = "INFO"; break; - case Level::warn: - level_name = "WARN"; break; - case Level::err: - level_name = "ERROR"; break; - case Level::fatal: - level_name = "FATAL"; break; - case Level::off: - level_name = "OFF"; break; - default: - level_name = "UNKNOWN"; + switch (level) { + case Level::trace: + level_name = "TRACE"; + break; + case Level::debug: + level_name = "DEBUG"; + break; + case Level::info: + level_name = "INFO"; + break; + case Level::warn: + level_name = "WARN"; + break; + case Level::err: + level_name = "ERROR"; + break; + case Level::fatal: + level_name = "FATAL"; + break; + case Level::off: + level_name = "OFF"; + break; + default: + level_name = "UNKNOWN"; } // @@ -179,49 +176,44 @@ void _log(int level, const char* tag, const char *msg) time(&now); tm_now = localtime(&now); char time_str[128]; - if(tm_now != nullptr){ + if (tm_now != nullptr) { snprintf(time_str, sizeof(time_str), "%02d-%02d-%02d %02d:%02d:%02d", - tm_now->tm_year, tm_now->tm_mon, tm_now->tm_mday, tm_now->tm_hour, - tm_now->tm_min, tm_now->tm_sec); + tm_now->tm_year, tm_now->tm_mon, tm_now->tm_mday, + tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec); } // fprintf(stderr, "%s [%s][%s] %s\n", time_str, level_name, tag, msg); #else spdlog::default_logger_raw()->log(spdlog::source_loc{}, - (spdlog::level::level_enum)level, - msg); + (spdlog::level::level_enum)level, msg); #endif } - #if defined(__ANDROID__) || defined(__APPLE__) namespace { -//from stackoverflow -struct BacktraceState -{ - void** current; - void** end; +// from stackoverflow +struct BacktraceState { + void **current; + void **end; }; -static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg) -{ - BacktraceState* state = static_cast(arg); +static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context *context, + void *arg) { + BacktraceState *state = static_cast(arg); uintptr_t pc = _Unwind_GetIP(context); if (pc) { if (state->current == state->end) { return _URC_END_OF_STACK; } else { - *state->current++ = reinterpret_cast(pc); + *state->current++ = reinterpret_cast(pc); } } return _URC_NO_REASON; } - -size_t captureBacktrace(void** buffer, size_t max) -{ +size_t captureBacktrace(void **buffer, size_t max) { BacktraceState state = {buffer, buffer + max}; #if defined(__arm64__) _Unwind_Backtrace(unwindCallback, &state); @@ -229,27 +221,25 @@ size_t captureBacktrace(void** buffer, size_t max) return state.current - buffer; } -void dumpBacktrace(std::ostream& os, void** buffer, size_t count) -{ +void dumpBacktrace(std::ostream &os, void **buffer, size_t count) { for (size_t idx = 0; idx < count; ++idx) { - const void* addr = buffer[idx]; - const char* symbol = ""; + const void *addr = buffer[idx]; + const char *symbol = ""; Dl_info info; if (dladdr(addr, &info) && info.dli_sname) { symbol = info.dli_sname; } - os << " #" << std::setw(2) << idx << ": " << addr << " " << symbol << "\n"; + os << " #" << std::setw(2) << idx << ": " << addr << " " << symbol + << "\n"; } } -} //namespace +} // namespace - -void dump_stack_trace(int max) -{ - std::vector buffer(max); +void dump_stack_trace(int max) { + std::vector buffer(max); std::ostringstream oss; logging::dumpBacktrace(oss, buffer.data(), @@ -258,28 +248,27 @@ void dump_stack_trace(int max) HMP_WRN("{}", oss.str()); } -#else +#else -void dump_stack_trace(int max) -{ +void dump_stack_trace(int max) { using namespace backward; - StackTrace st; + StackTrace st; st.load_here(max); size_t depth_no_py = max; TraceResolver tr; tr.load_stacktrace(st); - for (size_t i = 0; i < st.size(); ++i){ + for (size_t i = 0; i < st.size(); ++i) { ResolvedTrace trace = tr.resolve(st[i]); - if(trace.object_function.substr(0, 3) == "_Py"){ + if (trace.object_function.substr(0, 3) == "_Py") { depth_no_py = i + 1; break; } } // - if(depth_no_py < max){ + if (depth_no_py < max) { std::cerr << "## Python Stack ignored" << std::endl; st.load_here(depth_no_py); } @@ -288,6 +277,5 @@ void dump_stack_trace(int max) } #endif - - -}} //namespace hmp::logging +} +} // namespace hmp::logging diff --git a/bmf/hml/src/core/ref_ptr.cpp b/bmf/hml/src/core/ref_ptr.cpp index c917712e..ec3c4813 100644 --- a/bmf/hml/src/core/ref_ptr.cpp +++ b/bmf/hml/src/core/ref_ptr.cpp @@ -15,18 +15,16 @@ */ #include -namespace hmp{ +namespace hmp { -RefObject::~RefObject() -{ +RefObject::~RefObject() { auto refcount = refcount_.load(); - //sanit check - if(refcount){ - HMP_ERR("RefObject: invalid state of RefObject {}, refcount={}", (void*)this, refcount); + // sanit check + if (refcount) { + HMP_ERR("RefObject: invalid state of RefObject {}, refcount={}", + (void *)this, refcount); } } - - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/core/stream.cpp b/bmf/hml/src/core/stream.cpp index 2a78964c..d403351a 100644 --- a/bmf/hml/src/core/stream.cpp +++ b/bmf/hml/src/core/stream.cpp @@ -16,7 +16,7 @@ #include #include -namespace hmp{ +namespace hmp { namespace { @@ -25,122 +25,90 @@ HMP_DECLARE_STREAM_MANAGER(kCPU); HMP_DECLARE_STREAM_MANAGER(kCUDA); #endif - const static Device sCPUDevice(kCPU); -//dummy cpu stream -class CPUStream : public StreamInterface -{ -public: - CPUStream() - { - } +// dummy cpu stream +class CPUStream : public StreamInterface { + public: + CPUStream() {} - CPUStream(uint64_t flags) - { - } + CPUStream(uint64_t flags) {} - ~CPUStream() - { - } + ~CPUStream() {} - const Device &device() const override - { - return sCPUDevice; - } + const Device &device() const override { return sCPUDevice; } - StreamHandle handle() const override - { - return 0; - } - - bool query() override - { - return true; - } + StreamHandle handle() const override { return 0; } - virtual void synchronize() override - { - } -}; + bool query() override { return true; } + virtual void synchronize() override {} +}; // -static thread_local RefPtr sCurrentStream; +static thread_local RefPtr sCurrentStream; -class CPUStreamManager : public impl::StreamManager -{ -public: - void setCurrent(const Stream& stream) override - { +class CPUStreamManager : public impl::StreamManager { + public: + void setCurrent(const Stream &stream) override { auto ref = stream.unsafeGet(); - auto cpuStream = dynamic_cast(ref.get()); + auto cpuStream = dynamic_cast(ref.get()); HMP_REQUIRE(cpuStream, "Invalid CPU stream"); sCurrentStream = ref.cast(); } - optional getCurrent() const override - { - if(!sCurrentStream){ - return Stream(makeRefPtr()); //get default stream by default - } - else{ + optional getCurrent() const override { + if (!sCurrentStream) { + return Stream( + makeRefPtr()); // get default stream by default + } else { return Stream(sCurrentStream); } } - Stream create(uint64_t flags = 0) override - { + Stream create(uint64_t flags = 0) override { return Stream(makeRefPtr(flags)); } - }; static CPUStreamManager sCPUStreamManager; HMP_REGISTER_STREAM_MANAGER(kCPU, &sCPUStreamManager); -} //namespace - - +} // namespace -namespace impl{ +namespace impl { -static StreamManager *sStreamManagers[static_cast(DeviceType::NumDeviceTypes)]; +static StreamManager + *sStreamManagers[static_cast(DeviceType::NumDeviceTypes)]; -void registerStreamManager(DeviceType dtype, StreamManager *sm) -{ - //as it only init before main, so no lock is needed - sStreamManagers[static_cast(dtype)] = sm; +void registerStreamManager(DeviceType dtype, StreamManager *sm) { + // as it only init before main, so no lock is needed + sStreamManagers[static_cast(dtype)] = sm; } -} //namespace impl +} // namespace impl - -std::string stringfy(const Stream &stream) -{ - return fmt::format("Stream({}, {})", - stringfy(stream.device()), stream.handle()); +std::string stringfy(const Stream &stream) { + return fmt::format("Stream({}, {})", stringfy(stream.device()), + stream.handle()); } -optional current_stream(DeviceType dtype) -{ +optional current_stream(DeviceType dtype) { auto sm = impl::sStreamManagers[static_cast(dtype)]; HMP_REQUIRE(sm, "Stream on device type {} is not supported", dtype); return sm->getCurrent(); } -void set_current_stream(const Stream &stream) -{ +void set_current_stream(const Stream &stream) { auto dtype = stream.device().type(); auto sm = impl::sStreamManagers[static_cast(dtype)]; HMP_REQUIRE(sm, "Stream on device type {} is not supported", dtype); sm->setCurrent(stream); } -Stream create_stream(DeviceType dtype, uint64_t flags) -{ +Stream create_stream(DeviceType dtype, uint64_t flags) { #ifndef HMP_BUILD_SHARED HMP_IMPORT_STREAM_MANAGER(kCPU); #ifdef HMP_ENABLE_CUDA @@ -148,35 +116,29 @@ Stream create_stream(DeviceType dtype, uint64_t flags) #endif #endif - auto sm = impl::sStreamManagers[static_cast(dtype)]; HMP_REQUIRE(sm, "Stream on device type {} is not supported", dtype); return sm->create(flags); } -StreamGuard::StreamGuard(const Stream& stream) -{ +StreamGuard::StreamGuard(const Stream &stream) { auto dtype = stream.device().type(); auto current = current_stream(dtype); - if(current != stream){ + if (current != stream) { set_current_stream(stream); } origin_ = current; } - -StreamGuard::StreamGuard(StreamGuard &&other) -{ +StreamGuard::StreamGuard(StreamGuard &&other) { origin_ = other.origin_; other.origin_.reset(); } -StreamGuard::~StreamGuard() -{ - if(origin_){ +StreamGuard::~StreamGuard() { + if (origin_) { set_current_stream(origin_.value()); } } - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/core/tensor_info.cpp b/bmf/hml/src/core/tensor_info.cpp index 7c1af690..0af410f6 100644 --- a/bmf/hml/src/core/tensor_info.cpp +++ b/bmf/hml/src/core/tensor_info.cpp @@ -16,53 +16,51 @@ #include #include -namespace hmp{ +namespace hmp { - -TensorInfo::TensorInfo(const Buffer &buffer, const SizeArray &shape, int64_t bufferOffset) -{ +TensorInfo::TensorInfo(const Buffer &buffer, const SizeArray &shape, + int64_t bufferOffset) { buffer_ = buffer; setSizesAndStrides(shape, bufferOffset); } -TensorInfo::TensorInfo(const Buffer &buffer, const SizeArray &shape, const SizeArray &strides, int64_t bufferOffset) -{ +TensorInfo::TensorInfo(const Buffer &buffer, const SizeArray &shape, + const SizeArray &strides, int64_t bufferOffset) { buffer_ = buffer; setSizesAndStrides(shape, strides, bufferOffset); } - -void TensorInfo::setSizesAndStrides(const SizeArray &shape, int64_t bufferOffset) -{ +void TensorInfo::setSizesAndStrides(const SizeArray &shape, + int64_t bufferOffset) { auto strides = calcContiguousStrides(shape); setSizesAndStrides(shape, strides, bufferOffset); } -void TensorInfo::setSizesAndStrides(const SizeArray &shape, const SizeArray &strides, int64_t bufferOffset) -{ +void TensorInfo::setSizesAndStrides(const SizeArray &shape, + const SizeArray &strides, + int64_t bufferOffset) { HMP_REQUIRE(shape.size() == strides.size(), - "Invalid size of shape({}) and strides({}) are not matched", shape.size(), strides.size()); + "Invalid size of shape({}) and strides({}) are not matched", + shape.size(), strides.size()); HMP_REQUIRE(bufferOffset >= 0, "Invalid bufferOffset = {}", bufferOffset); HMP_REQUIRE(buffer_.defined(), "Buffer is not defined"); - //NOTE: we won't check if shape and strides are out of range + // NOTE: we won't check if shape and strides are out of range bufferOffset_ = bufferOffset; shape_ = shape; strides_ = strides; nitems_ = calcNumel(shape); } - -bool TensorInfo::is_contiguous() const -{ +bool TensorInfo::is_contiguous() const { auto cStrides = calcContiguousStrides(shape_); - for(size_t i = 0; i < cStrides.size(); ++i){ - if(cStrides[i] != strides_[i]){ + for (size_t i = 0; i < cStrides.size(); ++i) { + if (cStrides[i] != strides_[i]) { return false; } } - + return true; } -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/core/timer.cpp b/bmf/hml/src/core/timer.cpp index a9b75ecb..a6fc48e8 100644 --- a/bmf/hml/src/core/timer.cpp +++ b/bmf/hml/src/core/timer.cpp @@ -17,92 +17,76 @@ #include #include -namespace hmp{ +namespace hmp { -namespace impl{ +namespace impl { -static TimerManager *sTimerManagers[static_cast(DeviceType::NumDeviceTypes)]; +static TimerManager + *sTimerManagers[static_cast(DeviceType::NumDeviceTypes)]; -void registerTimerManager(DeviceType dtype, TimerManager *tm) -{ - //as it only init before main, so no lock is needed - sTimerManagers[static_cast(dtype)] = tm; +void registerTimerManager(DeviceType dtype, TimerManager *tm) { + // as it only init before main, so no lock is needed + sTimerManagers[static_cast(dtype)] = tm; } -} //namespace impl +} // namespace impl - -std::string stringfy(const Timer &timer) -{ +std::string stringfy(const Timer &timer) { return fmt::format("Timer({}, {})", timer.device(), timer.is_stopped()); } -Timer create_timer(DeviceType dtype) -{ +Timer create_timer(DeviceType dtype) { auto tm = impl::sTimerManagers[static_cast(dtype)]; HMP_REQUIRE(tm, "Timer on device type {} is not supported", dtype); return tm->create(); } - ////// namespace { const static Device sCPUDevice(kCPU); -class CPUTimer : public TimerInterface -{ - using TimePoint = decltype(std::chrono::high_resolution_clock::now()); +class CPUTimer : public TimerInterface { + using TimePoint = decltype(std::chrono::high_resolution_clock::now()); TimePoint begin_, end_; int state_ = -1; // -1 - not inited, 0 - stopped, 1 - started -public: - void start() override - { + public: + void start() override { begin_ = std::chrono::high_resolution_clock::now(); state_ = 1; } - void stop() override - { + void stop() override { HMP_REQUIRE(state_ == 1, "CPUTimer is not started"); end_ = std::chrono::high_resolution_clock::now(); state_ = 0; } - double elapsed() override - { + double elapsed() override { TimePoint end = end_; - if(state_ != 0){ + if (state_ != 0) { HMP_REQUIRE(state_ == 1, "CPUTimer is not inited"); end = std::chrono::high_resolution_clock::now(); } - return std::chrono::duration_cast(end - begin_).count()/1e9; + return std::chrono::duration_cast(end - + begin_) + .count() / + 1e9; } - bool is_stopped() const override - { - return state_ == 0 || state_ == -1; - } + bool is_stopped() const override { return state_ == 0 || state_ == -1; } - const Device& device() const override - { - return sCPUDevice; - } + const Device &device() const override { return sCPUDevice; } }; -class CPUTimerManager : public impl::TimerManager -{ -public: - RefPtr create() override - { - return makeRefPtr(); - } +class CPUTimerManager : public impl::TimerManager { + public: + RefPtr create() override { return makeRefPtr(); } }; - static CPUTimerManager scpuTimerManager; HMP_REGISTER_TIMER_MANAGER(kCPU, &scpuTimerManager); -} //namespace +} // namespace -} //namespace hmp +} // namespace hmp diff --git a/bmf/hml/src/cuda/cuda_allocator.cpp b/bmf/hml/src/cuda/cuda_allocator.cpp index 44722069..10f51087 100644 --- a/bmf/hml/src/cuda/cuda_allocator.cpp +++ b/bmf/hml/src/cuda/cuda_allocator.cpp @@ -25,59 +25,50 @@ #include #include -namespace hmp{ -namespace cuda{ +namespace hmp { +namespace cuda { namespace { +constexpr size_t kMinBlockSize = + 512; // all sizes are rounded to at least 512 bytes +constexpr size_t kSmallSize = 1048576; // largest "small" allocation is 1 MiB +constexpr size_t kSmallBuffer = + 2097152; // "small" allocations are packed in 2 MiB blocks +constexpr size_t kLargeBuffer = + 20971520; // "large" allocations may be packed in 20 MiB blocks +constexpr size_t kMinLargeAlloc = + 10485760; // allocations between 1 and 10 MiB may use kLargeBuffer +constexpr size_t kRoundLarge = 2097152; // round up large allocs to 2 MiB -constexpr size_t kMinBlockSize = 512; // all sizes are rounded to at least 512 bytes -constexpr size_t kSmallSize = 1048576; // largest "small" allocation is 1 MiB -constexpr size_t kSmallBuffer = 2097152; // "small" allocations are packed in 2 MiB blocks -constexpr size_t kLargeBuffer = 20971520; // "large" allocations may be packed in 20 MiB blocks -constexpr size_t kMinLargeAlloc = 10485760; // allocations between 1 and 10 MiB may use kLargeBuffer -constexpr size_t kRoundLarge = 2097152; // round up large allocs to 2 MiB - - -void update_stat(MemoryStat& stat, int64_t size) -{ +void update_stat(MemoryStat &stat, int64_t size) { stat.current += size; - HMP_REQUIRE(stat.current >= 0, "Negtive amount of memory detected {} {}", stat.current, size); + HMP_REQUIRE(stat.current >= 0, "Negtive amount of memory detected {} {}", + stat.current, size); stat.peak = std::max(stat.current, stat.peak); - if(size > 0){ + if (size > 0) { stat.allocated += size; - } - else{ + } else { stat.freed -= size; } } - -using MallocFunc = cudaError_t(*)(void**, size_t); -using FreeFunc = cudaError_t(*)(void*); +using MallocFunc = cudaError_t (*)(void **, size_t); +using FreeFunc = cudaError_t (*)(void *); struct Block; -using BlockComparison = bool(*)(const Block*, const Block*); -using BlockPool = std::set; +using BlockComparison = bool (*)(const Block *, const Block *); +using BlockPool = std::set; +struct Block { + Block(int64_t size_) : size(size_) {} -struct Block{ - Block(int64_t size_) - : size(size_) - { - } - - Block(int device_, int64_t size_, void* ptr_, BlockPool *pool_) - : device(device_), size(size_), ptr(ptr_), pool(pool_) - { - } + Block(int device_, int64_t size_, void *ptr_, BlockPool *pool_) + : device(device_), size(size_), ptr(ptr_), pool(pool_) {} - bool is_split() const - { - return (prev != nullptr) || (next != nullptr); - } + bool is_split() const { return (prev != nullptr) || (next != nullptr); } int device = 0; int event_count = 0; @@ -91,59 +82,55 @@ struct Block{ std::set streams; }; - -static bool block_comparator(const Block *a, const Block *b) -{ - if(a->size != b->size){ +static bool block_comparator(const Block *a, const Block *b) { + if (a->size != b->size) { return a->size < b->size; } return a->ptr < b->ptr; } -class CUDAAllocator : public Allocator -{ +class CUDAAllocator : public Allocator { DeviceMemoryStats stats_; mutable std::recursive_mutex mutex_; BlockPool small_blocks_; BlockPool large_blocks_; - std::unordered_map alloced_; - std::deque> freed_; + std::unordered_map alloced_; + std::deque> freed_; // MallocFunc malloc_; FreeFunc free_; DeviceType device_type_; int device_index_; -public: + + public: CUDAAllocator() = delete; - CUDAAllocator(DeviceType device, int index, MallocFunc malloc, FreeFunc free) - : small_blocks_(block_comparator), large_blocks_(block_comparator) - { + CUDAAllocator(DeviceType device, int index, MallocFunc malloc, + FreeFunc free) + : small_blocks_(block_comparator), large_blocks_(block_comparator) { malloc_ = malloc; free_ = free; device_type_ = device; device_index_ = index; } - DataPtr do_split(Block *block, int64_t size) - { + DataPtr do_split(Block *block, int64_t size) { std::lock_guard l(mutex_); HMP_REQUIRE(block, "CUDAAllocator: Internal error"); - //split if possible + // split if possible auto &pool = *block->pool; Block *remaining = nullptr; - if (should_split(block, size)){ + if (should_split(block, size)) { remaining = block; block = new Block(device_index_, size, block->ptr, block->pool); block->prev = remaining->prev; - if (block->prev) - { + if (block->prev) { block->prev->next = block; } block->next = remaining; @@ -157,13 +144,13 @@ class CUDAAllocator : public Allocator auto stream = reinterpret_cast( current_stream(kCUDA).value().handle()); - block->streams.insert(stream); //FIXME: take care of ptr used in multiple streams, now we only support current stream + block->streams.insert(stream); // FIXME: take care of ptr used in + // multiple streams, now we only support + // current stream block->allocated = true; alloced_[block->ptr] = block; - auto dptr = DataPtr( - block->ptr, [=](void *ptr) - { this->free(ptr); }, - Device(device_type_, device_index_)); + auto dptr = DataPtr(block->ptr, [=](void *ptr) { this->free(ptr); }, + Device(device_type_, device_index_)); update_stat(stats_.active, block->size); update_stat(stats_.segment, 1); @@ -171,22 +158,21 @@ class CUDAAllocator : public Allocator return dptr; } - DataPtr alloc(int64_t size) override - { + DataPtr alloc(int64_t size) override { process_events(); - //try alloc in pool + // try alloc in pool Block *block = nullptr; size = round_size(size); - auto& pool = get_pool(size); + auto &pool = get_pool(size); { std::lock_guard l(mutex_); Block search_key(size); - auto find_free_block = [&](){ + auto find_free_block = [&]() { Block *block = nullptr; auto it = pool.lower_bound(&search_key); - if(it != pool.end()){ + if (it != pool.end()) { block = *it; pool.erase(it); } @@ -194,7 +180,7 @@ class CUDAAllocator : public Allocator }; block = find_free_block(); - if(block != nullptr){ + if (block != nullptr) { return do_split(block, size); } } @@ -209,14 +195,14 @@ class CUDAAllocator : public Allocator return do_split(block, size); } - void free(void *ptr) - { + void free(void *ptr) { std::lock_guard l(mutex_); auto it = alloced_.find(ptr); HMP_REQUIRE(it != alloced_.end(), "CUDAAllocator: free unknown ptr!!"); // - for(auto sit = it->second->streams.begin(); sit != it->second->streams.end(); ++sit){ + for (auto sit = it->second->streams.begin(); + sit != it->second->streams.end(); ++sit) { cudaEvent_t event; HMP_CUDA_CHECK(cudaEventCreate(&event)); cudaEventRecord(event, *sit); @@ -229,51 +215,49 @@ class CUDAAllocator : public Allocator update_stat(stats_.active, -it->second->size); - if(it->second->event_count == 0){ + if (it->second->event_count == 0) { free_block(it->second); - } - else{ + } else { update_stat(stats_.inactive, it->second->size); } process_events(); } - void free_block(Block *block) - { + void free_block(Block *block) { HMP_REQUIRE(block->event_count == 0, "CUDAAllocator: internal error"); // std::lock_guard l(mutex_); auto &pool = *block->pool; - //merge block aggressively - while(try_merge_blocks(block, block->prev, pool) > 0); - while(try_merge_blocks(block, block->next, pool) > 0); + // merge block aggressively + while (try_merge_blocks(block, block->prev, pool) > 0) + ; + while (try_merge_blocks(block, block->next, pool) > 0) + ; pool.insert(block); update_stat(stats_.segment, -1); } - void process_events() - { + void process_events() { std::lock_guard l(mutex_); - while(!freed_.empty()){ + while (!freed_.empty()) { cudaEvent_t event = freed_.front().first; auto block = freed_.front().second; auto err = cudaEventQuery(event); - if(err == cudaErrorNotReady){ + if (err == cudaErrorNotReady) { cudaGetLastError(); break; - } - else{ + } else { HMP_CUDA_CHECK(err); HMP_CUDA_CHECK(cudaEventDestroy(event)); block->event_count -= 1; - if(block->event_count == 0){ + if (block->event_count == 0) { auto block_size = block->size; free_block(block); update_stat(stats_.inactive, -block_size); @@ -284,19 +268,17 @@ class CUDAAllocator : public Allocator } } - DeviceMemoryStats stats() - { + DeviceMemoryStats stats() { std::lock_guard l(mutex_); process_events(); return stats_; } // - cudaError_t cuda_malloc_with_retry(void **ptr, size_t size) - { + cudaError_t cuda_malloc_with_retry(void **ptr, size_t size) { auto rc = malloc_(ptr, size); - if(rc != cudaSuccess){ - cudaGetLastError(); // reset the last CUDA error + if (rc != cudaSuccess) { + cudaGetLastError(); // reset the last CUDA error { std::lock_guard l(mutex_); free_blocks(small_blocks_); @@ -309,45 +291,41 @@ class CUDAAllocator : public Allocator return rc; } - void free_blocks(BlockPool &blocks) - { - //free all non-split cached blocks + void free_blocks(BlockPool &blocks) { + // free all non-split cached blocks auto it = blocks.begin(); - while(it != blocks.end()){ + while (it != blocks.end()) { auto block = *it; - if(!block->is_split()){ + if (!block->is_split()) { HMP_CUDA_CHECK(free_(block->ptr)); - + auto cur = it; ++it; blocks.erase(cur); delete block; - } - else{ + } else { ++it; } } } - - size_t try_merge_blocks(Block *dst, Block *src, BlockPool &pool) - { - if (!src || src->allocated || src->event_count > 0){ + size_t try_merge_blocks(Block *dst, Block *src, BlockPool &pool) { + if (!src || src->allocated || src->event_count > 0) { return 0; } - HMP_REQUIRE(dst->is_split() && src->is_split(), "CUDAAllocator: internal error"); + HMP_REQUIRE(dst->is_split() && src->is_split(), + "CUDAAllocator: internal error"); - if (dst->prev == src){ + if (dst->prev == src) { dst->ptr = src->ptr; dst->prev = src->prev; - if (dst->prev){ + if (dst->prev) { dst->prev->next = dst; } - } - else{ + } else { dst->next = src->next; - if (dst->next){ + if (dst->next) { dst->next->prev = dst; } } @@ -360,118 +338,101 @@ class CUDAAllocator : public Allocator return subsumed_size; } - bool should_split(const Block *block, size_t size) - { + bool should_split(const Block *block, size_t size) { size_t remaining = block->size - size; - if (block->pool == &small_blocks_){ + if (block->pool == &small_blocks_) { return remaining >= kMinBlockSize; - } - else if (block->pool == &large_blocks_){ + } else if (block->pool == &large_blocks_) { return remaining > kSmallSize; - } - else{ + } else { HMP_REQUIRE(false, "Internal error"); } } - BlockPool &get_pool(size_t size) - { - if (size <= kSmallSize){ + BlockPool &get_pool(size_t size) { + if (size <= kSmallSize) { return small_blocks_; - } - else{ + } else { return large_blocks_; } } - size_t round_size(size_t size) - { - if (size < kMinBlockSize){ + size_t round_size(size_t size) { + if (size < kMinBlockSize) { return kMinBlockSize; - } - else{ + } else { return kMinBlockSize * ((size + kMinBlockSize - 1) / kMinBlockSize); } } - size_t get_allocation_size(size_t size) - { - if (size <= kSmallSize){ + size_t get_allocation_size(size_t size) { + if (size <= kSmallSize) { return kSmallBuffer; - } - else if (size < kMinLargeAlloc){ + } else if (size < kMinLargeAlloc) { return kLargeBuffer; - } - else{ + } else { return kRoundLarge * ((size + kRoundLarge - 1) / kRoundLarge); } } }; - -class CUDADeviceAllocator : public Allocator -{ +class CUDADeviceAllocator : public Allocator { std::vector> allocators_; -public: - CUDADeviceAllocator() - { + + public: + CUDADeviceAllocator() { int count = 0; - try{ + try { HMP_CUDA_CHECK(cudaGetDeviceCount(&count)); - } - catch(std::exception &e){ + } catch (std::exception &e) { HMP_WRN("cudaGetDeviceCount failed, {}", e.what()); } allocators_.resize(count); - for(int i = 0; i < count; ++i){ + for (int i = 0; i < count; ++i) { allocators_[i] = std::unique_ptr( new CUDAAllocator(kCUDA, i, &cudaMalloc, &cudaFree)); } } - DataPtr alloc(int64_t size) override - { + DataPtr alloc(int64_t size) override { int device; HMP_CUDA_CHECK(cudaGetDevice(&device)); - HMP_REQUIRE(device < allocators_.size(), - "device index {} is out of range {}", device, allocators_.size()); + HMP_REQUIRE(device < allocators_.size(), + "device index {} is out of range {}", device, + allocators_.size()); return allocators_.at(device)->alloc(size); } - DeviceMemoryStats stats(int device) - { - HMP_REQUIRE(device < allocators_.size(), - "device index {} is out of range {}", device, allocators_.size()); + DeviceMemoryStats stats(int device) { + HMP_REQUIRE(device < allocators_.size(), + "device index {} is out of range {}", device, + allocators_.size()); return allocators_.at(device)->stats(); } }; - static CUDADeviceAllocator sDefaultCUDAAllocator; -static CUDAAllocator sDefaultCPUAllocator(kCPU, 0, &cudaMallocHost, &cudaFreeHost); - +static CUDAAllocator sDefaultCPUAllocator(kCPU, 0, &cudaMallocHost, + &cudaFreeHost); -} //namespace +} // namespace HMP_REGISTER_ALLOCATOR(kCUDA, &sDefaultCUDAAllocator, 0); -HMP_REGISTER_ALLOCATOR(kCPU, &sDefaultCPUAllocator, 1); //pinned +HMP_REGISTER_ALLOCATOR(kCPU, &sDefaultCPUAllocator, 1); // pinned - -DeviceMemoryStats device_memory_stats(int device) -{ +DeviceMemoryStats device_memory_stats(int device) { return sDefaultCUDAAllocator.stats(device); } -DeviceMemoryStats host_memory_stats() -{ - return sDefaultCPUAllocator.stats(); -} +DeviceMemoryStats host_memory_stats() { return sDefaultCPUAllocator.stats(); } -int d2d_memcpy(void* dst, size_t dpitch, const void* src, size_t spitch, size_t width, size_t height){ - cudaMemcpy2D(dst, dpitch, src, spitch, width, height, cudaMemcpyDeviceToDevice); +int d2d_memcpy(void *dst, size_t dpitch, const void *src, size_t spitch, + size_t width, size_t height) { + cudaMemcpy2D(dst, dpitch, src, spitch, width, height, + cudaMemcpyDeviceToDevice); return 0; } - -}} //namespace \ No newline at end of file +} +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/cuda/device.cpp b/bmf/hml/src/cuda/device.cpp index 3bd3dbc4..4b6bf399 100644 --- a/bmf/hml/src/cuda/device.cpp +++ b/bmf/hml/src/cuda/device.cpp @@ -21,19 +21,13 @@ #include #include -namespace hmp{ -namespace cuda{ +namespace hmp { +namespace cuda { - -class CUDADeviceManager : public impl::DeviceManager -{ -public: - CUDADeviceManager() - { - initContext(); - } - static void initContext() - { +class CUDADeviceManager : public impl::DeviceManager { + public: + CUDADeviceManager() { initContext(); } + static void initContext() { cuInit(0); CUdevice device; const unsigned int flags = CU_CTX_SCHED_BLOCKING_SYNC; @@ -41,26 +35,24 @@ class CUDADeviceManager : public impl::DeviceManager HMP_CUDA_CHECK(cudaGetDeviceCount(&count)); for (int idx = 0; idx < count; idx++) { auto ret = cuDeviceGet(&device, idx); - HMP_REQUIRE(ret == CUDA_SUCCESS, "get CUdevice {} failed={}", idx, ret); + HMP_REQUIRE(ret == CUDA_SUCCESS, "get CUdevice {} failed={}", idx, + ret); ret = cuDevicePrimaryCtxSetFlags(device, flags); - HMP_REQUIRE(ret == CUDA_SUCCESS, "set device {} primary ctx flags failed={}", idx, ret); + HMP_REQUIRE(ret == CUDA_SUCCESS, + "set device {} primary ctx flags failed={}", idx, ret); } return; } - void setCurrent(const Device &dev) override - { + void setCurrent(const Device &dev) override { HMP_CUDA_CHECK(cudaSetDevice(dev.index())); - } - optional getCurrent() const override - { + optional getCurrent() const override { int index = 0; HMP_CUDA_CHECK(cudaGetDevice(&index)); return Device(kCUDA, index); } - int64_t count() const - { + int64_t count() const { int count = 0; HMP_CUDA_CHECK(cudaGetDeviceCount(&count)); return count; @@ -70,19 +62,19 @@ class CUDADeviceManager : public impl::DeviceManager static CUDADeviceManager sCUDADeviceManager; HMP_REGISTER_DEVICE_MANAGER(kCUDA, &sCUDADeviceManager); -static const cudaDeviceProp &get_device_prop(int device) -{ +static const cudaDeviceProp &get_device_prop(int device) { static cudaDeviceProp sProps[MaxDevices]; - static cudaDeviceProp* sPProps[MaxDevices]; + static cudaDeviceProp *sPProps[MaxDevices]; static std::mutex sPropsLock; - HMP_REQUIRE(device < MaxDevices, - "{} is exceed cuda::MaxDevices limitation {}", device, MaxDevices); + HMP_REQUIRE(device < MaxDevices, + "{} is exceed cuda::MaxDevices limitation {}", device, + MaxDevices); - if(sPProps[device] == nullptr){ + if (sPProps[device] == nullptr) { std::lock_guard l(sPropsLock); - if(sPProps[device] == nullptr){ - HMP_CUDA_CHECK(cudaGetDeviceProperties(sProps+device, device)); + if (sPProps[device] == nullptr) { + HMP_CUDA_CHECK(cudaGetDeviceProperties(sProps + device, device)); sPProps[device] = sProps + device; } } @@ -90,17 +82,12 @@ static const cudaDeviceProp &get_device_prop(int device) return *sPProps[device]; } - -int64_t DeviceProp::texture_pitch_alignment() -{ +int64_t DeviceProp::texture_pitch_alignment() { int device; HMP_CUDA_CHECK(cudaGetDevice(&device)); auto &prop = get_device_prop(device); return prop.texturePitchAlignment; } - - - - -}} //namespace +} +} // namespace diff --git a/bmf/hml/src/cuda/event.cpp b/bmf/hml/src/cuda/event.cpp index f85d9857..44db3ff0 100644 --- a/bmf/hml/src/cuda/event.cpp +++ b/bmf/hml/src/cuda/event.cpp @@ -16,16 +16,12 @@ #include #include -namespace hmp{ -namespace cuda{ +namespace hmp { +namespace cuda { -Event::Event() - : Event(false, true, false) -{ -} +Event::Event() : Event(false, true, false) {} -Event::Event(Event &&other) -{ +Event::Event(Event &&other) { event_ = other.event_; flags_ = other.flags_; is_created_ = other.is_created_; @@ -36,36 +32,33 @@ Event::Event(Event &&other) other.is_created_ = false; } - -Event::Event(bool enable_timing, bool blocking, bool interprocess) -{ +Event::Event(bool enable_timing, bool blocking, bool interprocess) { event_ = 0; is_created_ = false; device_index_ = -1; flags_ = 0; - if (!enable_timing){ + if (!enable_timing) { flags_ |= (unsigned int)cudaEventDisableTiming; } - if (blocking){ + if (blocking) { flags_ |= (unsigned int)cudaEventBlockingSync; } - if (interprocess){ + if (interprocess) { flags_ |= (unsigned int)cudaEventInterprocess; } } -Event::~Event() -{ - if(is_created_){ - HMP_CUDA_CHECK_WRN(cudaEventDestroy(reinterpret_cast(event_))); +Event::~Event() { + if (is_created_) { + HMP_CUDA_CHECK_WRN( + cudaEventDestroy(reinterpret_cast(event_))); } } -void Event::record(const optional &stream_) -{ +void Event::record(const optional &stream_) { auto stream = stream_.value_or(current_stream(kCUDA).value()); - if(!is_created_){ + if (!is_created_) { cudaEvent_t event; HMP_CUDA_CHECK(cudaEventCreateWithFlags(&event, flags_)); is_created_ = true; @@ -73,59 +66,54 @@ void Event::record(const optional &stream_) event_ = event; } - HMP_REQUIRE(device_index_ == stream.device().index(), + HMP_REQUIRE( + device_index_ == stream.device().index(), "Event is create on {} dose not match recording stream's device {}", device_index_, stream.device().index()); - HMP_CUDA_CHECK(cudaEventRecord( - reinterpret_cast(event_), - reinterpret_cast(stream.handle()))); + HMP_CUDA_CHECK( + cudaEventRecord(reinterpret_cast(event_), + reinterpret_cast(stream.handle()))); } -void Event::block(const optional &stream_) -{ +void Event::block(const optional &stream_) { auto stream = stream_.value_or(current_stream(kCUDA).value()); - if(is_created_){ - auto err = cudaStreamWaitEvent( - reinterpret_cast(stream.handle()), - reinterpret_cast(event_), 0); + if (is_created_) { + auto err = + cudaStreamWaitEvent(reinterpret_cast(stream.handle()), + reinterpret_cast(event_), 0); HMP_CUDA_CHECK(err); } } - -bool Event::query() const -{ - if(!is_created_){ +bool Event::query() const { + if (!is_created_) { return true; } auto err = cudaEventQuery(reinterpret_cast(event_)); - if(err == cudaSuccess){ + if (err == cudaSuccess) { return true; - } - else if(err != cudaErrorNotReady){ + } else if (err != cudaErrorNotReady) { HMP_CUDA_CHECK(err); } return false; } -void Event::synchronize() const -{ - if(is_created_){ - HMP_CUDA_CHECK(cudaEventSynchronize(reinterpret_cast(event_))); +void Event::synchronize() const { + if (is_created_) { + HMP_CUDA_CHECK( + cudaEventSynchronize(reinterpret_cast(event_))); } } -float Event::elapsed(const Event &other) -{ +float Event::elapsed(const Event &other) { HMP_REQUIRE(is_created() && other.is_created(), - "Event: Both events need be created"); + "Event: Both events need be created"); float ms = 0; - HMP_CUDA_CHECK(cudaEventElapsedTime(&ms, - reinterpret_cast(event_), - reinterpret_cast(other.event_))); + HMP_CUDA_CHECK( + cudaEventElapsedTime(&ms, reinterpret_cast(event_), + reinterpret_cast(other.event_))); return ms; } - - -}} //namespace \ No newline at end of file +} +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/cuda/stream.cpp b/bmf/hml/src/cuda/stream.cpp index 5d828b58..651d1622 100644 --- a/bmf/hml/src/cuda/stream.cpp +++ b/bmf/hml/src/cuda/stream.cpp @@ -22,27 +22,26 @@ #include #include -namespace hmp{ -namespace cuda{ +namespace hmp { +namespace cuda { -class CUDAStreamCache -{ +class CUDAStreamCache { std::mutex mutex_; std::deque streamCache_[MaxDevices]; -public: - cudaStream_t create(int device) - { + + public: + cudaStream_t create(int device) { std::lock_guard l(mutex_); HMP_REQUIRE(device < MaxDevices, - "CUDAStreamCache: device index({}) is out of range {}", device, MaxDevices); + "CUDAStreamCache: device index({}) is out of range {}", + device, MaxDevices); cudaStream_t stream = 0; auto &cache = streamCache_[device]; - if(!cache.empty()){ + if (!cache.empty()) { stream = cache.back(); cache.pop_back(); - } - else{ + } else { int oldDevice; HMP_CUDA_CHECK(cudaGetDevice(&oldDevice)); HMP_CUDA_CHECK(cudaSetDevice(device)); @@ -53,10 +52,10 @@ class CUDAStreamCache return stream; } - void destroy(cudaStream_t stream, int device) - { + void destroy(cudaStream_t stream, int device) { HMP_REQUIRE(device < MaxDevices, - "CUDAStreamCache: device index({}) is out of range {}", device, MaxDevices); + "CUDAStreamCache: device index({}) is out of range {}", + device, MaxDevices); HMP_CUDA_CHECK(cudaStreamSynchronize(stream)); // std::lock_guard l(mutex_); @@ -64,113 +63,96 @@ class CUDAStreamCache } }; - -static CUDAStreamCache &streamCache() -{ +static CUDAStreamCache &streamCache() { static CUDAStreamCache scache; return scache; } - - -class CUDAStream : public StreamInterface -{ +class CUDAStream : public StreamInterface { Device device_; cudaStream_t stream_; bool own_; -public: - CUDAStream() : own_(false), stream_(0) //default stream + + public: + CUDAStream() + : own_(false), stream_(0) // default stream { auto device = current_device(kCUDA); HMP_REQUIRE(device, "No CUDA device have been selected"); device_ = device.value(); } - CUDAStream(cudaStream_t stream, bool own) : own_(own), stream_(stream) //default stream + CUDAStream(cudaStream_t stream, bool own) + : own_(own), stream_(stream) // default stream { auto device = current_device(kCUDA); HMP_REQUIRE(device, "No CUDA device have been selected"); device_ = device.value(); } - CUDAStream(uint64_t flags) - : CUDAStream() - { + CUDAStream(uint64_t flags) : CUDAStream() { stream_ = streamCache().create(device_.index()); own_ = true; } - ~CUDAStream() - { - //do not destroy stream, as it may used in allocator - if(stream_ != 0 && own_){ + ~CUDAStream() { + // do not destroy stream, as it may used in allocator + if (stream_ != 0 && own_) { streamCache().destroy(stream_, device_.index()); } } - const Device &device() const override - { - return device_; - } + const Device &device() const override { return device_; } - StreamHandle handle() const override - { - static_assert(sizeof(StreamHandle) >= sizeof(cudaStream_t), "invalid size of cudaStream_t"); + StreamHandle handle() const override { + static_assert(sizeof(StreamHandle) >= sizeof(cudaStream_t), + "invalid size of cudaStream_t"); return reinterpret_cast(stream_); } - bool query() override - { + bool query() override { auto rc = cudaStreamQuery(stream_); return rc == cudaSuccess; } - virtual void synchronize() override - { + virtual void synchronize() override { HMP_CUDA_CHECK(cudaStreamSynchronize(stream_)); } -}; - +}; -HMP_API Stream wrap_stream(StreamHandle stream, bool own) -{ +HMP_API Stream wrap_stream(StreamHandle stream, bool own) { return Stream(makeRefPtr(cudaStream_t(stream), own)); } // -static thread_local RefPtr sCurrentStream; +static thread_local RefPtr sCurrentStream; -class CUDAStreamManager : public impl::StreamManager -{ -public: - void setCurrent(const Stream& stream) override - { +class CUDAStreamManager : public impl::StreamManager { + public: + void setCurrent(const Stream &stream) override { auto ref = stream.unsafeGet(); - auto cudaStream = dynamic_cast(ref.get()); + auto cudaStream = dynamic_cast(ref.get()); HMP_REQUIRE(cudaStream, "Invalid CUDA stream"); sCurrentStream = ref.cast(); } - optional getCurrent() const override - { - if(!sCurrentStream){ - return Stream(makeRefPtr()); //get default stream by default - } - else{ + optional getCurrent() const override { + if (!sCurrentStream) { + return Stream( + makeRefPtr()); // get default stream by default + } else { return Stream(sCurrentStream); } } - Stream create(uint64_t flags = 0) override - { + Stream create(uint64_t flags = 0) override { return Stream(makeRefPtr(flags)); } - }; static CUDAStreamManager sCUDAStreamManager; HMP_REGISTER_STREAM_MANAGER(kCUDA, &sCUDAStreamManager); - -}} //namesapce \ No newline at end of file +} +} // namesapce \ No newline at end of file diff --git a/bmf/hml/src/cuda/timer.cpp b/bmf/hml/src/cuda/timer.cpp index 840e119c..878f7ca0 100644 --- a/bmf/hml/src/cuda/timer.cpp +++ b/bmf/hml/src/cuda/timer.cpp @@ -17,69 +17,52 @@ #include #include -namespace hmp{ -namespace cuda{ +namespace hmp { +namespace cuda { namespace { -class CUDATimer : public TimerInterface -{ +class CUDATimer : public TimerInterface { Event begin_, end_; int state_ = -1; // -1 - not inited, 0 - stopped, 1 - started Device device_; -public: - CUDATimer() - : begin_(true), end_(true) - { + + public: + CUDATimer() : begin_(true), end_(true) { int index; HMP_CUDA_CHECK(cudaGetDevice(&index)); - device_ = Device(kCUDA, index); //FIXME: event may in different devices + device_ = Device(kCUDA, index); // FIXME: event may in different devices } - void start() override - { + void start() override { begin_.record(); state_ = 1; } - void stop() override - { + void stop() override { HMP_REQUIRE(state_ == 1, "CUDATimer is not started"); end_.record(); state_ = 0; } - double elapsed() override - { + double elapsed() override { HMP_REQUIRE(state_ == 0, "CUDATimer is not stopped"); - return begin_.elapsed(end_)/1e3; + return begin_.elapsed(end_) / 1e3; } - bool is_stopped() const override - { - return state_ == 0 || state_ == -1; - } + bool is_stopped() const override { return state_ == 0 || state_ == -1; } - const Device& device() const override - { - return device_; - } + const Device &device() const override { return device_; } }; -class CUDATimerManager : public impl::TimerManager -{ -public: - RefPtr create() override - { - return makeRefPtr(); - } +class CUDATimerManager : public impl::TimerManager { + public: + RefPtr create() override { return makeRefPtr(); } }; - static CUDATimerManager scudaTimerManager; HMP_REGISTER_TIMER_MANAGER(kCUDA, &scudaTimerManager); -} //namespace - - -}} //namespace \ No newline at end of file +} // namespace +} +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/dataexport/data_export.cpp b/bmf/hml/src/dataexport/data_export.cpp index c3a5c688..f3e0bf9e 100644 --- a/bmf/hml/src/dataexport/data_export.cpp +++ b/bmf/hml/src/dataexport/data_export.cpp @@ -3,120 +3,120 @@ #include #include -namespace hmp{ -static DLDataType get_dl_dtype(const Tensor& t) { +namespace hmp { +static DLDataType get_dl_dtype(const Tensor &t) { DLDataType dtype; dtype.lanes = 1; dtype.bits = sizeof_scalar_type(t.scalar_type()) * 8; switch (t.scalar_type()) { - case ScalarType::UInt8: - case ScalarType::UInt16: + case ScalarType::UInt8: + case ScalarType::UInt16: dtype.code = DLDataTypeCode::kDLUInt; break; - case ScalarType::Int8: - case ScalarType::Int16: - case ScalarType::Int32: - case ScalarType::Int64: + case ScalarType::Int8: + case ScalarType::Int16: + case ScalarType::Int32: + case ScalarType::Int64: dtype.code = DLDataTypeCode::kDLInt; break; - case ScalarType::Float64: - case ScalarType::Float32: - case ScalarType::Half: + case ScalarType::Float64: + case ScalarType::Float32: + case ScalarType::Half: dtype.code = DLDataTypeCode::kDLFloat; break; - case ScalarType::Undefined: - default: + case ScalarType::Undefined: + default: HMP_REQUIRE(false, "Undefined is not a valid ScalarType"); } return dtype; } -ScalarType to_scalar_type(const DLDataType& dtype) { - ScalarType stype; - HMP_REQUIRE(dtype.lanes == 1, "hmp does not support lanes != 1"); - switch (dtype.code) { +ScalarType to_scalar_type(const DLDataType &dtype) { + ScalarType stype; + HMP_REQUIRE(dtype.lanes == 1, "hmp does not support lanes != 1"); + switch (dtype.code) { case DLDataTypeCode::kDLUInt: - switch (dtype.bits) { + switch (dtype.bits) { case 8: - stype = ScalarType::UInt8; - break; + stype = ScalarType::UInt8; + break; case 16: - stype = ScalarType::UInt16; - break; + stype = ScalarType::UInt16; + break; default: - HMP_REQUIRE( - false, "Unsupported kUInt bits " + std::to_string(dtype.bits)); - } - break; + HMP_REQUIRE(false, + "Unsupported kUInt bits " + std::to_string(dtype.bits)); + } + break; case DLDataTypeCode::kDLInt: - switch (dtype.bits) { + switch (dtype.bits) { case 8: - stype = ScalarType::Int8; - break; + stype = ScalarType::Int8; + break; case 16: - stype = ScalarType::Int16; - break; + stype = ScalarType::Int16; + break; case 32: - stype = ScalarType::Int32; - break; + stype = ScalarType::Int32; + break; case 64: - stype = ScalarType::Int64; - break; + stype = ScalarType::Int64; + break; default: - HMP_REQUIRE( - false, "Unsupported kInt bits " + std::to_string(dtype.bits)); - } - break; + HMP_REQUIRE(false, + "Unsupported kInt bits " + std::to_string(dtype.bits)); + } + break; case DLDataTypeCode::kDLFloat: - switch (dtype.bits) { + switch (dtype.bits) { case 16: - stype = ScalarType::Half; - break; + stype = ScalarType::Half; + break; case 32: - stype = ScalarType::Float32; - break; + stype = ScalarType::Float32; + break; case 64: - stype = ScalarType::Float64; - break; + stype = ScalarType::Float64; + break; default: - HMP_REQUIRE( - false, "Unsupported kFloat bits " + std::to_string(dtype.bits)); - } - break; + HMP_REQUIRE(false, "Unsupported kFloat bits " + + std::to_string(dtype.bits)); + } + break; default: - HMP_REQUIRE( - false, "Unsupported code " + std::to_string(dtype.code)); - } - return stype; + HMP_REQUIRE(false, "Unsupported code " + std::to_string(dtype.code)); + } + return stype; } -static DLDevice get_dl_device(const Tensor& tensor, const int64_t& device_id) { +static DLDevice get_dl_device(const Tensor &tensor, const int64_t &device_id) { DLDevice ctx; ctx.device_id = device_id; switch (tensor.device().type()) { - case DeviceType::CPU: + case DeviceType::CPU: ctx.device_type = DLDeviceType::kDLCPU; break; - case DeviceType::CUDA: + case DeviceType::CUDA: ctx.device_type = DLDeviceType::kDLCUDA; break; - default: - HMP_REQUIRE(false, "Cannot pack tensors on " + stringfy(tensor.device())); + default: + HMP_REQUIRE(false, + "Cannot pack tensors on " + stringfy(tensor.device())); } return ctx; } -static Device get_hmp_device(const DLDevice& ctx) { +static Device get_hmp_device(const DLDevice &ctx) { switch (ctx.device_type) { - case DLDeviceType::kDLCPU: + case DLDeviceType::kDLCPU: return Device(DeviceType::CPU); #ifdef HMP_ENABLE_CUDA - case DLDeviceType::kDLCUDA: + case DLDeviceType::kDLCUDA: return Device(DeviceType::CUDA, ctx.device_id); #endif - default: - HMP_REQUIRE( - false, "Unsupported device_type: " + std::to_string(ctx.device_type)); + default: + HMP_REQUIRE(false, "Unsupported device_type: " + + std::to_string(ctx.device_type)); } } @@ -125,13 +125,13 @@ struct HmpDLMTensor { DLManagedTensor tensor; }; -void deleter(DLManagedTensor* arg) { - delete static_cast(arg->manager_ctx); +void deleter(DLManagedTensor *arg) { + delete static_cast(arg->manager_ctx); } -DLManagedTensor* to_dlpack(const Tensor& src) { +DLManagedTensor *to_dlpack(const Tensor &src) { - HmpDLMTensor* hmpDLMTensor(new HmpDLMTensor); + HmpDLMTensor *hmpDLMTensor(new HmpDLMTensor); hmpDLMTensor->handle = src; hmpDLMTensor->tensor.manager_ctx = hmpDLMTensor; hmpDLMTensor->tensor.deleter = &deleter; @@ -144,23 +144,24 @@ DLManagedTensor* to_dlpack(const Tensor& src) { hmpDLMTensor->tensor.dl_tensor.ndim = src.dim(); hmpDLMTensor->tensor.dl_tensor.dtype = get_dl_dtype(src); hmpDLMTensor->tensor.dl_tensor.shape = - const_cast(src.shape().data()); + const_cast(src.shape().data()); hmpDLMTensor->tensor.dl_tensor.strides = - const_cast(src.strides().data()); + const_cast(src.strides().data()); hmpDLMTensor->tensor.dl_tensor.byte_offset = 0; return &(hmpDLMTensor->tensor); } -Tensor from_dlpack( - const DLManagedTensor* src) { +Tensor from_dlpack(const DLManagedTensor *src) { Device device = get_hmp_device(src->dl_tensor.device); ScalarType stype = to_scalar_type(src->dl_tensor.dtype); DataPtr dp{src->dl_tensor.data, device}; - SizeArray shape{src->dl_tensor.shape, src->dl_tensor.shape + src->dl_tensor.ndim}; + SizeArray shape{src->dl_tensor.shape, + src->dl_tensor.shape + src->dl_tensor.ndim}; if (!src->dl_tensor.strides) { return from_buffer({src->dl_tensor.data, device}, stype, shape); } - SizeArray strides{src->dl_tensor.strides, src->dl_tensor.strides + src->dl_tensor.ndim}; + SizeArray strides{src->dl_tensor.strides, + src->dl_tensor.strides + src->dl_tensor.ndim}; return from_buffer({src->dl_tensor.data, device}, stype, shape, strides); } } // namespace hmp \ No newline at end of file diff --git a/bmf/hml/src/ffmpeg/ffmpeg.cpp b/bmf/hml/src/ffmpeg/ffmpeg.cpp index 832f4b42..1fbbaa30 100644 --- a/bmf/hml/src/ffmpeg/ffmpeg.cpp +++ b/bmf/hml/src/ffmpeg/ffmpeg.cpp @@ -19,15 +19,12 @@ #include -namespace hmp{ -namespace ffmpeg{ +namespace hmp { +namespace ffmpeg { - - -struct VideoReader::Private -{ +struct VideoReader::Private { std::shared_ptr avfc; - std::shared_ptr avcc; + std::shared_ptr avcc; std::shared_ptr avpkt; std::shared_ptr avframe; @@ -36,15 +33,14 @@ struct VideoReader::Private int streamIndex; }; - -VideoReader::VideoReader(const std::string &fn) -{ +VideoReader::VideoReader(const std::string &fn) { self = std::make_shared(); // AVFormatContext *avfc = avformat_alloc_context(); HMP_REQUIRE(avfc, "FFMPEG: allocate AVFormatContext failed"); - self->avfc = decltype(self->avfc)(avfc, std::ptr_fun(avformat_free_context)); + self->avfc = + decltype(self->avfc)(avfc, std::ptr_fun(avformat_free_context)); auto rc = avformat_open_input(&avfc, fn.c_str(), NULL, NULL); HMP_REQUIRE(rc == 0, "FFMPEG: open file {} failed", fn); @@ -52,10 +48,10 @@ VideoReader::VideoReader(const std::string &fn) rc = avformat_find_stream_info(avfc, NULL); HMP_REQUIRE(rc == 0, "FFMPEG: failed to get stream info"); - //using first video stream + // using first video stream AVStream *avs = 0; - for(int i = 0; i < avfc->nb_streams; i ++){ - if(avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){ + for (int i = 0; i < avfc->nb_streams; i++) { + if (avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { avs = avfc->streams[i]; self->streamIndex = i; break; @@ -65,13 +61,13 @@ VideoReader::VideoReader(const std::string &fn) self->pix_info = make_pixel_info(*avs->codecpar); auto avc = avcodec_find_decoder(avs->codecpar->codec_id); - HMP_REQUIRE(avc, - "FFMPEG: failed to find the codec with code_id {}", avs->codecpar->codec_id); + HMP_REQUIRE(avc, "FFMPEG: failed to find the codec with code_id {}", + avs->codecpar->codec_id); auto avcc = avcodec_alloc_context3(avc); HMP_REQUIRE(avcc, "FFMPEG: failed to alloc AVCodecContext"); - self->avcc = std::shared_ptr(avcc, - [](AVCodecContext *ptr){ avcodec_free_context(&ptr); }); + self->avcc = std::shared_ptr( + avcc, [](AVCodecContext *ptr) { avcodec_free_context(&ptr); }); rc = avcodec_parameters_to_context(avcc, avs->codecpar); HMP_REQUIRE(rc == 0, "FFMPEG: failed to fill codec context"); @@ -79,36 +75,35 @@ VideoReader::VideoReader(const std::string &fn) rc = avcodec_open2(avcc, avc, NULL); HMP_REQUIRE(rc == 0, "FFMPEG: failed to open codec"); - self->avpkt = std::shared_ptr(av_packet_alloc(), - [](AVPacket *pkt) { av_packet_free(&pkt); }); + self->avpkt = std::shared_ptr( + av_packet_alloc(), [](AVPacket *pkt) { av_packet_free(&pkt); }); - self->avframe = std::shared_ptr(av_frame_alloc(), - [](AVFrame *frame) { av_frame_free(&frame); }); + self->avframe = std::shared_ptr( + av_frame_alloc(), [](AVFrame *frame) { av_frame_free(&frame); }); HMP_REQUIRE(self->avpkt && self->avframe, - "FFMPEG: alloc AVPacket or AVFrame failed"); + "FFMPEG: alloc AVPacket or AVFrame failed"); } -std::vector VideoReader::read(int64_t nframe) -{ +std::vector VideoReader::read(int64_t nframe) { auto &pix_info = self->pix_info; std::vector frames; int nread = 0; - while(nread < nframe){ - auto rc = av_read_frame(self->avfc.get(), self->avpkt.get()); - if(rc >= 0){ - if(self->avpkt->stream_index == self->streamIndex){ + while (nread < nframe) { + auto rc = av_read_frame(self->avfc.get(), self->avpkt.get()); + if (rc >= 0) { + if (self->avpkt->stream_index == self->streamIndex) { rc = avcodec_send_packet(self->avcc.get(), self->avpkt.get()); HMP_REQUIRE(rc >= 0, "FFMPEG: decode failed, rc={}", rc); - while(rc >= 0){ - rc = avcodec_receive_frame(self->avcc.get(), self->avframe.get()); - if(rc == AVERROR(EAGAIN) || rc == AVERROR_EOF){ + while (rc >= 0) { + rc = avcodec_receive_frame(self->avcc.get(), + self->avframe.get()); + if (rc == AVERROR(EAGAIN) || rc == AVERROR_EOF) { break; - } - else{ - HMP_REQUIRE(rc >= 0 , "FFMPEG: receive frame failed"); + } else { + HMP_REQUIRE(rc >= 0, "FFMPEG: receive frame failed"); } auto f = from_video_frame(self->avframe.get()); @@ -120,9 +115,8 @@ std::vector VideoReader::read(int64_t nframe) } av_packet_unref(self->avpkt.get()); - } - else{ - if(rc != AVERROR_EOF){ + } else { + if (rc != AVERROR_EOF) { HMP_WRN("ReadFrame failed with error {}", AVErr2Str(rc)); } break; @@ -132,11 +126,9 @@ std::vector VideoReader::read(int64_t nframe) return frames; } - -struct VideoWriter::Private -{ +struct VideoWriter::Private { std::shared_ptr avfc; - std::shared_ptr avcc; + std::shared_ptr avcc; std::shared_ptr avpkt; AVStream *avs; @@ -150,53 +142,55 @@ struct VideoWriter::Private int64_t ptsStep; //[FIXME] workaround to make it works }; -//https://libav.org/documentation/doxygen/master/encode__video_8c_source.html -static void encodeVideo(AVFormatContext *avfc, AVCodecContext *avcc, AVFrame *avframe, AVPacket *avpkt) -{ +// https://libav.org/documentation/doxygen/master/encode__video_8c_source.html +static void encodeVideo(AVFormatContext *avfc, AVCodecContext *avcc, + AVFrame *avframe, AVPacket *avpkt) { auto rc = avcodec_send_frame(avcc, avframe); - while (rc >= 0){ + while (rc >= 0) { rc = avcodec_receive_packet(avcc, avpkt); - if (rc == AVERROR(EAGAIN) || rc == AVERROR_EOF){ + if (rc == AVERROR(EAGAIN) || rc == AVERROR_EOF) { break; } HMP_REQUIRE(rc >= 0, - "VideoWriter: receiving packet failed with error {}", AVErr2Str(rc)); + "VideoWriter: receiving packet failed with error {}", + AVErr2Str(rc)); rc = av_interleaved_write_frame(avfc, avpkt); av_packet_unref(avpkt); - HMP_REQUIRE(rc == 0, - "VideoWriter: write packet failed with error {}", AVErr2Str(rc)); + HMP_REQUIRE(rc == 0, "VideoWriter: write packet failed with error {}", + AVErr2Str(rc)); } } - -VideoWriter::VideoWriter(const std::string &fn, int width, int height, int fps, const PixelInfo &pix_info, int kbs) -{ +VideoWriter::VideoWriter(const std::string &fn, int width, int height, int fps, + const PixelInfo &pix_info, int kbs) { self = std::make_shared(); - //h265 +// h265 #if 0 const std::string codec("libx265"); const std::string codec_priv_key = "x265-params"; const std::string codec_priv_value = "keyint=60:min-keyint=60:scenecut=0"; #else - //h264 + // h264 const std::string codec("libx264"); const std::string codec_priv_key = "x264-params"; - const std::string codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1"; + const std::string codec_priv_value = + "keyint=60:min-keyint=60:scenecut=0:force-cfr=1"; #endif self->streamIndex = 0; self->pts = 0; self->fps = fps; - self->ptsStep = 12800/fps; + self->ptsStep = 12800 / fps; // AVFormatContext *avfc = nullptr; avformat_alloc_output_context2(&avfc, 0, 0, fn.c_str()); HMP_REQUIRE(avfc, "VideoWriter: allocate AVFormatContext failed"); - self->avfc = decltype(self->avfc)(avfc, std::ptr_fun(avformat_free_context)); + self->avfc = + decltype(self->avfc)(avfc, std::ptr_fun(avformat_free_context)); AVStream *avs = avformat_new_stream(avfc, NULL); self->avs = avs; @@ -206,12 +200,13 @@ VideoWriter::VideoWriter(const std::string &fn, int width, int height, int fps, auto avcc = avcodec_alloc_context3(avc); HMP_REQUIRE(avcc, "VideoWriter: allocate avcodec context failed"); - self->avcc = std::shared_ptr(avcc, - [](AVCodecContext *ptr){ avcodec_free_context(&ptr); }); + self->avcc = std::shared_ptr( + avcc, [](AVCodecContext *ptr) { avcodec_free_context(&ptr); }); av_opt_set(avcc->priv_data, "preset", "fast", 0); av_opt_set(avcc->priv_data, "", "fast", 0); - av_opt_set(avcc->priv_data, codec_priv_key.c_str(), codec_priv_value.c_str(), 0); + av_opt_set(avcc->priv_data, codec_priv_key.c_str(), + codec_priv_value.c_str(), 0); avcc->width = width; avcc->height = height; avcc->sample_aspect_ratio = av_make_q(1, 1); @@ -219,7 +214,7 @@ VideoWriter::VideoWriter(const std::string &fn, int width, int height, int fps, avcc->rc_buffer_size = kbs * 2000; avcc->rc_max_rate = kbs * 1500; avcc->rc_min_rate = kbs * 1000; - avcc->time_base = AVRational{1, fps*2}; + avcc->time_base = AVRational{1, fps * 2}; avcc->framerate = AVRational{fps, 1}; avcc->gop_size = 10; avcc->max_b_frames = 1; @@ -232,70 +227,63 @@ VideoWriter::VideoWriter(const std::string &fn, int width, int height, int fps, self->pix_info = pix_info; // - self->avpkt = std::shared_ptr(av_packet_alloc(), - [](AVPacket *pkt) { av_packet_free(&pkt); }); + self->avpkt = std::shared_ptr( + av_packet_alloc(), [](AVPacket *pkt) { av_packet_free(&pkt); }); self->avpkt->stream_index = self->streamIndex; self->avpkt->duration = 1; - HMP_REQUIRE(self->avpkt, - "FFMPEG: alloc AVPacket or AVFrame failed"); + HMP_REQUIRE(self->avpkt, "FFMPEG: alloc AVPacket or AVFrame failed"); // - HMP_REQUIRE(avcodec_open2(avcc, avc, NULL) >= 0, "VideoWriter: open codec failed"); + HMP_REQUIRE(avcodec_open2(avcc, avc, NULL) >= 0, + "VideoWriter: open codec failed"); avcodec_parameters_from_context(avs->codecpar, avcc); - if(avfc->oformat->flags & AVFMT_GLOBALHEADER){ + if (avfc->oformat->flags & AVFMT_GLOBALHEADER) { avfc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } - if(!(avfc->oformat->flags & AVFMT_NOFILE)){ + if (!(avfc->oformat->flags & AVFMT_NOFILE)) { auto rc = avio_open(&avfc->pb, fn.c_str(), AVIO_FLAG_WRITE); HMP_REQUIRE(rc >= 0, "VideoWriter: open file({}) to write failed", fn); } - AVDictionary* muxer_opts = NULL; - HMP_REQUIRE( - avformat_write_header(avfc, &muxer_opts) >= 0, - "VideoWriter: write header failed"); - + AVDictionary *muxer_opts = NULL; + HMP_REQUIRE(avformat_write_header(avfc, &muxer_opts) >= 0, + "VideoWriter: write header failed"); } -VideoWriter::~VideoWriter() -{ - //flush +VideoWriter::~VideoWriter() { + // flush encodeVideo(self->avfc.get(), self->avcc.get(), NULL, self->avpkt.get()); av_write_trailer(self->avfc.get()); } - -void VideoWriter::write(const std::vector &images) -{ +void VideoWriter::write(const std::vector &images) { HMP_REQUIRE(images[0].format() == self->pix_info.format(), - "VideoWriter: invalid pixel format, expect {}, got {}", - self->pix_info.format(), images[0].format()); - HMP_REQUIRE(images[0].width() == self->avcc->width && - images[0].height() == self->avcc->height, - "VideoWriter: invalid image size"); + "VideoWriter: invalid pixel format, expect {}, got {}", + self->pix_info.format(), images[0].format()); + HMP_REQUIRE(images[0].width() == self->avcc->width && + images[0].height() == self->avcc->height, + "VideoWriter: invalid image size"); HMP_REQUIRE(images[0].plane(0).is_cpu(), - "VideoWriter: only support CPU images, got {}", - stringfy(images[0].plane(0).device())); + "VideoWriter: only support CPU images, got {}", + stringfy(images[0].plane(0).device())); int batch = images.size(); - for(int i = 0; i < batch; ++i){ + for (int i = 0; i < batch; ++i) { // - auto avframe = std::shared_ptr( - to_video_frame(images[i]), - [](AVFrame *avf){ - av_frame_free(&avf); - }); + auto avframe = + std::shared_ptr(to_video_frame(images[i]), + [](AVFrame *avf) { av_frame_free(&avf); }); avframe->pts = self->pts; self->pts += self->ptsStep; - encodeVideo(self->avfc.get(), self->avcc.get(), avframe.get(), self->avpkt.get()); + encodeVideo(self->avfc.get(), self->avcc.get(), avframe.get(), + self->avpkt.get()); } } - - -}} //namespace hmp::ffmpeg \ No newline at end of file +} +} // namespace hmp::ffmpeg \ No newline at end of file diff --git a/bmf/hml/src/hmp_capi.cpp b/bmf/hml/src/hmp_capi.cpp index bdecafa6..a08ecd28 100644 --- a/bmf/hml/src/hmp_capi.cpp +++ b/bmf/hml/src/hmp_capi.cpp @@ -18,642 +18,438 @@ thread_local std::string s_hmp_last_error; -#define HMP_PROTECT(...) \ - try{ \ - __VA_ARGS__ \ - } catch(const std::exception &e){ \ - s_hmp_last_error = e.what(); \ - HMP_WRN("Exception: {}", e.what()); \ +#define HMP_PROTECT(...) \ + try { \ + __VA_ARGS__ \ + } catch (const std::exception &e) { \ + s_hmp_last_error = e.what(); \ + HMP_WRN("Exception: {}", e.what()); \ } - using namespace hmp; - - -const char *hmp_last_error() -{ - return s_hmp_last_error.c_str(); -} +const char *hmp_last_error() { return s_hmp_last_error.c_str(); } /////// hmp_Scalar /////////// -hmp_Scalar hmp_scalar_float(double v) -{ - return new Scalar(v); -} +hmp_Scalar hmp_scalar_float(double v) { return new Scalar(v); } -hmp_Scalar hmp_scalar_int(int64_t v) -{ - return new Scalar(v); -} +hmp_Scalar hmp_scalar_int(int64_t v) { return new Scalar(v); } -hmp_Scalar hmp_scalar_bool(bool v) -{ - return new Scalar(v); -} +hmp_Scalar hmp_scalar_bool(bool v) { return new Scalar(v); } -void hmp_scalar_free(hmp_Scalar scalar) -{ - if(scalar){ +void hmp_scalar_free(hmp_Scalar scalar) { + if (scalar) { delete scalar; } } - ////////// hmp_Device ////////// -int hmp_device_count(int device_type) -{ - HMP_PROTECT( - return device_count(DeviceType(device_type)); - ) +int hmp_device_count(int device_type) { + HMP_PROTECT(return device_count(DeviceType(device_type));) return 0; } - - ////////// hmp_Stream ///////// -hmp_Stream hmp_stream_create(int device_type, uint64_t flags) -{ +hmp_Stream hmp_stream_create(int device_type, uint64_t flags) { HMP_PROTECT( - return new Stream(create_stream((DeviceType)device_type, flags)); - ) + return new Stream(create_stream((DeviceType)device_type, flags));) return nullptr; } -void hmp_stream_free(hmp_Stream stream) -{ - if(stream){ +void hmp_stream_free(hmp_Stream stream) { + if (stream) { delete stream; } } -bool hmp_stream_query(hmp_Stream stream) -{ - HMP_PROTECT( - return stream->query(); - ) +bool hmp_stream_query(hmp_Stream stream) { + HMP_PROTECT(return stream->query();) return false; } -void hmp_stream_synchronize(hmp_Stream stream) -{ - HMP_PROTECT( - stream->synchronize(); - ) +void hmp_stream_synchronize(hmp_Stream stream) { + HMP_PROTECT(stream->synchronize();) } -uint64_t hmp_stream_handle(const hmp_Stream stream) -{ - return stream->handle(); -} +uint64_t hmp_stream_handle(const hmp_Stream stream) { return stream->handle(); } -int hmp_stream_device_type(const hmp_Stream stream) -{ +int hmp_stream_device_type(const hmp_Stream stream) { return (int)stream->device().type(); } -int hmp_stream_device_index(const hmp_Stream stream) -{ +int hmp_stream_device_index(const hmp_Stream stream) { return stream->device().index(); } - -void hmp_stream_set_current(const hmp_Stream stream) -{ +void hmp_stream_set_current(const hmp_Stream stream) { return set_current_stream(*stream); } -hmp_Stream hmp_stream_current(int device_type) -{ +hmp_Stream hmp_stream_current(int device_type) { HMP_PROTECT( - return new Stream(current_stream((DeviceType)device_type).value()); - ) + return new Stream(current_stream((DeviceType)device_type).value());) return nullptr; } - -hmp_StreamGuard hmp_stream_guard_create(hmp_Stream stream) -{ - HMP_PROTECT( - return new StreamGuard(*stream); - ) +hmp_StreamGuard hmp_stream_guard_create(hmp_Stream stream) { + HMP_PROTECT(return new StreamGuard(*stream);) return nullptr; } -void hmp_stream_guard_free(hmp_StreamGuard guard) -{ - if(guard){ +void hmp_stream_guard_free(hmp_StreamGuard guard) { + if (guard) { delete guard; } } - /////// hmp_Tensor /////////// -hmp_Tensor hmp_tensor_empty(const int64_t *shape, int ndim, int type, const char *device, bool pinned_memory) -{ - SizeArray vshape(shape, shape+ndim); +hmp_Tensor hmp_tensor_empty(const int64_t *shape, int ndim, int type, + const char *device, bool pinned_memory) { + SizeArray vshape(shape, shape + ndim); auto options = TensorOptions((ScalarType)type) - .device(Device(device)) - .pinned_memory(pinned_memory); - HMP_PROTECT( - return new Tensor(empty(vshape, options)); - ); + .device(Device(device)) + .pinned_memory(pinned_memory); + HMP_PROTECT(return new Tensor(empty(vshape, options));); return nullptr; } -hmp_Tensor hmp_tensor_arange(int64_t start, int64_t end, int64_t step, int type, const char *device, bool pinned_memory) -{ +hmp_Tensor hmp_tensor_arange(int64_t start, int64_t end, int64_t step, int type, + const char *device, bool pinned_memory) { auto options = TensorOptions((ScalarType)type) - .device(Device(device)) - .pinned_memory(pinned_memory); - HMP_PROTECT( - return new Tensor(arange(start, end, step, options)); - ) + .device(Device(device)) + .pinned_memory(pinned_memory); + HMP_PROTECT(return new Tensor(arange(start, end, step, options));) return nullptr; } -void hmp_tensor_free(hmp_Tensor tensor) -{ - if(tensor){ +void hmp_tensor_free(hmp_Tensor tensor) { + if (tensor) { delete tensor; } } - -thread_local std::string s_tensor_stringfy_str; -const char* hmp_tensor_stringfy(hmp_Tensor tensor, int *size) -{ - HMP_PROTECT( - s_tensor_stringfy_str = stringfy(*tensor); - *size = s_tensor_stringfy_str.size(); - return s_tensor_stringfy_str.c_str(); - ) +thread_local std::string s_tensor_stringfy_str; +const char *hmp_tensor_stringfy(hmp_Tensor tensor, int *size) { + HMP_PROTECT(s_tensor_stringfy_str = stringfy(*tensor); + *size = s_tensor_stringfy_str.size(); + return s_tensor_stringfy_str.c_str();) return nullptr; } -void hmp_tensor_fill(hmp_Tensor tensor, hmp_Scalar value) -{ - HMP_PROTECT( - fill(*tensor, *value); - ) +void hmp_tensor_fill(hmp_Tensor tensor, hmp_Scalar value) { + HMP_PROTECT(fill(*tensor, *value);) } -bool hmp_tensor_defined(hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->defined(); - ) +bool hmp_tensor_defined(hmp_Tensor tensor) { + HMP_PROTECT(return tensor->defined();) return false; } -int64_t hmp_tensor_dim(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->dim(); - ) +int64_t hmp_tensor_dim(const hmp_Tensor tensor) { + HMP_PROTECT(return tensor->dim();) return -1; } -int64_t hmp_tensor_size(const hmp_Tensor tensor, int64_t dim) -{ - HMP_PROTECT( - return tensor->size(dim); - ) +int64_t hmp_tensor_size(const hmp_Tensor tensor, int64_t dim) { + HMP_PROTECT(return tensor->size(dim);) return -1; } - -int64_t hmp_tensor_itemsize(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->itemsize(); - ) +int64_t hmp_tensor_itemsize(const hmp_Tensor tensor) { + HMP_PROTECT(return tensor->itemsize();) return -1; } -int64_t hmp_tensor_stride(const hmp_Tensor tensor, int64_t dim) -{ - HMP_PROTECT( - return tensor->stride(dim); - ) +int64_t hmp_tensor_stride(const hmp_Tensor tensor, int64_t dim) { + HMP_PROTECT(return tensor->stride(dim);) return -1; } -int64_t hmp_tensor_nitems(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->nitems(); - ) +int64_t hmp_tensor_nitems(const hmp_Tensor tensor) { + HMP_PROTECT(return tensor->nitems();) return -1; } -int64_t hmp_tensor_nbytes(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->nbytes(); - ) +int64_t hmp_tensor_nbytes(const hmp_Tensor tensor) { + HMP_PROTECT(return tensor->nbytes();) return -1; } -int hmp_tensor_dtype(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return (int)tensor->dtype(); - ) +int hmp_tensor_dtype(const hmp_Tensor tensor) { + HMP_PROTECT(return (int)tensor->dtype();) return -1; } -void* hmp_tensor_data(hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->unsafe_data(); - ) +void *hmp_tensor_data(hmp_Tensor tensor) { + HMP_PROTECT(return tensor->unsafe_data();) return nullptr; } -bool hmp_tensor_is_contiguous(hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->is_contiguous(); - ) +bool hmp_tensor_is_contiguous(hmp_Tensor tensor) { + HMP_PROTECT(return tensor->is_contiguous();) return false; } -int hmp_tensor_device_type(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return (int)tensor->device_type(); - ) +int hmp_tensor_device_type(const hmp_Tensor tensor) { + HMP_PROTECT(return (int)tensor->device_type();) return -1; } -int hmp_tensor_device_index(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return tensor->device_index(); - ) +int hmp_tensor_device_index(const hmp_Tensor tensor) { + HMP_PROTECT(return tensor->device_index();) return -1; } - -hmp_Tensor hmp_tensor_clone(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return new Tensor(tensor->clone()); - ) +hmp_Tensor hmp_tensor_clone(const hmp_Tensor tensor) { + HMP_PROTECT(return new Tensor(tensor->clone());) return nullptr; } -hmp_Tensor hmp_tensor_alias(const hmp_Tensor tensor) -{ - HMP_PROTECT( - return new Tensor(tensor->alias()); - ) +hmp_Tensor hmp_tensor_alias(const hmp_Tensor tensor) { + HMP_PROTECT(return new Tensor(tensor->alias());) return nullptr; } -hmp_Tensor hmp_tensor_view(const hmp_Tensor tensor, const int64_t *shape, int ndim) -{ - HMP_PROTECT( - SizeArray vshape{shape, shape+ndim}; - return new Tensor(tensor->view(vshape)); - ) +hmp_Tensor hmp_tensor_view(const hmp_Tensor tensor, const int64_t *shape, + int ndim) { + HMP_PROTECT(SizeArray vshape{shape, shape + ndim}; + return new Tensor(tensor->view(vshape));) return nullptr; } -hmp_Tensor hmp_tensor_reshape(const hmp_Tensor tensor, const int64_t *shape, int ndim) -{ - HMP_PROTECT( - SizeArray vshape{shape, shape+ndim}; - return new Tensor(tensor->reshape(vshape)); - ) +hmp_Tensor hmp_tensor_reshape(const hmp_Tensor tensor, const int64_t *shape, + int ndim) { + HMP_PROTECT(SizeArray vshape{shape, shape + ndim}; + return new Tensor(tensor->reshape(vshape));) return nullptr; } - -hmp_Tensor hmp_tensor_slice(const hmp_Tensor tensor, int64_t dim, - int64_t start, int64_t end, int64_t step) -{ - HMP_PROTECT( - return new Tensor(tensor->slice(dim, start, end, step)); - ) +hmp_Tensor hmp_tensor_slice(const hmp_Tensor tensor, int64_t dim, int64_t start, + int64_t end, int64_t step) { + HMP_PROTECT(return new Tensor(tensor->slice(dim, start, end, step));) return nullptr; } - -hmp_Tensor hmp_tensor_select(const hmp_Tensor tensor, int64_t dim, int64_t index) -{ - HMP_PROTECT( - return new Tensor(tensor->select(dim, index)); - ) +hmp_Tensor hmp_tensor_select(const hmp_Tensor tensor, int64_t dim, + int64_t index) { + HMP_PROTECT(return new Tensor(tensor->select(dim, index));) return nullptr; } - -hmp_Tensor hmp_tensor_permute(const hmp_Tensor tensor, const int64_t *dims, int ndim) -{ - HMP_PROTECT( - SizeArray vdims{dims, dims+ndim}; - return new Tensor(tensor->permute(vdims)); - ) +hmp_Tensor hmp_tensor_permute(const hmp_Tensor tensor, const int64_t *dims, + int ndim) { + HMP_PROTECT(SizeArray vdims{dims, dims + ndim}; + return new Tensor(tensor->permute(vdims));) return nullptr; } - -hmp_Tensor hmp_tensor_squeeze(const hmp_Tensor tensor, int64_t dim) -{ - HMP_PROTECT( - return new Tensor(tensor->squeeze(dim)); - ) +hmp_Tensor hmp_tensor_squeeze(const hmp_Tensor tensor, int64_t dim) { + HMP_PROTECT(return new Tensor(tensor->squeeze(dim));) return nullptr; } - -hmp_Tensor hmp_tensor_unsqueeze(const hmp_Tensor tensor, int64_t dim) -{ - HMP_PROTECT( - return new Tensor(tensor->unsqueeze(dim)); - ) +hmp_Tensor hmp_tensor_unsqueeze(const hmp_Tensor tensor, int64_t dim) { + HMP_PROTECT(return new Tensor(tensor->unsqueeze(dim));) return nullptr; } - -hmp_Tensor hmp_tensor_to_device(const hmp_Tensor data, const char *device, bool non_blocking) -{ - HMP_PROTECT( - return new Tensor(data->to(Device(device), non_blocking)); - ) +hmp_Tensor hmp_tensor_to_device(const hmp_Tensor data, const char *device, + bool non_blocking) { + HMP_PROTECT(return new Tensor(data->to(Device(device), non_blocking));) return nullptr; } -hmp_Tensor hmp_tensor_to_dtype(const hmp_Tensor data, int dtype) -{ - HMP_PROTECT( - return new Tensor(data->to((ScalarType)dtype)); - ) +hmp_Tensor hmp_tensor_to_dtype(const hmp_Tensor data, int dtype) { + HMP_PROTECT(return new Tensor(data->to((ScalarType)dtype));) return nullptr; } -void hmp_tensor_copy_from(hmp_Tensor data, const hmp_Tensor from) -{ +void hmp_tensor_copy_from(hmp_Tensor data, const hmp_Tensor from) { data->copy_(*from); } /////////////////// hmp_ColorModel //////////// -hmp_ColorModel hmp_color_model(int cs, int cr, int cp, int ctc) -{ - HMP_PROTECT( - return new ColorModel((ColorSpace)cs, (ColorRange)cr, - (ColorPrimaries)cp, (ColorTransferCharacteristic)ctc); - ) +hmp_ColorModel hmp_color_model(int cs, int cr, int cp, int ctc) { + HMP_PROTECT(return new ColorModel((ColorSpace)cs, (ColorRange)cr, + (ColorPrimaries)cp, + (ColorTransferCharacteristic)ctc);) return nullptr; } -void hmp_color_model_free(hmp_ColorModel cm) -{ - if(cm){ +void hmp_color_model_free(hmp_ColorModel cm) { + if (cm) { delete cm; } } -int hmp_color_model_space(const hmp_ColorModel cm) -{ - return (int)cm->space(); -} +int hmp_color_model_space(const hmp_ColorModel cm) { return (int)cm->space(); } -int hmp_color_model_range(const hmp_ColorModel cm) -{ - return (int)cm->range(); -} +int hmp_color_model_range(const hmp_ColorModel cm) { return (int)cm->range(); } -int hmp_color_model_primaries(const hmp_ColorModel cm) -{ +int hmp_color_model_primaries(const hmp_ColorModel cm) { return (int)cm->primaries(); } -int hmp_color_model_ctc(const hmp_ColorModel cm) -{ +int hmp_color_model_ctc(const hmp_ColorModel cm) { return (int)cm->transfer_characteristic(); } - -hmp_PixelInfo hmp_pixel_info(int format, const hmp_ColorModel cm) -{ - HMP_PROTECT( - return new PixelInfo((PixelFormat)format, *cm); - ) +hmp_PixelInfo hmp_pixel_info(int format, const hmp_ColorModel cm) { + HMP_PROTECT(return new PixelInfo((PixelFormat)format, *cm);) return nullptr; } -hmp_PixelInfo hmp_pixel_info_v1(int format, int cs, int cr) -{ - HMP_PROTECT( - return new PixelInfo((PixelFormat)format, (ColorSpace)cs, (ColorRange)cr); - ) +hmp_PixelInfo hmp_pixel_info_v1(int format, int cs, int cr) { + HMP_PROTECT(return new PixelInfo((PixelFormat)format, (ColorSpace)cs, + (ColorRange)cr);) return nullptr; } -hmp_PixelInfo hmp_pixel_info_v2(int format, int cp, int ctc) -{ - HMP_PROTECT( - return new PixelInfo((PixelFormat)format, - (ColorPrimaries)cp, (ColorTransferCharacteristic)ctc); - ) +hmp_PixelInfo hmp_pixel_info_v2(int format, int cp, int ctc) { + HMP_PROTECT(return new PixelInfo((PixelFormat)format, (ColorPrimaries)cp, + (ColorTransferCharacteristic)ctc);) return nullptr; } -void hmp_pixel_info_free(hmp_PixelInfo pix_info) -{ - if(pix_info){ +void hmp_pixel_info_free(hmp_PixelInfo pix_info) { + if (pix_info) { delete pix_info; } } -int hmp_pixel_info_format(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_format(const hmp_PixelInfo pix_info) { return (int)pix_info->format(); } -int hmp_pixel_info_space(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_space(const hmp_PixelInfo pix_info) { return (int)pix_info->space(); } -int hmp_pixel_info_range(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_range(const hmp_PixelInfo pix_info) { return (int)pix_info->range(); } -int hmp_pixel_info_primaries(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_primaries(const hmp_PixelInfo pix_info) { return (int)pix_info->primaries(); } -int hmp_pixel_info_ctc(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_ctc(const hmp_PixelInfo pix_info) { return (int)pix_info->transfer_characteristic(); } -int hmp_pixel_info_infer_space(const hmp_PixelInfo pix_info) -{ +int hmp_pixel_info_infer_space(const hmp_PixelInfo pix_info) { return (int)pix_info->infer_space(); } -const hmp_ColorModel hmp_pixel_info_color_model(const hmp_PixelInfo pix_info) -{ +const hmp_ColorModel hmp_pixel_info_color_model(const hmp_PixelInfo pix_info) { return (const hmp_ColorModel)&pix_info->color_model(); } -bool hmp_pixel_info_is_rgbx(const hmp_PixelInfo pix_info) -{ +bool hmp_pixel_info_is_rgbx(const hmp_PixelInfo pix_info) { return pix_info->is_rgbx(); } thread_local std::string s_pixel_info_stringfy_str; -const char *hmp_pixel_info_stringfy(const hmp_PixelInfo pix_info, int *size) -{ +const char *hmp_pixel_info_stringfy(const hmp_PixelInfo pix_info, int *size) { s_pixel_info_stringfy_str = stringfy(*pix_info); *size = s_pixel_info_stringfy_str.size(); return s_pixel_info_stringfy_str.c_str(); } - /////////////////// hmp_Frame ///////////////// -hmp_Frame hmp_frame_make(int width, int height, const hmp_PixelInfo pix_info, const char *device) -{ - HMP_PROTECT( - return new Frame(width, height, *pix_info, Device(device)); - ) +hmp_Frame hmp_frame_make(int width, int height, const hmp_PixelInfo pix_info, + const char *device) { + HMP_PROTECT(return new Frame(width, height, *pix_info, Device(device));) return nullptr; } -hmp_Frame hmp_frame_from_data(hmp_Tensor *data, int size, const hmp_PixelInfo pix_info) -{ +hmp_Frame hmp_frame_from_data(hmp_Tensor *data, int size, + const hmp_PixelInfo pix_info) { TensorList vdata; - for(int i = 0; i < size; ++i){ + for (int i = 0; i < size; ++i) { vdata.push_back(*data[i]); } - HMP_PROTECT( - return new Frame(vdata, *pix_info); - ) + HMP_PROTECT(return new Frame(vdata, *pix_info);) return nullptr; } -hmp_Frame hmp_frame_from_data_v1(hmp_Tensor *data, int size, int width, int height, const hmp_PixelInfo pix_info) -{ +hmp_Frame hmp_frame_from_data_v1(hmp_Tensor *data, int size, int width, + int height, const hmp_PixelInfo pix_info) { TensorList vdata; - for(int i = 0; i < size; ++i){ + for (int i = 0; i < size; ++i) { vdata.push_back(*data[i]); } - HMP_PROTECT( - return new Frame(vdata, width, height, *pix_info); - ) + HMP_PROTECT(return new Frame(vdata, width, height, *pix_info);) return nullptr; } -void hmp_frame_free(hmp_Frame frame) -{ - if(frame){ +void hmp_frame_free(hmp_Frame frame) { + if (frame) { delete frame; } } -bool hmp_frame_defined(const hmp_Frame frame) -{ - return *frame; -} +bool hmp_frame_defined(const hmp_Frame frame) { return *frame; } -const hmp_PixelInfo hmp_frame_pix_info(const hmp_Frame frame) -{ +const hmp_PixelInfo hmp_frame_pix_info(const hmp_Frame frame) { return (const hmp_PixelInfo)&frame->pix_info(); } -int hmp_frame_format(const hmp_Frame frame) -{ - return (int)frame->format(); -} +int hmp_frame_format(const hmp_Frame frame) { return (int)frame->format(); } -int hmp_frame_width(const hmp_Frame frame) -{ - return frame->width(); -} +int hmp_frame_width(const hmp_Frame frame) { return frame->width(); } -int hmp_frame_height(const hmp_Frame frame) -{ - return frame->height(); -} +int hmp_frame_height(const hmp_Frame frame) { return frame->height(); } -int hmp_frame_dtype(const hmp_Frame frame) -{ - return (int)frame->dtype(); -} +int hmp_frame_dtype(const hmp_Frame frame) { return (int)frame->dtype(); } -int hmp_frame_device_type(const hmp_Frame frame) -{ +int hmp_frame_device_type(const hmp_Frame frame) { return (int)frame->device().type(); } -int hmp_frame_device_index(const hmp_Frame frame) -{ +int hmp_frame_device_index(const hmp_Frame frame) { return frame->device().index(); } -int64_t hmp_frame_nplanes(const hmp_Frame frame) -{ - return frame->nplanes(); -} +int64_t hmp_frame_nplanes(const hmp_Frame frame) { return frame->nplanes(); } -const hmp_Tensor hmp_frame_plane(const hmp_Frame frame, int64_t p) -{ +const hmp_Tensor hmp_frame_plane(const hmp_Frame frame, int64_t p) { return &frame->plane(p); } -hmp_Frame hmp_frame_to_device(const hmp_Frame frame, const char *device, bool non_blocking) -{ - HMP_PROTECT( - return new Frame(frame->to(Device(device), non_blocking)); - ) +hmp_Frame hmp_frame_to_device(const hmp_Frame frame, const char *device, + bool non_blocking) { + HMP_PROTECT(return new Frame(frame->to(Device(device), non_blocking));) return nullptr; } -void hmp_frame_copy_from(hmp_Frame self, const hmp_Frame from) -{ - HMP_PROTECT( - self->copy_(*from); - ) +void hmp_frame_copy_from(hmp_Frame self, const hmp_Frame from) { + HMP_PROTECT(self->copy_(*from);) } -hmp_Frame hmp_frame_clone(const hmp_Frame frame) -{ - HMP_PROTECT( - return new Frame(frame->clone()); - ) +hmp_Frame hmp_frame_clone(const hmp_Frame frame) { + HMP_PROTECT(return new Frame(frame->clone());) return nullptr; } -hmp_Frame hmp_frame_crop(const hmp_Frame frame, int left, int top, int width, int height) -{ - HMP_PROTECT( - return new Frame(frame->crop(left, top, width, height)); - ) +hmp_Frame hmp_frame_crop(const hmp_Frame frame, int left, int top, int width, + int height) { + HMP_PROTECT(return new Frame(frame->crop(left, top, width, height));) return nullptr; } -hmp_Frame hmp_frame_reformat(const hmp_Frame frame, const hmp_PixelInfo pix_info) -{ - HMP_PROTECT( - return new Frame(frame->reformat(*pix_info)); - ) +hmp_Frame hmp_frame_reformat(const hmp_Frame frame, + const hmp_PixelInfo pix_info) { + HMP_PROTECT(return new Frame(frame->reformat(*pix_info));) return nullptr; } thread_local std::string s_frame_stringfy_str; -const char* hmp_frame_stringfy(const hmp_Frame frame, int *size) -{ +const char *hmp_frame_stringfy(const hmp_Frame frame, int *size) { s_frame_stringfy_str = stringfy(*frame); *size = s_frame_stringfy_str.size(); return s_frame_stringfy_str.c_str(); diff --git a/bmf/hml/src/imgproc/formats.cpp b/bmf/hml/src/imgproc/formats.cpp index c22873af..b428a931 100644 --- a/bmf/hml/src/imgproc/formats.cpp +++ b/bmf/hml/src/imgproc/formats.cpp @@ -20,306 +20,280 @@ #include #include -namespace hmp{ +namespace hmp { - -static ColorRange infer_color_range(PixelFormat fmt, ColorRange hint = CR_UNSPECIFIED) -{ - if(fmt == PF_YUVJ420P && hint == CR_UNSPECIFIED){ +static ColorRange infer_color_range(PixelFormat fmt, + ColorRange hint = CR_UNSPECIFIED) { + if (fmt == PF_YUVJ420P && hint == CR_UNSPECIFIED) { return CR_JPEG; - } - else{ + } else { return hint; } } ColorModel::ColorModel() - : ColorModel( - CS_UNSPECIFIED, CR_UNSPECIFIED, - CP_UNSPECIFIED, CTC_UNSPECIFIED) -{ -} - + : ColorModel(CS_UNSPECIFIED, CR_UNSPECIFIED, CP_UNSPECIFIED, + CTC_UNSPECIFIED) {} ColorModel::ColorModel(ColorSpace cs, ColorRange cr) - : ColorModel(cs, cr, - CP_UNSPECIFIED, CTC_UNSPECIFIED) -{ -} + : ColorModel(cs, cr, CP_UNSPECIFIED, CTC_UNSPECIFIED) {} ColorModel::ColorModel(ColorPrimaries cp, ColorTransferCharacteristic ctc) - : ColorModel(CS_UNSPECIFIED, CR_UNSPECIFIED, - cp, ctc) -{ -} - -ColorModel::ColorModel(ColorSpace cs, ColorRange cr, ColorPrimaries cp, ColorTransferCharacteristic ctc) -{ - cm_ = cs | (cr<<8) | (cp << 16) | (ctc << 24); -} + : ColorModel(CS_UNSPECIFIED, CR_UNSPECIFIED, cp, ctc) {} -ColorSpace ColorModel::space() const -{ - return ColorSpace(cm_ & 0xff); +ColorModel::ColorModel(ColorSpace cs, ColorRange cr, ColorPrimaries cp, + ColorTransferCharacteristic ctc) { + cm_ = cs | (cr << 8) | (cp << 16) | (ctc << 24); } -ColorRange ColorModel::range() const -{ - return ColorRange((cm_ >> 8) & 0xff); -} +ColorSpace ColorModel::space() const { return ColorSpace(cm_ & 0xff); } +ColorRange ColorModel::range() const { return ColorRange((cm_ >> 8) & 0xff); } -ColorPrimaries ColorModel::primaries() const -{ +ColorPrimaries ColorModel::primaries() const { return ColorPrimaries((cm_ >> 16) & 0xff); } - -ColorTransferCharacteristic ColorModel::transfer_characteristic() const -{ +ColorTransferCharacteristic ColorModel::transfer_characteristic() const { return ColorTransferCharacteristic((cm_ >> 24) & 0xff); } - -PixelInfo::PixelInfo() - : format_(PF_NONE) -{ -} +PixelInfo::PixelInfo() : format_(PF_NONE) {} PixelInfo::PixelInfo(PixelFormat format, ColorModel color_model, int align) - : format_(format), color_model_(color_model), align_(align) -{ -} + : format_(format), color_model_(color_model), align_(align) {} -PixelInfo::PixelInfo(PixelFormat format, ColorSpace cs, ColorRange cr, int align) - : format_(format), color_model_(cs, infer_color_range(format, cr)), align_(align) -{ -} +PixelInfo::PixelInfo(PixelFormat format, ColorSpace cs, ColorRange cr, + int align) + : format_(format), color_model_(cs, infer_color_range(format, cr)), + align_(align) {} -PixelInfo::PixelInfo(PixelFormat format, ColorPrimaries cp, ColorTransferCharacteristic ctc, int align) - : format_(format), color_model_(CS_UNSPECIFIED, infer_color_range(format), cp, ctc), align_(align) -{ -} +PixelInfo::PixelInfo(PixelFormat format, ColorPrimaries cp, + ColorTransferCharacteristic ctc, int align) + : format_(format), + color_model_(CS_UNSPECIFIED, infer_color_range(format), cp, ctc), + align_(align) {} -bool PixelInfo::is_rgbx() const -{ +bool PixelInfo::is_rgbx() const { return PixelFormatDesc(format()).nplanes() == 1; } - -ColorSpace PixelInfo::infer_space() const -{ - if(space() != CS_UNSPECIFIED){ +ColorSpace PixelInfo::infer_space() const { + if (space() != CS_UNSPECIFIED) { return space(); - } - else{ - if(format() == PF_NV12 || format() == PF_NV21){ + } else { + if (format() == PF_NV12 || format() == PF_NV21) { return CS_BT470BG; - } - else if(format() == PF_P010LE || format() == PF_YUV420P10LE){ + } else if (format() == PF_P010LE || format() == PF_YUV420P10LE) { return CS_BT2020_CL; - } - else{ + } else { return CS_BT709; } } } - const static int sMaxPlanes = 4; - -std::string stringfy(const PixelInfo &pix_info) -{ - return fmt::format("PixelInfo({}, {}, {}, {}, {})", - pix_info.format(), pix_info.space(), pix_info.range(), - pix_info.primaries(), pix_info.transfer_characteristic()); +std::string stringfy(const PixelInfo &pix_info) { + return fmt::format("PixelInfo({}, {}, {}, {}, {})", pix_info.format(), + pix_info.space(), pix_info.range(), pix_info.primaries(), + pix_info.transfer_characteristic()); } - -std::string stringfy(const PixelFormat &format) -{ - switch (format) - { -#define STRINGFY_CASE(name) case PixelFormat::name : return "k"#name; - HMP_FORALL_PIXEL_FORMATS(STRINGFY_CASE) +std::string stringfy(const PixelFormat &format) { + switch (format) { +#define STRINGFY_CASE(name) \ + case PixelFormat::name: \ + return "k" #name; + HMP_FORALL_PIXEL_FORMATS(STRINGFY_CASE) #undef STRINGFY_CASE default: return fmt::format("PixelFormat({})", static_cast(format)); } } - -std::string stringfy(const ChannelFormat &format) -{ - switch (format) - { - case ChannelFormat::NCHW: return "kNCHW"; - case ChannelFormat::NHWC: return "kNHWC"; - default: - return fmt::format("ChannelFormat({})", static_cast(format)); +std::string stringfy(const ChannelFormat &format) { + switch (format) { + case ChannelFormat::NCHW: + return "kNCHW"; + case ChannelFormat::NHWC: + return "kNHWC"; + default: + return fmt::format("ChannelFormat({})", static_cast(format)); } } -std::string stringfy(const ImageRotationMode &mode) -{ - switch (mode) - { - case ImageRotationMode::Rotate0: return "kRotate0"; - case ImageRotationMode::Rotate90: return "kRotate90"; - case ImageRotationMode::Rotate180: return "kRotate180"; - case ImageRotationMode::Rotate270: return "kRotate270"; - default: - return fmt::format("ImageRotationMode({})", static_cast(mode)); +std::string stringfy(const ImageRotationMode &mode) { + switch (mode) { + case ImageRotationMode::Rotate0: + return "kRotate0"; + case ImageRotationMode::Rotate90: + return "kRotate90"; + case ImageRotationMode::Rotate180: + return "kRotate180"; + case ImageRotationMode::Rotate270: + return "kRotate270"; + default: + return fmt::format("ImageRotationMode({})", static_cast(mode)); }; } - -std::string stringfy(const ImageFilterMode &mode) -{ - switch (mode) - { - case ImageFilterMode::Nearest : return "kNearest"; - case ImageFilterMode::Bilinear : return "kBilinear"; - case ImageFilterMode::Bicubic : return "kBicubic"; - default: - return fmt::format("ImageFilterMode({})", static_cast(mode)); +std::string stringfy(const ImageFilterMode &mode) { + switch (mode) { + case ImageFilterMode::Nearest: + return "kNearest"; + case ImageFilterMode::Bilinear: + return "kBilinear"; + case ImageFilterMode::Bicubic: + return "kBicubic"; + default: + return fmt::format("ImageFilterMode({})", static_cast(mode)); } } - -std::string stringfy(const ImageAxis &axis) -{ - switch(axis){ - case ImageAxis::Horizontal : return "kHorizontal"; - case ImageAxis::Vertical : return "kVertical"; - case ImageAxis::HorizontalAndVertical: return "kHorizontalAndVertical"; - default: - return fmt::format("ImageAxis({})", static_cast(axis)); +std::string stringfy(const ImageAxis &axis) { + switch (axis) { + case ImageAxis::Horizontal: + return "kHorizontal"; + case ImageAxis::Vertical: + return "kVertical"; + case ImageAxis::HorizontalAndVertical: + return "kHorizontalAndVertical"; + default: + return fmt::format("ImageAxis({})", static_cast(axis)); } } - -struct PixelFormatDesc::Private{ - PixelFormat format; // - ScalarType dtype; // - int nplanes; // - int32_t ratio[sMaxPlanes]; //ratio related to first plane, packed like `(height_ratio << 8) | width_ratio<<4 | channels` +struct PixelFormatDesc::Private { + PixelFormat format; // + ScalarType dtype; // + int nplanes; // + int32_t ratio[sMaxPlanes]; // ratio related to first plane, packed like + // `(height_ratio << 8) | width_ratio<<4 | + // channels` }; static PixelFormatDesc::Private sPixelFormatMetas[]{ // - PixelFormatDesc::Private{PixelFormat::PF_YUV420P, kUInt8, 3, {0x111, 0x221, 0x221, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_YUVJ420P, kUInt8, 3, {0x111, 0x221, 0x221, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_YUV422P, kUInt8, 3, {0x111, 0x121, 0x121, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_YUV444P, kUInt8, 3, {0x111, 0x111, 0x111, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_NV12, kUInt8, 2, {0x111, 0x222, 0x00, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_NV21, kUInt8, 2, {0x111, 0x222, 0x00, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_P010LE, kUInt16, 2, {0x111, 0x222, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_P016LE, kUInt16, 2, {0x111, 0x222, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_YUV422P10LE, kUInt16, 3, {0x111, 0x121, 0x121, 0x0}}, - PixelFormatDesc::Private{PixelFormat::PF_YUV420P10LE, kUInt16, 3, {0x111, 0x221, 0x221, 0x0}}, - - PixelFormatDesc::Private{PixelFormat::PF_GRAY8, kUInt8, 1, {0x111, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_YUVA420P, kUInt8, 4, {0x111, 0x221, 0x221, 0x111}}, // - PixelFormatDesc::Private{PixelFormat::PF_GRAY16, kUInt16, 1, {0x111, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_RGB24, kUInt8, 1, {0x113, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_BGR24, kUInt8, 1, {0x113, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_RGB48, kUInt16, 1, {0x113, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_YA8, kUInt8, 1, {0x112, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_RGBA32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_ARGB32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_ABGR32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_BGRA32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // - PixelFormatDesc::Private{PixelFormat::PF_RGBA64, kUInt16, 1, {0x114, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_YUV420P, kUInt8, 3, {0x111, 0x221, 0x221, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_YUVJ420P, kUInt8, 3, {0x111, 0x221, 0x221, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_YUV422P, kUInt8, 3, {0x111, 0x121, 0x121, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_YUV444P, kUInt8, 3, {0x111, 0x111, 0x111, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_NV12, kUInt8, 2, {0x111, 0x222, 0x00, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_NV21, kUInt8, 2, {0x111, 0x222, 0x00, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_P010LE, kUInt16, 2, {0x111, 0x222, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_P016LE, kUInt16, 2, {0x111, 0x222, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_YUV422P10LE, kUInt16, 3, {0x111, 0x121, 0x121, 0x0}}, + PixelFormatDesc::Private{ + PixelFormat::PF_YUV420P10LE, kUInt16, 3, {0x111, 0x221, 0x221, 0x0}}, + + PixelFormatDesc::Private{ + PixelFormat::PF_GRAY8, kUInt8, 1, {0x111, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_YUVA420P, kUInt8, 4, {0x111, 0x221, 0x221, 0x111}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_GRAY16, kUInt16, 1, {0x111, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_RGB24, kUInt8, 1, {0x113, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_BGR24, kUInt8, 1, {0x113, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_RGB48, kUInt16, 1, {0x113, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_YA8, kUInt8, 1, {0x112, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_RGBA32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_ARGB32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_ABGR32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_BGRA32, kUInt8, 1, {0x114, 0x00, 0x00, 0x0}}, // + PixelFormatDesc::Private{ + PixelFormat::PF_RGBA64, kUInt16, 1, {0x114, 0x00, 0x00, 0x0}}, // }; #define RC(v) ((v)&0xf) -#define RW(v) (((v)>>4)&0xf) -#define RH(v) (((v)>>8)&0xf) +#define RW(v) (((v) >> 4) & 0xf) +#define RH(v) (((v) >> 8) & 0xf) - -PixelFormatDesc::PixelFormatDesc(int format) - : pix_format_(format) -{ - for(size_t i = 0; i < sizeof(sPixelFormatMetas)/sizeof(Private); ++i){ - if(sPixelFormatMetas[i].format == format){ +PixelFormatDesc::PixelFormatDesc(int format) : pix_format_(format) { + for (size_t i = 0; i < sizeof(sPixelFormatMetas) / sizeof(Private); ++i) { + if (sPixelFormatMetas[i].format == format) { meta_ = &sPixelFormatMetas[i]; } } } -int PixelFormatDesc::nplanes() const -{ +int PixelFormatDesc::nplanes() const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); return meta_->nplanes; } -ScalarType PixelFormatDesc::dtype() const -{ +ScalarType PixelFormatDesc::dtype() const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); return meta_->dtype; } -int PixelFormatDesc::format() const -{ - return pix_format_; -} - +int PixelFormatDesc::format() const { return pix_format_; } -int PixelFormatDesc::channels(int plane) const -{ +int PixelFormatDesc::channels(int plane) const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); - HMP_REQUIRE(plane < meta_->nplanes, - "Plane index {} is out of range {}", plane, meta_->nplanes); + HMP_REQUIRE(plane < meta_->nplanes, "Plane index {} is out of range {}", + plane, meta_->nplanes); return RC(meta_->ratio[plane]); } -int PixelFormatDesc::infer_width(int width, int plane) const -{ +int PixelFormatDesc::infer_width(int width, int plane) const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); - HMP_REQUIRE(plane < meta_->nplanes, - "Plane index {} is out of range {}", plane, meta_->nplanes); - return width/RW(meta_->ratio[plane]); + HMP_REQUIRE(plane < meta_->nplanes, "Plane index {} is out of range {}", + plane, meta_->nplanes); + return width / RW(meta_->ratio[plane]); } -int PixelFormatDesc::infer_height(int height, int plane) const -{ +int PixelFormatDesc::infer_height(int height, int plane) const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); - HMP_REQUIRE(plane < meta_->nplanes, - "Plane index {} is out of range {}", plane, meta_->nplanes); - return height/RH(meta_->ratio[plane]); + HMP_REQUIRE(plane < meta_->nplanes, "Plane index {} is out of range {}", + plane, meta_->nplanes); + return height / RH(meta_->ratio[plane]); } - -int PixelFormatDesc::infer_nitems(int width, int height) const -{ +int PixelFormatDesc::infer_nitems(int width, int height) const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); int nitems = 0; - for(int i = 0; i < nplanes(); ++i){ + for (int i = 0; i < nplanes(); ++i) { nitems += infer_nitems(width, height, i); } return nitems; } -int PixelFormatDesc::infer_nitems(int width, int height, int plane) const -{ +int PixelFormatDesc::infer_nitems(int width, int height, int plane) const { HMP_REQUIRE(defined(), "PixelFormat {} is not supported", pix_format_); - return infer_width(width, plane) * infer_height(height, plane) * channels(plane); + return infer_width(width, plane) * infer_height(height, plane) * + channels(plane); } -static std::unordered_map PixelFormatStringfyMap { -#define ADDPAIR(name) {"k"#name, name}, +static std::unordered_map PixelFormatStringfyMap{ +#define ADDPAIR(name) {"k" #name, name}, HMP_FORALL_PIXEL_FORMATS(ADDPAIR) #undef ADDPAIR }; PixelFormat get_pixel_format(std::string pixfmt) { auto it = PixelFormatStringfyMap.find(pixfmt); - if(it != PixelFormatStringfyMap.end()) { + if (it != PixelFormatStringfyMap.end()) { return it->second; } return PF_NONE; } -} //namespace hmp +} // namespace hmp diff --git a/bmf/hml/src/imgproc/image.cpp b/bmf/hml/src/imgproc/image.cpp index 44f6fcad..65b97bee 100644 --- a/bmf/hml/src/imgproc/image.cpp +++ b/bmf/hml/src/imgproc/image.cpp @@ -17,98 +17,82 @@ #include #include -namespace hmp{ +namespace hmp { -Frame::Frame(const TensorList &data, int width, int height, const PixelInfo& pix_info) - : pix_info_(pix_info), width_(width), height_(height) -{ +Frame::Frame(const TensorList &data, int width, int height, + const PixelInfo &pix_info) + : pix_info_(pix_info), width_(width), height_(height) { pix_desc_ = PixelFormatDesc(pix_info_.format()); // convert to HWC layout if pixel format is supported - if(pix_desc_.defined()){ + if (pix_desc_.defined()) { data_ = img::frame_format(data, pix_desc_, width, height); - } - else{ + } else { data_ = data; } } Frame::Frame(const TensorList &data, const PixelInfo &pix_info) - : Frame(data, data[0].size(1), data[0].size(0), pix_info) -{ -} + : Frame(data, data[0].size(1), data[0].size(0), pix_info) {} Frame::Frame(const Tensor &data, const PixelInfo &pix_info) - : Frame({data}, data.size(1), data.size(0), pix_info) -{ -} + : Frame({data}, data.size(1), data.size(0), pix_info) {} - -Frame::Frame(int width, int height, const PixelInfo &pix_info, const Device &device) - : pix_info_(pix_info), width_(width), height_(height) -{ +Frame::Frame(int width, int height, const PixelInfo &pix_info, + const Device &device) + : pix_info_(pix_info), width_(width), height_(height) { pix_desc_ = PixelFormatDesc(pix_info_.format()); - HMP_REQUIRE(pix_desc_.defined(), - "PixelFormat {} is not supported by hmp", pix_info_.format()); + HMP_REQUIRE(pix_desc_.defined(), "PixelFormat {} is not supported by hmp", + pix_info_.format()); auto options = TensorOptions(device).dtype(pix_desc_.dtype()); - for(int i = 0; i < pix_desc_.nplanes(); ++i){ + for (int i = 0; i < pix_desc_.nplanes(); ++i) { SizeArray shape{pix_desc_.infer_height(height, i), - pix_desc_.infer_width(width, i), - pix_desc_.channels(i)}; + pix_desc_.infer_width(width, i), pix_desc_.channels(i)}; data_.push_back(empty(shape, options)); } } - -Frame Frame::to(const Device &device, bool non_blocking) const -{ +Frame Frame::to(const Device &device, bool non_blocking) const { TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { out.push_back(d.to(device, non_blocking)); } return Frame(out, width_, height_, pix_info_); } - -Frame Frame::to(DeviceType device, bool non_blocking) const -{ +Frame Frame::to(DeviceType device, bool non_blocking) const { TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { out.push_back(d.to(device, non_blocking)); } return Frame(out, width_, height_, pix_info_); } - - -Frame &Frame::copy_(const Frame &from) -{ - HMP_REQUIRE(format() == from.format(), - "Can't copy from different PixelFormat {}, expect {}", - from.format(), format()); - for(size_t i = 0; i < data_.size(); ++i){ +Frame &Frame::copy_(const Frame &from) { + HMP_REQUIRE(format() == from.format(), + "Can't copy from different PixelFormat {}, expect {}", + from.format(), format()); + for (size_t i = 0; i < data_.size(); ++i) { data_[i].copy_(from.data_[i]); } return *this; } -Frame Frame::clone() const -{ +Frame Frame::clone() const { TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { out.push_back(d.clone()); } return Frame(out, width_, height_, pix_info_); } - -Frame Frame::crop(int left, int top, int w, int h) const -{ - HMP_REQUIRE(pix_desc_.defined(), - "Frame::crop: pixel format {} is not supported", pix_desc_.format()); +Frame Frame::crop(int left, int top, int w, int h) const { + HMP_REQUIRE(pix_desc_.defined(), + "Frame::crop: pixel format {} is not supported", + pix_desc_.format()); auto width = this->width(); auto height = this->height(); @@ -117,24 +101,26 @@ Frame Frame::crop(int left, int top, int w, int h) const auto right = left + w; auto bottom = top + h; - HMP_REQUIRE(left < right && right <= width, - "Frame::crop expect left({}) < right({}) and right <= {}", left, right, width); - HMP_REQUIRE(top < bottom && bottom <= height, - "Frame::crop expect top({}) < bottom({}) and bottom <= {}", top, bottom, height); - - //normalize - double left_d = double(left)/width; - double right_d = double(right)/width; - double bottom_d = double(bottom)/height; - double top_d = double(top)/height; + HMP_REQUIRE(left < right && right <= width, + "Frame::crop expect left({}) < right({}) and right <= {}", left, + right, width); + HMP_REQUIRE(top < bottom && bottom <= height, + "Frame::crop expect top({}) < bottom({}) and bottom <= {}", top, + bottom, height); + + // normalize + double left_d = double(left) / width; + double right_d = double(right) / width; + double bottom_d = double(bottom) / height; + double top_d = double(top) / height; // TensorList out; - for(auto &d : data_){ - auto l = int(std::round(left_d*d.size(1))); - auto r = int(std::round(right_d*d.size(1))); - auto b = int(std::round(bottom_d*d.size(0))); - auto t = int(std::round(top_d*d.size(0))); + for (auto &d : data_) { + auto l = int(std::round(left_d * d.size(1))); + auto r = int(std::round(right_d * d.size(1))); + auto b = int(std::round(bottom_d * d.size(0))); + auto t = int(std::round(top_d * d.size(0))); out.push_back(d.slice(0, t, b).slice(1, l, r)); } @@ -142,16 +128,17 @@ Frame Frame::crop(int left, int top, int w, int h) const return Frame(out, w, h, pix_info_); } -PixelFormat format420_list[] = {PF_YUV420P, PF_NV12, PF_NV21, PF_P010LE, PF_YUV420P10LE}; +PixelFormat format420_list[] = {PF_YUV420P, PF_NV12, PF_NV21, PF_P010LE, + PF_YUV420P10LE}; static bool is_420(const PixelFormat &pix_fmt) { for (auto i : format420_list) { - if (pix_fmt == i) return true; + if (pix_fmt == i) + return true; } return false; } -Frame Frame::reformat(const PixelInfo &pix_info) -{ +Frame Frame::reformat(const PixelInfo &pix_info) { if (pix_info_.format() == PF_RGB24 || pix_info_.format() == PF_RGB48) { auto yuv = img::rgb_to_yuv(data_[0], pix_info, kNHWC); return Frame(yuv, width_, height_, pix_info); @@ -163,15 +150,15 @@ Frame Frame::reformat(const PixelInfo &pix_info) auto yuv = img::yuv_to_yuv(data_, pix_info, pix_info_); return Frame(yuv, width_, height_, pix_info); } - - HMP_REQUIRE(false, "{} to {} not support", stringfy(pix_info_.format()), stringfy(pix_info.format())); + + HMP_REQUIRE(false, "{} to {} not support", stringfy(pix_info_.format()), + stringfy(pix_info.format())); } -std::string stringfy(const Frame &frame) -{ - return fmt::format("Frame({}, {}, {}, ({}, {}, {}))", - frame.device(), frame.dtype(), frame.format(), - frame.nplanes(), frame.height(), frame.width()); +std::string stringfy(const Frame &frame) { + return fmt::format("Frame({}, {}, {}, ({}, {}, {}))", frame.device(), + frame.dtype(), frame.format(), frame.nplanes(), + frame.height(), frame.width()); } -} //namespace hmp +} // namespace hmp diff --git a/bmf/hml/src/imgproc/image_seq.cpp b/bmf/hml/src/imgproc/image_seq.cpp index d386d63b..1cca2295 100644 --- a/bmf/hml/src/imgproc/image_seq.cpp +++ b/bmf/hml/src/imgproc/image_seq.cpp @@ -17,53 +17,43 @@ #include #include -namespace hmp{ +namespace hmp { /////////////////////////// FrameSeq ///////////////////////// FrameSeq::FrameSeq(const TensorList &data, const PixelInfo &pix_info) - : pix_info_(pix_info), pix_desc_(pix_info.format()) -{ - HMP_REQUIRE(pix_desc_.defined(), - "Unsupported PixelFormat {}", pix_info.format()); - - for(auto &d : data){ - if(d.dim() == 3){ - data_.push_back(d.unsqueeze(-1)); //add channel dim - } - else{ + : pix_info_(pix_info), pix_desc_(pix_info.format()) { + HMP_REQUIRE(pix_desc_.defined(), "Unsupported PixelFormat {}", + pix_info.format()); + + for (auto &d : data) { + if (d.dim() == 3) { + data_.push_back(d.unsqueeze(-1)); // add channel dim + } else { data_.push_back(d.alias()); } } } -FrameSeq::operator bool() const -{ - return data_.size() > 0; -} +FrameSeq::operator bool() const { return data_.size() > 0; } -FrameSeq FrameSeq::to(const Device &device, bool non_blocking) const -{ +FrameSeq FrameSeq::to(const Device &device, bool non_blocking) const { TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { out.push_back(d.to(device, non_blocking)); } return FrameSeq(out, pix_info_); } - -FrameSeq FrameSeq::to(DeviceType device, bool non_blocking) const -{ +FrameSeq FrameSeq::to(DeviceType device, bool non_blocking) const { TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { out.push_back(d.to(device, non_blocking)); } return FrameSeq(out, pix_info_); } - -FrameSeq FrameSeq::crop(int left, int top, int w, int h) const -{ +FrameSeq FrameSeq::crop(int left, int top, int w, int h) const { auto width = this->width(); auto height = this->height(); left = wrap_size(left, width); @@ -71,24 +61,26 @@ FrameSeq FrameSeq::crop(int left, int top, int w, int h) const auto right = left + w; auto bottom = top + h; - HMP_REQUIRE(left < right && right <= width, - "FrameSeq::crop expect left({}) < right({}) and right <= {}", left, right, width); - HMP_REQUIRE(top < bottom && bottom <= height, - "FrameSeq::crop expect top({}) < bottom({}) and bottom <= {}", top, bottom, height); - - //normalize - double left_d = double(left)/width; - double right_d = double(right)/width; - double bottom_d = double(bottom)/height; - double top_d = double(top)/height; + HMP_REQUIRE(left < right && right <= width, + "FrameSeq::crop expect left({}) < right({}) and right <= {}", + left, right, width); + HMP_REQUIRE(top < bottom && bottom <= height, + "FrameSeq::crop expect top({}) < bottom({}) and bottom <= {}", + top, bottom, height); + + // normalize + double left_d = double(left) / width; + double right_d = double(right) / width; + double bottom_d = double(bottom) / height; + double top_d = double(top) / height; // TensorList out; - for(auto &d : data_){ - auto l = int(std::round(left_d*d.size(2))); - auto r = int(std::round(right_d*d.size(2))); - auto b = int(std::round(bottom_d*d.size(1))); - auto t = int(std::round(top_d*d.size(1))); + for (auto &d : data_) { + auto l = int(std::round(left_d * d.size(2))); + auto r = int(std::round(right_d * d.size(2))); + auto b = int(std::round(bottom_d * d.size(1))); + auto t = int(std::round(top_d * d.size(1))); out.push_back(d.slice(1, t, b).slice(2, l, r)); } @@ -96,33 +88,30 @@ FrameSeq FrameSeq::crop(int left, int top, int w, int h) const return FrameSeq(out, pix_info_); } -Frame FrameSeq::operator[](int64_t index) const -{ +Frame FrameSeq::operator[](int64_t index) const { HMP_REQUIRE(index < batch(), "FrameSeq: index out of range"); TensorList planes; - for(auto &d : data_){ + for (auto &d : data_) { planes.push_back(d.select(0, index)); } return Frame(planes, pix_info_); } -FrameSeq FrameSeq::slice(int64_t start, optional end) const -{ +FrameSeq FrameSeq::slice(int64_t start, optional end) const { TensorList data; - for(auto &d : data_){ + for (auto &d : data_) { data.push_back(d.slice(0, start, end)); } return FrameSeq(data, pix_info_); } - -//Tensor FrameSeq::to_rgb(ChannelFormat cformat) const +// Tensor FrameSeq::to_rgb(ChannelFormat cformat) const //{ // return to_image(cformat).data(); //} -//ImageSeq FrameSeq::to_image(ChannelFormat cformat) const +// ImageSeq FrameSeq::to_image(ChannelFormat cformat) const //{ // if(pix_info_.is_rgbx()){ // HMP_REQUIRE(data_.size() == 1, "Internal error"); @@ -137,15 +126,13 @@ FrameSeq FrameSeq::slice(int64_t start, optional end) const // } //} - -FrameSeq FrameSeq::resize(int width, int height, ImageFilterMode mode) const -{ - if(!pix_info_.is_rgbx()){ +FrameSeq FrameSeq::resize(int width, int height, ImageFilterMode mode) const { + if (!pix_info_.is_rgbx()) { auto wscale = double(width) / this->width(); - auto hscale = double(height) / this->height(); + auto hscale = double(height) / this->height(); TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { auto w = int64_t(std::round(d.size(2) * wscale)); auto h = int64_t(std::round(d.size(1) * hscale)); auto shape = d.shape(); @@ -156,55 +143,48 @@ FrameSeq FrameSeq::resize(int width, int height, ImageFilterMode mode) const out = img::yuv_resize(out, data_, pix_info_, mode); return FrameSeq(out, pix_info_); - } - else{ + } else { auto out = img::resize(data_[0], width, height, mode, kNHWC); return FrameSeq({out}, pix_info_); } } - -FrameSeq FrameSeq::rotate(ImageRotationMode mode) const -{ - if(!pix_info_.is_rgbx()){ - bool shapeChanged = mode == ImageRotationMode::Rotate90 || mode == ImageRotationMode::Rotate270; +FrameSeq FrameSeq::rotate(ImageRotationMode mode) const { + if (!pix_info_.is_rgbx()) { + bool shapeChanged = mode == ImageRotationMode::Rotate90 || + mode == ImageRotationMode::Rotate270; TensorList out; - for(auto &d : data_){ + for (auto &d : data_) { auto shape = d.shape(); - if(shapeChanged){ - std::swap(shape[d.dim()-2], shape[d.dim()-3]); + if (shapeChanged) { + std::swap(shape[d.dim() - 2], shape[d.dim() - 3]); } out.push_back(empty(shape, d.options())); } out = img::yuv_rotate(out, data_, pix_info_, mode); return FrameSeq(out, pix_info_); - } - else{ + } else { auto out = img::rotate(data_[0], mode, kNHWC); return FrameSeq({out}, pix_info_); } } - -FrameSeq FrameSeq::mirror(ImageAxis axis) const -{ - if(!pix_info_.is_rgbx()){ +FrameSeq FrameSeq::mirror(ImageAxis axis) const { + if (!pix_info_.is_rgbx()) { TensorList out; - for(auto &d: data_){ + for (auto &d : data_) { out.push_back(empty_like(d, d.options())); } out = img::yuv_mirror(out, data_, pix_info_, axis); return FrameSeq(out, pix_info_); - } - else{ + } else { auto out = img::mirror(data_[0], axis, kNHWC); return FrameSeq({out}, pix_info_); } } -FrameSeq FrameSeq::reformat(const PixelInfo &pix_info) -{ +FrameSeq FrameSeq::reformat(const PixelInfo &pix_info) { if (pix_info_.format() == PF_RGB24) { auto yuv = img::rgb_to_yuv(data_[0], pix_info, kNHWC); return FrameSeq(yuv, pix_info); @@ -214,71 +194,74 @@ FrameSeq FrameSeq::reformat(const PixelInfo &pix_info) return FrameSeq({rgb}, pix_info); } - HMP_REQUIRE(false, "{} to {} not support", stringfy(pix_info_.format()), stringfy(pix_info.format())); + HMP_REQUIRE(false, "{} to {} not support", stringfy(pix_info_.format()), + stringfy(pix_info.format())); } - -FrameSeq concat(const std::vector &frames) -{ +FrameSeq concat(const std::vector &frames) { HMP_REQUIRE(frames.size(), "Frame::concat: expect at least 1 frame"); - for(size_t i = 1; i < frames.size(); ++i){ - HMP_REQUIRE(frames[i].format() == frames[0].format(), + for (size_t i = 1; i < frames.size(); ++i) { + HMP_REQUIRE( + frames[i].format() == frames[0].format(), "Frame::concat: got unexpect pixel format {} at {}, expect {}", frames[i].format(), i, frames[0].format()); - HMP_REQUIRE(frames[i].width() == frames[0].width() - && frames[i].height() == frames[0].height() - && frames[i].nplanes() == frames[0].nplanes(), - "Frame::concat: expect all frame have same shape"); + HMP_REQUIRE(frames[i].width() == frames[0].width() && + frames[i].height() == frames[0].height() && + frames[i].nplanes() == frames[0].nplanes(), + "Frame::concat: expect all frame have same shape"); } - //do tensor concat + // do tensor concat TensorList planes; - for(int64_t p = 0; p < frames[0].nplanes(); ++p){ + for (int64_t p = 0; p < frames[0].nplanes(); ++p) { TensorList tensors; - for (size_t i = 0; i < frames.size(); ++i){ - tensors.push_back(frames[i].plane(p).unsqueeze(0)); //add batch dim + for (size_t i = 0; i < frames.size(); ++i) { + tensors.push_back(frames[i].plane(p).unsqueeze(0)); // add batch dim } - //concat along axis=0 + // concat along axis=0 planes.push_back(hmp::concat(tensors, 0)); } - return FrameSeq(planes, frames[0].pix_info()); } -FrameSeq concat(const std::vector &frames) -{ +FrameSeq concat(const std::vector &frames) { HMP_REQUIRE(frames.size(), "FrameSeq::concat: require frames.size() > 0"); - //check - for(size_t i = 1; i < frames.size(); ++i){ + // check + for (size_t i = 1; i < frames.size(); ++i) { HMP_REQUIRE(frames[i].format() == frames[0].format(), - "FrameSeq::concat expect all frame have same format {}, got {} at {}", frames[0].format(), frames[i].format(), i); - HMP_REQUIRE(frames[i].width() == frames[0].width() && frames[i].height() == frames[0].height(), - "FrameSeq::concat expect all frame have same size ({}, {}), got ({}, {}) at {}", - frames[0].width(), frames[0].height(), frames[i].width(), frames[i].height(), i); + "FrameSeq::concat expect all frame have same format {}, " + "got {} at {}", + frames[0].format(), frames[i].format(), i); + HMP_REQUIRE(frames[i].width() == frames[0].width() && + frames[i].height() == frames[0].height(), + "FrameSeq::concat expect all frame have same size ({}, " + "{}), got ({}, {}) at {}", + frames[0].width(), frames[0].height(), frames[i].width(), + frames[i].height(), i); } - //do tensor concat + // do tensor concat TensorList planes; - for(int64_t p = 0; p < frames[0].nplanes(); ++p){ + for (int64_t p = 0; p < frames[0].nplanes(); ++p) { TensorList tensors; - for (size_t i = 0; i < frames.size(); ++i){ + for (size_t i = 0; i < frames.size(); ++i) { tensors.push_back(frames[i].plane(p)); } - //concat along axis=0 + // concat along axis=0 planes.push_back(hmp::concat(tensors, 0)); } return FrameSeq(planes, frames[0].pix_info()); } -std::string stringfy(const FrameSeq &frames) -{ +std::string stringfy(const FrameSeq &frames) { return fmt::format("FrameSeq({}, {}, {}, ({}, {}, {}, {}))", - frames.device(), frames.dtype(), frames.format(), - frames.batch(), frames.nplanes(), frames.height(), frames.width()); + frames.device(), frames.dtype(), frames.format(), + frames.batch(), frames.nplanes(), frames.height(), + frames.width()); } } // diff --git a/bmf/hml/src/imgproc/imgproc.cpp b/bmf/hml/src/imgproc/imgproc.cpp index 549001d5..a41f3f1e 100644 --- a/bmf/hml/src/imgproc/imgproc.cpp +++ b/bmf/hml/src/imgproc/imgproc.cpp @@ -18,89 +18,80 @@ #include #include -namespace hmp{ -namespace img{ +namespace hmp { +namespace img { - -TensorList frame_format(const TensorList &data, const PixelFormatDesc &pix_desc, int width, int height, bool has_batch) -{ - HMP_REQUIRE(data.size() == pix_desc.nplanes(), - "Expect {} planes for pixel format {}, got {}", - pix_desc.nplanes(), pix_desc.format(), data.size()); +TensorList frame_format(const TensorList &data, const PixelFormatDesc &pix_desc, + int width, int height, bool has_batch) { + HMP_REQUIRE(data.size() == pix_desc.nplanes(), + "Expect {} planes for pixel format {}, got {}", + pix_desc.nplanes(), pix_desc.format(), data.size()); TensorList out; - for(int i = 0; i < data.size(); ++i){ + for (int i = 0; i < data.size(); ++i) { SizeArray shape{pix_desc.infer_height(height, i), - pix_desc.infer_width(width, i), - pix_desc.channels(i)}; - if(has_batch){ + pix_desc.infer_width(width, i), pix_desc.channels(i)}; + if (has_batch) { shape.insert(shape.begin(), data[i].size(0)); } HMP_REQUIRE(data[i].dtype() == pix_desc.dtype(), - "Expect {} for pixel format {}, got {}", - pix_desc.dtype(), pix_desc.format(), data[i].dtype()); + "Expect {} for pixel format {}, got {}", pix_desc.dtype(), + pix_desc.format(), data[i].dtype()); out.push_back(data[i].view(shape)); } return out; } -TensorList frame_format(const TensorList &data, PixelFormat format, int width, int height, bool has_batch) -{ - return frame_format(data, PixelFormatDesc(format), width, height, has_batch); +TensorList frame_format(const TensorList &data, PixelFormat format, int width, + int height, bool has_batch) { + return frame_format(data, PixelFormatDesc(format), width, height, + has_batch); } - -TensorList frame_format(const TensorList &data, PixelFormat format, bool has_batch) -{ - HMP_REQUIRE(data[0].dim() >= 2 + has_batch, - "Infer frame size failed, expect ndim >= {}, got {}", - 2 + has_batch, data[0].dim()); +TensorList frame_format(const TensorList &data, PixelFormat format, + bool has_batch) { + HMP_REQUIRE(data[0].dim() >= 2 + has_batch, + "Infer frame size failed, expect ndim >= {}, got {}", + 2 + has_batch, data[0].dim()); int hdim = has_batch ? 1 : 0; - int width = data[0].size(hdim+1); + int width = data[0].size(hdim + 1); int height = data[0].size(hdim); return frame_format(data, format, width, height, has_batch); } - -Tensor image_format(const Tensor &image, ChannelFormat cformat, bool batch_first) -{ - if(image.dim() == 4){ +Tensor image_format(const Tensor &image, ChannelFormat cformat, + bool batch_first) { + if (image.dim() == 4) { return image; - } - else if(image.dim() == 3){ //add batch dim - if(batch_first){ + } else if (image.dim() == 3) { // add batch dim + if (batch_first) { return image.unsqueeze(0); - } - else{ - if(cformat == kNCHW){ + } else { + if (cformat == kNCHW) { return image.unsqueeze(1); - } - else{ + } else { return image.unsqueeze(3); } } - } - else if(image.dim() == 2){ - if(cformat == kNCHW){ + } else if (image.dim() == 2) { + if (cformat == kNCHW) { return image.unsqueeze(0).unsqueeze(1); - } - else{ + } else { return image.unsqueeze(0).unsqueeze(3); } - } - else{ - HMP_REQUIRE(false, "Image data need at least 2 dims and less than or equal to 4 dims, got {}", - image.dim()); + } else { + HMP_REQUIRE(false, "Image data need at least 2 dims and less than or " + "equal to 4 dims, got {}", + image.dim()); } } - -TensorList image_format(const TensorList &images, ChannelFormat cformat, bool batch_first) -{ +TensorList image_format(const TensorList &images, ChannelFormat cformat, + bool batch_first) { TensorList vimages; - for(auto &img : images){ + for (auto &img : images) { vimages.push_back(image_format(img, cformat, batch_first)); } return vimages; @@ -108,139 +99,127 @@ TensorList image_format(const TensorList &images, ChannelFormat cformat, bool ba #ifndef HMP_ENABLE_MOBILE - -static SizeArray remove_cdim(const Tensor &src, ChannelFormat cformat) -{ +static SizeArray remove_cdim(const Tensor &src, ChannelFormat cformat) { SizeArray shape; - if(src.dim() >= 3){ - if(cformat == kNCHW){ + if (src.dim() >= 3) { + if (cformat == kNCHW) { shape = {1, src.size(-2), src.size(-1)}; - } - else{ + } else { shape = {src.size(-3), src.size(-2), 1}; } } - if(src.dim() == 4){ + if (src.dim() == 4) { shape.insert(shape.begin(), src.size(0)); } return shape; -} - +} -static int infer_wdim(const Tensor &im, ChannelFormat cformat) -{ +static int infer_wdim(const Tensor &im, ChannelFormat cformat) { HMP_REQUIRE(im.dim() >= 2, "Image need at least 2 dims, got {}", im.dim()); return (cformat == kNCHW || im.dim() == 2) ? im.dim() - 1 : im.dim() - 2; } - -static PPixelFormat infer_ppixel_format(const PixelInfo &info) -{ +static PPixelFormat infer_ppixel_format(const PixelInfo &info) { auto space = info.infer_space(); - if(space == CS_BT709){ - switch(info.format()){ - case PF_YUV420P: - return PPixelFormat::H420; - case PF_YUV422P: - return PPixelFormat::H422; - case PF_YUV444P: - return PPixelFormat::H444; - case PF_NV12: - return PPixelFormat::NV12_BT709; - case PF_NV21: - return PPixelFormat::NV21_BT709; - default: - HMP_REQUIRE(false, "Unsupport PixelInfo"); + if (space == CS_BT709) { + switch (info.format()) { + case PF_YUV420P: + return PPixelFormat::H420; + case PF_YUV422P: + return PPixelFormat::H422; + case PF_YUV444P: + return PPixelFormat::H444; + case PF_NV12: + return PPixelFormat::NV12_BT709; + case PF_NV21: + return PPixelFormat::NV21_BT709; + default: + HMP_REQUIRE(false, "Unsupport PixelInfo"); } - } - else if(space == CS_BT470BG){ - switch(info.format()){ - case PF_YUV420P: - return PPixelFormat::I420; - case PF_YUV422P: - return PPixelFormat::I422; - case PF_YUV444P: - return PPixelFormat::I444; - case PF_NV12: - return PPixelFormat::NV12; - case PF_NV21: - return PPixelFormat::NV21; - default: - HMP_REQUIRE(false, "Unsupport PixelInfo"); + } else if (space == CS_BT470BG) { + switch (info.format()) { + case PF_YUV420P: + return PPixelFormat::I420; + case PF_YUV422P: + return PPixelFormat::I422; + case PF_YUV444P: + return PPixelFormat::I444; + case PF_NV12: + return PPixelFormat::NV12; + case PF_NV21: + return PPixelFormat::NV21; + default: + HMP_REQUIRE(false, "Unsupport PixelInfo"); } - } - else if(space == CS_BT2020_NCL || space == CS_BT2020_CL){ - switch(info.format()){ - case PF_P010LE: - return PPixelFormat::P010; - case PF_YUV420P10LE: - return PPixelFormat::U420; - case PF_YUV422P10LE: - return PPixelFormat::U422; - case PF_YUV444P10LE: - return PPixelFormat::U444; - default: - HMP_REQUIRE(false, "Unsupport PixelInfo"); + } else if (space == CS_BT2020_NCL || space == CS_BT2020_CL) { + switch (info.format()) { + case PF_P010LE: + return PPixelFormat::P010; + case PF_YUV420P10LE: + return PPixelFormat::U420; + case PF_YUV422P10LE: + return PPixelFormat::U422; + case PF_YUV444P10LE: + return PPixelFormat::U444; + default: + HMP_REQUIRE(false, "Unsupport PixelInfo"); } } HMP_REQUIRE(false, "Unsupport PixelInfo"); } - -Tensor &yuv_to_rgb(Tensor &dst, const TensorList &src, const PixelInfo &pix_info, ChannelFormat cformat) -{ +Tensor &yuv_to_rgb(Tensor &dst, const TensorList &src, + const PixelInfo &pix_info, ChannelFormat cformat) { auto pformat = infer_ppixel_format(pix_info); return kernel::yuv_to_rgb(dst, src, pformat, cformat); } -Tensor yuv_to_rgb(const TensorList &src, const PixelInfo &pix_info, ChannelFormat cformat) -{ +Tensor yuv_to_rgb(const TensorList &src, const PixelInfo &pix_info, + ChannelFormat cformat) { auto has_batch_dim = src[0].dim() == 4; auto stmp = frame_format(src, pix_info.format(), has_batch_dim); - + auto dshape = SizeArray(4, 0); auto batch = has_batch_dim ? stmp[0].size(0) : int64_t(1); auto width = has_batch_dim ? stmp[0].size(2) : stmp[0].size(1); auto height = has_batch_dim ? stmp[0].size(1) : stmp[0].size(0); - if(cformat == ChannelFormat::NCHW){ + if (cformat == ChannelFormat::NCHW) { dshape = {batch, int64_t(3), height, width}; - } - else{ + } else { dshape = {batch, height, width, int64_t(3)}; } auto dst = empty(dshape, stmp[0].options()); dst = yuv_to_rgb(dst, src, pix_info, cformat); - if(!has_batch_dim){ + if (!has_batch_dim) { dst.squeeze_(0); } return dst; } -TensorList &rgb_to_yuv(TensorList &dst, const Tensor &src, const PixelInfo &pix_info, ChannelFormat cformat) -{ +TensorList &rgb_to_yuv(TensorList &dst, const Tensor &src, + const PixelInfo &pix_info, ChannelFormat cformat) { auto pformat = infer_ppixel_format(pix_info); return kernel::rgb_to_yuv(dst, src, pformat, cformat); } - -TensorList rgb_to_yuv(const Tensor &src, const PixelInfo &pix_info, ChannelFormat cformat) -{ +TensorList rgb_to_yuv(const Tensor &src, const PixelInfo &pix_info, + ChannelFormat cformat) { auto wdim = infer_wdim(src, cformat); auto hdim = wdim - 1; auto pix_desc = PixelFormatDesc(pix_info.format()); TensorList dst; auto has_batch_dim = src.dim() == 4; - for(int i = 0; i < pix_desc.nplanes(); ++i){ + for (int i = 0; i < pix_desc.nplanes(); ++i) { auto width = pix_desc.infer_width(src.size(wdim), i); auto height = pix_desc.infer_height(src.size(hdim), i); auto channels = pix_desc.channels(i); - if(has_batch_dim){ - dst.push_back(empty({src.size(0), height, width, channels}, src.options())); - } - else{ + if (has_batch_dim) { + dst.push_back( + empty({src.size(0), height, width, channels}, src.options())); + } else { dst.push_back(empty({height, width, channels}, src.options())); } } @@ -249,17 +228,17 @@ TensorList rgb_to_yuv(const Tensor &src, const PixelInfo &pix_info, ChannelForma } TensorList &yuv_to_yuv(TensorList &dst, const TensorList &src, - const PixelInfo &dpix_info, const PixelInfo &spix_info) -{ + const PixelInfo &dpix_info, const PixelInfo &spix_info) { auto src_format = infer_ppixel_format(spix_info); auto dst_format = infer_ppixel_format(dpix_info); - HMP_REQUIRE(src_format != dst_format, "yuv_to_yuv: src and dst format cannot be the same."); + HMP_REQUIRE(src_format != dst_format, + "yuv_to_yuv: src and dst format cannot be the same."); return kernel::yuv_to_yuv(dst, src, dst_format, src_format); } -TensorList yuv_to_yuv(const TensorList &src, const PixelInfo &dpix_info, const PixelInfo &spix_info) -{ +TensorList yuv_to_yuv(const TensorList &src, const PixelInfo &dpix_info, + const PixelInfo &spix_info) { TensorList dst; auto has_batch_dim = src[0].dim() == 4; // auto pix_desc = PixelFormatDesc(spix_info.format()); @@ -270,60 +249,68 @@ TensorList yuv_to_yuv(const TensorList &src, const PixelInfo &dpix_info, const P // auto width = src[0].size(wdim); // auto height = src[0].size(hdim); int shift = 0; - if ((dpix_info.format() == PF_NV12 || dpix_info.format() == PF_NV12 || dpix_info.format() == PF_P010LE) && - (spix_info.format() == PF_YUV420P || spix_info.format() == PF_YUV420P10LE)) { + if ((dpix_info.format() == PF_NV12 || dpix_info.format() == PF_NV12 || + dpix_info.format() == PF_P010LE) && + (spix_info.format() == PF_YUV420P || + spix_info.format() == PF_YUV420P10LE)) { shift = 0; - } - else if ((dpix_info.format() == PF_YUV420P || dpix_info.format() == PF_YUV420P10LE) && - (spix_info.format() == PF_NV12 || spix_info.format() == PF_NV12 || spix_info.format() == PF_P010LE)) { + } else if ((dpix_info.format() == PF_YUV420P || + dpix_info.format() == PF_YUV420P10LE) && + (spix_info.format() == PF_NV12 || + spix_info.format() == PF_NV12 || + spix_info.format() == PF_P010LE)) { shift = 1; - } - else { + } else { HMP_REQUIRE(false, "Unsupport PixelInfo"); } - if(has_batch_dim){ - dst.push_back(empty({src[0].size(0), height, width, 1}, src[0].options())); - dst.push_back(empty({src[0].size(0), (height + 1) >> shift, (width + 1) >> shift, 1}, src[0].options())); - dst.push_back(empty({src[0].size(0), (height + 1) >> shift, (width + 1) >> shift, 1}, src[0].options())); - } - else { + if (has_batch_dim) { + dst.push_back( + empty({src[0].size(0), height, width, 1}, src[0].options())); + dst.push_back(empty( + {src[0].size(0), (height + 1) >> shift, (width + 1) >> shift, 1}, + src[0].options())); + dst.push_back(empty( + {src[0].size(0), (height + 1) >> shift, (width + 1) >> shift, 1}, + src[0].options())); + } else { dst.push_back(empty({height, width, 1}, src[0].options())); - dst.push_back(empty({(height + 1) >> shift, (width + 1) >> shift, 1}, src[0].options())); - dst.push_back(empty({(height + 1) >> shift, (width + 1) >> shift, 1}, src[0].options())); + dst.push_back(empty({(height + 1) >> shift, (width + 1) >> shift, 1}, + src[0].options())); + dst.push_back(empty({(height + 1) >> shift, (width + 1) >> shift, 1}, + src[0].options())); } return yuv_to_yuv(dst, src, dpix_info, spix_info); } TensorList &yuv_resize(TensorList &dst, const TensorList &src, - const PixelInfo &pix_info, ImageFilterMode mode) -{ + const PixelInfo &pix_info, ImageFilterMode mode) { auto format = infer_ppixel_format(pix_info); return kernel::yuv_resize(dst, src, format, mode); } TensorList &yuv_rotate(TensorList &dst, const TensorList &src, - const PixelInfo &pix_info, ImageRotationMode rotate) -{ + const PixelInfo &pix_info, ImageRotationMode rotate) { auto format = infer_ppixel_format(pix_info); return kernel::yuv_rotate(dst, src, format, rotate); } -TensorList &yuv_mirror(TensorList &dst, const TensorList &src, const PixelInfo &pix_info, ImageAxis axis) -{ +TensorList &yuv_mirror(TensorList &dst, const TensorList &src, + const PixelInfo &pix_info, ImageAxis axis) { auto format = infer_ppixel_format(pix_info); return kernel::yuv_mirror(dst, src, format, axis); } -Tensor &resize(Tensor &dst, const Tensor &src, ImageFilterMode mode, ChannelFormat cformat) -{ +Tensor &resize(Tensor &dst, const Tensor &src, ImageFilterMode mode, + ChannelFormat cformat) { return kernel::img_resize(dst, src, mode, cformat); } -Tensor resize(const Tensor &src, int width, int height, ImageFilterMode mode, ChannelFormat cformat) -{ +Tensor resize(const Tensor &src, int width, int height, ImageFilterMode mode, + ChannelFormat cformat) { auto dshape = src.shape(); - auto wdim = (cformat == kNCHW || src.dim() == 2) ? src.dim() - 1 : src.dim() - 2; + auto wdim = + (cformat == kNCHW || src.dim() == 2) ? src.dim() - 1 : src.dim() - 2; auto hdim = wdim - 1; dshape[wdim] = width; dshape[hdim] = height; @@ -332,17 +319,19 @@ Tensor resize(const Tensor &src, int width, int height, ImageFilterMode mode, Ch return resize(dst, src, mode, cformat); } -Tensor &rotate(Tensor &dst, const Tensor &src, ImageRotationMode mode, ChannelFormat cformat) -{ +Tensor &rotate(Tensor &dst, const Tensor &src, ImageRotationMode mode, + ChannelFormat cformat) { return kernel::img_rotate(dst, src, mode, cformat); } -Tensor rotate(const Tensor &src, ImageRotationMode mode, ChannelFormat cformat) -{ +Tensor rotate(const Tensor &src, ImageRotationMode mode, + ChannelFormat cformat) { auto dshape = src.shape(); - auto wdim = (cformat == kNCHW || src.dim() == 2) ? src.dim() - 1 : src.dim() - 2; + auto wdim = + (cformat == kNCHW || src.dim() == 2) ? src.dim() - 1 : src.dim() - 2; auto hdim = wdim - 1; - if(mode == ImageRotationMode::Rotate90 || mode == ImageRotationMode::Rotate270){ + if (mode == ImageRotationMode::Rotate90 || + mode == ImageRotationMode::Rotate270) { std::swap(dshape[wdim], dshape[hdim]); } auto dst = empty(dshape, src.options()); @@ -350,152 +339,136 @@ Tensor rotate(const Tensor &src, ImageRotationMode mode, ChannelFormat cformat) return rotate(dst, src, mode, cformat); } -Tensor &mirror(Tensor &dst, const Tensor &src, ImageAxis axis, ChannelFormat cformat) -{ +Tensor &mirror(Tensor &dst, const Tensor &src, ImageAxis axis, + ChannelFormat cformat) { return kernel::img_mirror(dst, src, axis, cformat); } - -Tensor mirror(const Tensor &src, ImageAxis axis, ChannelFormat cformat) -{ +Tensor mirror(const Tensor &src, ImageAxis axis, ChannelFormat cformat) { auto dst = empty_like(src); return mirror(dst, src, axis, cformat); } -Tensor normalize(const Tensor &src, const Tensor &mean, const Tensor& std, ChannelFormat cformat) -{ +Tensor normalize(const Tensor &src, const Tensor &mean, const Tensor &std, + ChannelFormat cformat) { auto dst = empty_like(src, src.options().dtype(kFloat32)); return normalize(dst, src, mean, std, cformat); } -Tensor& normalize(Tensor &dst, const Tensor &src, const Tensor &mean, const Tensor &std, ChannelFormat cformat) -{ +Tensor &normalize(Tensor &dst, const Tensor &src, const Tensor &mean, + const Tensor &std, ChannelFormat cformat) { return kernel::img_normalize(dst, src, mean, std, cformat); } -Tensor &erode(Tensor &dst, const Tensor &src, const optional &kernel_, ChannelFormat cformat) -{ +Tensor &erode(Tensor &dst, const Tensor &src, const optional &kernel_, + ChannelFormat cformat) { Tensor kernel; - if(kernel_){ + if (kernel_) { kernel = kernel_.value(); - } - else{ + } else { kernel = ones({3, 3}, src.options().dtype(kFloat32)); } return kernel::img_erode(dst, src, kernel, cformat); } - -Tensor erode(const Tensor &src, const optional &kernel_, ChannelFormat cformat) -{ +Tensor erode(const Tensor &src, const optional &kernel_, + ChannelFormat cformat) { auto dst = empty_like(src); return erode(dst, src, kernel_, cformat); } - -Tensor &dilate(Tensor &dst, const Tensor &src, const optional &kernel_, ChannelFormat cformat) -{ +Tensor &dilate(Tensor &dst, const Tensor &src, const optional &kernel_, + ChannelFormat cformat) { Tensor kernel; - if(kernel_){ + if (kernel_) { kernel = kernel_.value(); - } - else{ + } else { kernel = ones({3, 3}, src.options().dtype(kFloat32)); } return kernel::img_dilate(dst, src, kernel, cformat); } -Tensor dilate(const Tensor &src, const optional &kernel_, ChannelFormat cformat) -{ +Tensor dilate(const Tensor &src, const optional &kernel_, + ChannelFormat cformat) { auto dst = empty_like(src); return dilate(dst, src, kernel_, cformat); - } Tensor &sobel(Tensor &dst, const Tensor &src, int64_t dx, int64_t dy, - int64_t ksize, const Scalar& scale, const Scalar& delta, - ChannelFormat cformat) -{ + int64_t ksize, const Scalar &scale, const Scalar &delta, + ChannelFormat cformat) { return kernel::img_sobel(dst, src, dx, dy, ksize, scale, delta, cformat); } - -Tensor sobel(const Tensor &src, int64_t dx, int64_t dy, - int64_t ksize, const Scalar& scale, const Scalar& delta, - ChannelFormat cformat) -{ +Tensor sobel(const Tensor &src, int64_t dx, int64_t dy, int64_t ksize, + const Scalar &scale, const Scalar &delta, ChannelFormat cformat) { auto dst = empty_like(src); return sobel(dst, src, dx, dy, ksize, scale, delta, cformat); } -Tensor &canny(Tensor &dst, const Tensor &src, const Scalar &low_thresh, const Scalar &high_thresh, - int64_t aperture_size, bool l2_gradient, ChannelFormat cformat) -{ - return kernel::img_canny( - dst, src, low_thresh, high_thresh, aperture_size, l2_gradient, cformat); +Tensor &canny(Tensor &dst, const Tensor &src, const Scalar &low_thresh, + const Scalar &high_thresh, int64_t aperture_size, + bool l2_gradient, ChannelFormat cformat) { + return kernel::img_canny(dst, src, low_thresh, high_thresh, aperture_size, + l2_gradient, cformat); } -Tensor canny(const Tensor &src, const Scalar &low_thresh, const Scalar &high_thresh, - int64_t aperture_size, bool l2_gradient, ChannelFormat cformat) -{ +Tensor canny(const Tensor &src, const Scalar &low_thresh, + const Scalar &high_thresh, int64_t aperture_size, bool l2_gradient, + ChannelFormat cformat) { auto shape = remove_cdim(src, cformat); auto dst = empty(shape, src.options()); - canny(dst, src, low_thresh, high_thresh, aperture_size, l2_gradient, cformat); + canny(dst, src, low_thresh, high_thresh, aperture_size, l2_gradient, + cformat); dst.squeeze_(); return dst; } - -Tensor &filter2d(Tensor &dst, const Tensor &src, - const Tensor &kernel, const Scalar& delta, ChannelFormat cformat) -{ +Tensor &filter2d(Tensor &dst, const Tensor &src, const Tensor &kernel, + const Scalar &delta, ChannelFormat cformat) { return kernel::img_filter2d(dst, src, kernel, delta, cformat); } - -Tensor filter2d(const Tensor &src, - const Tensor &kernel, const Scalar& delta, ChannelFormat cformat) -{ +Tensor filter2d(const Tensor &src, const Tensor &kernel, const Scalar &delta, + ChannelFormat cformat) { auto dst = empty_like(src); return filter2d(dst, src, kernel, delta, cformat); } - -Tensor bilateral_filter(const Tensor &src, int d, - const Scalar& sigma_color, const Scalar& sigma_space, ChannelFormat cformat) -{ +Tensor bilateral_filter(const Tensor &src, int d, const Scalar &sigma_color, + const Scalar &sigma_space, ChannelFormat cformat) { auto dst = empty_like(src); return bilateral_filter(dst, src, d, sigma_color, sigma_space, cformat); } -Tensor& bilateral_filter(Tensor &dst, const Tensor &src, int d, - const Scalar& sigma_color, const Scalar& sigma_space, ChannelFormat cformat) -{ - return kernel::img_bilateral_filter(dst, src, d, sigma_color, sigma_space, cformat); +Tensor &bilateral_filter(Tensor &dst, const Tensor &src, int d, + const Scalar &sigma_color, const Scalar &sigma_space, + ChannelFormat cformat) { + return kernel::img_bilateral_filter(dst, src, d, sigma_color, sigma_space, + cformat); } -Tensor gaussian_blur(const Tensor &src, int kx, int ky, - const Scalar& sigma_x, const Scalar& sigma_y, ChannelFormat cformat) -{ +Tensor gaussian_blur(const Tensor &src, int kx, int ky, const Scalar &sigma_x, + const Scalar &sigma_y, ChannelFormat cformat) { auto dst = empty_like(src); return gaussian_blur(dst, src, kx, ky, sigma_x, sigma_y, cformat); } -Tensor& gaussian_blur(Tensor &dst, const Tensor &src, int kx, int ky, - const Scalar& sigma_x, const Scalar& sigma_y, ChannelFormat cformat) -{ - return kernel::img_gaussian_blur(dst, src, kx, ky, sigma_x, sigma_y, cformat); +Tensor &gaussian_blur(Tensor &dst, const Tensor &src, int kx, int ky, + const Scalar &sigma_x, const Scalar &sigma_y, + ChannelFormat cformat) { + return kernel::img_gaussian_blur(dst, src, kx, ky, sigma_x, sigma_y, + cformat); } - Tensor warp_perspective(const Tensor &src, int64_t width, int64_t height, - const Tensor &M, ImageFilterMode mode, ChannelFormat cformat) -{ + const Tensor &M, ImageFilterMode mode, + ChannelFormat cformat) { auto wdim = infer_wdim(src, cformat); auto dshape = src.shape(); dshape[wdim] = width; - dshape[wdim-1] = height; + dshape[wdim - 1] = height; auto dst = empty(dshape, src.options()); warp_perspective(dst, src, M, mode, cformat); @@ -503,35 +476,33 @@ Tensor warp_perspective(const Tensor &src, int64_t width, int64_t height, return dst; } -Tensor &warp_perspective(Tensor &dst, const Tensor &src, - const Tensor &M, ImageFilterMode mode, ChannelFormat cformat) -{ +Tensor &warp_perspective(Tensor &dst, const Tensor &src, const Tensor &M, + ImageFilterMode mode, ChannelFormat cformat) { return kernel::img_warp_perspective(dst, src, M, mode, cformat); } - -//dst = src0 * (1 - alpha) + src1 * (alpha); -Tensor &overlay(Tensor &dst, const Tensor &src0, const Tensor &src1, const Tensor &alpha) -{ +// dst = src0 * (1 - alpha) + src1 * (alpha); +Tensor &overlay(Tensor &dst, const Tensor &src0, const Tensor &src1, + const Tensor &alpha) { return kernel::img_overlay(dst, src0, src1, alpha); } - -Tensor overlay( const Tensor &src0, const Tensor &src1, const Tensor &alpha) -{ +Tensor overlay(const Tensor &src0, const Tensor &src1, const Tensor &alpha) { auto dst = empty_like(src0); return overlay(dst, src0, src1, alpha); } -Tensor transfer(const Tensor &src, const ChannelFormat &src_format, const ChannelFormat &dst_format) -{ +Tensor transfer(const Tensor &src, const ChannelFormat &src_format, + const ChannelFormat &dst_format) { HMP_REQUIRE(src.dim() == 3 || src.dim() == 4, "dims must be 3 or 4"); Tensor dst; if (src.dim() == 3) { - if(dst_format == ChannelFormat::NCHW && src_format == ChannelFormat::NHWC){ + if (dst_format == ChannelFormat::NCHW && + src_format == ChannelFormat::NHWC) { dst = src.permute({2, 0, 1}); - } else if(dst_format == ChannelFormat::NHWC && src_format == ChannelFormat::NCHW){ + } else if (dst_format == ChannelFormat::NHWC && + src_format == ChannelFormat::NCHW) { dst = src.permute({1, 2, 0}); } else { dst = src; @@ -539,9 +510,11 @@ Tensor transfer(const Tensor &src, const ChannelFormat &src_format, const Channe dst = dst.contiguous(); } else if (src.dim() == 4) { - if(dst_format == ChannelFormat::NCHW && src_format == ChannelFormat::NHWC){ + if (dst_format == ChannelFormat::NCHW && + src_format == ChannelFormat::NHWC) { dst = src.permute({0, 3, 1, 2}); - } else if(dst_format == ChannelFormat::NHWC && src_format == ChannelFormat::NCHW){ + } else if (dst_format == ChannelFormat::NHWC && + src_format == ChannelFormat::NCHW) { dst = src.permute({0, 2, 3, 1}); } else { dst = src; @@ -551,7 +524,6 @@ Tensor transfer(const Tensor &src, const ChannelFormat &src_format, const Channe return dst; } -#endif //HMP_ENABLE_MOBILE - - -}} //namespace hmp::img +#endif // HMP_ENABLE_MOBILE +} +} // namespace hmp::img diff --git a/bmf/hml/src/kernel/binary_ops.cpp b/bmf/hml/src/kernel/binary_ops.cpp index 3979075c..9f19d390 100644 --- a/bmf/hml/src/kernel/binary_ops.cpp +++ b/bmf/hml/src/kernel/binary_ops.cpp @@ -16,8 +16,8 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { HMP_DEFINE_DISPATCH_STUB(mul_stub) HMP_DEFINE_DISPATCH_STUB(mul_scalar_stub) @@ -30,46 +30,38 @@ HMP_DEFINE_DISPATCH_STUB(div_stub) HMP_DEFINE_DISPATCH_STUB(div_scalar_stub) HMP_DEFINE_DISPATCH_STUB(div_scalar_stub2) - -#define WRAP_BINARY_OP(op)\ - Tensor& op(Tensor &out, const Tensor &ina, const Tensor &inb) \ - { \ - checkShape({out, ina, inb}, out.shape(), #op); \ - checkDevice({out, ina, inb}, out.device(), #op); \ - return op##_stub(out.device_type(), out, ina, inb); \ - } \ - Tensor& op(Tensor &out, const Tensor &ina, const Scalar &inb) \ - { \ - checkShape({out, ina}, out.shape(), #op); \ - checkDevice({out, ina}, out.device(), #op); \ - return op##_scalar_stub(out.device_type(), out, ina, inb); \ +#define WRAP_BINARY_OP(op) \ + Tensor &op(Tensor &out, const Tensor &ina, const Tensor &inb) { \ + checkShape({out, ina, inb}, out.shape(), #op); \ + checkDevice({out, ina, inb}, out.device(), #op); \ + return op##_stub(out.device_type(), out, ina, inb); \ + } \ + Tensor &op(Tensor &out, const Tensor &ina, const Scalar &inb) { \ + checkShape({out, ina}, out.shape(), #op); \ + checkDevice({out, ina}, out.device(), #op); \ + return op##_scalar_stub(out.device_type(), out, ina, inb); \ } - -#define WRAP_BINARY_OP2(op)\ - Tensor& op(Tensor &out, const Tensor &ina, const Tensor &inb) \ - { \ - checkShape({out, ina, inb}, out.shape(), #op); \ - checkDevice({out, ina, inb}, out.device(), #op); \ - return op##_stub(out.device_type(), out, ina, inb); \ - } \ - Tensor& op(Tensor &out, const Tensor &ina, const Scalar &inb) \ - { \ - checkShape({out, ina}, out.shape(), #op); \ - checkDevice({out, ina}, out.device(), #op); \ - return op##_scalar_stub(out.device_type(), out, ina, inb); \ - } \ - Tensor& op(Tensor &out, const Scalar &ina, const Tensor &inb) \ - { \ - checkShape({out, inb}, out.shape(), #op); \ - checkDevice({out, inb}, out.device(), #op); \ - return op##_scalar_stub2(out.device_type(), out, ina, inb); \ +#define WRAP_BINARY_OP2(op) \ + Tensor &op(Tensor &out, const Tensor &ina, const Tensor &inb) { \ + checkShape({out, ina, inb}, out.shape(), #op); \ + checkDevice({out, ina, inb}, out.device(), #op); \ + return op##_stub(out.device_type(), out, ina, inb); \ + } \ + Tensor &op(Tensor &out, const Tensor &ina, const Scalar &inb) { \ + checkShape({out, ina}, out.shape(), #op); \ + checkDevice({out, ina}, out.device(), #op); \ + return op##_scalar_stub(out.device_type(), out, ina, inb); \ + } \ + Tensor &op(Tensor &out, const Scalar &ina, const Tensor &inb) { \ + checkShape({out, inb}, out.shape(), #op); \ + checkDevice({out, inb}, out.device(), #op); \ + return op##_scalar_stub2(out.device_type(), out, ina, inb); \ } WRAP_BINARY_OP(mul) WRAP_BINARY_OP(add) WRAP_BINARY_OP2(sub) WRAP_BINARY_OP2(div) - - -}} //namespace hmp::kernel \ No newline at end of file +} +} // namespace hmp::kernel \ No newline at end of file diff --git a/bmf/hml/src/kernel/cpu/binary_ops.cpp b/bmf/hml/src/kernel/cpu/binary_ops.cpp index 7a6cc901..2485a114 100644 --- a/bmf/hml/src/kernel/cpu/binary_ops.cpp +++ b/bmf/hml/src/kernel/cpu/binary_ops.cpp @@ -16,137 +16,96 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { namespace { -Tensor& mul_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "mul_cpu", [&](){ - cpu::bop_kernel(out, ina, inb, - [&](scalar_t a, scalar_t b){ - return a * b; - }); +Tensor &mul_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "mul_cpu", [&]() { + cpu::bop_kernel( + out, ina, inb, [&](scalar_t a, scalar_t b) { return a * b; }); }); return out; } - -Tensor& mul_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "mul_scalar_cpu", [&](){ +Tensor &mul_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "mul_scalar_cpu", [&]() { auto b = inb.to(); cpu::uop_kernel(out, ina, - [&](scalar_t a){ - return a * b; - }); + [&](scalar_t a) { return a * b; }); }); return out; } - -Tensor& add_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "add_cpu", [&](){ - cpu::bop_kernel(out, ina, inb, - [&](scalar_t a, scalar_t b){ - return a + b; - }); +Tensor &add_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "add_cpu", [&]() { + cpu::bop_kernel( + out, ina, inb, [&](scalar_t a, scalar_t b) { return a + b; }); }); return out; } - -Tensor& add_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "add_scalar_cpu", [&](){ +Tensor &add_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "add_scalar_cpu", [&]() { auto b = inb.to(); cpu::uop_kernel(out, ina, - [&](scalar_t a){ - return a + b; - }); + [&](scalar_t a) { return a + b; }); }); return out; } - -Tensor& sub_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_cpu", [&](){ - cpu::bop_kernel(out, ina, inb, - [&](scalar_t a, scalar_t b){ - return a - b; - }); +Tensor &sub_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_cpu", [&]() { + cpu::bop_kernel( + out, ina, inb, [&](scalar_t a, scalar_t b) { return a - b; }); }); return out; } - -Tensor& sub_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_scalar_cpu", [&](){ +Tensor &sub_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_scalar_cpu", [&]() { auto b = inb.to(); cpu::uop_kernel(out, ina, - [&](scalar_t a){ - return a - b; - }); + [&](scalar_t a) { return a - b; }); }); return out; } - -Tensor& sub_scalar2_cpu(Tensor &out, const Scalar &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_scalar_cpu", [&](){ +Tensor &sub_scalar2_cpu(Tensor &out, const Scalar &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "sub_scalar_cpu", [&]() { auto a = ina.to(); cpu::uop_kernel(out, inb, - [&](scalar_t b){ - return a - b; - }); + [&](scalar_t b) { return a - b; }); }); return out; } - -Tensor& div_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_cpu", [&](){ - cpu::bop_kernel(out, ina, inb, - [&](scalar_t a, scalar_t b){ - return a / b; - }); +Tensor &div_cpu(Tensor &out, const Tensor &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_cpu", [&]() { + cpu::bop_kernel( + out, ina, inb, [&](scalar_t a, scalar_t b) { return a / b; }); }); return out; } - -Tensor& div_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_scalar_cpu", [&](){ +Tensor &div_scalar_cpu(Tensor &out, const Tensor &ina, const Scalar &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_scalar_cpu", [&]() { auto b = inb.to(); cpu::uop_kernel(out, ina, - [&](scalar_t a){ - return a / b; - }); + [&](scalar_t a) { return a / b; }); }); return out; } - -Tensor& div_scalar2_cpu(Tensor &out, const Scalar &ina, const Tensor &inb) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_scalar_cpu", [&](){ +Tensor &div_scalar2_cpu(Tensor &out, const Scalar &ina, const Tensor &inb) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(out.scalar_type(), "div_scalar_cpu", [&]() { auto a = ina.to(); cpu::uop_kernel(out, inb, - [&](scalar_t b){ - return a / b; - }); + [&](scalar_t b) { return a / b; }); }); return out; } - - HMP_DEVICE_DISPATCH(kCPU, mul_stub, &mul_cpu) HMP_DEVICE_DISPATCH(kCPU, mul_scalar_stub, &mul_scalar_cpu) HMP_DEVICE_DISPATCH(kCPU, add_stub, &add_cpu) @@ -157,6 +116,6 @@ HMP_DEVICE_DISPATCH(kCPU, sub_scalar_stub2, &sub_scalar2_cpu) HMP_DEVICE_DISPATCH(kCPU, div_stub, &div_cpu) HMP_DEVICE_DISPATCH(kCPU, div_scalar_stub, &div_scalar_cpu) HMP_DEVICE_DISPATCH(kCPU, div_scalar_stub2, &div_scalar2_cpu) - - -}}} // \ No newline at end of file +} +} +} // \ No newline at end of file diff --git a/bmf/hml/src/kernel/cpu/imgproc.cpp b/bmf/hml/src/kernel/cpu/imgproc.cpp index 1365ed75..45f665ab 100644 --- a/bmf/hml/src/kernel/cpu/imgproc.cpp +++ b/bmf/hml/src/kernel/cpu/imgproc.cpp @@ -19,293 +19,328 @@ #include #include -namespace hmp{ -namespace kernel{ -namespace{ +namespace hmp { +namespace kernel { +namespace { // scalar_t, dst, src, batch, width, height need pre-defined -#define PIXEL_FORMAT_CASE(Op, Format, Cformat) \ - case(PPixelFormat::Format): \ - do{ \ - Op op(dst, src); \ - cpu::invoke_img_elementwise_kernel([&](int batch, int w, int h) mutable{\ - op(batch, w, h); \ - }, batch, width, height); \ - }while(0); \ +#define PIXEL_FORMAT_CASE(Op, Format, Cformat) \ + case (PPixelFormat::Format): \ + do { \ + Op op(dst, src); \ + cpu::invoke_img_elementwise_kernel( \ + [&](int batch, int w, int h) mutable { op(batch, w, h); }, \ + batch, width, height); \ + } while (0); \ break; +#define PIXEL_FORMAT_DISPATCH(Op, format, Cformat, name) \ + switch (format) { \ + PIXEL_FORMAT_CASE(Op, H420, Cformat) \ + PIXEL_FORMAT_CASE(Op, H422, Cformat) \ + PIXEL_FORMAT_CASE(Op, H444, Cformat) \ + PIXEL_FORMAT_CASE(Op, I420, Cformat) \ + PIXEL_FORMAT_CASE(Op, I422, Cformat) \ + PIXEL_FORMAT_CASE(Op, I444, Cformat) \ + PIXEL_FORMAT_CASE(Op, NV21, Cformat) \ + PIXEL_FORMAT_CASE(Op, NV12, Cformat) \ + PIXEL_FORMAT_CASE(Op, NV21_BT709, Cformat) \ + PIXEL_FORMAT_CASE(Op, NV12_BT709, Cformat) \ + default: \ + HMP_REQUIRE(false, "{} : unsupported PPixelFormat {}", name, format); \ + } -#define PIXEL_FORMAT_DISPATCH(Op, format, Cformat, name) \ - switch(format){ \ - PIXEL_FORMAT_CASE(Op, H420, Cformat) \ - PIXEL_FORMAT_CASE(Op, H422, Cformat) \ - PIXEL_FORMAT_CASE(Op, H444, Cformat) \ - PIXEL_FORMAT_CASE(Op, I420, Cformat) \ - PIXEL_FORMAT_CASE(Op, I422, Cformat) \ - PIXEL_FORMAT_CASE(Op, I444, Cformat) \ - PIXEL_FORMAT_CASE(Op, NV21, Cformat) \ - PIXEL_FORMAT_CASE(Op, NV12, Cformat) \ - PIXEL_FORMAT_CASE(Op, NV21_BT709, Cformat) \ - PIXEL_FORMAT_CASE(Op, NV12_BT709, Cformat) \ - default: \ - HMP_REQUIRE(false, "{} : unsupported PPixelFormat {}", name, format); \ - } - - -Tensor &yuv_to_rgb_cpu(Tensor &dst, const TensorList &src, PPixelFormat format, ChannelFormat cformat) -{ +Tensor &yuv_to_rgb_cpu(Tensor &dst, const TensorList &src, PPixelFormat format, + ChannelFormat cformat) { auto batch = src[0].size(0); auto height = src[0].size(1); auto width = src[0].size(2); - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src[0].scalar_type(), "yuv_to_rgb_cpu", [&](){ - if(cformat == kNCHW){ - PIXEL_FORMAT_DISPATCH(YUV2RGB, format, kNCHW, "yuv_to_rgb_cpu"); - } - else{ - PIXEL_FORMAT_DISPATCH(YUV2RGB, format, ChannelFormat::NHWC, "yuv_to_rgb_cpu"); - } - }); - + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src[0].scalar_type(), "yuv_to_rgb_cpu", [&]() { + if (cformat == kNCHW) { + PIXEL_FORMAT_DISPATCH(YUV2RGB, format, kNCHW, "yuv_to_rgb_cpu"); + } else { + PIXEL_FORMAT_DISPATCH(YUV2RGB, format, ChannelFormat::NHWC, + "yuv_to_rgb_cpu"); + } + }); + return dst; } - - -TensorList &rgb_to_yuv_cpu(TensorList &dst, const Tensor &src, PPixelFormat format, ChannelFormat cformat) -{ +TensorList &rgb_to_yuv_cpu(TensorList &dst, const Tensor &src, + PPixelFormat format, ChannelFormat cformat) { auto batch = dst[0].size(0); auto height = dst[0].size(1); auto width = dst[0].size(2); - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(dst[0].scalar_type(), "rgb_to_yuv_cpu", [&](){ - if(cformat == kNCHW){ - PIXEL_FORMAT_DISPATCH(RGB2YUV, format, kNCHW, "rgb_to_yuv_cpu"); - } - else{ - PIXEL_FORMAT_DISPATCH(RGB2YUV, format, ChannelFormat::NHWC, "rgb_to_yuv_cpu"); - } - }); - + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + dst[0].scalar_type(), "rgb_to_yuv_cpu", [&]() { + if (cformat == kNCHW) { + PIXEL_FORMAT_DISPATCH(RGB2YUV, format, kNCHW, "rgb_to_yuv_cpu"); + } else { + PIXEL_FORMAT_DISPATCH(RGB2YUV, format, ChannelFormat::NHWC, + "rgb_to_yuv_cpu"); + } + }); + return dst; } -TensorList &yuv_to_yuv_cpu(TensorList &dst, const TensorList &src, PPixelFormat dformat, PPixelFormat sformat) -{ +TensorList &yuv_to_yuv_cpu(TensorList &dst, const TensorList &src, + PPixelFormat dformat, PPixelFormat sformat) { auto batch = src[0].size(0); auto height = src[0].size(1); auto width = src[0].size(2); - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src[0].scalar_type(), "yuv_to_yuv_cpu", [&](){ - if (dformat == PPixelFormat::NV12 && (sformat == PPixelFormat::H420 || sformat == PPixelFormat::I420)) { - YUV2YUV yuv2yuv(dst, src); - cpu::invoke_img_elementwise_kernel([=]HMP_HOST_DEVICE(int batch, int w, int h) mutable{ - yuv2yuv(batch, w, h); - }, batch, width, height); - } - else if ((dformat == PPixelFormat::H420 || sformat == PPixelFormat::I420) && sformat == PPixelFormat::NV12) { - YUV2YUV yuv2yuv(dst, src); - cpu::invoke_img_elementwise_kernel([=]HMP_HOST_DEVICE(int batch, int w, int h) mutable{ - yuv2yuv(batch, w, h); - }, batch, width, height); - } - else if (dformat == PPixelFormat::P010 || sformat == PPixelFormat::U420) { - YUV2YUV yuv2yuv(dst, src); - cpu::invoke_img_elementwise_kernel([=]HMP_HOST_DEVICE(int batch, int w, int h) mutable{ - yuv2yuv(batch, w, h); - }, batch, width, height); - } - - else if (dformat == PPixelFormat::U420 || sformat == PPixelFormat::P010) { - YUV2YUV yuv2yuv(dst, src); - cpu::invoke_img_elementwise_kernel([=]HMP_HOST_DEVICE(int batch, int w, int h) mutable{ - yuv2yuv(batch, w, h); - }, batch, width, height); - } - else { - HMP_REQUIRE(false, "Only supports conversion between nv12 and yuv420p or between p010 and yuv420p10."); - } - }); - + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src[0].scalar_type(), "yuv_to_yuv_cpu", [&]() { + if (dformat == PPixelFormat::NV12 && + (sformat == PPixelFormat::H420 || + sformat == PPixelFormat::I420)) { + YUV2YUV + yuv2yuv(dst, src); + cpu::invoke_img_elementwise_kernel( + [=] HMP_HOST_DEVICE(int batch, int w, int h) mutable { + yuv2yuv(batch, w, h); + }, + batch, width, height); + } else if ((dformat == PPixelFormat::H420 || + sformat == PPixelFormat::I420) && + sformat == PPixelFormat::NV12) { + YUV2YUV + yuv2yuv(dst, src); + cpu::invoke_img_elementwise_kernel( + [=] HMP_HOST_DEVICE(int batch, int w, int h) mutable { + yuv2yuv(batch, w, h); + }, + batch, width, height); + } else if (dformat == PPixelFormat::P010 || + sformat == PPixelFormat::U420) { + YUV2YUV + yuv2yuv(dst, src); + cpu::invoke_img_elementwise_kernel( + [=] HMP_HOST_DEVICE(int batch, int w, int h) mutable { + yuv2yuv(batch, w, h); + }, + batch, width, height); + } + + else if (dformat == PPixelFormat::U420 || + sformat == PPixelFormat::P010) { + YUV2YUV + yuv2yuv(dst, src); + cpu::invoke_img_elementwise_kernel( + [=] HMP_HOST_DEVICE(int batch, int w, int h) mutable { + yuv2yuv(batch, w, h); + }, + batch, width, height); + } else { + HMP_REQUIRE(false, "Only supports conversion between nv12 and " + "yuv420p or between p010 and yuv420p10."); + } + }); + return dst; } -Tensor &img_resize_cpu(Tensor &dst, const Tensor &src, ImageFilterMode mode, ChannelFormat cformat) -{ - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src.scalar_type(), "img_resize_cpu", [&](){ - auto channel = cformat == kNCHW ? 1 : src.size(-1); - HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_resize_cpu", [&](){ - using vtype = Vector; - using wtype = Vector; - - using Iter = ImageSeqIter; - auto src_iter = Iter::from_tensor(src, cformat); - auto dst_iter = Iter::from_tensor(dst, cformat); - - auto wscale = float(src_iter.width()) / dst_iter.width(); - auto hscale = float(src_iter.height()) / dst_iter.height(); - auto wscale_offset = 0.f; - auto hscale_offset = 0.f; - if(mode == ImageFilterMode::Bilinear || mode == ImageFilterMode::Bicubic){ - wscale_offset = 0.5f * wscale - 0.5f; - hscale_offset = 0.5f * hscale - 0.5f; - } +Tensor &img_resize_cpu(Tensor &dst, const Tensor &src, ImageFilterMode mode, + ChannelFormat cformat) { + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src.scalar_type(), "img_resize_cpu", [&]() { + auto channel = cformat == kNCHW ? 1 : src.size(-1); + HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_resize_cpu", [&]() { + using vtype = Vector; + using wtype = Vector; + + using Iter = ImageSeqIter; + auto src_iter = Iter::from_tensor(src, cformat); + auto dst_iter = Iter::from_tensor(dst, cformat); + + auto wscale = float(src_iter.width()) / dst_iter.width(); + auto hscale = float(src_iter.height()) / dst_iter.height(); + auto wscale_offset = 0.f; + auto hscale_offset = 0.f; + if (mode == ImageFilterMode::Bilinear || + mode == ImageFilterMode::Bicubic) { + wscale_offset = 0.5f * wscale - 0.5f; + hscale_offset = 0.5f * hscale - 0.5f; + } - HMP_DISPATCH_IMAGE_FILTER(mode, Iter, wtype, vtype, "img_resize_cpu", [&](){ - filter_t filter(src_iter); - cpu::invoke_img_elementwise_kernel([&] (int batch, int w, int h) mutable { - auto x = w * wscale + wscale_offset; - auto y = h * hscale + hscale_offset; - dst_iter.set(batch, w, h, filter(batch, x, y)); - }, dst_iter.batch(), dst_iter.width(), dst_iter.height()); + HMP_DISPATCH_IMAGE_FILTER( + mode, Iter, wtype, vtype, "img_resize_cpu", [&]() { + filter_t filter(src_iter); + cpu::invoke_img_elementwise_kernel( + [&](int batch, int w, int h) mutable { + auto x = w * wscale + wscale_offset; + auto y = h * hscale + hscale_offset; + dst_iter.set(batch, w, h, filter(batch, x, y)); + }, + dst_iter.batch(), dst_iter.width(), + dst_iter.height()); + }); }); }); - }); return dst; } - TensorList &yuv_resize_cpu(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageFilterMode mode) -{ - for(size_t i = 0; i < src.size(); ++i){ + PPixelFormat format, ImageFilterMode mode) { + for (size_t i = 0; i < src.size(); ++i) { img_resize_cpu(dst[i], src[i], mode, ChannelFormat::NHWC); } return dst; } +Tensor &img_mirror_cpu(Tensor &dst, const Tensor &src, ImageAxis axis, + ChannelFormat cformat) { + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src.scalar_type(), "img_mirror_cpu", [&]() { + auto channel = cformat == kNCHW ? 1 : src.size(-1); + HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_mirror_cpu", [&]() { + using vtype = Vector; + + using Iter = ImageSeqIter; + auto src_iter = Iter::from_tensor(src, cformat); + auto dst_iter = Iter::from_tensor(dst, cformat); + + cpu::invoke_img_elementwise_kernel( + [&](int batch, int w, int h) mutable { + auto hmirror = + static_cast(axis) & + static_cast(ImageAxis::Horizontal); + auto vmirror = + static_cast(axis) & + static_cast(ImageAxis::Vertical); + auto x = hmirror ? dst_iter.width() - 1 - w : w; + auto y = vmirror ? dst_iter.height() - 1 - h : h; + dst_iter.set(batch, w, h, src_iter.get(batch, x, y)); + }, + dst_iter.batch(), dst_iter.width(), dst_iter.height()); + }); -Tensor &img_mirror_cpu(Tensor &dst, const Tensor &src, ImageAxis axis, ChannelFormat cformat) -{ - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src.scalar_type(), "img_mirror_cpu", [&](){ - auto channel = cformat == kNCHW ? 1 : src.size(-1); - HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_mirror_cpu", [&](){ - using vtype = Vector; - - using Iter = ImageSeqIter; - auto src_iter = Iter::from_tensor(src, cformat); - auto dst_iter = Iter::from_tensor(dst, cformat); - - cpu::invoke_img_elementwise_kernel([&](int batch, int w, int h) mutable { - auto hmirror = static_cast(axis) & static_cast(ImageAxis::Horizontal); - auto vmirror = static_cast(axis) & static_cast(ImageAxis::Vertical); - auto x = hmirror ? dst_iter.width()- 1 - w : w; - auto y = vmirror ? dst_iter.height()- 1 - h : h; - dst_iter.set(batch, w, h, src_iter.get(batch, x, y)); - }, dst_iter.batch(), dst_iter.width(), dst_iter.height()); }); - }); - return dst; } - TensorList &yuv_mirror_cpu(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageAxis axis) -{ - for(size_t i = 0; i < src.size(); ++i){ + PPixelFormat format, ImageAxis axis) { + for (size_t i = 0; i < src.size(); ++i) { img_mirror_cpu(dst[i], src[i], axis, ChannelFormat::NHWC); } return dst; } +Tensor &img_rotate_cpu(Tensor &dst, const Tensor &src, ImageRotationMode mode, + ChannelFormat cformat) { + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src.scalar_type(), "img_rotate_cpu", [&]() { + auto channel = cformat == kNCHW ? 1 : src.size(-1); + HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_rotate_cpu", [&]() { + using vtype = Vector; + + using Iter = ImageSeqIter; + auto src_iter = Iter::from_tensor(src, cformat); + auto dst_iter = Iter::from_tensor(dst, cformat); + + cpu::invoke_img_elementwise_kernel( + [&](int batch, int w, int h) mutable { + int x, y; + switch (mode) { + case ImageRotationMode::Rotate90: + x = h; + y = dst_iter.width() - 1 - w; + break; + case ImageRotationMode::Rotate180: + x = dst_iter.width() - 1 - w; + y = dst_iter.height() - 1 - h; + break; + case ImageRotationMode::Rotate270: + x = dst_iter.height() - 1 - h; + y = w; + break; + default: + x = w; + y = h; + } + dst_iter.set(batch, w, h, src_iter.get(batch, x, y)); -Tensor &img_rotate_cpu(Tensor &dst, const Tensor &src, ImageRotationMode mode, ChannelFormat cformat) -{ - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src.scalar_type(), "img_rotate_cpu", [&](){ - auto channel = cformat == kNCHW ? 1 : src.size(-1); - HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_rotate_cpu", [&](){ - using vtype = Vector; - - using Iter = ImageSeqIter; - auto src_iter = Iter::from_tensor(src, cformat); - auto dst_iter = Iter::from_tensor(dst, cformat); - - cpu::invoke_img_elementwise_kernel([&] (int batch, int w, int h) mutable { - int x, y; - switch(mode){ - case ImageRotationMode::Rotate90: - x = h; - y = dst_iter.width() - 1 - w; - break; - case ImageRotationMode::Rotate180: - x = dst_iter.width() - 1 - w; - y = dst_iter.height() - 1 - h; - break; - case ImageRotationMode::Rotate270: - x = dst_iter.height() - 1 - h; - y = w; - break; - default: - x = w; - y = h; - } - dst_iter.set(batch, w, h, src_iter.get(batch, x, y)); - - }, dst_iter.batch(), dst_iter.width(), dst_iter.height()); + }, + dst_iter.batch(), dst_iter.width(), dst_iter.height()); + }); }); - }); return dst; } - TensorList &yuv_rotate_cpu(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageRotationMode mode) -{ - for(size_t i = 0; i < src.size(); ++i){ + PPixelFormat format, ImageRotationMode mode) { + for (size_t i = 0; i < src.size(); ++i) { img_rotate_cpu(dst[i], src[i], mode, ChannelFormat::NHWC); } return dst; } - - -Tensor& img_normalize_cpu(Tensor &dst, const Tensor &src, const Tensor &mean, const Tensor &std, ChannelFormat cformat) -{ +Tensor &img_normalize_cpu(Tensor &dst, const Tensor &src, const Tensor &mean, + const Tensor &std, ChannelFormat cformat) { auto fmean = mean.to(kFloat32); auto fstd = std.to(kFloat32); - HMP_DISPATCH_IMAGE_TYPES_AND_HALF(src.scalar_type(), "img_normalize_cpu", [&](){ - using iscalar_t = scalar_t; - HMP_DISPATCH_FLOAT32_AND_HALF(dst.scalar_type(), "img_normalize_cpu", [&](){ - using oscalar_t = scalar_t; - HMP_DISPATCH_CHANNEL_FORMAT(cformat, "img_normalize_cpu", [&](){ - int channel = cformat == kNCHW ? src.size(1) : src.size(-1); - HMP_DISPATCH_IMAGE_CHANNEL(channel, "img_normalize_cpu", [&](){ - using itype = Vector; - using otype = Vector; - auto src_iter = ImageSeqIter::from_tensor(src, cformat); - auto dst_iter = ImageSeqIter::from_tensor(dst, cformat); - auto fmean_ptr = fmean.data(); - auto fmean_stride = fmean.stride(0); - auto fstd_ptr = fstd.data(); - auto fstd_stride = fstd.stride(0); - - cpu::invoke_img_elementwise_kernel([&] (int batch, int w, int h) mutable { - auto in = src_iter.get(batch, w, h); - otype out; - for(int i = 0; i < C::size(); ++i){ - out[i] = (in[i] - fmean_ptr[i*fmean_stride]) / fstd_ptr[i*fstd_stride]; - } - dst_iter.set(batch, w, h, out); - }, dst_iter.batch_, dst_iter.width_, dst_iter.height_); + HMP_DISPATCH_IMAGE_TYPES_AND_HALF( + src.scalar_type(), "img_normalize_cpu", [&]() { + using iscalar_t = scalar_t; + HMP_DISPATCH_FLOAT32_AND_HALF( + dst.scalar_type(), "img_normalize_cpu", [&]() { + using oscalar_t = scalar_t; + HMP_DISPATCH_CHANNEL_FORMAT( + cformat, "img_normalize_cpu", [&]() { + int channel = + cformat == kNCHW ? src.size(1) : src.size(-1); + HMP_DISPATCH_IMAGE_CHANNEL( + channel, "img_normalize_cpu", [&]() { + using itype = Vector; + using otype = Vector; + auto src_iter = + ImageSeqIter::from_tensor( + src, cformat); + auto dst_iter = + ImageSeqIter::from_tensor( + dst, cformat); + auto fmean_ptr = fmean.data(); + auto fmean_stride = fmean.stride(0); + auto fstd_ptr = fstd.data(); + auto fstd_stride = fstd.stride(0); + + cpu::invoke_img_elementwise_kernel( + [&](int batch, int w, int h) mutable { + auto in = src_iter.get(batch, w, h); + otype out; + for (int i = 0; i < C::size(); + ++i) { + out[i] = + (in[i] - + fmean_ptr[i * + fmean_stride]) / + fstd_ptr[i * fstd_stride]; + } + dst_iter.set(batch, w, h, out); + }, + dst_iter.batch_, dst_iter.width_, + dst_iter.height_); + }); + }); }); - }); }); - }); - return dst; } - - HMP_DEVICE_DISPATCH(kCPU, yuv_to_rgb_stub, &yuv_to_rgb_cpu) HMP_DEVICE_DISPATCH(kCPU, rgb_to_yuv_stub, &rgb_to_yuv_cpu) HMP_DEVICE_DISPATCH(kCPU, yuv_to_yuv_stub, &yuv_to_yuv_cpu) @@ -316,6 +351,6 @@ HMP_DEVICE_DISPATCH(kCPU, img_resize_stub, &img_resize_cpu) HMP_DEVICE_DISPATCH(kCPU, img_rotate_stub, &img_rotate_cpu) HMP_DEVICE_DISPATCH(kCPU, img_mirror_stub, &img_mirror_cpu) HMP_DEVICE_DISPATCH(kCPU, img_normalize_stub, &img_normalize_cpu) - - -}}} //namespace hmp::kernel +} +} +} // namespace hmp::kernel diff --git a/bmf/hml/src/kernel/cpu/tensor_factory.cpp b/bmf/hml/src/kernel/cpu/tensor_factory.cpp index 6ffb84e3..0a530d4d 100644 --- a/bmf/hml/src/kernel/cpu/tensor_factory.cpp +++ b/bmf/hml/src/kernel/cpu/tensor_factory.cpp @@ -17,66 +17,55 @@ #include #include -namespace hmp{ -namespace kernel{ -namespace{ +namespace hmp { +namespace kernel { +namespace { -Tensor &fill_cpu_impl(Tensor &self, const Scalar &value) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "fill_cpu", [&](){ +Tensor &fill_cpu_impl(Tensor &self, const Scalar &value) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "fill_cpu", [&]() { auto v = value.to(); - cpu::gen_kernel(self, [&](int64_t idx){ - return v; - }); + cpu::gen_kernel(self, [&](int64_t idx) { return v; }); }); return self; } - -Tensor &arange_cpu_impl(Tensor &self, int64_t start, int64_t end, int64_t step) -{ - HMP_DISPATCH_ALL_TYPES(self.scalar_type(), "arange_cpu", [&](){ - cpu::gen_kernel(self, [&](int64_t idx){ - return start + idx * step; - }); +Tensor &arange_cpu_impl(Tensor &self, int64_t start, int64_t end, + int64_t step) { + HMP_DISPATCH_ALL_TYPES(self.scalar_type(), "arange_cpu", [&]() { + cpu::gen_kernel( + self, [&](int64_t idx) { return start + idx * step; }); }); return self; } - -Tensor ©_cpu_impl(Tensor &self, const Tensor &other) -{ +Tensor ©_cpu_impl(Tensor &self, const Tensor &other) { #ifndef HMP_ENABLE_MOBILE - HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "copy_cpu", [&](){ + HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "copy_cpu", [&]() { using oscalar_t = scalar_t; - HMP_DISPATCH_ALL_TYPES_AND_HALF(other.scalar_type(), "copy_cpu", [&](){ + HMP_DISPATCH_ALL_TYPES_AND_HALF(other.scalar_type(), "copy_cpu", [&]() { using iscalar_t = scalar_t; - cpu::uop_kernel(self, other, - [&](scalar_t v){ - return cast(v); - }); + cpu::uop_kernel( + self, other, [&](scalar_t v) { return cast(v); }); }); }); #else - HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "copy_cpu", [&](){ + HMP_DISPATCH_ALL_TYPES_AND_HALF(self.scalar_type(), "copy_cpu", [&]() { using oscalar_t = scalar_t; using iscalar_t = scalar_t; - cpu::uop_kernel(self, other, - [&](scalar_t v){ - return cast(v); - }); + cpu::uop_kernel( + self, other, [&](scalar_t v) { return cast(v); }); }); #endif return self; } - HMP_DEVICE_DISPATCH(kCPU, fill_stub, &fill_cpu_impl) HMP_DEVICE_DISPATCH(kCPU, copy_stub, ©_cpu_impl) HMP_DEVICE_DISPATCH(kCPU, arange_stub, &arange_cpu_impl) - -}}} // \ No newline at end of file +} +} +} // \ No newline at end of file diff --git a/bmf/hml/src/kernel/cpu/unary_ops.cpp b/bmf/hml/src/kernel/cpu/unary_ops.cpp index 3775076e..5bc15d2f 100644 --- a/bmf/hml/src/kernel/cpu/unary_ops.cpp +++ b/bmf/hml/src/kernel/cpu/unary_ops.cpp @@ -17,86 +17,76 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { namespace { -Tensor& round_cpu(Tensor &out, const Tensor &in) -{ - HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF(in.scalar_type(), "round_cpu", [&](){ - cpu::uop_kernel(out, in, [&](scalar_t v){ - return std::round(v); +Tensor &round_cpu(Tensor &out, const Tensor &in) { + HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF( + in.scalar_type(), "round_cpu", [&]() { + cpu::uop_kernel( + out, in, [&](scalar_t v) { return std::round(v); }); }); - }); return out; } -Tensor& ceil_cpu(Tensor &out, const Tensor &in) -{ - HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF(in.scalar_type(), "ceil_cpu", [&](){ - cpu::uop_kernel(out, in, [&](scalar_t v){ - return std::ceil(v); +Tensor &ceil_cpu(Tensor &out, const Tensor &in) { + HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF( + in.scalar_type(), "ceil_cpu", [&]() { + cpu::uop_kernel( + out, in, [&](scalar_t v) { return std::ceil(v); }); }); - }); return out; } -Tensor& floor_cpu(Tensor &out, const Tensor &in) -{ - HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF(in.scalar_type(), "floor_cpu", [&](){ - cpu::uop_kernel(out, in, [&](scalar_t v){ - return std::floor(v); +Tensor &floor_cpu(Tensor &out, const Tensor &in) { + HMP_DISPATCH_FLOATING_POINT_TYPES_AND_HALF( + in.scalar_type(), "floor_cpu", [&]() { + cpu::uop_kernel( + out, in, [&](scalar_t v) { return std::floor(v); }); }); - }); return out; } - -Tensor& abs_cpu(Tensor &out, const Tensor &in) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "abs_cpu", [&](){ - cpu::uop_kernel(out, in, [&](scalar_t v){ - return std::abs(v); - }); +Tensor &abs_cpu(Tensor &out, const Tensor &in) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "abs_cpu", [&]() { + cpu::uop_kernel( + out, in, [&](scalar_t v) { return std::abs(v); }); }); return out; } - -Tensor& minus_cpu(Tensor &out, const Tensor &in) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "minus_cpu", [&](){ - cpu::uop_kernel(out, in, [&](scalar_t v){ - return -v; - }); +Tensor &minus_cpu(Tensor &out, const Tensor &in) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "minus_cpu", [&]() { + cpu::uop_kernel(out, in, + [&](scalar_t v) { return -v; }); }); return out; } - -Tensor& clip_cpu(Tensor &out, const Tensor &in, const Scalar &min, const Scalar &max) -{ - HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "clip_cpu", [&](){ +Tensor &clip_cpu(Tensor &out, const Tensor &in, const Scalar &min, + const Scalar &max) { + HMP_DISPATCH_ALL_TYPES_AND_HALF(in.scalar_type(), "clip_cpu", [&]() { auto min_v = min.to(); auto max_v = max.to(); HMP_REQUIRE(min_v <= max_v, - "clip_cpu: expect min <= max, got min={}, max={}", min_v, max_v); + "clip_cpu: expect min <= max, got min={}, max={}", min_v, + max_v); - cpu::uop_kernel(out, in, [&](scalar_t v){ + cpu::uop_kernel(out, in, [&](scalar_t v) { return v < min_v ? min_v : (v > max_v ? max_v : v); }); }); return out; } - HMP_DEVICE_DISPATCH(kCPU, round_stub, &round_cpu) HMP_DEVICE_DISPATCH(kCPU, ceil_stub, &ceil_cpu) HMP_DEVICE_DISPATCH(kCPU, floor_stub, &floor_cpu) HMP_DEVICE_DISPATCH(kCPU, abs_stub, &abs_cpu) HMP_DEVICE_DISPATCH(kCPU, minus_stub, &minus_cpu) HMP_DEVICE_DISPATCH(kCPU, clip_stub, &clip_cpu) - - -}}} // \ No newline at end of file +} +} +} // \ No newline at end of file diff --git a/bmf/hml/src/kernel/cv2/imgproc_cpu.cpp b/bmf/hml/src/kernel/cv2/imgproc_cpu.cpp index 079cf522..a7142e28 100644 --- a/bmf/hml/src/kernel/cv2/imgproc_cpu.cpp +++ b/bmf/hml/src/kernel/cv2/imgproc_cpu.cpp @@ -17,139 +17,137 @@ #include #include -namespace hmp{ -namespace kernel{ -namespace{ +namespace hmp { +namespace kernel { +namespace { - -inline Tensor &img_morph_cpu(cv::MorphTypes algo, - Tensor &dst, const Tensor &src, const Tensor &kernel, ChannelFormat cformat) -{ +inline Tensor &img_morph_cpu(cv::MorphTypes algo, Tensor &dst, + const Tensor &src, const Tensor &kernel, + ChannelFormat cformat) { auto kmat = ocv::to_cv_mat(kernel, false); - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - ocv::morph(algo, smat, dmat, kmat); - }, cformat, dst, src); + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + ocv::morph(algo, smat, dmat, kmat); + }, + cformat, dst, src); return dst; } - Tensor &img_erode_cpu(Tensor &dst, const Tensor &src, const Tensor &kernel, - ChannelFormat cformat) -{ + ChannelFormat cformat) { return img_morph_cpu(cv::MORPH_ERODE, dst, src, kernel, cformat); } - Tensor &img_dilate_cpu(Tensor &dst, const Tensor &src, const Tensor &kernel, - ChannelFormat cformat) -{ + ChannelFormat cformat) { return img_morph_cpu(cv::MORPH_DILATE, dst, src, kernel, cformat); } - - Tensor &img_sobel_cpu(Tensor &dst, const Tensor &src, int64_t dx, int64_t dy, - int64_t ksize, const Scalar& scale, const Scalar& delta, - ChannelFormat cformat) -{ - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - auto ddepth = ocv::to_cv_type(dst.dtype()); - cv::Sobel(smat, dmat, ddepth, dx, dy, - ksize, scale.to(), delta.to()); - }, cformat, dst, src); + int64_t ksize, const Scalar &scale, const Scalar &delta, + ChannelFormat cformat) { + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + auto ddepth = ocv::to_cv_type(dst.dtype()); + cv::Sobel(smat, dmat, ddepth, dx, dy, ksize, scale.to(), + delta.to()); + }, + cformat, dst, src); return dst; } - -Tensor &img_canny_cpu(Tensor &dst, const Tensor &src, - const Scalar &threshold1, const Scalar &threshold2, - int64_t aperture_size, bool l2_gradient, ChannelFormat cformat) -{ +Tensor &img_canny_cpu(Tensor &dst, const Tensor &src, const Scalar &threshold1, + const Scalar &threshold2, int64_t aperture_size, + bool l2_gradient, ChannelFormat cformat) { auto stmp = src; auto dtmp = dst; - if(cformat == kNCHW && src.size(1) > 1){ - stmp = src.permute({0, 2, 3, 1}).contiguous(); //to NHWC + if (cformat == kNCHW && src.size(1) > 1) { + stmp = src.permute({0, 2, 3, 1}).contiguous(); // to NHWC HMP_REQUIRE(dst.size(1) == 1, "img_canny_cpu: invalid dst shape"); - dtmp = dst.squeeze(1).unsqueeze_(-1); //to NHWC + dtmp = dst.squeeze(1).unsqueeze_(-1); // to NHWC cformat = kNHWC; } - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - cv::Canny(smat, dmat, threshold1.to(), threshold2.to(), - aperture_size, l2_gradient); - }, cformat, dtmp, stmp); + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + cv::Canny(smat, dmat, threshold1.to(), + threshold2.to(), aperture_size, l2_gradient); + }, + cformat, dtmp, stmp); return dst; } - -Tensor &img_filter2d_cpu(Tensor &dst, const Tensor &src, - const Tensor &kernel, const Scalar& delta, ChannelFormat cformat) -{ +Tensor &img_filter2d_cpu(Tensor &dst, const Tensor &src, const Tensor &kernel, + const Scalar &delta, ChannelFormat cformat) { auto kmat = ocv::to_cv_mat(kernel, false); - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - auto ddepth = ocv::to_cv_type(dst.dtype()); - cv::filter2D(smat, dmat, ddepth, kmat, - cv::Point(-1,-1), delta.to()); - }, cformat, dst, src); + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + auto ddepth = ocv::to_cv_type(dst.dtype()); + cv::filter2D(smat, dmat, ddepth, kmat, cv::Point(-1, -1), + delta.to()); + }, + cformat, dst, src); return dst; } - -Tensor& img_gaussian_blur_cpu(Tensor &dst, const Tensor &src, int kx, int ky, - const Scalar& sigma_x, const Scalar& sigma_y, ChannelFormat cformat) -{ - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - cv::GaussianBlur(smat, dmat, {kx, ky}, - sigma_x.to(), sigma_y.to()); - }, cformat, dst, src); +Tensor &img_gaussian_blur_cpu(Tensor &dst, const Tensor &src, int kx, int ky, + const Scalar &sigma_x, const Scalar &sigma_y, + ChannelFormat cformat) { + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + cv::GaussianBlur(smat, dmat, {kx, ky}, sigma_x.to(), + sigma_y.to()); + }, + cformat, dst, src); return dst; } - - -Tensor& img_bilateral_filter_cpu(Tensor &dst, const Tensor &src, int d, - const Scalar& sigma_color, const Scalar& sigma_space, ChannelFormat cformat) -{ +Tensor &img_bilateral_filter_cpu(Tensor &dst, const Tensor &src, int d, + const Scalar &sigma_color, + const Scalar &sigma_space, + ChannelFormat cformat) { auto stmp = src; auto dtmp = dst; - if(cformat == kNCHW){ + if (cformat == kNCHW) { stmp = src.permute({0, 2, 3, 1}).contiguous(); dtmp = empty_like(stmp); } - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - cv::bilateralFilter(smat, dmat, d, - sigma_color.to(), sigma_space.to()); - }, kNHWC, dtmp, stmp); + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + cv::bilateralFilter(smat, dmat, d, sigma_color.to(), + sigma_space.to()); + }, + kNHWC, dtmp, stmp); - if(cformat == kNCHW){ + if (cformat == kNCHW) { dst.copy_(dtmp.permute({0, 3, 1, 2})); } return dst; } - - Tensor &img_warp_perspective_cpu(Tensor &dst, const Tensor &src, - const Tensor &M, ImageFilterMode mode, ChannelFormat cformat) -{ + const Tensor &M, ImageFilterMode mode, + ChannelFormat cformat) { auto m = ocv::to_cv_mat(M, false); - ocv::foreach_image([&](cv::Mat &dmat, const cv::Mat &smat){ - auto dsize = cv::Size(dmat.cols, dmat.rows); - auto flags = ocv::to_cv_filter_mode(mode); - cv::warpPerspective(smat, dmat, m, dsize, flags, cv::BORDER_REPLICATE); - }, cformat, dst, src); + ocv::foreach_image( + [&](cv::Mat &dmat, const cv::Mat &smat) { + auto dsize = cv::Size(dmat.cols, dmat.rows); + auto flags = ocv::to_cv_filter_mode(mode); + cv::warpPerspective(smat, dmat, m, dsize, flags, + cv::BORDER_REPLICATE); + }, + cformat, dst, src); return dst; } - HMP_DEVICE_DISPATCH(kCPU, img_erode_stub, &img_erode_cpu); HMP_DEVICE_DISPATCH(kCPU, img_dilate_stub, &img_dilate_cpu); HMP_DEVICE_DISPATCH(kCPU, img_sobel_stub, &img_sobel_cpu); @@ -158,6 +156,6 @@ HMP_DEVICE_DISPATCH(kCPU, img_filter2d_stub, &img_filter2d_cpu); HMP_DEVICE_DISPATCH(kCPU, img_gaussian_blur_stub, &img_gaussian_blur_cpu); HMP_DEVICE_DISPATCH(kCPU, img_bilateral_filter_stub, &img_bilateral_filter_cpu); HMP_DEVICE_DISPATCH(kCPU, img_warp_perspective_stub, &img_warp_perspective_cpu); - - -}}} //namespace hmp::kernel \ No newline at end of file +} +} +} // namespace hmp::kernel \ No newline at end of file diff --git a/bmf/hml/src/kernel/dispatch_stub.cpp b/bmf/hml/src/kernel/dispatch_stub.cpp index e4a49fab..c3b1a6ad 100644 --- a/bmf/hml/src/kernel/dispatch_stub.cpp +++ b/bmf/hml/src/kernel/dispatch_stub.cpp @@ -15,8 +15,4 @@ */ #include - -namespace hmp{ - - -} //namespace \ No newline at end of file +namespace hmp {} // namespace \ No newline at end of file diff --git a/bmf/hml/src/kernel/imgproc.cpp b/bmf/hml/src/kernel/imgproc.cpp index bf555ed9..94c949da 100644 --- a/bmf/hml/src/kernel/imgproc.cpp +++ b/bmf/hml/src/kernel/imgproc.cpp @@ -19,23 +19,21 @@ #include #include -namespace hmp{ - - -std::string stringfy(const PPixelFormat &format) -{ - switch (format) - { -#define STRINGFY_CASE(name) case PPixelFormat::name : return "k"#name; - HMP_FORALL_PPIXEL_FORMATS(STRINGFY_CASE) +namespace hmp { + +std::string stringfy(const PPixelFormat &format) { + switch (format) { +#define STRINGFY_CASE(name) \ + case PPixelFormat::name: \ + return "k" #name; + HMP_FORALL_PPIXEL_FORMATS(STRINGFY_CASE) #undef STRINGFY_CASE default: return fmt::format("PPixelFormat({})", static_cast(format)); } } - -namespace kernel{ +namespace kernel { HMP_DEFINE_DISPATCH_STUB(yuv_to_rgb_stub) HMP_DEFINE_DISPATCH_STUB(rgb_to_yuv_stub) @@ -58,65 +56,69 @@ HMP_DEFINE_DISPATCH_STUB(img_warp_perspective_stub) namespace { - - static inline void img_common_check(const Tensor &tensor, ChannelFormat cformat, - int64_t idx, const std::string &name) -{ - if(cformat == ChannelFormat::NHWC){ - HMP_REQUIRE(tensor.stride(-1) == 1, - "{}: expect {}th image tensor's channel stride is contiguous(0), got {}", - name, idx, tensor.stride(-1)); + int64_t idx, const std::string &name) { + if (cformat == ChannelFormat::NHWC) { + HMP_REQUIRE(tensor.stride(-1) == 1, "{}: expect {}th image tensor's " + "channel stride is contiguous(0), " + "got {}", + name, idx, tensor.stride(-1)); HMP_REQUIRE(tensor.stride(-2) == tensor.size(-1), - "{}: expect {}th image tensor's width stride is contiguous({}), got {}", - name, idx, tensor.size(-1), tensor.stride(-2)); - } - else{ - HMP_REQUIRE(tensor.stride(-1) == 1, - "{}: expect {}th image tensor's width stride is contiguous(1), got {}", - name, idx, tensor.stride(-1)); + "{}: expect {}th image tensor's width stride is " + "contiguous({}), got {}", + name, idx, tensor.size(-1), tensor.stride(-2)); + } else { + HMP_REQUIRE(tensor.stride(-1) == 1, "{}: expect {}th image tensor's " + "width stride is contiguous(1), " + "got {}", + name, idx, tensor.stride(-1)); } } -static inline void img_common_check(const Tensor &dst, const Tensor &src, - ChannelFormat cformat, const std::string &name) -{ +static inline void img_common_check(const Tensor &dst, const Tensor &src, + ChannelFormat cformat, + const std::string &name) { checkDevice({src, dst}, dst.device(), name); img_common_check(dst, cformat, 0, name); img_common_check(src, cformat, 1, name); - HMP_REQUIRE(src.size(0) == dst.size(0), - "{}: expect src and dst image have same batch dim, got src={}, dst={}", - name, src.size(0), dst.size(0)); + HMP_REQUIRE( + src.size(0) == dst.size(0), + "{}: expect src and dst image have same batch dim, got src={}, dst={}", + name, src.size(0), dst.size(0)); } -static inline void yuv_common_check(const TensorList &tensors, size_t idx, const std::string &name) -{ - for(size_t i = 0; i < tensors.size(); ++i){ +static inline void yuv_common_check(const TensorList &tensors, size_t idx, + const std::string &name) { + for (size_t i = 0; i < tensors.size(); ++i) { img_common_check(tensors[i], ChannelFormat::NHWC, idx, name); } } -static inline void yuv_common_check(const TensorList &dst, const TensorList &src, const std::string &name) -{ - HMP_REQUIRE(dst.size() == src.size(), - "{}: expect src and dst have same planes, got src={}, dst={}", name, src.size(), dst.size()); - for(size_t i = 0; i < dst.size(); ++i){ +static inline void yuv_common_check(const TensorList &dst, + const TensorList &src, + const std::string &name) { + HMP_REQUIRE(dst.size() == src.size(), + "{}: expect src and dst have same planes, got src={}, dst={}", + name, src.size(), dst.size()); + for (size_t i = 0; i < dst.size(); ++i) { img_common_check(dst[i], src[i], ChannelFormat::NHWC, name); } } -} //namespace +} // namespace -Tensor &yuv_to_rgb(Tensor &dst, const TensorList &src, PPixelFormat pformat, ChannelFormat cformat) -{ +Tensor &yuv_to_rgb(Tensor &dst, const TensorList &src, PPixelFormat pformat, + ChannelFormat cformat) { auto stmp = img::image_format(src, kNHWC); auto dtmp = img::image_format(dst, cformat); yuv_common_check(stmp, 1, "yuv_to_rgb"); img_common_check(dtmp, cformat, 0, "yuv_to_rgb"); auto cdim = cformat == kNCHW ? -3 : -1; - HMP_REQUIRE(dtmp.size(cdim) == 3, "yuv_to_rgb: require 3 channels for dtmp, got {}", dtmp.size(cdim)); + HMP_REQUIRE(dtmp.size(cdim) == 3, + "yuv_to_rgb: require 3 channels for dtmp, got {}", + dtmp.size(cdim)); // yuv_to_rgb_stub(dtmp.device_type(), dtmp, stmp, pformat, cformat); @@ -125,23 +127,25 @@ Tensor &yuv_to_rgb(Tensor &dst, const TensorList &src, PPixelFormat pformat, Cha return dst; } -TensorList &rgb_to_yuv(TensorList &dst, const Tensor &src, PPixelFormat pformat, ChannelFormat cformat) -{ +TensorList &rgb_to_yuv(TensorList &dst, const Tensor &src, PPixelFormat pformat, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, kNHWC); yuv_common_check(dtmp, 0, "rgb_to_yuv"); img_common_check(stmp, cformat, 1, "rgb_to_yuv"); auto cdim = cformat == kNCHW ? -3 : -1; - HMP_REQUIRE(stmp.size(cdim) == 3, "rgb_to_yuv: require 3 channels for dst, got {}", stmp.size(cdim)); + HMP_REQUIRE(stmp.size(cdim) == 3, + "rgb_to_yuv: require 3 channels for dst, got {}", + stmp.size(cdim)); rgb_to_yuv_stub(stmp.device_type(), dtmp, stmp, pformat, cformat); return dst; } -TensorList &yuv_to_yuv(TensorList &dst, const TensorList &src, PPixelFormat dformat, PPixelFormat sformat) -{ +TensorList &yuv_to_yuv(TensorList &dst, const TensorList &src, + PPixelFormat dformat, PPixelFormat sformat) { auto stmp = img::image_format(src, kNHWC); auto dtmp = img::image_format(dst, kNHWC); yuv_common_check(stmp, 0, "yuv_to_yuv"); @@ -152,8 +156,7 @@ TensorList &yuv_to_yuv(TensorList &dst, const TensorList &src, PPixelFormat dfor } TensorList &yuv_resize(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageFilterMode mode) -{ + PPixelFormat format, ImageFilterMode mode) { auto stmp = img::image_format(src, kNHWC); auto dtmp = img::image_format(dst, kNHWC); @@ -164,23 +167,26 @@ TensorList &yuv_resize(TensorList &dst, const TensorList &src, return dst; } - -TensorList &yuv_rotate(TensorList &dst, const TensorList &src, PPixelFormat format, ImageRotationMode rotate) -{ +TensorList &yuv_rotate(TensorList &dst, const TensorList &src, + PPixelFormat format, ImageRotationMode rotate) { auto stmp = img::image_format(src, kNHWC); auto dtmp = img::image_format(dst, kNHWC); yuv_common_check(dtmp, stmp, "yuv_rotate"); - if(rotate == ImageRotationMode::Rotate0 || rotate == ImageRotationMode::Rotate180){ - HMP_REQUIRE(dtmp[0].size(1) == stmp[0].size(1) && dtmp[0].size(2) == stmp[0].size(2), - "yuv_rotate: image size are not matched with rotatation mode"); - } - else if(rotate == ImageRotationMode::Rotate90 || rotate == ImageRotationMode::Rotate270){ - HMP_REQUIRE(dtmp[0].size(1) == stmp[0].size(2) && dtmp[0].size(2) == stmp[0].size(1), - "yuv_rotate: image size are not matched with rotatation mode"); - } - else{ + if (rotate == ImageRotationMode::Rotate0 || + rotate == ImageRotationMode::Rotate180) { + HMP_REQUIRE( + dtmp[0].size(1) == stmp[0].size(1) && + dtmp[0].size(2) == stmp[0].size(2), + "yuv_rotate: image size are not matched with rotatation mode"); + } else if (rotate == ImageRotationMode::Rotate90 || + rotate == ImageRotationMode::Rotate270) { + HMP_REQUIRE( + dtmp[0].size(1) == stmp[0].size(2) && + dtmp[0].size(2) == stmp[0].size(1), + "yuv_rotate: image size are not matched with rotatation mode"); + } else { HMP_REQUIRE(false, "yuv_rotate: internal error") } @@ -189,75 +195,76 @@ TensorList &yuv_rotate(TensorList &dst, const TensorList &src, PPixelFormat form return dst; } - -TensorList &yuv_mirror(TensorList &dst, const TensorList &src, PPixelFormat format, ImageAxis axis) -{ +TensorList &yuv_mirror(TensorList &dst, const TensorList &src, + PPixelFormat format, ImageAxis axis) { auto stmp = img::image_format(src, kNHWC); auto dtmp = img::image_format(dst, kNHWC); yuv_common_check(dtmp, stmp, "yuv_mirror"); - HMP_REQUIRE(stmp[0].shape() == dtmp[0].shape(), + HMP_REQUIRE( + stmp[0].shape() == dtmp[0].shape(), "yuv_mirror: expect src and dst have same shape, got src={}, dst={}", - stmp[0].shape(), dtmp[0].shape()); + stmp[0].shape(), dtmp[0].shape()); yuv_mirror_stub(stmp[0].device_type(), dtmp, stmp, format, axis); return dst; } - -Tensor &img_resize(Tensor &dst, const Tensor &src, ImageFilterMode mode, ChannelFormat cformat) -{ +Tensor &img_resize(Tensor &dst, const Tensor &src, ImageFilterMode mode, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "im_resize"); - HMP_REQUIRE(stmp.size(0) == dtmp.size(0), - "image_resize: expect same size of batch dim, src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE(stmp.size(0) == dtmp.size(0), + "image_resize: expect same size of batch dim, src={}, dst={}", + stmp.shape(), dtmp.shape()); auto cdim = cformat == kNCHW ? 1 : -1; - HMP_REQUIRE(stmp.size(cdim) == dtmp.size(cdim), - "image_resize: expect same size of channel dim, src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE(stmp.size(cdim) == dtmp.size(cdim), + "image_resize: expect same size of channel dim, src={}, dst={}", + stmp.shape(), dtmp.shape()); img_resize_stub(dtmp.device_type(), dtmp, stmp, mode, cformat); return dst; } -Tensor &img_rotate(Tensor &dst, const Tensor &src, ImageRotationMode mode, ChannelFormat cformat) -{ +Tensor &img_rotate(Tensor &dst, const Tensor &src, ImageRotationMode mode, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "im_rotate"); int64_t cdim, wdim, hdim; - if(cformat == kNCHW){ + if (cformat == kNCHW) { wdim = -1; hdim = -2; cdim = -3; - } - else{ + } else { cdim = -1; wdim = -2; hdim = -3; } - HMP_REQUIRE(stmp.size(cdim) == dtmp.size(cdim), - "image_rotate: expect same size of channel dim, src={}, dst={}", stmp.shape(), dtmp.shape()); - - bool shapeChanged = mode == ImageRotationMode::Rotate90 || mode == ImageRotationMode::Rotate270; - if(shapeChanged){ - HMP_REQUIRE(stmp.size(hdim) == dtmp.size(wdim) && stmp.size(wdim) == dtmp.size(hdim), - "img_rotate: image size is invalid, expec {}, got {}", - SizeArray{stmp.size(wdim), stmp.size(hdim)}, - SizeArray{dtmp.size(hdim), dtmp.size(wdim)} - ); - } - else{ - HMP_REQUIRE(stmp.size(wdim) == dtmp.size(wdim) && stmp.size(hdim) == dtmp.size(hdim), - "img_rotate: image size is invalid, expec {}, got {}", - SizeArray{stmp.size(wdim), stmp.size(hdim)}, - SizeArray{dtmp.size(wdim), dtmp.size(hdim)} - ); + HMP_REQUIRE(stmp.size(cdim) == dtmp.size(cdim), + "image_rotate: expect same size of channel dim, src={}, dst={}", + stmp.shape(), dtmp.shape()); + + bool shapeChanged = mode == ImageRotationMode::Rotate90 || + mode == ImageRotationMode::Rotate270; + if (shapeChanged) { + HMP_REQUIRE(stmp.size(hdim) == dtmp.size(wdim) && + stmp.size(wdim) == dtmp.size(hdim), + "img_rotate: image size is invalid, expec {}, got {}", + SizeArray{stmp.size(wdim), stmp.size(hdim)}, + SizeArray{dtmp.size(hdim), dtmp.size(wdim)}); + } else { + HMP_REQUIRE(stmp.size(wdim) == dtmp.size(wdim) && + stmp.size(hdim) == dtmp.size(hdim), + "img_rotate: image size is invalid, expec {}, got {}", + SizeArray{stmp.size(wdim), stmp.size(hdim)}, + SizeArray{dtmp.size(wdim), dtmp.size(hdim)}); } img_rotate_stub(dtmp.device_type(), dtmp, stmp, mode, cformat); @@ -265,198 +272,205 @@ Tensor &img_rotate(Tensor &dst, const Tensor &src, ImageRotationMode mode, Chann return dst; } - -Tensor &img_mirror(Tensor &dst, const Tensor &src, ImageAxis axis, ChannelFormat cformat) -{ +Tensor &img_mirror(Tensor &dst, const Tensor &src, ImageAxis axis, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_mirror"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_mirror: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_mirror: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); img_mirror_stub(stmp.device_type(), dtmp, stmp, axis, cformat); return dst; } - -Tensor& img_normalize(Tensor &dst, const Tensor &src, const Tensor &mean, const Tensor &std, ChannelFormat cformat) -{ +Tensor &img_normalize(Tensor &dst, const Tensor &src, const Tensor &mean, + const Tensor &std, ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); checkDevice({stmp, mean, std}, stmp.device(), "img_normalize"); img_common_check(dtmp, stmp, cformat, "img_normalize"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_normalize: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_normalize: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); auto cdim = cformat == kNCHW ? 1 : -1; - HMP_REQUIRE(mean.dim() == 1 && std.dim() == 1 && - mean.size(0) == std.size(0) && mean.size(0) == stmp.size(cdim), - "img_normalize: invalid mean or std shape, expect ({},)", stmp.size(cdim)); + HMP_REQUIRE(mean.dim() == 1 && std.dim() == 1 && + mean.size(0) == std.size(0) && + mean.size(0) == stmp.size(cdim), + "img_normalize: invalid mean or std shape, expect ({},)", + stmp.size(cdim)); img_normalize_stub(stmp.device_type(), dtmp, stmp, mean, std, cformat); return dst; - } - -Tensor &img_erode(Tensor &dst, const Tensor &src, const Tensor &kernel, ChannelFormat cformat) -{ +Tensor &img_erode(Tensor &dst, const Tensor &src, const Tensor &kernel, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_erode"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_erode: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_erode: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); img_erode_stub(stmp.device_type(), dtmp, stmp, kernel, cformat); return dst; } -Tensor &img_dilate(Tensor &dst, const Tensor &src, const Tensor &kernel, ChannelFormat cformat) -{ +Tensor &img_dilate(Tensor &dst, const Tensor &src, const Tensor &kernel, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_dilate"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_dilate: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_dilate: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); img_dilate_stub(stmp.device_type(), dtmp, stmp, kernel, cformat); return dst; } - Tensor &img_sobel(Tensor &dst, const Tensor &src, int64_t dx, int64_t dy, - int64_t ksize, const Scalar& scale, const Scalar& delta, ChannelFormat cformat) -{ + int64_t ksize, const Scalar &scale, const Scalar &delta, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_sobel"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_sobel: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_sobel: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); - img_sobel_stub(stmp.device_type(), dtmp, stmp, dx, dy, ksize, scale, delta, cformat); + img_sobel_stub(stmp.device_type(), dtmp, stmp, dx, dy, ksize, scale, delta, + cformat); return dst; } - -Tensor &img_canny(Tensor &dst, const Tensor &src, const Scalar &low_thresh, const Scalar &high_thresh, - int64_t aperture_size, bool l2_gradient, ChannelFormat cformat) -{ +Tensor &img_canny(Tensor &dst, const Tensor &src, const Scalar &low_thresh, + const Scalar &high_thresh, int64_t aperture_size, + bool l2_gradient, ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_canny"); auto cdim = cformat == kNCHW ? 1 : -1; HMP_REQUIRE(dtmp.size(cdim) == 1, - "img_canny: invalid dst shape, expect 1 channel, got {}", stmp.size(cdim)); + "img_canny: invalid dst shape, expect 1 channel, got {}", + stmp.size(cdim)); img_canny_stub(stmp.device_type(), dtmp, stmp, low_thresh, high_thresh, - aperture_size, l2_gradient, cformat); + aperture_size, l2_gradient, cformat); return dst; } - -Tensor &img_warp_perspective(Tensor &dst, const Tensor &src, - const Tensor &M, ImageFilterMode mode, ChannelFormat cformat) -{ +Tensor &img_warp_perspective(Tensor &dst, const Tensor &src, const Tensor &M, + ImageFilterMode mode, ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_warp_perspective"); - img_warp_perspective_stub(stmp.device_type(), dtmp, stmp, M, - mode, cformat); + img_warp_perspective_stub(stmp.device_type(), dtmp, stmp, M, mode, cformat); return dst; } - -Tensor &img_filter2d(Tensor &dst, const Tensor &src, - const Tensor &kernel, const Scalar& delta, ChannelFormat cformat) -{ +Tensor &img_filter2d(Tensor &dst, const Tensor &src, const Tensor &kernel, + const Scalar &delta, ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_filter2d"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_filter2d: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); + HMP_REQUIRE( + stmp.shape() == dtmp.shape(), + "img_filter2d: expect src and dst have same shape, got src={}, dst={}", + stmp.shape(), dtmp.shape()); img_filter2d_stub(stmp.device_type(), dtmp, stmp, kernel, delta, cformat); return dst; } - -Tensor& img_bilateral_filter(Tensor &dst, const Tensor &src, int d, - const Scalar& sigma_color, const Scalar& sigma_space, ChannelFormat cformat) -{ +Tensor &img_bilateral_filter(Tensor &dst, const Tensor &src, int d, + const Scalar &sigma_color, + const Scalar &sigma_space, ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_bilateral_filter"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_bilateral_filter: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); - img_bilateral_filter_stub(stmp.device_type(), dtmp, stmp, d, sigma_color, sigma_space, cformat); + HMP_REQUIRE(stmp.shape() == dtmp.shape(), "img_bilateral_filter: expect " + "src and dst have same shape, " + "got src={}, dst={}", + stmp.shape(), dtmp.shape()); + img_bilateral_filter_stub(stmp.device_type(), dtmp, stmp, d, sigma_color, + sigma_space, cformat); return dst; } -Tensor& img_gaussian_blur(Tensor &dst, const Tensor &src, int kx, int ky, - const Scalar& sigma_x, const Scalar& sigma_y, ChannelFormat cformat) -{ +Tensor &img_gaussian_blur(Tensor &dst, const Tensor &src, int kx, int ky, + const Scalar &sigma_x, const Scalar &sigma_y, + ChannelFormat cformat) { auto stmp = img::image_format(src, cformat); auto dtmp = img::image_format(dst, cformat); img_common_check(dtmp, stmp, cformat, "img_gaussian_blur"); - HMP_REQUIRE(stmp.shape() == dtmp.shape(), - "img_gaussian_blur: expect src and dst have same shape, got src={}, dst={}", stmp.shape(), dtmp.shape()); - img_gaussian_blur_stub(stmp.device_type(), dtmp, stmp, kx, ky, sigma_x, sigma_y, cformat); + HMP_REQUIRE(stmp.shape() == dtmp.shape(), "img_gaussian_blur: expect src " + "and dst have same shape, got " + "src={}, dst={}", + stmp.shape(), dtmp.shape()); + img_gaussian_blur_stub(stmp.device_type(), dtmp, stmp, kx, ky, sigma_x, + sigma_y, cformat); return dst; } - Tensor &img_overlay(Tensor &dst, const Tensor &src0, const Tensor &src1, - const Tensor &alpha, ChannelFormat cformat) -{ + const Tensor &alpha, ChannelFormat cformat) { HMP_REQUIRE(dst.dim() == 4, - "img_overlay: expect dst tensor have 4 dims, got {}", dst.dim()); + "img_overlay: expect dst tensor have 4 dims, got {}", + dst.dim()); checkShape({src0, src1}, dst.shape(), "img_overlay"); HMP_REQUIRE(alpha.dim() >= 2, - "img_overlay: expect alpha tensor have at least 2 dims, got {}", alpha.dim()); + "img_overlay: expect alpha tensor have at least 2 dims, got {}", + alpha.dim()); // auto tmp = alpha; auto new_shape = tmp.shape(); - if(new_shape.size() == 2){ - new_shape.insert(new_shape.begin(), 1); //unsqueeze batch dim + if (new_shape.size() == 2) { + new_shape.insert(new_shape.begin(), 1); // unsqueeze batch dim } - if(new_shape.size() == 3){ //unsqueeze channel dim - if(cformat == kNCHW){ - new_shape.insert(new_shape.begin()+1, 1); - } - else{ + if (new_shape.size() == 3) { // unsqueeze channel dim + if (cformat == kNCHW) { + new_shape.insert(new_shape.begin() + 1, 1); + } else { new_shape.insert(new_shape.end(), 1); } } tmp = tmp.view(new_shape).expand_as(dst); // - if(!dst.is_same(src0)){ + if (!dst.is_same(src0)) { copy(dst, src0); } - dst.mul_(1-tmp).add_(tmp * src1); + dst.mul_(1 - tmp).add_(tmp * src1); return dst; } - - - -}} //namespace \ No newline at end of file +} +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/kernel/libyuv/imgproc.cpp b/bmf/hml/src/kernel/libyuv/imgproc.cpp index a3a05ee9..4ee82b0e 100644 --- a/bmf/hml/src/kernel/libyuv/imgproc.cpp +++ b/bmf/hml/src/kernel/libyuv/imgproc.cpp @@ -18,100 +18,100 @@ #include #include -namespace hmp{ -namespace kernel{ -namespace{ +namespace hmp { +namespace kernel { +namespace { - -Tensor &yuv_to_rgb_cpu(Tensor &dst, const TensorList &src, PPixelFormat pformat, ChannelFormat cformat) -{ +Tensor &yuv_to_rgb_cpu(Tensor &dst, const TensorList &src, PPixelFormat pformat, + ChannelFormat cformat) { auto out = dst; - if(cformat == ChannelFormat::NCHW){ - out = empty({dst.size(0), dst.size(2), dst.size(3), dst.size(1)}, dst.options()); + if (cformat == ChannelFormat::NCHW) { + out = empty({dst.size(0), dst.size(2), dst.size(3), dst.size(1)}, + dst.options()); } auto width = out.size(2); auto height = out.size(1); - for(int64_t i = 0; i < out.size(0); ++i){ + for (int64_t i = 0; i < out.size(0); ++i) { auto d = out.select(0, i); TensorList ss; - for(auto &s : src){ + for (auto &s : src) { ss.push_back(s.select(0, i)); } - switch (pformat) - { + switch (pformat) { case PPixelFormat::I420: - HMP_REQUIRE(ss.size() == 3, "yuv_to_rgb_cpu: expect 3 input planes, got {}", ss.size()); - libyuv::I420ToRAW( //I420ToRGB24 have invalid order?? - ss[0].data(), ss[0].stride(0), - ss[1].data(), ss[1].stride(0), - ss[2].data(), ss[2].stride(0), + HMP_REQUIRE(ss.size() == 3, + "yuv_to_rgb_cpu: expect 3 input planes, got {}", + ss.size()); + libyuv::I420ToRAW( // I420ToRGB24 have invalid order?? + ss[0].data(), ss[0].stride(0), ss[1].data(), + ss[1].stride(0), ss[2].data(), ss[2].stride(0), d.data(), d.stride(0), d.size(1), d.size(0)); break; case PPixelFormat::H420: - HMP_REQUIRE(ss.size() == 3, "yuv_to_rgb_cpu: expect 3 input planes, got {}", ss.size()); - libyuv::H420ToRAW( //H420ToRGB24 have invalid order?? - ss[0].data(), ss[0].stride(0), - ss[1].data(), ss[1].stride(0), - ss[2].data(), ss[2].stride(0), + HMP_REQUIRE(ss.size() == 3, + "yuv_to_rgb_cpu: expect 3 input planes, got {}", + ss.size()); + libyuv::H420ToRAW( // H420ToRGB24 have invalid order?? + ss[0].data(), ss[0].stride(0), ss[1].data(), + ss[1].stride(0), ss[2].data(), ss[2].stride(0), d.data(), d.stride(0), d.size(1), d.size(0)); break; default: - HMP_REQUIRE(false, - "yuv_to_rgb_cpu: unsupport pixel format {}", pformat); + HMP_REQUIRE(false, "yuv_to_rgb_cpu: unsupport pixel format {}", + pformat); break; } } - if(cformat == ChannelFormat::NCHW){ + if (cformat == ChannelFormat::NCHW) { copy(dst, out.permute({0, 3, 1, 2})); } return dst; } - - -TensorList &rgb_to_yuv_cpu(TensorList &dst, const Tensor &src, PPixelFormat pformat, ChannelFormat cformat) -{ - auto w = cformat == ChannelFormat::NHWC ? src : src.permute({0, 2, 3, 1}).contiguous(); +TensorList &rgb_to_yuv_cpu(TensorList &dst, const Tensor &src, + PPixelFormat pformat, ChannelFormat cformat) { + auto w = cformat == ChannelFormat::NHWC + ? src + : src.permute({0, 2, 3, 1}).contiguous(); auto width = w.size(2); auto height = w.size(1); - for(int64_t i = 0; i < src.size(0); ++i){ + for (int64_t i = 0; i < src.size(0); ++i) { auto s = w.select(0, i); TensorList ds; - for(auto &d : dst){ + for (auto &d : dst) { ds.push_back(d.select(0, i)); } - switch (pformat) - { + switch (pformat) { case PPixelFormat::I420: - HMP_REQUIRE(ds.size() == 3, "rgb_to_yuv_cpu: expect 3 input planes, got {}", ds.size()); - libyuv::RAWToI420( - s.data(), s.stride(0), - ds[0].data(), ds[0].stride(0), - ds[1].data(), ds[1].stride(0), - ds[2].data(), ds[2].stride(0), - s.size(1), s.size(0)); + HMP_REQUIRE(ds.size() == 3, + "rgb_to_yuv_cpu: expect 3 input planes, got {}", + ds.size()); + libyuv::RAWToI420( + s.data(), s.stride(0), ds[0].data(), + ds[0].stride(0), ds[1].data(), ds[1].stride(0), + ds[2].data(), ds[2].stride(0), s.size(1), s.size(0)); break; case PPixelFormat::H420: - HMP_REQUIRE(ds.size() == 3, "rgb_to_yuv_cpu: expect 3 input planes, got {}", ds.size()); - libyuv::RAWToJ420( //FIXME: No RAWToJ420 found - s.data(), s.stride(0), - ds[0].data(), ds[0].stride(0), - ds[1].data(), ds[1].stride(0), - ds[2].data(), ds[2].stride(0), - s.size(1), s.size(0)); + HMP_REQUIRE(ds.size() == 3, + "rgb_to_yuv_cpu: expect 3 input planes, got {}", + ds.size()); + libyuv::RAWToJ420( // FIXME: No RAWToJ420 found + s.data(), s.stride(0), ds[0].data(), + ds[0].stride(0), ds[1].data(), ds[1].stride(0), + ds[2].data(), ds[2].stride(0), s.size(1), s.size(0)); break; default: - HMP_REQUIRE(false, - "rgb_to_yuv_cpu: unsupport pixel format {}", pformat); + HMP_REQUIRE(false, "rgb_to_yuv_cpu: unsupport pixel format {}", + pformat); break; } } @@ -119,128 +119,125 @@ TensorList &rgb_to_yuv_cpu(TensorList &dst, const Tensor &src, PPixelFormat pfor return dst; } - - TensorList &yuv_resize_cpu(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageFilterMode mode) -{ + PPixelFormat format, ImageFilterMode mode) { auto batch = src[0].size(0); auto m = getLibYUVFilterMode(mode); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src[0].scalar_type(), "yuv_resize_cpu", [&]() { - for (int64_t i = 0; i < src.size(); ++i){ - for (int64_t j = 0; j < batch; ++j){ - auto d = dst[i].select(0, j); - auto s = src[i].select(0, j); - libyuvScalePlane(d, s, m); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src[0].scalar_type(), "yuv_resize_cpu", [&]() { + for (int64_t i = 0; i < src.size(); ++i) { + for (int64_t j = 0; j < batch; ++j) { + auto d = dst[i].select(0, j); + auto s = src[i].select(0, j); + libyuvScalePlane(d, s, m); + } } - } - }); + }); return dst; } TensorList &yuv_rotate_cpu(TensorList &dst, const TensorList &src, - PPixelFormat format, ImageRotationMode rotate) -{ + PPixelFormat format, ImageRotationMode rotate) { auto batch = src[0].size(0); auto m = getLibYUVRotationMode(rotate); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src[0].scalar_type(), "yuv_rotate_cpu", [&]() { - for (int64_t i = 0; i < src.size(); ++i){ - for (int64_t j = 0; j < batch; ++j){ - auto d = dst[i].select(0, j); - auto s = src[i].select(0, j); - libyuvRotatePlane(d, s, m); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src[0].scalar_type(), "yuv_rotate_cpu", [&]() { + for (int64_t i = 0; i < src.size(); ++i) { + for (int64_t j = 0; j < batch; ++j) { + auto d = dst[i].select(0, j); + auto s = src[i].select(0, j); + libyuvRotatePlane(d, s, m); + } } - } - }); + }); return dst; } - -TensorList &yuv_mirror_cpu(TensorList &dst, const TensorList &src, PPixelFormat format, ImageAxis axis) -{ +TensorList &yuv_mirror_cpu(TensorList &dst, const TensorList &src, + PPixelFormat format, ImageAxis axis) { auto batch = src[0].size(0); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src[0].scalar_type(), "yuv_mirror_cpu", [&]() { - for (int64_t i = 0; i < src.size(); ++i){ - for (int64_t j = 0; j < batch; ++j){ - auto d = dst[i].select(0, j); - auto s = src[i].select(0, j); - libyuvMirrorPlane(d, s, axis); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src[0].scalar_type(), "yuv_mirror_cpu", [&]() { + for (int64_t i = 0; i < src.size(); ++i) { + for (int64_t j = 0; j < batch; ++j) { + auto d = dst[i].select(0, j); + auto s = src[i].select(0, j); + libyuvMirrorPlane(d, s, axis); + } } - } - }); + }); return dst; } -Tensor &img_resize_cpu(Tensor &dst, const Tensor &src, ImageFilterMode mode_, ChannelFormat cformat) -{ +Tensor &img_resize_cpu(Tensor &dst, const Tensor &src, ImageFilterMode mode_, + ChannelFormat cformat) { HMP_REQUIRE(cformat == ChannelFormat::NCHW, - "img_resize_cpu: only support NCHW layout"); + "img_resize_cpu: only support NCHW layout"); auto batch = src.size(0); auto mode = getLibYUVFilterMode(mode_); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src.scalar_type(), "img_resize_cpu", [&](){ - for(int64_t i = 0; i < batch; ++i){ - auto d = dst.select(0, i); - auto s = src.select(0, i); - libyuvScalePlane(d, s, mode); - } - }); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src.scalar_type(), "img_resize_cpu", [&]() { + for (int64_t i = 0; i < batch; ++i) { + auto d = dst.select(0, i); + auto s = src.select(0, i); + libyuvScalePlane(d, s, mode); + } + }); return dst; } - - -Tensor &img_rotate_cpu(Tensor &dst, const Tensor &src, ImageRotationMode mode_, ChannelFormat cformat) -{ +Tensor &img_rotate_cpu(Tensor &dst, const Tensor &src, ImageRotationMode mode_, + ChannelFormat cformat) { HMP_REQUIRE(cformat == ChannelFormat::NCHW, - "img_rotate_cpu: only support NCHW layout"); + "img_rotate_cpu: only support NCHW layout"); auto batch = src.size(0); auto mode = getLibYUVRotationMode(mode_); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src.scalar_type(), "img_rotate_cpu", [&](){ - for(int64_t i = 0; i < batch; ++i){ - auto d = dst.select(0, i); - auto s = src.select(0, i); - libyuvRotatePlane(d, s, mode); - } - }); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src.scalar_type(), "img_rotate_cpu", [&]() { + for (int64_t i = 0; i < batch; ++i) { + auto d = dst.select(0, i); + auto s = src.select(0, i); + libyuvRotatePlane(d, s, mode); + } + }); return dst; } - -Tensor &img_mirror_cpu(Tensor &dst, const Tensor &src, ImageAxis axis, ChannelFormat cformat) -{ +Tensor &img_mirror_cpu(Tensor &dst, const Tensor &src, ImageAxis axis, + ChannelFormat cformat) { HMP_REQUIRE(cformat == ChannelFormat::NCHW, - "img_mirror_cpu: only support NCHW layout"); + "img_mirror_cpu: only support NCHW layout"); auto batch = src.size(0); - HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES(src.scalar_type(), "img_mirror_cpu", [&](){ - for(int64_t i = 0; i < batch; ++i){ - auto d = dst.select(0, i); - auto s = src.select(0, i); - libyuvMirrorPlane(d, s, axis); - } - }); + HMP_DISPATCH_UNSIGNED_INTEGRAL_TYPES( + src.scalar_type(), "img_mirror_cpu", [&]() { + for (int64_t i = 0; i < batch; ++i) { + auto d = dst.select(0, i); + auto s = src.select(0, i); + libyuvMirrorPlane(d, s, axis); + } + }); return dst; } - -//HMP_DEVICE_DISPATCH(kCPU, yuv_to_rgb_stub, &yuv_to_rgb_cpu) -//HMP_DEVICE_DISPATCH(kCPU, rgb_to_yuv_stub, &rgb_to_yuv_cpu) -//HMP_DEVICE_DISPATCH(kCPU, yuv_resize_stub, &yuv_resize_cpu) -//HMP_DEVICE_DISPATCH(kCPU, yuv_rotate_stub, &yuv_rotate_cpu) -//HMP_DEVICE_DISPATCH(kCPU, yuv_mirror_stub, &yuv_mirror_cpu) -//HMP_DEVICE_DISPATCH(kCPU, img_resize_stub, &img_resize_cpu) -//HMP_DEVICE_DISPATCH(kCPU, img_rotate_stub, &img_rotate_cpu) -//HMP_DEVICE_DISPATCH(kCPU, img_mirror_stub, &img_mirror_cpu) - - -}}} //namespace hmp::kernel \ No newline at end of file +// HMP_DEVICE_DISPATCH(kCPU, yuv_to_rgb_stub, &yuv_to_rgb_cpu) +// HMP_DEVICE_DISPATCH(kCPU, rgb_to_yuv_stub, &rgb_to_yuv_cpu) +// HMP_DEVICE_DISPATCH(kCPU, yuv_resize_stub, &yuv_resize_cpu) +// HMP_DEVICE_DISPATCH(kCPU, yuv_rotate_stub, &yuv_rotate_cpu) +// HMP_DEVICE_DISPATCH(kCPU, yuv_mirror_stub, &yuv_mirror_cpu) +// HMP_DEVICE_DISPATCH(kCPU, img_resize_stub, &img_resize_cpu) +// HMP_DEVICE_DISPATCH(kCPU, img_rotate_stub, &img_rotate_cpu) +// HMP_DEVICE_DISPATCH(kCPU, img_mirror_stub, &img_mirror_cpu) +} +} +} // namespace hmp::kernel \ No newline at end of file diff --git a/bmf/hml/src/kernel/shape_transform.cpp b/bmf/hml/src/kernel/shape_transform.cpp index 134f1cbb..1284a7af 100644 --- a/bmf/hml/src/kernel/shape_transform.cpp +++ b/bmf/hml/src/kernel/shape_transform.cpp @@ -16,54 +16,48 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { - -static SizeArray calcConcatShape(const TensorList &tensors, int64_t axis) -{ +static SizeArray calcConcatShape(const TensorList &tensors, int64_t axis) { SizeArray shape(tensors[0].shape()); - HMP_REQUIRE(axis < shape.size(), - "concat: axis({}) is out of range({})", axis, shape.size()); + HMP_REQUIRE(axis < shape.size(), "concat: axis({}) is out of range({})", + axis, shape.size()); - for(int64_t i = 1; i < tensors.size(); ++i){ - HMP_REQUIRE(tensors[i].dim() == shape.size(), - "concat: {}th tensor has invalid dim({}), expect {}", - i, tensors[i].dim(), shape.size()); + for (int64_t i = 1; i < tensors.size(); ++i) { + HMP_REQUIRE(tensors[i].dim() == shape.size(), + "concat: {}th tensor has invalid dim({}), expect {}", i, + tensors[i].dim(), shape.size()); shape[axis] += tensors[i].size(axis); } return shape; } - -static SizeArray calcStackShape(const TensorList &tensors, int64_t axis) -{ +static SizeArray calcStackShape(const TensorList &tensors, int64_t axis) { SizeArray shape(tensors[0].shape()); - HMP_REQUIRE(axis <= shape.size(), - "stack: axis({}) is out of range({})", axis, shape.size() + 1); + HMP_REQUIRE(axis <= shape.size(), "stack: axis({}) is out of range({})", + axis, shape.size() + 1); shape.insert(shape.begin() + axis, 1); - for(int64_t i = 1; i < tensors.size(); ++i){ - HMP_REQUIRE(tensors[i].shape() == tensors[0].shape(), - "stack: {}th tensor has invalid shape({}), expect {}", - i, tensors[i].shape(), tensors[0].shape()); + for (int64_t i = 1; i < tensors.size(); ++i) { + HMP_REQUIRE(tensors[i].shape() == tensors[0].shape(), + "stack: {}th tensor has invalid shape({}), expect {}", i, + tensors[i].shape(), tensors[0].shape()); shape[axis] += 1; } return shape; } - -Tensor& concat(Tensor &out, const TensorList &tensors, int64_t axis) -{ +Tensor &concat(Tensor &out, const TensorList &tensors, int64_t axis) { axis = wrap_size(axis, tensors[0].dim()); auto shape = calcConcatShape(tensors, axis); HMP_REQUIRE(out.shape() == shape, "concat: expect out has shape {}, got {}", - shape, out.shape()); + shape, out.shape()); - for(int64_t i = 0, si = 0; i < tensors.size(); ++i){ + for (int64_t i = 0, si = 0; i < tensors.size(); ++i) { auto &t = tensors[i]; auto tmp = out.slice(axis, si, si + t.size(axis)); copy(tmp, t); @@ -73,9 +67,7 @@ Tensor& concat(Tensor &out, const TensorList &tensors, int64_t axis) return out; } - -Tensor concat(const TensorList &tensors, int64_t axis) -{ +Tensor concat(const TensorList &tensors, int64_t axis) { axis = wrap_size(axis, tensors[0].dim()); auto shape = calcConcatShape(tensors, axis); auto out = empty(shape, tensors[0].options()); @@ -85,16 +77,14 @@ Tensor concat(const TensorList &tensors, int64_t axis) return out; } - -Tensor& stack(Tensor &out, const TensorList &tensors, int64_t axis) -{ +Tensor &stack(Tensor &out, const TensorList &tensors, int64_t axis) { axis = wrap_size(axis, tensors[0].dim() + 1); auto shape = calcStackShape(tensors, axis); HMP_REQUIRE(out.shape() == shape, "stack: expect out has shape {}, got {}", - shape, out.shape()); + shape, out.shape()); - for(int64_t i = 0; i < tensors.size(); ++i){ + for (int64_t i = 0; i < tensors.size(); ++i) { auto &t = tensors[i]; auto tmp = out.select(axis, i); copy(tmp, t); @@ -103,8 +93,7 @@ Tensor& stack(Tensor &out, const TensorList &tensors, int64_t axis) return out; } -Tensor stack(const TensorList &tensors, int64_t axis) -{ +Tensor stack(const TensorList &tensors, int64_t axis) { axis = wrap_size(axis, tensors[0].dim() + 1); auto shape = calcStackShape(tensors, axis); auto out = empty(shape, tensors[0].options()); @@ -114,46 +103,36 @@ Tensor stack(const TensorList &tensors, int64_t axis) return out; } - -Tensor atleast_2d(const Tensor &in) -{ - if(in.dim() < 2){ +Tensor atleast_2d(const Tensor &in) { + if (in.dim() < 2) { return in.reshape({1, -1}); - } - else{ + } else { return in; } } - -Tensor& vstack(Tensor &out, const TensorList &tensors_) -{ +Tensor &vstack(Tensor &out, const TensorList &tensors_) { TensorList tensors; - for(auto &t : tensors_){ + for (auto &t : tensors_) { tensors.push_back(atleast_2d(t)); } return kernel::concat(out, tensors, 0); } -Tensor vstack(const TensorList &tensors_) -{ +Tensor vstack(const TensorList &tensors_) { TensorList tensors; - for(auto &t : tensors_){ + for (auto &t : tensors_) { tensors.push_back(atleast_2d(t)); } return kernel::concat(tensors, 0); } -Tensor& hstack(Tensor &out, const TensorList &tensors) -{ +Tensor &hstack(Tensor &out, const TensorList &tensors) { return kernel::concat(out, tensors, -1); } -Tensor hstack(const TensorList &tensors) -{ - return kernel::concat(tensors, -1); +Tensor hstack(const TensorList &tensors) { return kernel::concat(tensors, -1); } } - -}} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/kernel/tensor_factory.cpp b/bmf/hml/src/kernel/tensor_factory.cpp index 54f757e1..e9704653 100644 --- a/bmf/hml/src/kernel/tensor_factory.cpp +++ b/bmf/hml/src/kernel/tensor_factory.cpp @@ -17,18 +17,17 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { HMP_DEFINE_DISPATCH_STUB(fill_stub) HMP_DEFINE_DISPATCH_STUB(copy_stub) HMP_DEFINE_DISPATCH_STUB(arange_stub) -Tensor empty(const SizeArray &shape, const TensorOptions &options) -{ +Tensor empty(const SizeArray &shape, const TensorOptions &options) { int64_t nitems = TensorInfo::calcNumel(shape); unsigned flags = 0; - if(options.pinned_memory()){ + if (options.pinned_memory()) { flags |= static_cast(AllocatorFlags::Pinned); } @@ -39,12 +38,11 @@ Tensor empty(const SizeArray &shape, const TensorOptions &options) HMP_REQUIRE(nitems > 0, "Invalid tensor shape={}", shape); return Tensor(makeRefPtr( - Buffer(scalar_type, nitems, allocator, options.pinned_memory()), shape)); + Buffer(scalar_type, nitems, allocator, options.pinned_memory()), + shape)); } - -Tensor& copy(Tensor &self, const Tensor &other) -{ +Tensor ©(Tensor &self, const Tensor &other) { #ifndef HMP_BUILD_SHARED HMP_IMPORT_DEVICE_DISPATCH(kCPU, copy_stub); #ifdef HMP_EANBLE_CUDA @@ -53,12 +51,13 @@ Tensor& copy(Tensor &self, const Tensor &other) #endif HMP_REQUIRE(self.shape() == other.shape(), - "copy: can not copy data from shape {}, expect shape {}", other.shape(), self.shape()); + "copy: can not copy data from shape {}, expect shape {}", + other.shape(), self.shape()); - //always do copy in device kernel - auto device_type = self.device_type() == kCPU ? other.device_type() : self.device_type(); + // always do copy in device kernel + auto device_type = + self.device_type() == kCPU ? other.device_type() : self.device_type(); return copy_stub(device_type, self, other); } - - -}} // \ No newline at end of file +} +} // \ No newline at end of file diff --git a/bmf/hml/src/kernel/unary_ops.cpp b/bmf/hml/src/kernel/unary_ops.cpp index 39e9700c..20bec715 100644 --- a/bmf/hml/src/kernel/unary_ops.cpp +++ b/bmf/hml/src/kernel/unary_ops.cpp @@ -16,8 +16,8 @@ #include #include -namespace hmp{ -namespace kernel{ +namespace hmp { +namespace kernel { HMP_DEFINE_DISPATCH_STUB(round_stub) HMP_DEFINE_DISPATCH_STUB(ceil_stub) @@ -26,13 +26,11 @@ HMP_DEFINE_DISPATCH_STUB(abs_stub) HMP_DEFINE_DISPATCH_STUB(minus_stub) HMP_DEFINE_DISPATCH_STUB(clip_stub) - -#define WRAP_UNARY_OP(op) \ - Tensor& op(Tensor& out, const Tensor &input) \ - { \ - checkShape({out, input}, input.shape(), #op); \ - checkDevice({out, input}, input.device(), #op); \ - return op##_stub(input.device_type(), out, input); \ +#define WRAP_UNARY_OP(op) \ + Tensor &op(Tensor &out, const Tensor &input) { \ + checkShape({out, input}, input.shape(), #op); \ + checkDevice({out, input}, input.device(), #op); \ + return op##_stub(input.device_type(), out, input); \ } WRAP_UNARY_OP(round) @@ -41,16 +39,12 @@ WRAP_UNARY_OP(floor) WRAP_UNARY_OP(abs) WRAP_UNARY_OP(minus) - - -Tensor& clip(Tensor &out, const Tensor &input, const Scalar &min, const Scalar &max) -{ +Tensor &clip(Tensor &out, const Tensor &input, const Scalar &min, + const Scalar &max) { checkShape({out, input}, input.shape(), "clip"); checkDevice({out, input}, input.device(), "clip"); return clip_stub(input.device_type(), out, input, min, max); } - - - -}} //namespace hmp::kernel \ No newline at end of file +} +} // namespace hmp::kernel \ No newline at end of file diff --git a/bmf/hml/src/stringfy.cpp b/bmf/hml/src/stringfy.cpp index ba41b768..e44a5ec2 100644 --- a/bmf/hml/src/stringfy.cpp +++ b/bmf/hml/src/stringfy.cpp @@ -19,97 +19,85 @@ #include #include -namespace hmp{ +namespace hmp { ////// -std::string stringfy(const Tensor &tensor) -{ - if(tensor.defined()){ +std::string stringfy(const Tensor &tensor) { + if (tensor.defined()) { Tensor tmp = tensor; // - if(!tmp.is_contiguous()){ + if (!tmp.is_contiguous()) { tmp = tmp.contiguous(); } - if(!tmp.is_cpu()){ + if (!tmp.is_cpu()) { auto t = empty_like(tmp, tmp.options().device(kCPU)); copy(t, tmp); tmp = t; } std::stringstream ss; - ss << fmt::format("Tensor({}, {}, {})\n", - tensor.device(), - tensor.scalar_type(), - tensor.shape()); + ss << fmt::format("Tensor({}, {}, {})\n", tensor.device(), + tensor.scalar_type(), tensor.shape()); - if(tmp.dim() == 1){ + if (tmp.dim() == 1) { tmp = tmp.reshape({1, 1, tmp.size(0)}); - } - else if(tmp.dim() == 2){ + } else if (tmp.dim() == 2) { tmp = tmp.reshape({1, tmp.size(0), tmp.size(1)}); - } - else{ + } else { tmp = tmp.reshape({-1, tmp.size(-2), tmp.size(-1)}); } - HMP_DISPATCH_ALL_TYPES_AND_HALF(tmp.scalar_type(), "stringfy", [&](){ + HMP_DISPATCH_ALL_TYPES_AND_HALF(tmp.scalar_type(), "stringfy", [&]() { auto oriShape = tensor.shape(); auto shape = tmp.shape(); - for(int64_t i = 0; i < shape[0]; ++i){ - if(oriShape.size() <= 2){ - //do nothing - } - else{ - + for (int64_t i = 0; i < shape[0]; ++i) { + if (oriShape.size() <= 2) { + // do nothing + } else { } - if(i != 0){ + if (i != 0) { ss << ",\n"; } auto tab = " "; - if(tensor.dim() >= 2){ + if (tensor.dim() >= 2) { ss << "["; } - for(int64_t j = 0; j < shape[1]; ++j){ + for (int64_t j = 0; j < shape[1]; ++j) { auto ptr = tmp.select(0, i).select(0, j).data(); - if(j != 0){ + if (j != 0) { ss << ",\n"; } - if(j != 0){ + if (j != 0) { ss << tab << "["; - } - else{ + } else { ss << "["; } - for(int64_t k = 0; k < shape[2]; ++k){ - if(k != 0){ + for (int64_t k = 0; k < shape[2]; ++k) { + if (k != 0) { ss << ", "; } ss << fmt::format("{}", ptr[k]); } ss << "]"; - } - if(tensor.dim() >= 2){ + if (tensor.dim() >= 2) { ss << "]"; } } }); - return ss.str(); - } - else{ + } else { return "Tensor(Undefined)"; } } - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/tensor.cpp b/bmf/hml/src/tensor.cpp index f7d14fd1..272012ea 100644 --- a/bmf/hml/src/tensor.cpp +++ b/bmf/hml/src/tensor.cpp @@ -23,53 +23,40 @@ #include #include -namespace hmp{ +namespace hmp { - -Tensor from_buffer(DataPtr &&data, ScalarType scalarType, - const SizeArray &shape, const optional &strides) -{ +Tensor from_buffer(DataPtr &&data, ScalarType scalarType, + const SizeArray &shape, const optional &strides) { auto nitems = TensorInfo::calcNumel(shape); auto buffer = Buffer(std::move(data), scalarType, nitems, nullptr); checkSizeArray(shape, "from_buffer"); - if(strides){ + if (strides) { return makeRefPtr(buffer, shape, strides.value()); - } - else{ + } else { return makeRefPtr(buffer, shape); } } ///////// -std::string Tensor::repr() const -{ - if(defined()){ - return fmt::format("Tensor({}, {}, {})", - device(), - scalar_type(), - shape()); - } - else{ +std::string Tensor::repr() const { + if (defined()) { + return fmt::format("Tensor({}, {}, {})", device(), scalar_type(), + shape()); + } else { return "Tensor(Undefined)"; } - } -Tensor& Tensor::fill_(const Scalar &value) -{ - return hmp::fill(*this, value); -} +Tensor &Tensor::fill_(const Scalar &value) { return hmp::fill(*this, value); } -Tensor Tensor::to(const Device &device, bool non_blocking) const -{ +Tensor Tensor::to(const Device &device, bool non_blocking) const { Tensor out; - if(this->device() == device){ + if (this->device() == device) { out = alias(); - } - else{ + } else { auto options = this->options().device(device); - if(device.type() == kCPU && non_blocking){ + if (device.type() == kCPU && non_blocking) { options = options.pinned_memory(true); } auto tmp = empty_like(*this, options); @@ -79,43 +66,34 @@ Tensor Tensor::to(const Device &device, bool non_blocking) const return out; } - -Tensor Tensor::to(DeviceType device, bool non_blocking) const -{ +Tensor Tensor::to(DeviceType device, bool non_blocking) const { return to(Device(device), non_blocking); } -Tensor Tensor::to(ScalarType dtype) const -{ - if(this->dtype() == dtype){ +Tensor Tensor::to(ScalarType dtype) const { + if (this->dtype() == dtype) { return alias(); - } - else{ - auto tmp = empty_like( - *this, - this->options().dtype(dtype)); + } else { + auto tmp = empty_like(*this, this->options().dtype(dtype)); copy(tmp, *this); return tmp; } } - -Tensor& Tensor::copy_(const Tensor &src) -{ +Tensor &Tensor::copy_(const Tensor &src) { copy(*this, src); return *this; } - -Tensor Tensor::as_strided(const SizeArray &shape, const SizeArray &strides, optional offset) const -{ +Tensor Tensor::as_strided(const SizeArray &shape, const SizeArray &strides, + optional offset) const { auto self = alias(); self.as_strided_(shape, strides, offset); return self; } -Tensor& Tensor::as_strided_(const SizeArray &shape, const SizeArray &strides, optional offset_) -{ +Tensor &Tensor::as_strided_(const SizeArray &shape, const SizeArray &strides, + optional offset_) { checkSizeArray(shape, "as_strides_"); auto offset = offset_.value_or(tensorInfo()->bufferOffset()); @@ -123,103 +101,83 @@ Tensor& Tensor::as_strided_(const SizeArray &shape, const SizeArray &strides, op return *this; } - -Tensor Tensor::expand(const SizeArray &shape) const -{ +Tensor Tensor::expand(const SizeArray &shape) const { auto result = inferExpandGeometry(this->shape(), this->strides(), shape); return as_strided(result.shape, result.strides); } - -Tensor Tensor::expand_as(const Tensor &other) const -{ +Tensor Tensor::expand_as(const Tensor &other) const { return expand(other.shape()); } - -Tensor& Tensor::squeeze_(optional dim) -{ - if(dim){ - auto result = inferSqueezeGeometry(*this, - wrap_size(dim.value(), this->dim())); +Tensor &Tensor::squeeze_(optional dim) { + if (dim) { + auto result = + inferSqueezeGeometry(*this, wrap_size(dim.value(), this->dim())); return as_strided_(result.shape, result.strides); - } - else{ + } else { auto result = inferSqueezeGeometry(*this); return as_strided_(result.shape, result.strides); } } -Tensor Tensor::squeeze(optional dim) const -{ +Tensor Tensor::squeeze(optional dim) const { auto out = alias(); return out.squeeze_(dim); } -Tensor& Tensor::unsqueeze_(int64_t dim_) -{ +Tensor &Tensor::unsqueeze_(int64_t dim_) { auto dim = wrap_size(dim_, this->dim() + 1); auto result = inferUnsqueezeGeometry(*this, dim); return as_strided_(result.shape, result.strides); } - -Tensor Tensor::unsqueeze(int64_t dim) const -{ +Tensor Tensor::unsqueeze(int64_t dim) const { auto out = alias(); return out.unsqueeze_(dim); } - -Tensor Tensor::alias() const -{ - auto out = makeRefPtr( - tensorInfo()->buffer(), - shape(), - strides(), - tensorInfo()->bufferOffset()); +Tensor Tensor::alias() const { + auto out = makeRefPtr(tensorInfo()->buffer(), shape(), + strides(), tensorInfo()->bufferOffset()); return Tensor(std::move(out)); } -Tensor Tensor::view(const SizeArray &shape_) const -{ +Tensor Tensor::view(const SizeArray &shape_) const { auto shape = inferSize(shape_, nitems()); auto strides_ = computeStride(this->shape(), this->strides(), shape); - HMP_REQUIRE(strides_, "can not view tensor as {} from {}", shape_, this->shape()); + HMP_REQUIRE(strides_, "can not view tensor as {} from {}", shape_, + this->shape()); return as_strided(shape, strides_.value()); } -Tensor Tensor::clone() const -{ +Tensor Tensor::clone() const { auto tmp = empty_like(*this, this->options()); copy(tmp, *this); return tmp; } - -Tensor Tensor::reshape(const SizeArray &shape_) const -{ +Tensor Tensor::reshape(const SizeArray &shape_) const { auto shape = inferSize(shape_, nitems()); auto strides = computeStride(this->shape(), this->strides(), shape); - if(strides){ + if (strides) { return view(shape_); - } - else{ + } else { auto tmp = clone(); return tmp.view(shape); } } - -Tensor Tensor::transpose(int64_t dim0, int64_t dim1) const -{ +Tensor Tensor::transpose(int64_t dim0, int64_t dim1) const { dim0 = wrap_size(dim0, dim()); dim1 = wrap_size(dim1, dim()); - HMP_REQUIRE(dim0 < dim(), "transpose: dim0({}) is out of range {}", dim0, dim()); - HMP_REQUIRE(dim1 < dim(), "transpose: dim1({}) is out of range {}", dim1, dim()); + HMP_REQUIRE(dim0 < dim(), "transpose: dim0({}) is out of range {}", dim0, + dim()); + HMP_REQUIRE(dim1 < dim(), "transpose: dim1({}) is out of range {}", dim1, + dim()); auto shape = this->shape(); auto strides = this->strides(); @@ -229,20 +187,19 @@ Tensor Tensor::transpose(int64_t dim0, int64_t dim1) const return as_strided(shape, strides); } -Tensor Tensor::permute(const SizeArray &dims) const -{ +Tensor Tensor::permute(const SizeArray &dims) const { HMP_REQUIRE(dims.size() == this->dim(), - "permute: invalid dim={}, expect {}", dims.size(), this->dim()); + "permute: invalid dim={}, expect {}", dims.size(), this->dim()); SizeArray flags(this->dim(), 0); SizeArray newShape(this->dim(), 0), newStrides(this->dim(), 0); - for(size_t i = 0; i < this->dim(); ++i){ + for (size_t i = 0; i < this->dim(); ++i) { auto dim = wrap_size(dims[i], this->dim()); HMP_REQUIRE(dim < this->dim(), - "permute: invalid dim={} at {}, expect less than {}", - dim, i, this->dim() - ); - HMP_REQUIRE(!flags[dim], "permute: duplicate dim={} at {} found", dim, i); + "permute: invalid dim={} at {}, expect less than {}", dim, + i, this->dim()); + HMP_REQUIRE(!flags[dim], "permute: duplicate dim={} at {} found", dim, + i); newShape[i] = this->size(dim); newStrides[i] = this->stride(dim); @@ -252,22 +209,27 @@ Tensor Tensor::permute(const SizeArray &dims) const return as_strided(newShape, newStrides); } -Tensor Tensor::slice(int64_t dim, int64_t start, optional end_, int64_t step) const -{ +Tensor Tensor::slice(int64_t dim, int64_t start, optional end_, + int64_t step) const { dim = wrap_size(dim, this->dim()); - HMP_REQUIRE(dim < this->dim(), "slice: dim({}) is out of range {}", dim, this->dim()); + HMP_REQUIRE(dim < this->dim(), "slice: dim({}) is out of range {}", dim, + this->dim()); HMP_REQUIRE(step > 0, "slice: required step > 0, got step={}", step); auto end = end_.value_or(size(dim)); start = wrap_size(start, size(dim)); end = wrap_size(end, size(dim)); HMP_REQUIRE(start < size(dim), - "slice: start {} is out of range, need less than {}", start, size(dim)); - HMP_REQUIRE(end <= size(dim), - "slice: start {} is out of range, need less or equal to {}", end, size(dim)); - auto size = (end + step - 1 - start) / step; //divup - HMP_REQUIRE(size > 0, - "slice: expect at least 1 row selected, start={}, end={}, step={}", start, end, step); + "slice: start {} is out of range, need less than {}", start, + size(dim)); + HMP_REQUIRE(end <= size(dim), + "slice: start {} is out of range, need less or equal to {}", + end, size(dim)); + auto size = (end + step - 1 - start) / step; // divup + HMP_REQUIRE( + size > 0, + "slice: expect at least 1 row selected, start={}, end={}, step={}", + start, end, step); auto newBufferOffset = tensorInfo()->bufferOffset() + start * stride(dim); auto newShape = this->shape(); @@ -278,72 +240,65 @@ Tensor Tensor::slice(int64_t dim, int64_t start, optional end_, int64_t return as_strided(newShape, newStrides, newBufferOffset); } - -Tensor Tensor::select(int64_t dim, int64_t index) const -{ +Tensor Tensor::select(int64_t dim, int64_t index) const { dim = wrap_size(dim, this->dim()); - HMP_REQUIRE(dim < this->dim(), "select : dim({}) is out of range {}", dim, this->dim()); + HMP_REQUIRE(dim < this->dim(), "select : dim({}) is out of range {}", dim, + this->dim()); index = wrap_size(index, size(dim)); HMP_REQUIRE(index < size(dim), - "select: index {} is out of range, need less than {}", index, size(dim)); + "select: index {} is out of range, need less than {}", index, + size(dim)); auto out = slice(dim, index, index + 1); - //squeeze + // squeeze auto newShape = out.shape(); auto newStrides = out.strides(); HMP_REQUIRE(newShape[dim] == 1, "select: internal error"); newShape.erase(newShape.begin() + dim); newStrides.erase(newStrides.begin() + dim); - out.tensorInfo()->setSizesAndStrides( - newShape, newStrides, - out.tensorInfo()->bufferOffset()); + out.tensorInfo()->setSizesAndStrides(newShape, newStrides, + out.tensorInfo()->bufferOffset()); return out; } -//factory functions -Tensor empty(const SizeArray &shape, const TensorOptions &options) -{ +// factory functions +Tensor empty(const SizeArray &shape, const TensorOptions &options) { checkSizeArray(shape, "empty"); DeviceGuard dguard(options.device()); return kernel::empty(shape, options); } -Tensor empty_like(const Tensor &other, const optional &options_) -{ +Tensor empty_like(const Tensor &other, + const optional &options_) { auto options = options_.value_or(other.options()); return kernel::empty(other.shape(), options); } -Tensor zeros(const SizeArray &shape, const TensorOptions &options) -{ +Tensor zeros(const SizeArray &shape, const TensorOptions &options) { return empty(shape, options).fill_(0); } -Tensor zeros_like(const Tensor &other, const optional &options_) -{ +Tensor zeros_like(const Tensor &other, + const optional &options_) { auto options = options_.value_or(other.options()); return zeros(other.shape(), options); } - -Tensor ones(const SizeArray &shape, const TensorOptions &options) -{ +Tensor ones(const SizeArray &shape, const TensorOptions &options) { return empty(shape, options).fill_(1); } -Tensor ones_like(const Tensor &other, const optional &options_) -{ +Tensor ones_like(const Tensor &other, const optional &options_) { auto options = options_.value_or(other.options()); return ones(other.shape(), options); } -Tensor& fill(Tensor &self, const Scalar& value) -{ +Tensor &fill(Tensor &self, const Scalar &value) { using namespace kernel; #ifndef HMP_BUILD_SHARED HMP_IMPORT_DEVICE_DISPATCH(kCPU, fill_stub); @@ -357,9 +312,8 @@ Tensor& fill(Tensor &self, const Scalar& value) return self; } - -Tensor arange(int64_t start, int64_t end, int64_t step, const TensorOptions &options) -{ +Tensor arange(int64_t start, int64_t end, int64_t step, + const TensorOptions &options) { using namespace kernel; #ifndef HMP_BUILD_SHARED HMP_IMPORT_DEVICE_DISPATCH(kCPU, fill_stub); @@ -368,188 +322,139 @@ Tensor arange(int64_t start, int64_t end, int64_t step, const TensorOptions &opt #endif #endif - HMP_REQUIRE(start < end, "arange: expect start < end, got start={}, end={}", start, end); + HMP_REQUIRE(start < end, "arange: expect start < end, got start={}, end={}", + start, end); HMP_REQUIRE(step > 0, "arange: expect step > 0, got step={}", step); - auto size = (end - start + step - 1) / step; //divup + auto size = (end - start + step - 1) / step; // divup auto out = hmp::empty({size}, options); kernel::arange_stub(out.device_type(), out, start, end, step); return out; } -Tensor Tensor::contiguous() const -{ - if(this->is_contiguous()){ +Tensor Tensor::contiguous() const { + if (this->is_contiguous()) { return *this; - } - else{ + } else { return clone(); } } - ////// Unary ops -#define DEFINE_TENSOR_UOPS(op) \ - Tensor Tensor::op() const \ - { \ - auto out = empty_like(*this, this->options()); \ - kernel::op(out, *this); \ - return out; \ - } \ - Tensor& Tensor::op##_()\ - { \ - kernel::op(*this, *this); \ - return *this; \ +#define DEFINE_TENSOR_UOPS(op) \ + Tensor Tensor::op() const { \ + auto out = empty_like(*this, this->options()); \ + kernel::op(out, *this); \ + return out; \ + } \ + Tensor &Tensor::op##_() { \ + kernel::op(*this, *this); \ + return *this; \ } - DEFINE_TENSOR_UOPS(round) DEFINE_TENSOR_UOPS(ceil) DEFINE_TENSOR_UOPS(floor) DEFINE_TENSOR_UOPS(abs) - -Tensor Tensor::clip(const Scalar &min, const Scalar &max) const -{ +Tensor Tensor::clip(const Scalar &min, const Scalar &max) const { auto out = empty_like(*this, this->options()); kernel::clip(out, *this, min, max); return out; } -Tensor& Tensor::clip_(const Scalar &min, const Scalar &max) -{ +Tensor &Tensor::clip_(const Scalar &min, const Scalar &max) { kernel::clip(*this, *this, min, max); return *this; } - ////// Binary ops -#define DEFINE_TENSOR_BOPS(name, op) \ - Tensor Tensor::name(const Tensor &b) const{ \ - auto out = empty_like(*this, this->options()); \ - kernel::name(out, *this, b); \ - return out; \ - } \ - Tensor& Tensor::name##_(const Tensor &b){ \ - kernel::name(*this, *this, b); \ - return *this; \ - } \ - Tensor Tensor::operator op(const Tensor &b) const{ \ - return name(b); \ - } \ - Tensor& Tensor::operator op##=(const Tensor &b){ \ - return name##_(b); \ - } \ - Tensor Tensor::name(const Scalar &b) const{ \ - auto out = empty_like(*this, this->options()); \ - kernel::name(out, *this, b); \ - return out; \ - } \ - Tensor& Tensor::name##_(const Scalar &b){ \ - kernel::name(*this, *this, b); \ - return *this; \ - } \ - Tensor Tensor::operator op(const Scalar &b) const{ \ - return name(b); \ - } \ - Tensor& Tensor::operator op##=(const Scalar &b){ \ - return name##_(b); \ - } - +#define DEFINE_TENSOR_BOPS(name, op) \ + Tensor Tensor::name(const Tensor &b) const { \ + auto out = empty_like(*this, this->options()); \ + kernel::name(out, *this, b); \ + return out; \ + } \ + Tensor &Tensor::name##_(const Tensor &b) { \ + kernel::name(*this, *this, b); \ + return *this; \ + } \ + Tensor Tensor::operator op(const Tensor &b) const { return name(b); } \ + Tensor &Tensor::operator op##=(const Tensor &b) { return name##_(b); } \ + Tensor Tensor::name(const Scalar &b) const { \ + auto out = empty_like(*this, this->options()); \ + kernel::name(out, *this, b); \ + return out; \ + } \ + Tensor &Tensor::name##_(const Scalar &b) { \ + kernel::name(*this, *this, b); \ + return *this; \ + } \ + Tensor Tensor::operator op(const Scalar &b) const { return name(b); } \ + Tensor &Tensor::operator op##=(const Scalar &b) { return name##_(b); } DEFINE_TENSOR_BOPS(mul, *) DEFINE_TENSOR_BOPS(add, +) DEFINE_TENSOR_BOPS(sub, -) DEFINE_TENSOR_BOPS(div, /) +Tensor operator*(const Scalar &a, const Tensor &b) { return b * a; } -Tensor operator*(const Scalar &a, const Tensor &b) -{ - return b * a; -} +Tensor operator+(const Scalar &a, const Tensor &b) { return b + a; } -Tensor operator+(const Scalar &a, const Tensor &b) -{ - return b + a; -} - -Tensor operator-(const Scalar &a, const Tensor &b) -{ +Tensor operator-(const Scalar &a, const Tensor &b) { auto out = empty_like(b, b.options()); kernel::sub(out, a, b); return out; } -Tensor operator/(const Scalar &a, const Tensor &b) -{ +Tensor operator/(const Scalar &a, const Tensor &b) { auto out = empty_like(b, b.options()); kernel::div(out, a, b); return out; } // shape transform -Tensor Tensor::flatten() const -{ - return reshape({-1}); -} +Tensor Tensor::flatten() const { return reshape({-1}); } +void Tensor::tofile(const std::string &fn) { hmp::tofile(*this, fn); } -void Tensor::tofile(const std::string &fn) -{ - hmp::tofile(*this, fn); -} - -//copy functions -Tensor& copy(Tensor &self, const Tensor &other) -{ +// copy functions +Tensor ©(Tensor &self, const Tensor &other) { return kernel::copy(self, other); } - -//shape transformation -Tensor concat(const TensorList &tensors, int64_t axis) -{ +// shape transformation +Tensor concat(const TensorList &tensors, int64_t axis) { return kernel::concat(tensors, axis); } -Tensor& concat(Tensor &out, const TensorList &tensors, int64_t axis) -{ +Tensor &concat(Tensor &out, const TensorList &tensors, int64_t axis) { return kernel::concat(out, tensors, axis); } -Tensor stack(const TensorList &tensors, int64_t axis) -{ +Tensor stack(const TensorList &tensors, int64_t axis) { return kernel::stack(tensors, axis); } -Tensor& stack(Tensor &out, const TensorList &tensors, int64_t axis) -{ +Tensor &stack(Tensor &out, const TensorList &tensors, int64_t axis) { return kernel::stack(out, tensors, axis); } -Tensor vstack(const TensorList &tensors) -{ - return kernel::vstack(tensors); -} +Tensor vstack(const TensorList &tensors) { return kernel::vstack(tensors); } -Tensor& vstack(Tensor &out, const TensorList &tensors) -{ +Tensor &vstack(Tensor &out, const TensorList &tensors) { return kernel::vstack(out, tensors); } -Tensor hstack(const TensorList &tensors) -{ - return kernel::hstack(tensors); -} +Tensor hstack(const TensorList &tensors) { return kernel::hstack(tensors); } -Tensor& hstack(Tensor &out, const TensorList &tensors) -{ +Tensor &hstack(Tensor &out, const TensorList &tensors) { return kernel::hstack(out, tensors); } - #if defined(__ANDROID__) && HMP_NDK_VERSION < 24 #define FSEEK fseek #define FTELL ftell @@ -558,8 +463,8 @@ Tensor& hstack(Tensor &out, const TensorList &tensors) #define FTELL ftello #endif -Tensor fromfile(const std::string &fn, ScalarType dtype, int64_t count, int64_t offset) -{ +Tensor fromfile(const std::string &fn, ScalarType dtype, int64_t count, + int64_t offset) { auto fp = std::shared_ptr(fopen(fn.c_str(), "rb"), fclose); HMP_REQUIRE(fp, "Open file {} failed", fn); @@ -569,7 +474,7 @@ Tensor fromfile(const std::string &fn, ScalarType dtype, int64_t count, int64_t auto itemsize = sizeof_scalar_type(dtype); offset *= itemsize; // - if(FSEEK(fp.get(), offset, SEEK_SET) < 0){ + if (FSEEK(fp.get(), offset, SEEK_SET) < 0) { throw std::runtime_error("Invalid file offset"); } @@ -584,15 +489,16 @@ Tensor fromfile(const std::string &fn, ScalarType dtype, int64_t count, int64_t return data; } -void tofile(const Tensor &data, const std::string &fn) -{ +void tofile(const Tensor &data, const std::string &fn) { auto fp = std::shared_ptr(fopen(fn.c_str(), "wb"), fclose); HMP_REQUIRE(fp, "Open file {} failed", fn); auto tmp = data.cpu().contiguous(); - auto nwrite = fwrite(tmp.unsafe_data(), tmp.itemsize(), tmp.nitems(), fp.get()); - HMP_REQUIRE(nwrite == tmp.nitems(), "write data to file failed, errno={} {}, {}", - errno, nwrite, tmp.nitems()); + auto nwrite = + fwrite(tmp.unsafe_data(), tmp.itemsize(), tmp.nitems(), fp.get()); + HMP_REQUIRE(nwrite == tmp.nitems(), + "write data to file failed, errno={} {}, {}", errno, nwrite, + tmp.nitems()); } -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/tests/test_allocator.cpp b/bmf/hml/src/tests/test_allocator.cpp index a0e11a4e..c7a92f19 100644 --- a/bmf/hml/src/tests/test_allocator.cpp +++ b/bmf/hml/src/tests/test_allocator.cpp @@ -24,19 +24,13 @@ #include #include - -namespace hmp{ +namespace hmp { #ifdef HMP_ENABLE_CUDA -static bool has_cuda() -{ - return device_count(kCUDA) > 0; -} - +static bool has_cuda() { return device_count(kCUDA) > 0; } -TEST(TestAllocator, cuda_device_allocator) -{ - if(!has_cuda()){ +TEST(TestAllocator, cuda_device_allocator) { + if (!has_cuda()) { #ifdef GTEST_SKIP GTEST_SKIP() << "No cuda device"; #else @@ -48,37 +42,36 @@ TEST(TestAllocator, cuda_device_allocator) auto ndev = device_count(kCUDA); std::vector> datas; - std::vector sizes(ndev, 0); //for each device - std::vector segs(ndev, 0); //for each device + std::vector sizes(ndev, 0); // for each device + std::vector segs(ndev, 0); // for each device - const int max_size = 4<<20; + const int max_size = 4 << 20; const int N = ndev * 1024; // - for(int i = 0; i < ndev; ++i){ + for (int i = 0; i < ndev; ++i) { auto stats = cuda::device_memory_stats(i); ASSERT_EQ(0, stats.active.current); ASSERT_EQ(0, stats.segment.current); } - //random alloc and free - for(int i = 0; i < N; ++i){ + // random alloc and free + for (int i = 0; i < N; ++i) { auto did = rand() % ndev; - int64_t size = (rand()*int64_t(rand())) % max_size; + int64_t size = (rand() * int64_t(rand())) % max_size; size = size == 0 ? 1 : size; - bool replace = rand()%2; + bool replace = rand() % 2; DeviceGuard d(Device(kCUDA, did)); auto ptr = get_allocator(kCUDA)->alloc(size); - if(replace && datas.size()){ + if (replace && datas.size()) { auto ridx = rand() % datas.size(); auto &rptr = datas[ridx]; sizes[rptr.first.device().index()] -= rptr.second; segs[rptr.first.device().index()] -= 1; datas[ridx] = std::make_pair(std::move(ptr), size); - } - else{ + } else { datas.push_back(std::make_pair(std::move(ptr), size)); } @@ -86,9 +79,10 @@ TEST(TestAllocator, cuda_device_allocator) segs[did] += 1; } - //check - std::this_thread::sleep_for(std::chrono::milliseconds(10)); //wait cudaEvent - for(int i = 0; i < ndev; ++i){ + // check + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // wait + // cudaEvent + for (int i = 0; i < ndev; ++i) { auto stats = cuda::device_memory_stats(i); #if 0 //actually, we can't track allocated bytes @@ -100,18 +94,17 @@ TEST(TestAllocator, cuda_device_allocator) // datas.clear(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); //wait cudaEvent - for(int i = 0; i < ndev; ++i){ + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // wait + // cudaEvent + for (int i = 0; i < ndev; ++i) { auto stats = cuda::device_memory_stats(i); EXPECT_EQ(0, stats.active.current); ASSERT_EQ(0, stats.segment.current); } } - -TEST(TestAllocator, cuda_device_allocator_inactive) -{ - if(!has_cuda()){ +TEST(TestAllocator, cuda_device_allocator_inactive) { + if (!has_cuda()) { #ifdef GTEST_SKIP GTEST_SKIP() << "No cuda device"; #else @@ -121,7 +114,7 @@ TEST(TestAllocator, cuda_device_allocator_inactive) auto stream = create_stream(kCUDA); - auto a = empty({8<<20}, TensorOptions(kCPU).pinned_memory(true)); + auto a = empty({8 << 20}, TensorOptions(kCPU).pinned_memory(true)); { StreamGuard g(stream); @@ -134,7 +127,7 @@ TEST(TestAllocator, cuda_device_allocator_inactive) auto cpu_stats0 = cuda::host_memory_stats(); auto cuda_stats0 = cuda::device_memory_stats(0); - EXPECT_FALSE(stream.query()); //ensure copy is not finished + EXPECT_FALSE(stream.query()); // ensure copy is not finished stream.synchronize(); @@ -145,11 +138,10 @@ TEST(TestAllocator, cuda_device_allocator_inactive) EXPECT_EQ(a.nbytes(), cpu_stats0.inactive.current); EXPECT_EQ(a.nbytes(), cuda_stats0.inactive.current); - EXPECT_EQ(0, cpu_stats1.inactive.current); // + EXPECT_EQ(0, cpu_stats1.inactive.current); // EXPECT_EQ(0, cuda_stats1.inactive.current); // } #endif - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/tests/test_image.cpp b/bmf/hml/src/tests/test_image.cpp index 60e21c00..e45824f9 100644 --- a/bmf/hml/src/tests/test_image.cpp +++ b/bmf/hml/src/tests/test_image.cpp @@ -24,37 +24,30 @@ using namespace hmp; #include -class ImageTest : public testing::Test -{ -public: - void SetUp() override - { - - } - +class ImageTest : public testing::Test { + public: + void SetUp() override {} }; - -TEST_F(ImageTest, AVFrameInterOp) -{ +TEST_F(ImageTest, AVFrameInterOp) { #define BUF_REFCOUNT(t) t.tensorInfo()->buffer().refcount() - auto pix_info = PixelInfo(PF_YUV420P, - ColorModel(CS_BT709, CR_MPEG, CP_BT709, CTC_BT709)); + auto pix_info = PixelInfo( + PF_YUV420P, ColorModel(CS_BT709, CR_MPEG, CP_BT709, CTC_BT709)); auto f = Frame(1920, 1080, pix_info); - for(int i = 0; i < f.nplanes(); ++i){ - f.plane(i).fill_((i+1)*3); + for (int i = 0; i < f.nplanes(); ++i) { + f.plane(i).fill_((i + 1) * 3); } - for(int i = 0; i < f.nplanes(); ++i){ + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 1); } // Frame -> AVFrame -> Frame { auto vf = ffmpeg::to_video_frame(f); - for(int i = 0; i < f.nplanes(); ++i){ + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 2); } EXPECT_EQ(vf->colorspace, AVCOL_SPC_BT709); @@ -63,50 +56,50 @@ TEST_F(ImageTest, AVFrameInterOp) EXPECT_EQ(vf->color_trc, AVCOL_TRC_BT709); auto f1 = ffmpeg::from_video_frame(vf); - av_frame_free(&vf); //f is still refed - for(int i = 0; i < f.nplanes(); ++i){ + av_frame_free(&vf); // f is still refed + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 2); } } - //No ref to f now - for(int i = 0; i < f.nplanes(); ++i){ + // No ref to f now + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 1); } - //Frame |-> AVFrame -> AVFrame -> Frame + // Frame |-> AVFrame -> AVFrame -> Frame // |-> AVFrame -> AVFrame -> Frame { auto vf0 = ffmpeg::to_video_frame(f); - for(int i = 0; i < f.nplanes(); ++i){ //f is ref by vf0 + for (int i = 0; i < f.nplanes(); ++i) { // f is ref by vf0 EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 2); } auto vf1 = ffmpeg::to_video_frame(f); - for(int i = 0; i < f.nplanes(); ++i){ // f is ref by vf0, vf1 + for (int i = 0; i < f.nplanes(); ++i) { // f is ref by vf0, vf1 EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 3); } auto vf2 = av_frame_clone(vf0); // av_frame_free(&vf0); - for(int i = 0; i < f.nplanes(); ++i){ // f is ref by vf1, vf2 + for (int i = 0; i < f.nplanes(); ++i) { // f is ref by vf1, vf2 EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 3); } auto vf3 = av_frame_clone(vf1); // av_frame_free(&vf1); - for(int i = 0; i < f.nplanes(); ++i){ // f is ref by vf2, vf3 + for (int i = 0; i < f.nplanes(); ++i) { // f is ref by vf2, vf3 EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 3); } auto f2 = ffmpeg::from_video_frame(vf2); - av_frame_free(&vf2); //f is ref by f2, vf3 - for(int i = 0; i < f.nplanes(); ++i){ + av_frame_free(&vf2); // f is ref by f2, vf3 + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 3); } auto f3 = ffmpeg::from_video_frame(vf3); - av_frame_free(&vf3); //f is ref by f2, f3 - for(int i = 0; i < f.nplanes(); ++i){ + av_frame_free(&vf3); // f is ref by f2, f3 + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 3); } EXPECT_EQ(f3.format(), PF_YUV420P); @@ -115,84 +108,77 @@ TEST_F(ImageTest, AVFrameInterOp) EXPECT_EQ(f3.pix_info().primaries(), CP_BT709); EXPECT_EQ(f3.pix_info().transfer_characteristic(), CTC_BT709); - f2 = Frame(); //reset f2 - av_frame_free(&vf2); //f is ref by f3 - for(int i = 0; i < f.nplanes(); ++i){ + f2 = Frame(); // reset f2 + av_frame_free(&vf2); // f is ref by f3 + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 2); } - } - //No ref to f now - for(int i = 0; i < f.nplanes(); ++i){ + // No ref to f now + for (int i = 0; i < f.nplanes(); ++i) { EXPECT_EQ(BUF_REFCOUNT(f.plane(i)), 1); } - #undef BUF_REFCOUNT - } -#endif //HMP_EANBLE_FFMPEG - +#endif // HMP_EANBLE_FFMPEG -TEST(tensor_op, hwc_to_chw) -{ +TEST(tensor_op, hwc_to_chw) { auto pix_info = PixelInfo(PF_RGB24); auto f = Frame(1920, 1080, pix_info); auto t = f.plane(0); EXPECT_EQ(t.dim(), 3); - //H + // H EXPECT_EQ(t.size(HWC_H), 1080); - //W + // W EXPECT_EQ(t.size(HWC_W), 1920); - //C + // C EXPECT_EQ(t.size(HWC_C), 3); auto nchw = img::transfer(t, kNHWC, kNCHW); EXPECT_EQ(nchw.dim(), 3); - //C + // C EXPECT_EQ(nchw.size(CHW_C), 3); - //H + // H EXPECT_EQ(nchw.size(CHW_H), 1080); - //W + // W EXPECT_EQ(nchw.size(CHW_W), 1920); } -TEST(tensor_op, chw_to_hwc) -{ - //nchw +TEST(tensor_op, chw_to_hwc) { + // nchw auto pix_info = PixelInfo(PF_RGB24); auto f = Frame(1920, 1080, pix_info); auto t = f.plane(0); EXPECT_EQ(t.dim(), 3); - //H + // H EXPECT_EQ(t.size(HWC_H), 1080); - //W + // W EXPECT_EQ(t.size(HWC_W), 1920); - //C + // C EXPECT_EQ(t.size(HWC_C), 3); auto nchw = img::transfer(t, kNHWC, kNCHW); EXPECT_EQ(nchw.dim(), 3); - //C + // C EXPECT_EQ(nchw.size(CHW_C), 3); - //H + // H EXPECT_EQ(nchw.size(CHW_H), 1080); - //W + // W EXPECT_EQ(nchw.size(CHW_W), 1920); auto nhwc = img::transfer(nchw, kNCHW, kNHWC); EXPECT_EQ(nhwc.dim(), 3); - //H + // H EXPECT_EQ(nhwc.size(HWC_H), 1080); - //W + // W EXPECT_EQ(nhwc.size(HWC_W), 1920); - //C + // C EXPECT_EQ(nhwc.size(HWC_C), 3); } -TEST(tensor_op, reformat_then_transfer) -{ - //nchw +TEST(tensor_op, reformat_then_transfer) { + // nchw auto pix_info = PixelInfo(PF_YUV420P); auto f = Frame(1920, 1080, pix_info); auto rgb = PixelInfo(PF_RGB24); @@ -200,25 +186,24 @@ TEST(tensor_op, reformat_then_transfer) auto t = vf.plane(0); EXPECT_EQ(t.dim(), 3); - //H + // H EXPECT_EQ(t.size(HWC_H), 1080); - //W + // W EXPECT_EQ(t.size(HWC_W), 1920); - //C + // C EXPECT_EQ(t.size(HWC_C), 3); auto nchw = img::transfer(t, kNHWC, kNCHW); EXPECT_EQ(nchw.dim(), 3); - //C + // C EXPECT_EQ(nchw.size(CHW_C), 3); - //H + // H EXPECT_EQ(nchw.size(CHW_H), 1080); - //W + // W EXPECT_EQ(nchw.size(CHW_W), 1920); } -TEST(tensor_op, nhwc_to_nchw) -{ +TEST(tensor_op, nhwc_to_nchw) { auto pix_info = PixelInfo(PF_RGB24); auto f1 = Frame(1920, 1080, pix_info); auto f2 = Frame(1920, 1080, pix_info); @@ -226,32 +211,31 @@ TEST(tensor_op, nhwc_to_nchw) auto t = fs.plane(0); - //NHWC + // NHWC EXPECT_EQ(t.dim(), 4); - //N + // N EXPECT_EQ(t.size(NHWC_N), 2); - //H + // H EXPECT_EQ(t.size(NHWC_H), 1080); - //W + // W EXPECT_EQ(t.size(NHWC_W), 1920); - //C + // C EXPECT_EQ(t.size(NHWC_C), 3); auto nchw = img::transfer(t, kNHWC, kNCHW); EXPECT_EQ(nchw.dim(), 4); - //N + // N EXPECT_EQ(nchw.size(NCHW_N), 2); - //C + // C EXPECT_EQ(nchw.size(NCHW_C), 3); - //H + // H EXPECT_EQ(nchw.size(NCHW_H), 1080); - //W + // W EXPECT_EQ(nchw.size(NCHW_W), 1920); } -TEST(tensor_op, nchw_to_nhwc) -{ - //nchw +TEST(tensor_op, nchw_to_nhwc) { + // nchw auto pix_info = PixelInfo(PF_RGB24); auto f1 = Frame(1920, 1080, pix_info); auto f2 = Frame(1920, 1080, pix_info); @@ -263,18 +247,14 @@ TEST(tensor_op, nchw_to_nhwc) auto nhwc = img::transfer(nchw, kNCHW, kNHWC); - //NHWC + // NHWC EXPECT_EQ(t.dim(), 4); - //N + // N EXPECT_EQ(nhwc.size(NHWC_N), 2); - //H + // H EXPECT_EQ(nhwc.size(NHWC_H), 1080); - //W + // W EXPECT_EQ(nhwc.size(NHWC_W), 1920); - //C + // C EXPECT_EQ(nhwc.size(NHWC_C), 3); - } - - - diff --git a/bmf/hml/src/tests/test_ref_ptr.cpp b/bmf/hml/src/tests/test_ref_ptr.cpp index a6f8f9ae..4beffb4d 100644 --- a/bmf/hml/src/tests/test_ref_ptr.cpp +++ b/bmf/hml/src/tests/test_ref_ptr.cpp @@ -17,43 +17,39 @@ #include #include -namespace hmp{ +namespace hmp { namespace { -struct DummyObject : public RefObject -{ +struct DummyObject : public RefObject { std::atomic count = 0; }; +} // namespace -} //namespace - - - -TEST(RefPtr, multi_thread_ops) -{ +TEST(RefPtr, multi_thread_ops) { const int nthreads = 16; const int nops = 100000; auto obj = makeRefPtr(); std::atomic wait_count = 0; - auto op_func = [&](){ + auto op_func = [&]() { wait_count += 1; std::vector> copy_objs; std::vector> move_objs; - //wait - while(wait_count >= 0); //barrier + // wait + while (wait_count >= 0) + ; // barrier - //copy - for(int i = 0; i < nops; ++i){ + // copy + for (int i = 0; i < nops; ++i) { copy_objs.push_back(obj); } - //move - for(auto &o : copy_objs){ + // move + for (auto &o : copy_objs) { o->count += 1; move_objs.push_back(std::move(o)); } @@ -61,25 +57,24 @@ TEST(RefPtr, multi_thread_ops) // std::vector threads; - for(int i = 0; i < nthreads; ++i){ + for (int i = 0; i < nthreads; ++i) { threads.push_back(std::thread(op_func)); } - //wait all threads startup - while(wait_count != nthreads); //barrier + // wait all threads startup + while (wait_count != nthreads) + ; // barrier // wait_count.store(-1); // - //join - for(auto &t : threads){ + // join + for (auto &t : threads) { t.join(); } EXPECT_EQ(1, obj.refcount()); - EXPECT_EQ(nthreads*nops, obj->count); + EXPECT_EQ(nthreads * nops, obj->count); } - - -} //namespace \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/bmf/hml/src/tests/test_scalar.cpp b/bmf/hml/src/tests/test_scalar.cpp index f2f2e740..f7a8b09d 100644 --- a/bmf/hml/src/tests/test_scalar.cpp +++ b/bmf/hml/src/tests/test_scalar.cpp @@ -16,35 +16,25 @@ #include #include -namespace hmp{ +namespace hmp { - -template -void test_scalar_precision(int64_t value) -{ - T v = *reinterpret_cast(&value); +template void test_scalar_precision(int64_t value) { + T v = *reinterpret_cast(&value); auto scalar = Scalar(v); auto cast_v = scalar.to(); EXPECT_EQ(v, cast_v); } -TEST(TestScalar, precision_test) -{ +TEST(TestScalar, precision_test) { int64_t magic_value = 0xdeadbeefdeadbeefll; - -#define DISPATCH(dtype, _) { \ - test_scalar_precision(magic_value); \ - } +#define DISPATCH(dtype, _) \ + { test_scalar_precision(magic_value); } HMP_FORALL_SCALAR_TYPES(DISPATCH) #undef DISPATCH } - - - -} //namespace - +} // namespace diff --git a/bmf/hml/src/tests/test_tensor_options.cpp b/bmf/hml/src/tests/test_tensor_options.cpp index 8fa7e83f..60ed51f9 100644 --- a/bmf/hml/src/tests/test_tensor_options.cpp +++ b/bmf/hml/src/tests/test_tensor_options.cpp @@ -17,11 +17,9 @@ #include #include - #ifdef HMP_ENABLE_CUDA -TEST(TestTensorOptions, Construct) -{ +TEST(TestTensorOptions, Construct) { using namespace hmp; auto opt0 = TensorOptions::make(kCUDA, kFloat64, true); diff --git a/bmf/hml/src/torch/torch.cpp b/bmf/hml/src/torch/torch.cpp index 5ad699b2..d239bfb8 100644 --- a/bmf/hml/src/torch/torch.cpp +++ b/bmf/hml/src/torch/torch.cpp @@ -15,12 +15,11 @@ */ #include +namespace hmp { +namespace torch { -namespace hmp{ -namespace torch{ - -static inline c10::ScalarType typeMetaToScalarType(const caffe2::TypeMeta& dtype) -{ +static inline c10::ScalarType +typeMetaToScalarType(const caffe2::TypeMeta &dtype) { #if TORCH_VERSION_MAJOR >= 1 && TORCH_VERSION_MINOR >= 8 return dtype.toScalarType(); #else @@ -28,126 +27,117 @@ static inline c10::ScalarType typeMetaToScalarType(const caffe2::TypeMeta& dtype #endif } -inline c10::ScalarType scalar_type(const ScalarType s) -{ - switch(s){ - case kUInt8: return c10::kByte; - case kInt8: return c10::kChar; - case kInt16: return c10::kShort; - case kInt32: return c10::kInt; - case kInt64: return c10::kLong; - case kHalf: return c10::kHalf; - case kFloat32: return c10::kFloat; - case kFloat64: return c10::kDouble; - default: - HMP_REQUIRE(false, "hmp scalar type {} is not supported by torch", s); +inline c10::ScalarType scalar_type(const ScalarType s) { + switch (s) { + case kUInt8: + return c10::kByte; + case kInt8: + return c10::kChar; + case kInt16: + return c10::kShort; + case kInt32: + return c10::kInt; + case kInt64: + return c10::kLong; + case kHalf: + return c10::kHalf; + case kFloat32: + return c10::kFloat; + case kFloat64: + return c10::kDouble; + default: + HMP_REQUIRE(false, "hmp scalar type {} is not supported by torch", s); } } -inline ScalarType from_scalar_type(const c10::ScalarType &s) -{ - switch(s){ - case c10::kByte: return kUInt8; - case c10::kChar: return kInt8; - case c10::kShort: return kInt16; - case c10::kInt: return kInt32; - case c10::kLong: return kInt64; - case c10::kHalf: return kHalf; - case c10::kFloat: return kFloat32; - case c10::kDouble: return kFloat64; - default: - HMP_REQUIRE(false, "torch scalar type {} is not supported by hmp", s); +inline ScalarType from_scalar_type(const c10::ScalarType &s) { + switch (s) { + case c10::kByte: + return kUInt8; + case c10::kChar: + return kInt8; + case c10::kShort: + return kInt16; + case c10::kInt: + return kInt32; + case c10::kLong: + return kInt64; + case c10::kHalf: + return kHalf; + case c10::kFloat: + return kFloat32; + case c10::kDouble: + return kFloat64; + default: + HMP_REQUIRE(false, "torch scalar type {} is not supported by hmp", s); } } - -inline ScalarType from_scalar_type(const caffe2::TypeMeta &s) -{ +inline ScalarType from_scalar_type(const caffe2::TypeMeta &s) { return from_scalar_type(typeMetaToScalarType(s)); } -inline c10::DeviceType device_type(DeviceType d) -{ - switch(d){ - case kCPU: return c10::kCPU; - case kCUDA: return c10::kCUDA; - default: - HMP_REQUIRE(false, "hmp device type {} is not supported by torch", d); +inline c10::DeviceType device_type(DeviceType d) { + switch (d) { + case kCPU: + return c10::kCPU; + case kCUDA: + return c10::kCUDA; + default: + HMP_REQUIRE(false, "hmp device type {} is not supported by torch", d); } } - -inline DeviceType from_device_type(c10::DeviceType d) -{ - switch(d){ - case c10::kCPU: return kCPU; - case c10::kCUDA: return kCUDA; - default: - HMP_REQUIRE(false, "torch device type {} is not supported by hmp", d); +inline DeviceType from_device_type(c10::DeviceType d) { + switch (d) { + case c10::kCPU: + return kCPU; + case c10::kCUDA: + return kCUDA; + default: + HMP_REQUIRE(false, "torch device type {} is not supported by hmp", d); } } - -inline c10::Device device(const Device &d) -{ +inline c10::Device device(const Device &d) { auto index = d.type() == kCPU ? -1 : d.index(); return c10::Device(device_type(d.type()), index); } -inline Device from_device(const c10::Device &d) -{ +inline Device from_device(const c10::Device &d) { auto index = d.index() < 0 ? 0 : d.index(); return Device(from_device_type(d.type()), index); } - -inline c10::TensorOptions tensor_options(const TensorOptions &options) -{ +inline c10::TensorOptions tensor_options(const TensorOptions &options) { return c10::TensorOptions() - .device(device(options.device())) - .dtype(scalar_type(options.scalar_type())) - .pinned_memory(options.pinned_memory()); + .device(device(options.device())) + .dtype(scalar_type(options.scalar_type())) + .pinned_memory(options.pinned_memory()); } - -inline TensorOptions from_tensor_options(const c10::TensorOptions &options) -{ +inline TensorOptions from_tensor_options(const c10::TensorOptions &options) { return TensorOptions() - .device(from_device(options.device())) - .scalar_type(from_scalar_type(options.dtype())) - .pinned_memory(options.pinned_memory()); + .device(from_device(options.device())) + .scalar_type(from_scalar_type(options.dtype())) + .pinned_memory(options.pinned_memory()); } - -at::Tensor tensor(const Tensor &from) -{ +at::Tensor tensor(const Tensor &from) { auto info = from.tensorInfo(); - return at::from_blob( - info->unsafe_data(), - info->shape(), - info->strides(), - [info](void *){}, - tensor_options(from.options()) - ); + return at::from_blob(info->unsafe_data(), info->shape(), info->strides(), + [info](void *) {}, tensor_options(from.options())); } - -Tensor from_tensor(const at::Tensor &from) -{ +Tensor from_tensor(const at::Tensor &from) { auto sizes = from.sizes(); - auto strides = from.strides(); + auto strides = from.strides(); return from_buffer( - DataPtr(from.data_ptr(), [from](void*){}, from_device(from.device())), - from_scalar_type(from.dtype()), - SizeArray(sizes.begin(), sizes.end()), - SizeArray(strides.begin(), strides.end()) - ); + DataPtr(from.data_ptr(), [from](void *) {}, from_device(from.device())), + from_scalar_type(from.dtype()), SizeArray(sizes.begin(), sizes.end()), + SizeArray(strides.begin(), strides.end())); } - - - -}} // - - +} +} // diff --git a/bmf/python/py_bmf.cpp b/bmf/python/py_bmf.cpp index 7ef074b6..6451efd8 100644 --- a/bmf/python/py_bmf.cpp +++ b/bmf/python/py_bmf.cpp @@ -5,7 +5,6 @@ namespace py = pybind11; - void module_sdk_bind(py::module &m); void engine_bind(py::module &m); @@ -13,8 +12,7 @@ void engine_bind(py::module &m); void bmf_ffmpeg_bind(py::module &m); #endif -PYBIND11_MODULE(_bmf, m) -{ +PYBIND11_MODULE(_bmf, m) { m.doc() = "Bytedance Media Framework"; auto sdk = m.def_submodule("sdk"); @@ -23,16 +21,11 @@ PYBIND11_MODULE(_bmf, m) auto engine = m.def_submodule("engine"); engine_bind(engine); - m.def("get_version", [](){ - return BMF_BUILD_VERSION; - }); + m.def("get_version", []() { return BMF_BUILD_VERSION; }); - m.def("get_commit", [](){ - return BMF_BUILD_COMMIT; - }); + m.def("get_commit", []() { return BMF_BUILD_COMMIT; }); #ifdef BMF_ENABLE_FFMPEG bmf_ffmpeg_bind(sdk); #endif - } diff --git a/bmf/python/py_engine.cpp b/bmf/python/py_engine.cpp index 9a33dd8e..5749cf3e 100644 --- a/bmf/python/py_engine.cpp +++ b/bmf/python/py_engine.cpp @@ -9,49 +9,50 @@ namespace py = pybind11; - -void engine_bind(py::module &m) -{ +void engine_bind(py::module &m) { using namespace bmf; py::class_(m, "Graph") - .def_nogil(py::init(), - py::arg("graph_config"), py::arg("is_path")=false, py::arg("need_merge")=true) + .def_nogil(py::init(), + py::arg("graph_config"), py::arg("is_path") = false, + py::arg("need_merge") = true) .def_nogil("uid", &BMFGraph::uid) .def_nogil("start", &BMFGraph::start) - .def_nogil("update", &BMFGraph::update, py::arg("config"), py::arg("is_path")) + .def_nogil("update", &BMFGraph::update, py::arg("config"), + py::arg("is_path")) .def_nogil("close", &BMFGraph::close) .def_nogil("force_close", &BMFGraph::force_close) - .def_nogil("add_input_stream_packet", &BMFGraph::add_input_stream_packet, - py::arg("stream_name"), py::arg("packet"), py::arg("block")=false) - .def_nogil("poll_output_stream_packet", &BMFGraph::poll_output_stream_packet, - py::arg("stream_name"), py::arg("block")=true) - .def_nogil("status", &BMFGraph::status) - ; - + .def_nogil("add_input_stream_packet", + &BMFGraph::add_input_stream_packet, py::arg("stream_name"), + py::arg("packet"), py::arg("block") = false) + .def_nogil("poll_output_stream_packet", + &BMFGraph::poll_output_stream_packet, py::arg("stream_name"), + py::arg("block") = true) + .def_nogil("status", &BMFGraph::status); py::class_(m, "Module") - .def_nogil(py::init(), - py::arg("module_name"), py::arg("option"), py::arg("module_type")="", - py::arg("module_path")="", py::arg("module_entry")="") + .def_nogil(py::init(), + py::arg("module_name"), py::arg("option"), + py::arg("module_type") = "", py::arg("module_path") = "", + py::arg("module_entry") = "") .def_nogil("uid", &BMFModule::uid) .def_nogil("process", &BMFModule::process, py::arg("task")) .def_nogil("reset", &BMFModule::reset) .def_nogil("init", &BMFModule::init) - .def_nogil("close", &BMFModule::close) - ; + .def_nogil("close", &BMFModule::close); py::class_(m, "Callback") - .def(py::init([](py::function &cb){ - return std::make_unique([=](bmf_sdk::CBytes para) -> bmf_sdk::CBytes{ - py::gil_scoped_acquire gil; - auto res = cb(py::cast(para)); - return py::cast(res); - }); + .def(py::init([](py::function &cb) { + return std::make_unique( + [=](bmf_sdk::CBytes para) -> bmf_sdk::CBytes { + py::gil_scoped_acquire gil; + auto res = cb(py::cast(para)); + return py::cast(res); + }); })) - .def("uid", &BMFCallback::uid) - ; + .def("uid", &BMFCallback::uid); // Trace interface py::enum_(m, "TraceType") @@ -61,33 +62,36 @@ void engine_bind(py::module &m) .value("QUEUE_INFO", bmf_sdk::TraceType::QUEUE_INFO) .value("THROUGHPUT", bmf_sdk::TraceType::THROUGHPUT) .value("CUSTOM", bmf_sdk::TraceType::CUSTOM) - .value("TRACE_START", bmf_sdk::TraceType::TRACE_START) - ; + .value("TRACE_START", bmf_sdk::TraceType::TRACE_START); py::enum_(m, "TracePhase") .value("NONE", bmf_sdk::TracePhase::NONE) .value("START", bmf_sdk::TracePhase::START) - .value("END", bmf_sdk::TracePhase::END) - ; + .value("END", bmf_sdk::TracePhase::END); - m.def_nogil("trace", (void(*)(bmf_sdk::TraceType, const char*, bmf_sdk::TracePhase, const char*))&bmf_sdk::BMF_TRACE, - py::arg("category"), py::arg("name"), - py::arg("phase")=bmf_sdk::TracePhase::NONE, - py::arg("str")=__builtin_FUNCTION()); + m.def_nogil("trace", (void (*)(bmf_sdk::TraceType, const char *, + bmf_sdk::TracePhase, const char *)) & + bmf_sdk::BMF_TRACE, + py::arg("category"), py::arg("name"), + py::arg("phase") = bmf_sdk::TracePhase::NONE, + py::arg("str") = __builtin_FUNCTION()); - m.def_nogil("trace_info", (void(*)(bmf_sdk::TraceType, const char*, bmf_sdk::TracePhase, std::string, const char*))&bmf_sdk::BMF_TRACE, - py::arg("category"), py::arg("name"), - py::arg("phase")=bmf_sdk::TracePhase::NONE, - py::arg("info")=std::string(), - py::arg("str")=__builtin_FUNCTION()); + m.def_nogil("trace_info", + (void (*)(bmf_sdk::TraceType, const char *, bmf_sdk::TracePhase, + std::string, const char *)) & + bmf_sdk::BMF_TRACE, + py::arg("category"), py::arg("name"), + py::arg("phase") = bmf_sdk::TracePhase::NONE, + py::arg("info") = std::string(), + py::arg("str") = __builtin_FUNCTION()); - m.def_nogil("trace_done", [](){ - bmf_sdk::TraceLogger::instance()->format_logs(); - }); + m.def_nogil("trace_done", + []() { bmf_sdk::TraceLogger::instance()->format_logs(); }); - m.def_nogil("convert_filter_para", [](const std::string &config){ + m.def_nogil("convert_filter_para", [](const std::string &config) { JsonParam json_config = JsonParam(config); - bmf_engine::NodeConfig node_config = bmf_engine::NodeConfig(json_config); + bmf_engine::NodeConfig node_config = + bmf_engine::NodeConfig(json_config); bmf_engine::Optimizer::convert_filter_para(node_config); bmf_engine::Optimizer::replace_stream_name_with_id(node_config); return node_config.get_option().dump(); diff --git a/bmf/python/py_module_sdk.cpp b/bmf/python/py_module_sdk.cpp index 0d65a169..7634ae13 100644 --- a/bmf/python/py_module_sdk.cpp +++ b/bmf/python/py_module_sdk.cpp @@ -18,222 +18,186 @@ namespace py = pybind11; +namespace bmf_sdk { -namespace bmf_sdk{ - -class PythonObject -{ +class PythonObject { py::object obj_; -public: + + public: PythonObject(py::object &obj) : obj_(obj) {} py::object &obj() { return obj_; } - ~PythonObject() - { + ~PythonObject() { py::gil_scoped_acquire gil; obj_ = py::object(); } }; -} //namespace bmf_sdk +} // namespace bmf_sdk BMF_DEFINE_TYPE(bmf_sdk::PythonObject) - namespace { - // packet casters for python -struct PacketCaster{ +struct PacketCaster { std::function from; std::function to; }; static std::map s_packet_casters; -std::string get_py_class_name(const py::object &cls) -{ +std::string get_py_class_name(const py::object &cls) { return cls.attr("__module__").cast() + "." + - cls.attr("__name__").cast(); + cls.attr("__name__").cast(); } -void register_packet_caster(const std::string &cls_name, const PacketCaster &caster) -{ - if(s_packet_casters.find(cls_name) != s_packet_casters.end()){ +void register_packet_caster(const std::string &cls_name, + const PacketCaster &caster) { + if (s_packet_casters.find(cls_name) != s_packet_casters.end()) { throw std::runtime_error(cls_name + " has already registered"); } s_packet_casters[cls_name] = caster; } -void register_packet_caster(const py::object &cls, const PacketCaster &caster) -{ +void register_packet_caster(const py::object &cls, const PacketCaster &caster) { auto cls_name = get_py_class_name(cls); register_packet_caster(cls_name, caster); } - -py::object packet_get(bmf_sdk::Packet &pkt, const py::object &cls) -{ +py::object packet_get(bmf_sdk::Packet &pkt, const py::object &cls) { std::string cls_name; - if(cls.is_none()){ + if (cls.is_none()) { cls_name = "bmf.lib._bmf.sdk.PythonObject"; - } - else{ + } else { cls_name = get_py_class_name(cls); - if(s_packet_casters.find(cls_name) == s_packet_casters.end()){ + if (s_packet_casters.find(cls_name) == s_packet_casters.end()) { cls_name = "bmf.lib._bmf.sdk.PythonObject"; } } auto obj = s_packet_casters.at(cls_name).from(pkt); - if(cls_name == "bmf.lib._bmf.sdk.PythonObject"){ + if (cls_name == "bmf.lib._bmf.sdk.PythonObject") { obj = obj.cast().obj(); - if(cls.is_none() || obj.get_type().is(cls)){ + if (cls.is_none() || obj.get_type().is(cls)) { return obj; - } - else{ + } else { throw std::runtime_error("class type is not matched"); } - } - else{ + } else { return obj; } } - -bool packet_is(bmf_sdk::Packet &pkt, const py::object &cls) -{ - try{ - if(pkt){ +bool packet_is(bmf_sdk::Packet &pkt, const py::object &cls) { + try { + if (pkt) { packet_get(pkt, cls); return true; - } - else{ + } else { return false; } - } - catch(...){ + } catch (...) { return false; } } -bmf_sdk::Packet packet_init(py::object &obj) -{ - if(obj.is_none()){ +bmf_sdk::Packet packet_init(py::object &obj) { + if (obj.is_none()) { return bmf_sdk::Packet(); } auto cls_name = get_py_class_name(obj.attr("__class__")); - if(s_packet_casters.find(cls_name) == s_packet_casters.end()){ - return bmf_sdk::Packet(bmf_sdk::PythonObject(obj)); //support python types - } - else{ + if (s_packet_casters.find(cls_name) == s_packet_casters.end()) { + return bmf_sdk::Packet( + bmf_sdk::PythonObject(obj)); // support python types + } else { return s_packet_casters.at(cls_name).to(obj); } } +#define PACKET_REGISTER_TYPE(name, T) \ + register_packet_caster( \ + name, \ + PacketCaster{ \ + .from = [](Packet &pkt) { return py::cast(pkt.get()); }, \ + .to = [](py::object &obj) { return Packet(obj.cast()); }}); -#define PACKET_REGISTER_TYPE(name, T) \ - register_packet_caster(name, \ - PacketCaster{ \ - .from = [](Packet &pkt){ \ - return py::cast(pkt.get()); \ - }, \ - .to = [](py::object &obj){ \ - return Packet(obj.cast()); \ - } \ - }); - - - -#define PACKET_REGISTER_BMF_SDK_TYPE(T) \ +#define PACKET_REGISTER_BMF_SDK_TYPE(T) \ PACKET_REGISTER_TYPE("bmf.lib._bmf.sdk." #T, T) - - -hmp::TensorOptions parse_tensor_options(const py::kwargs &kwargs, const hmp::TensorOptions &ref) -{ +hmp::TensorOptions parse_tensor_options(const py::kwargs &kwargs, + const hmp::TensorOptions &ref) { using namespace hmp; TensorOptions opts(ref); - if (kwargs.contains("pinned_memory")){ - opts = opts.pinned_memory(py::cast(kwargs["pinned_memory"])); + if (kwargs.contains("pinned_memory")) { + opts = opts.pinned_memory(py::cast(kwargs["pinned_memory"])); } - if (kwargs.contains("device")){ - auto device = kwargs["device"]; - if (PyUnicode_Check(device.ptr())) - opts = opts.device(py::cast(kwargs["device"])); - else if (py::isinstance(kwargs["device"])) - opts = opts.device(py::cast(kwargs["device"])); - else - opts = opts.device(py::cast(kwargs["device"])); + if (kwargs.contains("device")) { + auto device = kwargs["device"]; + if (PyUnicode_Check(device.ptr())) + opts = opts.device(py::cast(kwargs["device"])); + else if (py::isinstance(kwargs["device"])) + opts = opts.device(py::cast(kwargs["device"])); + else + opts = opts.device(py::cast(kwargs["device"])); } - if (kwargs.contains("dtype")){ - opts = opts.dtype(py::cast(kwargs["dtype"])); + if (kwargs.contains("dtype")) { + opts = opts.dtype(py::cast(kwargs["dtype"])); } return opts; } - - -struct PyPacketQueue -{ +struct PyPacketQueue { PyPacketQueue(const std::shared_ptr> &queue) - : q_(queue) - { - } + : q_(queue) {} bool empty() const { return q_->empty(); } - int put(const bmf_sdk::Packet &pkt) { q_->push(pkt); return 0; } + int put(const bmf_sdk::Packet &pkt) { + q_->push(pkt); + return 0; + } - bmf_sdk::Packet get() - { + bmf_sdk::Packet get() { auto pkt = q_->front(); q_->pop(); - return pkt; + return pkt; } - bmf_sdk::Packet &front() - { - return q_->front(); - } + bmf_sdk::Packet &front() { return q_->front(); } std::shared_ptr> q_; }; - -} //namespace +} // namespace #ifdef BMF_ENABLE_FFMPEG -void bmf_ffmpeg_bind(py::module &m) -{ +void bmf_ffmpeg_bind(py::module &m) { using namespace bmf_sdk; auto ff = m.def_submodule("ffmpeg"); - ff.def("reformat", [](VideoFrame &vf, const std::string &format_str){ - auto new_vf = ffmpeg::reformat(vf, format_str); - return py::cast(new_vf); + ff.def("reformat", [](VideoFrame &vf, const std::string &format_str) { + auto new_vf = ffmpeg::reformat(vf, format_str); + return py::cast(new_vf); }); } #endif - -void module_sdk_bind(py::module &m) -{ +void module_sdk_bind(py::module &m) { using namespace bmf_sdk; // Rational py::class_(m, "Rational") .def(py::init(), py::arg("num"), py::arg("den")) .def_readwrite("den", &Rational::den) - .def_readwrite("num", &Rational::num) - ; + .def_readwrite("num", &Rational::num); // Timestamp py::enum_(m, "Timestamp") @@ -244,9 +208,7 @@ void module_sdk_bind(py::module &m) .value("kEOS", Timestamp::EOS) .value("kINF_SRC", Timestamp::INF_SRC) .value("kDONE", Timestamp::DONE) - .export_values() - ; - + .export_values(); // ModuleTag py::enum_(m, "ModuleTag") @@ -264,9 +226,7 @@ void module_sdk_bind(py::module &m) .value("TAG_DONE", ModuleTag::BMF_TAG_DONE) .export_values() .def(py::self | py::self) - .def(py::self |= py::self) - ; - + .def(py::self |= py::self); // OpaqueDataSet py::enum_(m, "OpaqueDataKey") @@ -280,7 +240,6 @@ void module_sdk_bind(py::module &m) .value("kReserved_7", OpaqueDataKey::kReserved_7) .export_values(); - // ModuleInfo py::class_(m, "ModuleInfo") .def_readwrite("module_name", &ModuleInfo::module_name) @@ -288,75 +247,77 @@ void module_sdk_bind(py::module &m) .def_readwrite("module_path", &ModuleInfo::module_path) .def_readwrite("module_type", &ModuleInfo::module_type) .def_readwrite("module_description", &ModuleInfo::module_description) - .def_readwrite("module_tag", &ModuleInfo::module_tag) - ; - + .def_readwrite("module_tag", &ModuleInfo::module_tag); py::class_(m, "OpaqueDataSet") .def("private_merge", &OpaqueDataSet::private_merge, py::arg("from")) - .def("private_get", [](OpaqueDataSet &self, py::object &cls) -> py::object{ - auto cls_name = get_py_class_name(cls); - if(cls_name == "builtins.dict"){ - auto json_sptr = self.private_get(); - if(!json_sptr){ - return py::none(); - } - return py::cast(*json_sptr); - } - else{ - throw std::invalid_argument(fmt::format("unsupported type {}", cls_name)); - } - }) - .def("private_attach", [](OpaqueDataSet &self, py::object &obj){ - auto cls_name = get_py_class_name(obj.attr("__class__")); - if(cls_name == "builtins.dict"){ - auto json = obj.cast(); - self.private_attach(&json); - } - else{ - throw std::invalid_argument(fmt::format("private attach type {} failed", cls_name)); - } - }) - .def("copy_props", &OpaqueDataSet::copy_props, py::arg("from")) - ; + .def("private_get", + [](OpaqueDataSet &self, py::object &cls) -> py::object { + auto cls_name = get_py_class_name(cls); + if (cls_name == "builtins.dict") { + auto json_sptr = self.private_get(); + if (!json_sptr) { + return py::none(); + } + return py::cast(*json_sptr); + } else { + throw std::invalid_argument( + fmt::format("unsupported type {}", cls_name)); + } + }) + .def("private_attach", + [](OpaqueDataSet &self, py::object &obj) { + auto cls_name = get_py_class_name(obj.attr("__class__")); + if (cls_name == "builtins.dict") { + auto json = obj.cast(); + self.private_attach(&json); + } else { + throw std::invalid_argument(fmt::format( + "private attach type {} failed", cls_name)); + } + }) + .def("copy_props", &OpaqueDataSet::copy_props, py::arg("from")); // SequenceData py::class_(m, "SequenceData") .def_property("pts", &SequenceData::pts, &SequenceData::set_pts) - .def_property("time_base", &SequenceData::time_base, &SequenceData::set_time_base) - .def("copy_props", &SequenceData::copy_props, py::arg("from")) - ; + .def_property("time_base", &SequenceData::time_base, + &SequenceData::set_time_base) + .def("copy_props", &SequenceData::copy_props, py::arg("from")); // Future py::class_(m, "Future") .def_property_readonly("device", &Future::device) .def_property("stream", &Future::stream, &Future::set_stream) .def("ready", &Future::ready) - .def("record", &Future::record, py::arg("use_current")=true) + .def("record", &Future::record, py::arg("use_current") = true) .def("synchronize", &Future::synchronize) - .def("copy_props", &Future::copy_props, py::arg("from")) - ; + .def("copy_props", &Future::copy_props, py::arg("from")); // VideoFrame py::class_(m, "VideoFrame") .def(py::init()) - .def(py::init([](int width, int height, const PixelInfo &pix_info, py::kwargs kwargs){ - auto opts = parse_tensor_options(kwargs, kUInt8); - return VideoFrame(width, height, pix_info, opts.device()); - }), py::arg("width"), py::arg("height"), py::arg("pix_info")) + .def(py::init([](int width, int height, const PixelInfo &pix_info, + py::kwargs kwargs) { + auto opts = parse_tensor_options(kwargs, kUInt8); + return VideoFrame(width, height, pix_info, opts.device()); + }), + py::arg("width"), py::arg("height"), py::arg("pix_info")) .def("defined", &VideoFrame::operator bool) .def_property_readonly("width", &VideoFrame::width) .def_property_readonly("height", &VideoFrame::height) .def_property_readonly("dtype", &VideoFrame::dtype) .def("frame", &VideoFrame::frame) - .def("crop", &VideoFrame::crop, py::arg("x"), py::arg("y"), py::arg("w"), py::arg("h")) - .def("cpu", &VideoFrame::cpu, py::arg("non_blocking")=false) + .def("crop", &VideoFrame::crop, py::arg("x"), py::arg("y"), + py::arg("w"), py::arg("h")) + .def("cpu", &VideoFrame::cpu, py::arg("non_blocking") = false) .def("cuda", &VideoFrame::cuda) .def("copy_", &VideoFrame::copy_) - .def("to", (VideoFrame(VideoFrame::*)(const Device&, bool) const)&VideoFrame::to, py::arg("device"), py::arg("non_blocking")=false) + .def("to", (VideoFrame (VideoFrame::*)(const Device &, bool) const) & + VideoFrame::to, + py::arg("device"), py::arg("non_blocking") = false) .def("copy_props", &VideoFrame::copy_props, py::arg("from")) - .def("reformat", &VideoFrame::reformat, py::arg("pix_info")) - ; + .def("reformat", &VideoFrame::reformat, py::arg("pix_info")); PACKET_REGISTER_BMF_SDK_TYPE(VideoFrame) // AudioFrame @@ -376,29 +337,36 @@ void module_sdk_bind(py::module &m) .value("kLAYOUT_5POINT0_BACK", AudioChannelLayout::kLAYOUT_5POINT0_BACK) .value("kLAYOUT_5POINT1_BACK", AudioChannelLayout::kLAYOUT_5POINT1_BACK) .value("kLAYOUT_6POINT0", AudioChannelLayout::kLAYOUT_6POINT0) - .value("kLAYOUT_6POINT0_FRONT", AudioChannelLayout::kLAYOUT_6POINT0_FRONT) + .value("kLAYOUT_6POINT0_FRONT", + AudioChannelLayout::kLAYOUT_6POINT0_FRONT) .value("kLAYOUT_HEXAGONAL", AudioChannelLayout::kLAYOUT_HEXAGONAL) .value("kLAYOUT_6POINT1", AudioChannelLayout::kLAYOUT_6POINT1) .value("kLAYOUT_6POINT1_BACK", AudioChannelLayout::kLAYOUT_6POINT1_BACK) - .value("kLAYOUT_6POINT1_FRONT", AudioChannelLayout::kLAYOUT_6POINT1_FRONT) + .value("kLAYOUT_6POINT1_FRONT", + AudioChannelLayout::kLAYOUT_6POINT1_FRONT) .value("kLAYOUT_7POINT0", AudioChannelLayout::kLAYOUT_7POINT0) - .value("kLAYOUT_7POINT0_FRONT", AudioChannelLayout::kLAYOUT_7POINT0_FRONT) + .value("kLAYOUT_7POINT0_FRONT", + AudioChannelLayout::kLAYOUT_7POINT0_FRONT) .value("kLAYOUT_7POINT1", AudioChannelLayout::kLAYOUT_7POINT1) .value("kLAYOUT_7POINT1_WIDE", AudioChannelLayout::kLAYOUT_7POINT1_WIDE) - .value("kLAYOUT_7POINT1_WIDE_BACK", AudioChannelLayout::kLAYOUT_7POINT1_WIDE_BACK) + .value("kLAYOUT_7POINT1_WIDE_BACK", + AudioChannelLayout::kLAYOUT_7POINT1_WIDE_BACK) .value("kLAYOUT_OCTAGONAL", AudioChannelLayout::kLAYOUT_OCTAGONAL) - .value("kLAYOUT_HEXADECAGONAL", AudioChannelLayout::kLAYOUT_HEXADECAGONAL) - .value("kLAYOUT_STEREO_DOWNMIX", AudioChannelLayout::kLAYOUT_STEREO_DOWNMIX) - .export_values() - ; - + .value("kLAYOUT_HEXADECAGONAL", + AudioChannelLayout::kLAYOUT_HEXADECAGONAL) + .value("kLAYOUT_STEREO_DOWNMIX", + AudioChannelLayout::kLAYOUT_STEREO_DOWNMIX) + .export_values(); py::class_(m, "AudioFrame") - .def(py::init([](int samples, uint64_t layout, bool planer, py::kwargs kwargs){ - auto opts = parse_tensor_options(kwargs, kUInt8); - return AudioFrame(samples, layout, planer, opts); - }), py::arg("samples"), py::arg("layout"), py::arg("planer") = true) - .def(py::init(), py::arg("data"), py::arg("layout"), py::arg("planer")=true) + .def(py::init([](int samples, uint64_t layout, bool planer, + py::kwargs kwargs) { + auto opts = parse_tensor_options(kwargs, kUInt8); + return AudioFrame(samples, layout, planer, opts); + }), + py::arg("samples"), py::arg("layout"), py::arg("planer") = true) + .def(py::init(), py::arg("data"), + py::arg("layout"), py::arg("planer") = true) .def("defined", &AudioFrame::operator bool) .def_property_readonly("layout", &AudioFrame::layout) .def_property_readonly("dtype", &AudioFrame::dtype) @@ -407,59 +375,54 @@ void module_sdk_bind(py::module &m) .def_property_readonly("nchannels", &AudioFrame::nchannels) .def_property_readonly("nplanes", &AudioFrame::nplanes) .def_property_readonly("planes", &AudioFrame::planes) - .def_property("sample_rate", &AudioFrame::sample_rate, &AudioFrame::set_sample_rate) + .def_property("sample_rate", &AudioFrame::sample_rate, + &AudioFrame::set_sample_rate) .def("copy_props", &AudioFrame::copy_props) .def("plane", &AudioFrame::plane) - .def("clone", &AudioFrame::clone) - ; + .def("clone", &AudioFrame::clone); PACKET_REGISTER_BMF_SDK_TYPE(AudioFrame) // BMFAVPacket py::class_(m, "BMFAVPacket") .def(py::init<>()) - .def(py::init()) - .def(py::init([](int size, const py::kwargs &kwargs){ + .def(py::init()) + .def(py::init([](int size, const py::kwargs &kwargs) { auto opts = parse_tensor_options(kwargs, kUInt8); return BMFAVPacket(size, opts); })) .def("defined", &BMFAVPacket::operator bool) - .def_property_readonly("data", (Tensor&(BMFAVPacket::*)())&BMFAVPacket::data) + .def_property_readonly("data", (Tensor & (BMFAVPacket::*)()) & + BMFAVPacket::data) .def_property_readonly("nbytes", &BMFAVPacket::nbytes) .def("copy_props", &BMFAVPacket::copy_props) .def("get_offset", &BMFAVPacket::get_offset) - .def("get_whence", &BMFAVPacket::get_whence) - ; + .def("get_whence", &BMFAVPacket::get_whence); PACKET_REGISTER_BMF_SDK_TYPE(BMFAVPacket) // PythonObject - py::class_(m, "PythonObject"); //dummy object + py::class_(m, "PythonObject"); // dummy object PACKET_REGISTER_BMF_SDK_TYPE(PythonObject) // Packet py::class_(m, "Packet") - .def(py::init([](py::object &obj){ - return packet_init(obj); - })) + .def(py::init([](py::object &obj) { return packet_init(obj); })) .def("defined", &Packet::operator bool) - .def("is_", [](Packet &self, py::object& cls){ - return packet_is(self, cls); - }) - .def("get", [](Packet &self, py::object& cls){ - return packet_get(self, cls); - }) + .def("is_", + [](Packet &self, py::object &cls) { return packet_is(self, cls); }) + .def("get", [](Packet &self, + py::object &cls) { return packet_get(self, cls); }) .def("get_timestamp", &Packet::timestamp) .def("set_timestamp", &Packet::set_timestamp) .def_property("timestamp", &Packet::timestamp, &Packet::set_timestamp) .def("get_time", &Packet::time) .def("set_time", &Packet::set_time) .def_property("time", &Packet::time, &Packet::set_time) - .def_property_readonly("class_name", [](const Packet &pkt){ - return pkt.type_info().name; - }) + .def_property_readonly( + "class_name", + [](const Packet &pkt) { return pkt.type_info().name; }) .def_static("generate_eos_packet", &Packet::generate_eos_packet) - .def_static("generate_eof_packet", &Packet::generate_eof_packet) - ; - //Map dict to JsonParam + .def_static("generate_eof_packet", &Packet::generate_eof_packet); + // Map dict to JsonParam PACKET_REGISTER_TYPE("builtins.dict", JsonParam); PACKET_REGISTER_TYPE("builtins.str", std::string); @@ -468,12 +431,11 @@ void module_sdk_bind(py::module &m) .def("put", &PyPacketQueue::put) .def("get", &PyPacketQueue::get) .def("empty", &PyPacketQueue::empty) - .def("front", &PyPacketQueue::front) - ; + .def("front", &PyPacketQueue::front); - auto convert_packet_queue_map = [](const PacketQueueMap &qmap){ + auto convert_packet_queue_map = [](const PacketQueueMap &qmap) { py::dict result; - for(auto &qp : qmap){ + for (auto &qp : qmap) { result[py::cast(qp.first)] = py::cast(PyPacketQueue(qp.second)); } return result; @@ -481,93 +443,97 @@ void module_sdk_bind(py::module &m) py::class_(m, "Task") .def(py::init, std::vector>(), - py::arg("node_id") = -1, - py::arg("input_stream_id_list") = std::vector{}, - py::arg("input_stream_id_list") = std::vector{}) + py::arg("node_id") = -1, + py::arg("input_stream_id_list") = std::vector{}, + py::arg("input_stream_id_list") = std::vector{}) .def_property("timestamp", &Task::timestamp, &Task::set_timestamp) .def("get_timestamp", &Task::timestamp) .def("set_timestamp", &Task::set_timestamp) .def("fill_input_packet", &Task::fill_input_packet, - py::arg("stream_id"), py::arg("packet")) + py::arg("stream_id"), py::arg("packet")) .def("fill_output_packet", &Task::fill_output_packet, - py::arg("stream_id"), py::arg("packet")) + py::arg("stream_id"), py::arg("packet")) .def("pop_packet_from_out_queue", &Task::pop_packet_from_out_queue, - py::arg("stream_id"), py::arg("packet")) - .def("pop_packet_from_out_queue", [](Task &task, int stream_id){ - Packet pkt; - if(!task.pop_packet_from_out_queue(stream_id, pkt)){ - throw std::runtime_error(fmt::format("Pop packet from output stream {} failed", stream_id)); - } - return pkt; - }, py::arg("stream_id")) + py::arg("stream_id"), py::arg("packet")) + .def("pop_packet_from_out_queue", + [](Task &task, int stream_id) { + Packet pkt; + if (!task.pop_packet_from_out_queue(stream_id, pkt)) { + throw std::runtime_error(fmt::format( + "Pop packet from output stream {} failed", stream_id)); + } + return pkt; + }, + py::arg("stream_id")) .def("pop_packet_from_input_queue", &Task::pop_packet_from_input_queue, - py::arg("stream_id"), py::arg("packet")) - .def("pop_packet_from_input_queue", [](Task &task, int stream_id){ - Packet pkt; - if(!task.pop_packet_from_input_queue(stream_id, pkt)){ - throw std::runtime_error(fmt::format("Pop packet from input stream {} failed", stream_id)); - } - return pkt; - }, py::arg("stream_id")) + py::arg("stream_id"), py::arg("packet")) + .def("pop_packet_from_input_queue", + [](Task &task, int stream_id) { + Packet pkt; + if (!task.pop_packet_from_input_queue(stream_id, pkt)) { + throw std::runtime_error(fmt::format( + "Pop packet from input stream {} failed", stream_id)); + } + return pkt; + }, + py::arg("stream_id")) .def("output_queue_empty", &Task::output_queue_empty, - py::arg("stream_id")) + py::arg("stream_id")) .def("input_queue_empty", &Task::input_queue_empty, - py::arg("stream_id")) - .def("get_outputs", [=](Task &task){ - return convert_packet_queue_map(task.get_outputs()); - }) - .def("get_inputs", [=](Task &task){ - return convert_packet_queue_map(task.get_inputs()); - }) + py::arg("stream_id")) + .def("get_outputs", + [=](Task &task) { + return convert_packet_queue_map(task.get_outputs()); + }) + .def("get_inputs", + [=](Task &task) { + return convert_packet_queue_map(task.get_inputs()); + }) .def("get_input_stream_ids", &Task::get_input_stream_ids) .def("get_output_stream_ids", &Task::get_output_stream_ids) .def("get_node", &Task::get_node) - .def("init", &Task::init, - py::arg("node_id") = -1, - py::arg("input_stream_id_list") = std::vector{}, - py::arg("input_stream_id_list") = std::vector{}) - ; + .def("init", &Task::init, py::arg("node_id") = -1, + py::arg("input_stream_id_list") = std::vector{}, + py::arg("input_stream_id_list") = std::vector{}); // AVLogBuffer py::class_>(m, "LogBuffer") - .def(py::init([](py::list buffer, const std::string &level){ - return std::make_unique([=](const std::string &log){ - py::gil_scoped_acquire gil; - buffer.append(py::cast(log)); - }, level); + .def(py::init([](py::list buffer, const std::string &level) { + return std::make_unique( + [=](const std::string &log) { + py::gil_scoped_acquire gil; + buffer.append(py::cast(log)); + }, + level); })) - .def("close", &LogBuffer::close) - ; - + .def("close", &LogBuffer::close); // ModuleFunctor py::register_exception(m, "ProcessDone"); py::class_(m, "ModuleFunctor") - .def(py::init([]( - int ninputs, int noutputs, - const std::string &name, - const std::string &type, - const std::string &path, - const std::string &entry, - py::dict option, int node_id){ - auto &M = ModuleManager::instance(); - auto factory = M.load_module(name, type, path, entry); - if(factory == nullptr){ - throw std::runtime_error("Create module " + name + " failed"); - } - return ModuleFunctor( - factory->make(node_id, py::cast(option)), - ninputs, noutputs); - }), py::arg("ninputs"), py::arg("noutputs"), - py::arg("name"), py::arg("type")=std::string(), - py::arg("path")=std::string(), py::arg("entry")=std::string(), - py::arg("option")=py::dict(), py::arg("node_id")=0) + .def(py::init([](int ninputs, int noutputs, const std::string &name, + const std::string &type, const std::string &path, + const std::string &entry, py::dict option, + int node_id) { + auto &M = ModuleManager::instance(); + auto factory = M.load_module(name, type, path, entry); + if (factory == nullptr) { + throw std::runtime_error("Create module " + name + + " failed"); + } + return ModuleFunctor( + factory->make(node_id, py::cast(option)), + ninputs, noutputs); + }), + py::arg("ninputs"), py::arg("noutputs"), py::arg("name"), + py::arg("type") = std::string(), py::arg("path") = std::string(), + py::arg("entry") = std::string(), py::arg("option") = py::dict(), + py::arg("node_id") = 0) .def_nogil("__call__", &ModuleFunctor::operator(), py::arg("inputs")) - .def_nogil("execute", &ModuleFunctor::execute, py::arg("inputs"), py::arg("cleanup")=true) - .def_nogil("fetch", &ModuleFunctor::fetch, py::arg("port")) - ; - + .def_nogil("execute", &ModuleFunctor::execute, py::arg("inputs"), + py::arg("cleanup") = true) + .def_nogil("fetch", &ModuleFunctor::fetch, py::arg("port")); } // diff --git a/bmf/sdk/cpp_sdk/include/bmf/sdk/compat/path.h b/bmf/sdk/cpp_sdk/include/bmf/sdk/compat/path.h index 8b49b5c8..8043d7b3 100644 --- a/bmf/sdk/cpp_sdk/include/bmf/sdk/compat/path.h +++ b/bmf/sdk/cpp_sdk/include/bmf/sdk/compat/path.h @@ -1,7 +1,8 @@ #pragma once #ifdef __APPLE__ -#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 #define CUSTOM_FILESYSTEM #endif //__IPHONE_OS_VERSION_MIN_REQUIRED #endif //__APPLE__ @@ -36,7 +37,9 @@ class path { path(const std::string &p) : p_(p) {} - path operator/(const path &p) { return p_ + std::string{preferred_separator} + p.p_; } + path operator/(const path &p) { + return p_ + std::string{preferred_separator} + p.p_; + } path &operator/=(const path &p) { p_ = p_ + std::string{preferred_separator} + p.p_; diff --git a/bmf/sdk/cpp_sdk/include/bmf/sdk/exception_factory.h b/bmf/sdk/cpp_sdk/include/bmf/sdk/exception_factory.h index e5f2f1bf..c63342cf 100644 --- a/bmf/sdk/cpp_sdk/include/bmf/sdk/exception_factory.h +++ b/bmf/sdk/cpp_sdk/include/bmf/sdk/exception_factory.h @@ -80,7 +80,7 @@ class BMF_API Exception : public std::exception { int code; ///< error code @see BMFStatus std::string err; ///< error description std::string func; ///< function name. Available only when the compiler - ///supports getting it + /// supports getting it std::string file; ///< source file name where the error has occurred int line; ///< line number in the source file where the error has occurred }; diff --git a/bmf/sdk/cpp_sdk/src/audio_frame.cpp b/bmf/sdk/cpp_sdk/src/audio_frame.cpp index 8c0b1f65..ab0f504a 100644 --- a/bmf/sdk/cpp_sdk/src/audio_frame.cpp +++ b/bmf/sdk/cpp_sdk/src/audio_frame.cpp @@ -1,12 +1,10 @@ #include #include -namespace bmf_sdk{ +namespace bmf_sdk { - -//copy from ffmpeg -static int popcount_c(uint32_t x) -{ +// copy from ffmpeg +static int popcount_c(uint32_t x) { x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; @@ -14,189 +12,137 @@ static int popcount_c(uint32_t x) return (x + (x >> 16)) & 0x3F; } - -static inline int popcount64_c(uint64_t x) -{ - return popcount_c(uint32_t(x)) + popcount_c((uint32_t(x>>32))); +static inline int popcount64_c(uint64_t x) { + return popcount_c(uint32_t(x)) + popcount_c((uint32_t(x >> 32))); } - -struct AudioFrame::Private -{ +struct AudioFrame::Private { Private(const TensorList &data_, bool planer_, uint64_t layout_) - : data(data_), layout(layout_), planer(planer_) - { - } + : data(data_), layout(layout_), planer(planer_) {} - static SizeArray infer_shape(int samples, bool planer, uint64_t layout) - { + static SizeArray infer_shape(int samples, bool planer, uint64_t layout) { HMP_REQUIRE(layout != 0, "can not infer_shape when layout == 0"); auto channels = popcount64_c(layout); - if(planer){ + if (planer) { return SizeArray{channels, samples}; - } - else{ + } else { return SizeArray{samples, channels}; } } - static TensorList construct(int samples, uint64_t layout, bool planer, const TensorOptions &options) - { - Tensor data_s = hmp::empty(infer_shape(samples, planer, layout), options); + static TensorList construct(int samples, uint64_t layout, bool planer, + const TensorOptions &options) { + Tensor data_s = + hmp::empty(infer_shape(samples, planer, layout), options); auto channels = popcount64_c(layout); TensorList data; - if(planer){ - for(int i = 0; i < channels; ++i){ + if (planer) { + for (int i = 0; i < channels; ++i) { data.push_back(data_s.select(0, i)); } - } - else{ + } else { data = {data_s}; } return data; } - - TensorList data; + TensorList data; bool planer; uint64_t layout; float sample_rate = 1; }; - -AudioFrame::AudioFrame(const TensorList &data, uint64_t layout, bool planer) -{ - //Note: channels from layout is not reliable if layout == 0 +AudioFrame::AudioFrame(const TensorList &data, uint64_t layout, bool planer) { + // Note: channels from layout is not reliable if layout == 0 auto channels = popcount64_c(layout); - if(planer){ + if (planer) { HMP_REQUIRE(channels == 0 || data.size() == channels, - "AudioFrame: data shape does not match channel layout, expect channels {}, got {}", - channels, data.size()); - for(auto &d : data){ - HMP_REQUIRE(d.defined() && d.dim() ==1, - "AudioFrame: expect 1d data for planer audio frame"); + "AudioFrame: data shape does not match channel layout, " + "expect channels {}, got {}", + channels, data.size()); + for (auto &d : data) { + HMP_REQUIRE(d.defined() && d.dim() == 1, + "AudioFrame: expect 1d data for planer audio frame"); HMP_REQUIRE(d.device_type() == kCPU, - "AudioFrame: only support cpu data"); + "AudioFrame: only support cpu data"); } - } - else{ - HMP_REQUIRE(data.size() == 1 && data[0].dim() ==2, - "AudioFrame: expect 2d data for interleave audio frame"); + } else { + HMP_REQUIRE(data.size() == 1 && data[0].dim() == 2, + "AudioFrame: expect 2d data for interleave audio frame"); HMP_REQUIRE(data[0].device_type() == kCPU, - "AudioFrame: only support cpu data"); + "AudioFrame: only support cpu data"); HMP_REQUIRE(channels == 0 || data[0].size(1) == channels, - "AudioFrame: data shape does not match channel layout, expect channels {}, got {}", - channels, data[0].size(1)); + "AudioFrame: data shape does not match channel layout, " + "expect channels {}, got {}", + channels, data[0].size(1)); } self = std::make_shared(data, planer, layout); } -AudioFrame::AudioFrame(int samples, uint64_t layout, bool planer, const TensorOptions &options) - : AudioFrame(Private::construct(samples, layout, planer, options), layout, planer) -{ -} - +AudioFrame::AudioFrame(int samples, uint64_t layout, bool planer, + const TensorOptions &options) + : AudioFrame(Private::construct(samples, layout, planer, options), layout, + planer) {} -AudioFrame AudioFrame::clone() const -{ - if(*this){ +AudioFrame AudioFrame::clone() const { + if (*this) { TensorList data; - for(auto &d : self->data){ + for (auto &d : self->data) { data.push_back(d.clone()); } auto copy = AudioFrame(data, self->layout, self->planer); copy.copy_props(*this); return copy; - } - else{ + } else { return AudioFrame(); } } -AudioFrame::operator bool() const -{ - return self.get() != nullptr; -} - - -uint64_t AudioFrame::layout() const -{ - return self->layout; -} - +AudioFrame::operator bool() const { return self.get() != nullptr; } -bool AudioFrame::planer() const -{ - return self->planer; -} +uint64_t AudioFrame::layout() const { return self->layout; } +bool AudioFrame::planer() const { return self->planer; } -int AudioFrame::nsamples() const -{ - return self->data[0].size(0); -} +int AudioFrame::nsamples() const { return self->data[0].size(0); } -int AudioFrame::nchannels() const -{ - if(self->planer){ +int AudioFrame::nchannels() const { + if (self->planer) { return self->data.size(); - } - else{ + } else { return self->data[0].size(1); } } +ScalarType AudioFrame::dtype() const { return self->data[0].dtype(); } -ScalarType AudioFrame::dtype() const -{ - return self->data[0].dtype(); -} - -void AudioFrame::set_sample_rate(float sample_rate) -{ - HMP_REQUIRE(sample_rate > 0, - "AudioFrame: expect sample_rate > 0, got {}", sample_rate); +void AudioFrame::set_sample_rate(float sample_rate) { + HMP_REQUIRE(sample_rate > 0, "AudioFrame: expect sample_rate > 0, got {}", + sample_rate); self->sample_rate = sample_rate; } +float AudioFrame::sample_rate() const { return self->sample_rate; } -float AudioFrame::sample_rate() const -{ - return self->sample_rate; -} +const TensorList &AudioFrame::planes() const { return self->data; } +int AudioFrame::nplanes() const { return self->data.size(); } -const TensorList& AudioFrame::planes() const -{ - return self->data; -} - -int AudioFrame::nplanes() const -{ - return self->data.size(); -} - -Tensor AudioFrame::plane(int p) const -{ +Tensor AudioFrame::plane(int p) const { HMP_REQUIRE(self.get() && p < self->data.size(), - "AudioFrame: plane index {} is out of range", p); + "AudioFrame: plane index {} is out of range", p); return self->data[p]; } -Tensor AudioFrame::operator[](int p) const -{ - return plane(p); -} - +Tensor AudioFrame::operator[](int p) const { return plane(p); } -AudioFrame& AudioFrame::copy_props(const AudioFrame &from) -{ +AudioFrame &AudioFrame::copy_props(const AudioFrame &from) { OpaqueDataSet::copy_props(from); SequenceData::copy_props(from); set_sample_rate(from.sample_rate()); @@ -204,5 +150,4 @@ AudioFrame& AudioFrame::copy_props(const AudioFrame &from) return *this; } - -} //namespace bmf_sdk \ No newline at end of file +} // namespace bmf_sdk \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/bmf_av_packet.cpp b/bmf/sdk/cpp_sdk/src/bmf_av_packet.cpp index b7cb3e16..87398fba 100644 --- a/bmf/sdk/cpp_sdk/src/bmf_av_packet.cpp +++ b/bmf/sdk/cpp_sdk/src/bmf_av_packet.cpp @@ -1,84 +1,57 @@ #include -namespace bmf_sdk{ +namespace bmf_sdk { -struct BMFAVPacket::Private -{ +struct BMFAVPacket::Private { Private(const Tensor &d) : data(d) {} - Tensor data; + Tensor data; }; -BMFAVPacket::BMFAVPacket(const Tensor &data) -{ +BMFAVPacket::BMFAVPacket(const Tensor &data) { HMP_REQUIRE(data.defined(), "BMFAVPacket: data is undefined"); - HMP_REQUIRE(data.device_type() == kCPU, - "BMFAVPacket: only support cpu buffer"); - HMP_REQUIRE(data.is_contiguous(), - "BMFAVPacket: only support contiguous buffer") + HMP_REQUIRE(data.device_type() == kCPU, + "BMFAVPacket: only support cpu buffer"); + HMP_REQUIRE(data.is_contiguous(), + "BMFAVPacket: only support contiguous buffer") self = std::make_shared(data); } BMFAVPacket::BMFAVPacket(int size, const TensorOptions &options) - : BMFAVPacket(hmp::empty({size}, options)) -{ -} - -BMFAVPacket::operator bool() const -{ - return self.get() != nullptr; -} + : BMFAVPacket(hmp::empty({size}, options)) {} +BMFAVPacket::operator bool() const { return self.get() != nullptr; } -Tensor& BMFAVPacket::data() -{ +Tensor &BMFAVPacket::data() { HMP_REQUIRE(*this, "BMFAVPacket: undefined BMFAVPacket detected"); return self->data; } -const Tensor& BMFAVPacket::data() const -{ +const Tensor &BMFAVPacket::data() const { HMP_REQUIRE(*this, "BMFAVPacket: undefined BMFAVPacket detected"); return self->data; } +void *BMFAVPacket::data_ptr() { return *this ? data().unsafe_data() : nullptr; } -void *BMFAVPacket::data_ptr() -{ +const void *BMFAVPacket::data_ptr() const { return *this ? data().unsafe_data() : nullptr; } -const void *BMFAVPacket::data_ptr() const -{ - return *this ? data().unsafe_data() : nullptr; -} +int BMFAVPacket::nbytes() const { return *this ? data().nbytes() : 0; } -int BMFAVPacket::nbytes() const -{ - return *this ? data().nbytes() : 0; -} - -BMFAVPacket& BMFAVPacket::copy_props(const BMFAVPacket &from) -{ +BMFAVPacket &BMFAVPacket::copy_props(const BMFAVPacket &from) { OpaqueDataSet::copy_props(from); SequenceData::copy_props(from); return *this; } -int64_t BMFAVPacket::get_offset() const { - return offset_; -} +int64_t BMFAVPacket::get_offset() const { return offset_; } -void BMFAVPacket::set_offset(int64_t offset) { - offset_ = offset; -} +void BMFAVPacket::set_offset(int64_t offset) { offset_ = offset; } -int BMFAVPacket::get_whence() const { - return whence_; -} +int BMFAVPacket::get_whence() const { return whence_; } -void BMFAVPacket::set_whence(int whence) { - whence_ = whence; -} +void BMFAVPacket::set_whence(int whence) { whence_ = whence; } -} //namespace +} // namespace diff --git a/bmf/sdk/cpp_sdk/src/bmf_capi.cpp b/bmf/sdk/cpp_sdk/src/bmf_capi.cpp index 1193096b..e68f2f99 100644 --- a/bmf/sdk/cpp_sdk/src/bmf_capi.cpp +++ b/bmf/sdk/cpp_sdk/src/bmf_capi.cpp @@ -2,902 +2,619 @@ #include #include -#define BMF_PROTECT(...) \ - try{ \ - __VA_ARGS__ \ - } catch(const std::exception &e){ \ - s_bmf_last_error = e.what(); \ +#define BMF_PROTECT(...) \ + try { \ + __VA_ARGS__ \ + } catch (const std::exception &e) { \ + s_bmf_last_error = e.what(); \ } - using namespace bmf_sdk; - thread_local std::string s_bmf_last_error; -void bmf_set_last_error(const char *errstr) -{ - s_bmf_last_error = errstr; -} +void bmf_set_last_error(const char *errstr) { s_bmf_last_error = errstr; } -const char *bmf_last_error() -{ - return s_bmf_last_error.c_str(); -} - - -const char *bmf_sdk_version() -{ - return BMF_SDK_VERSION; -} +const char *bmf_last_error() { return s_bmf_last_error.c_str(); } +const char *bmf_sdk_version() { return BMF_SDK_VERSION; } -char *bmf_strdup(char const *src) -{ +char *bmf_strdup(char const *src) { char *res; #ifdef _POSIX_VERSION res = strdup(src); #else - res = (char *) malloc(strlen(src) + 1); + res = (char *)malloc(strlen(src) + 1); strcpy(res, src); #endif return res; } ////////// Common //////////// -char* bmf_json_param_dump(bmf_JsonParam json) -{ +char *bmf_json_param_dump(bmf_JsonParam json) { auto str = json->dump(); return strdup(str.c_str()); } -bmf_JsonParam bmf_json_param_parse(const char* str) -{ - BMF_PROTECT( - bmf_JsonParam j = new JsonParam(); - j->parse(str); - return j; - ) +bmf_JsonParam bmf_json_param_parse(const char *str) { + BMF_PROTECT(bmf_JsonParam j = new JsonParam(); j->parse(str); return j;) return nullptr; } -void bmf_json_param_free(bmf_JsonParam json) -{ - if(json){ +void bmf_json_param_free(bmf_JsonParam json) { + if (json) { delete json; } } - ////////// VideoFrame //////////// -bmf_VideoFrame bmf_vf_from_frame(hmp_Frame frame) -{ - BMF_PROTECT( - return new VideoFrame(*frame); - ) +bmf_VideoFrame bmf_vf_from_frame(hmp_Frame frame) { + BMF_PROTECT(return new VideoFrame(*frame);) return nullptr; } -bmf_VideoFrame bmf_vf_make_frame(int width, int height, - const hmp_PixelInfo pix_info, const char *device) -{ +bmf_VideoFrame bmf_vf_make_frame(int width, int height, + const hmp_PixelInfo pix_info, + const char *device) { BMF_PROTECT( - return new VideoFrame(width, height, *pix_info, Device(device)); - ) + return new VideoFrame(width, height, *pix_info, Device(device));) return nullptr; } -void bmf_vf_free(bmf_VideoFrame vf) -{ - if(vf){ +void bmf_vf_free(bmf_VideoFrame vf) { + if (vf) { delete vf; } } +bool bmf_vf_defined(const bmf_VideoFrame vf) { return *vf; } +int bmf_vf_width(const bmf_VideoFrame vf) { return vf->width(); } -bool bmf_vf_defined(const bmf_VideoFrame vf) -{ - return *vf; -} -int bmf_vf_width(const bmf_VideoFrame vf) -{ - return vf->width(); -} +int bmf_vf_height(const bmf_VideoFrame vf) { return vf->height(); } -int bmf_vf_height(const bmf_VideoFrame vf) -{ - return vf->height(); -} +int bmf_vf_dtype(const bmf_VideoFrame vf) { return (int)vf->dtype(); } -int bmf_vf_dtype(const bmf_VideoFrame vf) -{ - return (int)vf->dtype(); -} - -const hmp_Frame bmf_vf_frame(const bmf_VideoFrame vf) -{ - BMF_PROTECT( - return (const hmp_Frame)&vf->frame(); - ) +const hmp_Frame bmf_vf_frame(const bmf_VideoFrame vf) { + BMF_PROTECT(return (const hmp_Frame)&vf->frame();) return nullptr; } -bmf_VideoFrame bmf_vf_cpu(const bmf_VideoFrame vf, bool non_blocking) -{ - BMF_PROTECT( - auto tmp = vf->cpu(non_blocking); - return new VideoFrame(tmp); - ) +bmf_VideoFrame bmf_vf_cpu(const bmf_VideoFrame vf, bool non_blocking) { + BMF_PROTECT(auto tmp = vf->cpu(non_blocking); return new VideoFrame(tmp);) return nullptr; } -bmf_VideoFrame bmf_vf_cuda(const bmf_VideoFrame vf) -{ - BMF_PROTECT( - auto tmp = vf->cuda(); - return new VideoFrame(tmp); - ) +bmf_VideoFrame bmf_vf_cuda(const bmf_VideoFrame vf) { + BMF_PROTECT(auto tmp = vf->cuda(); return new VideoFrame(tmp);) return nullptr; } - -int bmf_vf_device_type(const bmf_VideoFrame vf) -{ +int bmf_vf_device_type(const bmf_VideoFrame vf) { return (int)vf->device().type(); } -int bmf_vf_device_index(const bmf_VideoFrame vf) -{ +int bmf_vf_device_index(const bmf_VideoFrame vf) { return vf->device().index(); } -void bmf_vf_copy_from(bmf_VideoFrame vf, const bmf_VideoFrame from) -{ +void bmf_vf_copy_from(bmf_VideoFrame vf, const bmf_VideoFrame from) { vf->copy_(*from); } -bmf_VideoFrame bmf_vf_to_device(const bmf_VideoFrame vf, const char *device, bool non_blocking) -{ - BMF_PROTECT( - return new VideoFrame(vf->to(Device(device), non_blocking)); - ) +bmf_VideoFrame bmf_vf_to_device(const bmf_VideoFrame vf, const char *device, + bool non_blocking) { + BMF_PROTECT(return new VideoFrame(vf->to(Device(device), non_blocking));) return nullptr; } -void bmf_vf_copy_props(bmf_VideoFrame vf, const bmf_VideoFrame from) -{ +void bmf_vf_copy_props(bmf_VideoFrame vf, const bmf_VideoFrame from) { vf->copy_props(*from); } -void bmf_vf_private_merge(bmf_VideoFrame vf, const bmf_VideoFrame from) -{ +void bmf_vf_private_merge(bmf_VideoFrame vf, const bmf_VideoFrame from) { vf->private_merge(*from); } -const bmf_JsonParam bmf_vf_private_get_json_param(const bmf_VideoFrame vf) -{ +const bmf_JsonParam bmf_vf_private_get_json_param(const bmf_VideoFrame vf) { return (const bmf_JsonParam)vf->private_get(); } -void bmf_vf_private_attach_json_param(bmf_VideoFrame vf, const bmf_JsonParam json_param) -{ +void bmf_vf_private_attach_json_param(bmf_VideoFrame vf, + const bmf_JsonParam json_param) { vf->private_attach(json_param); } -bmf_VideoFrame bmf_vf_reformat(const bmf_VideoFrame vf, const hmp_PixelInfo pix_info) -{ - BMF_PROTECT( - return new VideoFrame(vf->reformat(*pix_info)); - ) +bmf_VideoFrame bmf_vf_reformat(const bmf_VideoFrame vf, + const hmp_PixelInfo pix_info) { + BMF_PROTECT(return new VideoFrame(vf->reformat(*pix_info));) return nullptr; } -void bmf_vf_set_pts(bmf_VideoFrame vf, int64_t pts) -{ - vf->set_pts(pts); -} +void bmf_vf_set_pts(bmf_VideoFrame vf, int64_t pts) { vf->set_pts(pts); } -int64_t bmf_vf_pts(bmf_VideoFrame vf) -{ - return vf->pts(); -} +int64_t bmf_vf_pts(bmf_VideoFrame vf) { return vf->pts(); } -void bmf_vf_set_time_base(bmf_VideoFrame vf, int num, int den) -{ +void bmf_vf_set_time_base(bmf_VideoFrame vf, int num, int den) { vf->set_time_base(Rational(num, den)); } -void bmf_vf_time_base(bmf_VideoFrame vf, int *num, int *den) -{ +void bmf_vf_time_base(bmf_VideoFrame vf, int *num, int *den) { *num = vf->time_base().num; *den = vf->time_base().den; } -bool bmf_vf_ready(const bmf_VideoFrame vf) -{ - return vf->ready(); -} +bool bmf_vf_ready(const bmf_VideoFrame vf) { return vf->ready(); } -void bmf_vf_record(bmf_VideoFrame vf, bool use_current) -{ +void bmf_vf_record(bmf_VideoFrame vf, bool use_current) { vf->record(use_current); } -void bmf_vf_synchronize(bmf_VideoFrame vf) -{ - vf->synchronize(); -} - +void bmf_vf_synchronize(bmf_VideoFrame vf) { vf->synchronize(); } ////////// AudioFrame //////////// -bmf_AudioFrame bmf_af_make_from_data(hmp_Tensor *data, int size, uint64_t layout, bool planer) -{ - BMF_PROTECT( - std::vector tensor_list; - for (int i=0; i tensor_list; + for (int i = 0; i < size; i++) { + tensor_list.push_back(*data[i]); + } return new AudioFrame(tensor_list, layout, planer);) return nullptr; } -bmf_AudioFrame bmf_af_make(int samples, uint64_t layout, bool planer, int dtype) -{ - BMF_PROTECT( - auto tensor_options = hmp::TensorOptions((hmp::ScalarType)dtype); - return new AudioFrame(samples, layout, planer, tensor_options); - ) +bmf_AudioFrame bmf_af_make(int samples, uint64_t layout, bool planer, + int dtype) { + BMF_PROTECT(auto tensor_options = + hmp::TensorOptions((hmp::ScalarType)dtype); + return new AudioFrame(samples, layout, planer, tensor_options);) return nullptr; } -void bmf_af_free(bmf_AudioFrame af) -{ - if(af){ +void bmf_af_free(bmf_AudioFrame af) { + if (af) { delete af; } } -bool bmf_af_defined(const bmf_AudioFrame af) -{ - return *af; -} +bool bmf_af_defined(const bmf_AudioFrame af) { return *af; } -uint64_t bmf_af_layout(const bmf_AudioFrame af) -{ - return af->layout(); -} +uint64_t bmf_af_layout(const bmf_AudioFrame af) { return af->layout(); } -int bmf_af_dtype(const bmf_AudioFrame af) -{ - return (int)af->dtype(); -} +int bmf_af_dtype(const bmf_AudioFrame af) { return (int)af->dtype(); } -bool bmf_af_planer(const bmf_AudioFrame af) -{ - return af->planer(); -} +bool bmf_af_planer(const bmf_AudioFrame af) { return af->planer(); } -int bmf_af_nsamples(const bmf_AudioFrame af) -{ - return af->nsamples(); -} +int bmf_af_nsamples(const bmf_AudioFrame af) { return af->nsamples(); } -int bmf_af_nchannels(const bmf_AudioFrame af) -{ - return af->nchannels(); -} +int bmf_af_nchannels(const bmf_AudioFrame af) { return af->nchannels(); } -void bmf_af_set_sample_rate(const bmf_AudioFrame af, float sr) -{ +void bmf_af_set_sample_rate(const bmf_AudioFrame af, float sr) { af->set_sample_rate(sr); } -float bmf_af_sample_rate(const bmf_AudioFrame af) -{ - return af->sample_rate(); -} +float bmf_af_sample_rate(const bmf_AudioFrame af) { return af->sample_rate(); } -int bmf_af_planes(const bmf_AudioFrame af, hmp_Tensor *data) -{ - if(data != nullptr){ - for(size_t i = 0; i < af->planes().size(); ++i){ +int bmf_af_planes(const bmf_AudioFrame af, hmp_Tensor *data) { + if (data != nullptr) { + for (size_t i = 0; i < af->planes().size(); ++i) { data[i] = new Tensor(af->planes()[i]); } } return (int)af->planes().size(); } -int bmf_af_nplanes(const bmf_AudioFrame af) -{ - return af->nplanes(); -} +int bmf_af_nplanes(const bmf_AudioFrame af) { return af->nplanes(); } -hmp_Tensor bmf_af_plane(const bmf_AudioFrame af, int p) -{ - BMF_PROTECT( - return new Tensor(af->plane(p)); - ) +hmp_Tensor bmf_af_plane(const bmf_AudioFrame af, int p) { + BMF_PROTECT(return new Tensor(af->plane(p));) return nullptr; } -void bmf_af_copy_props(bmf_AudioFrame af, const bmf_AudioFrame from) -{ +void bmf_af_copy_props(bmf_AudioFrame af, const bmf_AudioFrame from) { af->copy_props(*from); } -void bmf_af_private_merge(bmf_AudioFrame af, const bmf_AudioFrame from) -{ +void bmf_af_private_merge(bmf_AudioFrame af, const bmf_AudioFrame from) { af->private_merge(*from); } -const bmf_JsonParam bmf_af_private_get_json_param(const bmf_AudioFrame af) -{ +const bmf_JsonParam bmf_af_private_get_json_param(const bmf_AudioFrame af) { return (const bmf_JsonParam)af->private_get(); } -void bmf_af_private_attach_json_param(bmf_AudioFrame af, const bmf_JsonParam json_param) -{ +void bmf_af_private_attach_json_param(bmf_AudioFrame af, + const bmf_JsonParam json_param) { af->private_attach(json_param); } -void bmf_af_set_pts(bmf_AudioFrame af, int64_t pts) -{ - af->set_pts(pts); -} +void bmf_af_set_pts(bmf_AudioFrame af, int64_t pts) { af->set_pts(pts); } -int64_t bmf_af_pts(bmf_AudioFrame af) -{ - return af->pts(); -} +int64_t bmf_af_pts(bmf_AudioFrame af) { return af->pts(); } -void bmf_af_set_time_base(bmf_AudioFrame af, int num, int den) -{ +void bmf_af_set_time_base(bmf_AudioFrame af, int num, int den) { af->set_time_base(Rational(num, den)); } -void bmf_af_time_base(bmf_AudioFrame af, int *num, int *den) -{ +void bmf_af_time_base(bmf_AudioFrame af, int *num, int *den) { *num = af->time_base().num; *den = af->time_base().den; } - ////////// BMFAVPacket //////////// -bmf_BMFAVPacket bmf_pkt_make_from_data(hmp_Tensor data) -{ - BMF_PROTECT( - return new BMFAVPacket(*data); - ) +bmf_BMFAVPacket bmf_pkt_make_from_data(hmp_Tensor data) { + BMF_PROTECT(return new BMFAVPacket(*data);) return nullptr; } -bmf_BMFAVPacket bmf_pkt_make(int size, int dtype) -{ - BMF_PROTECT( - auto tensor_options = hmp::TensorOptions((hmp::ScalarType)dtype); - return new BMFAVPacket(size, tensor_options); - ) +bmf_BMFAVPacket bmf_pkt_make(int size, int dtype) { + BMF_PROTECT(auto tensor_options = + hmp::TensorOptions((hmp::ScalarType)dtype); + return new BMFAVPacket(size, tensor_options);) return nullptr; } -void bmf_pkt_free(bmf_BMFAVPacket pkt) -{ - if(pkt){ +void bmf_pkt_free(bmf_BMFAVPacket pkt) { + if (pkt) { delete pkt; } } -bool bmf_pkt_defined(const bmf_BMFAVPacket pkt) -{ - return *pkt; -} +bool bmf_pkt_defined(const bmf_BMFAVPacket pkt) { return *pkt; } -hmp_Tensor bmf_pkt_data(const bmf_BMFAVPacket pkt) -{ - BMF_PROTECT( - return new Tensor(pkt->data()); - ) +hmp_Tensor bmf_pkt_data(const bmf_BMFAVPacket pkt) { + BMF_PROTECT(return new Tensor(pkt->data());) return nullptr; } -void* bmf_pkt_data_ptr(bmf_BMFAVPacket pkt) -{ - return pkt->data_ptr(); -} +void *bmf_pkt_data_ptr(bmf_BMFAVPacket pkt) { return pkt->data_ptr(); } -const void* bmf_pkt_data_const_ptr(const bmf_BMFAVPacket pkt) -{ +const void *bmf_pkt_data_const_ptr(const bmf_BMFAVPacket pkt) { return pkt->data_ptr(); } -int bmf_pkt_nbytes(const bmf_BMFAVPacket pkt) -{ - return pkt->nbytes(); -} +int bmf_pkt_nbytes(const bmf_BMFAVPacket pkt) { return pkt->nbytes(); } -void bmf_pkt_copy_props(bmf_BMFAVPacket pkt, const bmf_BMFAVPacket from) -{ +void bmf_pkt_copy_props(bmf_BMFAVPacket pkt, const bmf_BMFAVPacket from) { pkt->copy_props(*from); } -void bmf_pkt_private_merge(bmf_BMFAVPacket pkt, const bmf_BMFAVPacket from) -{ +void bmf_pkt_private_merge(bmf_BMFAVPacket pkt, const bmf_BMFAVPacket from) { pkt->private_merge(*from); } -const bmf_JsonParam bmf_pkt_private_get_json_param(const bmf_BMFAVPacket pkt) -{ +const bmf_JsonParam bmf_pkt_private_get_json_param(const bmf_BMFAVPacket pkt) { return (const bmf_JsonParam)pkt->private_get(); } -void bmf_pkt_private_attach_json_param(bmf_BMFAVPacket pkt, const bmf_JsonParam json_param) -{ +void bmf_pkt_private_attach_json_param(bmf_BMFAVPacket pkt, + const bmf_JsonParam json_param) { pkt->private_attach(json_param); } -void bmf_pkt_set_pts(bmf_BMFAVPacket pkt, int64_t pts) -{ - pkt->set_pts(pts); -} +void bmf_pkt_set_pts(bmf_BMFAVPacket pkt, int64_t pts) { pkt->set_pts(pts); } -int64_t bmf_pkt_pts(bmf_BMFAVPacket pkt) -{ - return pkt->pts(); -} +int64_t bmf_pkt_pts(bmf_BMFAVPacket pkt) { return pkt->pts(); } -void bmf_pkt_set_time_base(bmf_BMFAVPacket pkt, int num, int den) -{ +void bmf_pkt_set_time_base(bmf_BMFAVPacket pkt, int num, int den) { pkt->set_time_base(Rational(num, den)); } -void bmf_pkt_time_base(bmf_BMFAVPacket pkt, int *num, int *den) -{ +void bmf_pkt_time_base(bmf_BMFAVPacket pkt, int *num, int *den) { *num = pkt->time_base().num; *den = pkt->time_base().den; } -int64_t bmf_pkt_offset(bmf_BMFAVPacket pkt) -{ - return pkt->get_offset(); -} - -int64_t bmf_pkt_whence(bmf_BMFAVPacket pkt) -{ - return pkt->get_whence(); -} +int64_t bmf_pkt_offset(bmf_BMFAVPacket pkt) { return pkt->get_offset(); } +int64_t bmf_pkt_whence(bmf_BMFAVPacket pkt) { return pkt->get_whence(); } /////////////// TypeInfo ///////////////// -const char* bmf_type_info_name(const bmf_TypeInfo type_info) -{ +const char *bmf_type_info_name(const bmf_TypeInfo type_info) { return type_info->name; } -unsigned long bmf_type_info_index(const bmf_TypeInfo type_info) -{ +unsigned long bmf_type_info_index(const bmf_TypeInfo type_info) { return type_info->index; } //////////////// Packet ////////////////// -void bmf_packet_free(bmf_Packet pkt) -{ - if(pkt){ +void bmf_packet_free(bmf_Packet pkt) { + if (pkt) { delete pkt; } } -int bmf_packet_defined(bmf_Packet pkt) -{ +int bmf_packet_defined(bmf_Packet pkt) { return pkt != nullptr && pkt->operator bool(); } -const bmf_TypeInfo bmf_packet_type_info(const bmf_Packet pkt) -{ +const bmf_TypeInfo bmf_packet_type_info(const bmf_Packet pkt) { return (const bmf_TypeInfo)&pkt->type_info(); } -bmf_Packet bmf_packet_generate_eos_packet() -{ +bmf_Packet bmf_packet_generate_eos_packet() { return new Packet(Packet::generate_eos_packet()); } -bmf_Packet bmf_packet_generate_eof_packet() -{ +bmf_Packet bmf_packet_generate_eof_packet() { return new Packet(Packet::generate_eof_packet()); } -bmf_Packet bmf_packet_generate_empty_packet() -{ - return new Packet(); -} +bmf_Packet bmf_packet_generate_empty_packet() { return new Packet(); } -int64_t bmf_packet_timestamp(const bmf_Packet pkt) -{ - return pkt->timestamp(); -} +int64_t bmf_packet_timestamp(const bmf_Packet pkt) { return pkt->timestamp(); } -void bmf_packet_set_timestamp(bmf_Packet pkt, int64_t timestamp) -{ +void bmf_packet_set_timestamp(bmf_Packet pkt, int64_t timestamp) { return pkt->set_timestamp(timestamp); } -bmf_Packet bmf_packet_from_videoframe(const bmf_VideoFrame vf) -{ - BMF_PROTECT( - return new Packet(*vf); - ) +bmf_Packet bmf_packet_from_videoframe(const bmf_VideoFrame vf) { + BMF_PROTECT(return new Packet(*vf);) return nullptr; } -bmf_VideoFrame bmf_packet_get_videoframe(const bmf_Packet pkt) -{ - BMF_PROTECT( - return new VideoFrame(pkt->get()); - ) +bmf_VideoFrame bmf_packet_get_videoframe(const bmf_Packet pkt) { + BMF_PROTECT(return new VideoFrame(pkt->get());) return nullptr; } -int bmf_packet_is_videoframe(const bmf_Packet pkt) -{ +int bmf_packet_is_videoframe(const bmf_Packet pkt) { return pkt->is(); } -bmf_Packet bmf_packet_from_audioframe(const bmf_AudioFrame af) -{ - BMF_PROTECT( - return new Packet(*af); - ) +bmf_Packet bmf_packet_from_audioframe(const bmf_AudioFrame af) { + BMF_PROTECT(return new Packet(*af);) return nullptr; } -bmf_AudioFrame bmf_packet_get_audioframe(const bmf_Packet pkt) -{ - BMF_PROTECT( - return new AudioFrame(pkt->get()); - ) +bmf_AudioFrame bmf_packet_get_audioframe(const bmf_Packet pkt) { + BMF_PROTECT(return new AudioFrame(pkt->get());) return nullptr; } -int bmf_packet_is_audioframe(const bmf_Packet pkt) -{ +int bmf_packet_is_audioframe(const bmf_Packet pkt) { return pkt->is(); } -bmf_Packet bmf_packet_from_bmfavpacket(const bmf_BMFAVPacket bmf_av_pkt) -{ - BMF_PROTECT( - return new Packet(*bmf_av_pkt); - ) +bmf_Packet bmf_packet_from_bmfavpacket(const bmf_BMFAVPacket bmf_av_pkt) { + BMF_PROTECT(return new Packet(*bmf_av_pkt);) return nullptr; } -bmf_BMFAVPacket bmf_packet_get_bmfavpacket(const bmf_Packet pkt) -{ - BMF_PROTECT( - return new BMFAVPacket(pkt->get()); - ) +bmf_BMFAVPacket bmf_packet_get_bmfavpacket(const bmf_Packet pkt) { + BMF_PROTECT(return new BMFAVPacket(pkt->get());) return nullptr; } -int bmf_packet_is_bmfavpacket(const bmf_Packet pkt) -{ +int bmf_packet_is_bmfavpacket(const bmf_Packet pkt) { return pkt->is(); } - -bmf_Packet bmf_packet_from_json_param(const bmf_JsonParam json) -{ - BMF_PROTECT( - return new Packet(*json); - ) +bmf_Packet bmf_packet_from_json_param(const bmf_JsonParam json) { + BMF_PROTECT(return new Packet(*json);) return nullptr; } -bmf_JsonParam bmf_packet_get_json_param(const bmf_Packet pkt) -{ - BMF_PROTECT( - return new JsonParam(pkt->get()); - ) +bmf_JsonParam bmf_packet_get_json_param(const bmf_Packet pkt) { + BMF_PROTECT(return new JsonParam(pkt->get());) return nullptr; - } -bmf_Packet bmf_packet_from_string_param(char *const str) -{ - BMF_PROTECT( - std::string string_value(str); - return new Packet(string_value); - ) +bmf_Packet bmf_packet_from_string_param(char *const str) { + BMF_PROTECT(std::string string_value(str); return new Packet(string_value);) return nullptr; } -char * const bmf_packet_get_string_param(const bmf_Packet pkt) -{ - BMF_PROTECT( - return bmf_strdup(pkt->get().c_str()); - ) +char *const bmf_packet_get_string_param(const bmf_Packet pkt) { + BMF_PROTECT(return bmf_strdup(pkt->get().c_str());) return nullptr; } -int bmf_packet_is_json_param(const bmf_Packet pkt) -{ +int bmf_packet_is_json_param(const bmf_Packet pkt) { return pkt->is(); } - //////////////////// Task ///////////////////// -bmf_Task bmf_task_make(int node_id, int *istream_ids, int ninputs, int *ostream_ids, int noutputs) -{ - BMF_PROTECT( - std::vector iids(istream_ids, istream_ids + ninputs); - std::vector oids(ostream_ids, ostream_ids + noutputs); - return new Task(node_id, iids, oids); - ) +bmf_Task bmf_task_make(int node_id, int *istream_ids, int ninputs, + int *ostream_ids, int noutputs) { + BMF_PROTECT(std::vector iids(istream_ids, istream_ids + ninputs); + std::vector oids(ostream_ids, ostream_ids + noutputs); + return new Task(node_id, iids, oids);) return nullptr; } -void bmf_task_free(bmf_Task task) -{ - if(task){ +void bmf_task_free(bmf_Task task) { + if (task) { delete task; } } -int bmf_task_fill_input_packet(bmf_Task task, int stream_id, const bmf_Packet packet) -{ - BMF_PROTECT( - return task->fill_input_packet(stream_id, *packet); - ) +int bmf_task_fill_input_packet(bmf_Task task, int stream_id, + const bmf_Packet packet) { + BMF_PROTECT(return task->fill_input_packet(stream_id, *packet);) return 0; } -int bmf_task_fill_output_packet(bmf_Task task, int stream_id, const bmf_Packet packet) -{ - BMF_PROTECT( - return task->fill_output_packet(stream_id, *packet); - ) +int bmf_task_fill_output_packet(bmf_Task task, int stream_id, + const bmf_Packet packet) { + BMF_PROTECT(return task->fill_output_packet(stream_id, *packet);) return 0; } -bmf_Packet bmf_task_pop_packet_from_out_queue(bmf_Task task, int stream_id) -{ - BMF_PROTECT( - Packet pkt; - if(task->pop_packet_from_out_queue(stream_id, pkt)){ - return new Packet(pkt); - } - else{ - throw std::runtime_error( - fmt::format("stream id out of range or no packet to pop from output stream {}", stream_id)); - } - ) +bmf_Packet bmf_task_pop_packet_from_out_queue(bmf_Task task, int stream_id) { + BMF_PROTECT(Packet pkt; if (task->pop_packet_from_out_queue(stream_id, + pkt)) { + return new Packet(pkt); + } else { + throw std::runtime_error(fmt::format( + "stream id out of range or no packet to pop from output stream {}", + stream_id)); + }) return nullptr; } -bmf_Packet bmf_task_pop_packet_from_input_queue(bmf_Task task, int stream_id) -{ - BMF_PROTECT( - Packet pkt; - if(task->pop_packet_from_input_queue(stream_id, pkt)){ - return new Packet(pkt); - } - else{ - throw std::runtime_error( - fmt::format("stream id out of range or no packet to pop from input stream {}", stream_id)); - } - ) +bmf_Packet bmf_task_pop_packet_from_input_queue(bmf_Task task, int stream_id) { + BMF_PROTECT(Packet pkt; if (task->pop_packet_from_input_queue(stream_id, + pkt)) { + return new Packet(pkt); + } else { + throw std::runtime_error(fmt::format( + "stream id out of range or no packet to pop from input stream {}", + stream_id)); + }) return nullptr; } -int64_t bmf_task_timestamp(const bmf_Task task) -{ - return task->timestamp(); -} +int64_t bmf_task_timestamp(const bmf_Task task) { return task->timestamp(); } -void bmf_task_set_timestamp(const bmf_Task task, int64_t timestamp) -{ +void bmf_task_set_timestamp(const bmf_Task task, int64_t timestamp) { return task->set_timestamp(timestamp); } - -int bmf_task_get_input_stream_ids(bmf_Task task, int *ids) -{ - BMF_PROTECT( - auto sids = task->get_input_stream_ids(); - for(size_t i = 0; i < sids.size() && ids; ++i){ - ids[i] = sids[i]; - } - return sids.size(); - ) +int bmf_task_get_input_stream_ids(bmf_Task task, int *ids) { + BMF_PROTECT(auto sids = task->get_input_stream_ids(); + for (size_t i = 0; i < sids.size() && ids; + ++i) { ids[i] = sids[i]; } return sids.size();) return -1; } -int bmf_task_get_output_stream_ids(bmf_Task task, int *ids) -{ - BMF_PROTECT( - auto sids = task->get_output_stream_ids(); - for(size_t i = 0; i < sids.size() && ids; ++i){ - ids[i] = sids[i]; - } - return sids.size(); - ) +int bmf_task_get_output_stream_ids(bmf_Task task, int *ids) { + BMF_PROTECT(auto sids = task->get_output_stream_ids(); + for (size_t i = 0; i < sids.size() && ids; + ++i) { ids[i] = sids[i]; } return sids.size();) return -1; } -int bmf_task_get_node(bmf_Task task) -{ - return task->get_node(); -} - - +int bmf_task_get_node(bmf_Task task) { return task->get_node(); } ////////// ModuleTag /////////// -bmf_ModuleTag bmf_module_tag_make(int64_t tag) -{ - BMF_PROTECT( - return new ModuleTag(static_cast(tag)); - ) +bmf_ModuleTag bmf_module_tag_make(int64_t tag) { + BMF_PROTECT(return new ModuleTag(static_cast(tag));) return nullptr; } -void bmf_module_tag_free(bmf_ModuleTag tag) -{ - if(tag) +void bmf_module_tag_free(bmf_ModuleTag tag) { + if (tag) free(tag); } - ////////// ModuleInfo /////////// -bmf_ModuleInfo bmf_module_info_make() -{ - BMF_PROTECT( - return new ModuleInfo(); - ) +bmf_ModuleInfo bmf_module_info_make() { + BMF_PROTECT(return new ModuleInfo();) return nullptr; } -void bmf_module_info_free(bmf_ModuleInfo info) -{ +void bmf_module_info_free(bmf_ModuleInfo info) { if (info) free(info); } -void bmf_module_info_set_description(bmf_ModuleInfo info, const char *description) -{ +void bmf_module_info_set_description(bmf_ModuleInfo info, + const char *description) { info->module_description = description; } -void bmf_module_info_set_tag(bmf_ModuleInfo info, const bmf_ModuleTag tag) -{ +void bmf_module_info_set_tag(bmf_ModuleInfo info, const bmf_ModuleTag tag) { info->module_tag = *tag; } - //////////////// ModuleFunctor //////////// -bmf_ModuleFunctor bmf_module_functor_make( - const char* name, const char* type, const char* path, - const char *entry, const char* option, - int ninputs, int noutputs, int node_id) -{ - BMF_PROTECT( - auto &M = ModuleManager::instance(); - ModuleInfo info(name, type, entry, path); - auto factory = M.load_module(info); - if(factory == nullptr){ - throw std::runtime_error("Load module " + info.module_name + " failed"); - } - JsonParam json_option; - json_option.parse(option); - auto m = factory->make(node_id, json_option); - return new ModuleFunctor(m, ninputs, noutputs); - ) +bmf_ModuleFunctor bmf_module_functor_make(const char *name, const char *type, + const char *path, const char *entry, + const char *option, int ninputs, + int noutputs, int node_id) { + BMF_PROTECT(auto &M = ModuleManager::instance(); + ModuleInfo info(name, type, entry, path); + auto factory = M.load_module(info); if (factory == nullptr) { + throw std::runtime_error("Load module " + info.module_name + + " failed"); + } JsonParam json_option; + json_option.parse(option); + auto m = factory->make(node_id, json_option); + return new ModuleFunctor(m, ninputs, noutputs);) return nullptr; } -void bmf_module_functor_free(bmf_ModuleFunctor mf) -{ - if(mf){ +void bmf_module_functor_free(bmf_ModuleFunctor mf) { + if (mf) { delete mf; } } -bmf_Packet* bmf_module_functor_call(bmf_ModuleFunctor mf, - const bmf_Packet *inputs, int ninputs, int *noutputs, bool *is_done) -{ - BMF_PROTECT( - std::vector ipkts; - for(int i = 0; i < ninputs; ++i){ - if(inputs[i]){ - ipkts.push_back(*inputs[i]); - } - else{ - ipkts.push_back(Packet()); - } +bmf_Packet *bmf_module_functor_call(bmf_ModuleFunctor mf, + const bmf_Packet *inputs, int ninputs, + int *noutputs, bool *is_done) { + BMF_PROTECT(std::vector ipkts; for (int i = 0; i < ninputs; ++i) { + if (inputs[i]) { + ipkts.push_back(*inputs[i]); + } else { + ipkts.push_back(Packet()); } + } - std::vector opkts; - try{ - opkts = (*mf)(ipkts); - } - catch(ProcessDone &e){ - s_bmf_last_error = e.what(); - *is_done = true; - return nullptr; - } + std::vector + opkts; + try { opkts = (*mf)(ipkts); } catch (ProcessDone &e) { + s_bmf_last_error = e.what(); + *is_done = true; + return nullptr; + } - auto buf = (bmf_Packet*)malloc(opkts.size()*sizeof(bmf_Packet)); - for(size_t i = 0; i < opkts.size(); ++i){ - if(opkts[i]){ - buf[i] = new Packet(opkts[i]); - } - else{ - buf[i] = nullptr; - } - } + auto buf = + (bmf_Packet *)malloc(opkts.size() * sizeof(bmf_Packet)); + for (size_t i = 0; i < opkts.size(); ++i) { + if (opkts[i]) { + buf[i] = new Packet(opkts[i]); + } else { + buf[i] = nullptr; + } + } - if(noutputs){ - *noutputs = opkts.size(); - } - return buf; - ) + if (noutputs) { *noutputs = opkts.size(); } return buf;) return nullptr; } - -int bmf_module_functor_execute(bmf_ModuleFunctor mf, const bmf_Packet *inputs, int ninputs, bool cleanup, bool *is_done) -{ - BMF_PROTECT( - std::vector ipkts; - for(int i = 0; i < ninputs; ++i){ - if(inputs[i]){ - ipkts.push_back(*inputs[i]); - } - else{ - ipkts.push_back(Packet()); - } +int bmf_module_functor_execute(bmf_ModuleFunctor mf, const bmf_Packet *inputs, + int ninputs, bool cleanup, bool *is_done) { + BMF_PROTECT(std::vector ipkts; for (int i = 0; i < ninputs; ++i) { + if (inputs[i]) { + ipkts.push_back(*inputs[i]); + } else { + ipkts.push_back(Packet()); } + } - try{ - mf->execute(ipkts, cleanup); - return 0; - } - catch(ProcessDone &e){ - s_bmf_last_error = e.what(); - *is_done = true; - return -1; - } - ) + try { + mf->execute(ipkts, cleanup); + return 0; + } catch (ProcessDone &e) { + s_bmf_last_error = e.what(); + *is_done = true; + return -1; + }) return -1; - } -bmf_Packet* bmf_module_functor_fetch(bmf_ModuleFunctor mf, int index, int *noutputs, bool *is_done) -{ - BMF_PROTECT( - auto opkts = mf->fetch(index); - - auto buf = (bmf_Packet*)malloc(opkts.size()*sizeof(bmf_Packet)); - for(size_t i = 0; i < opkts.size(); ++i){ - if(opkts[i]){ - buf[i] = new Packet(opkts[i]); - } - else{ - buf[i] = nullptr; - } - } +bmf_Packet *bmf_module_functor_fetch(bmf_ModuleFunctor mf, int index, + int *noutputs, bool *is_done) { + BMF_PROTECT(auto opkts = mf->fetch(index); - if(noutputs){ - *noutputs = opkts.size(); - } - return buf; - ) + auto buf = + (bmf_Packet *)malloc(opkts.size() * sizeof(bmf_Packet)); + for (size_t i = 0; i < opkts.size(); ++i) { + if (opkts[i]) { + buf[i] = new Packet(opkts[i]); + } else { + buf[i] = nullptr; + } + } + + if (noutputs) { *noutputs = opkts.size(); } return buf;) return nullptr; } diff --git a/bmf/sdk/cpp_sdk/src/c_android_vm.cpp b/bmf/sdk/cpp_sdk/src/c_android_vm.cpp index 034baa8d..42d28ffb 100644 --- a/bmf/sdk/cpp_sdk/src/c_android_vm.cpp +++ b/bmf/sdk/cpp_sdk/src/c_android_vm.cpp @@ -10,65 +10,71 @@ const int CreateJavaFuncErr = -4; const int RegisterNativesErr = -5; int init_jvm(JavaVM **p_vm, JNIEnv **p_env) { - - JavaVMOption opt[2]; - opt[0].optionString = "-Xplugin:libopenjdkjvmti.so"; - JavaVMInitArgs args; - args.version = JNI_VERSION_1_6; - args.options = opt; - args.nOptions = 1; // Uptick this to 5, it will pass in the no_sig_chain option - args.ignoreUnrecognized = JNI_FALSE; + JavaVMOption opt[2]; + opt[0].optionString = "-Xplugin:libopenjdkjvmti.so"; - void *libandroid_runtime_dso = dlopen("libnativehelper.so", RTLD_NOW); - void *libandroid_runtime_dso2 = dlopen("libandroid_runtime.so", RTLD_NOW); - void *jni = NULL; - JniInvocation_ctor_t JniInvocation_ctor; - JniInvocation_dtor_t JniInvocation_dtor; - JniInvocation_Init_t JniInvocation_Init; - JniInvocation_ctor = (JniInvocation_ctor_t) dlsym(libandroid_runtime_dso, "_ZN17JniInvocationImplC1Ev"); - JniInvocation_dtor = (JniInvocation_dtor_t) dlsym(libandroid_runtime_dso, "_ZN17JniInvocationImplD1Ev"); - JniInvocation_Init = (JniInvocation_Init_t) dlsym(libandroid_runtime_dso, "_ZN17JniInvocationImpl4InitEPKc"); - if (JniInvocation_ctor && - JniInvocation_dtor && - JniInvocation_Init) { + JavaVMInitArgs args; + args.version = JNI_VERSION_1_6; + args.options = opt; + args.nOptions = + 1; // Uptick this to 5, it will pass in the no_sig_chain option + args.ignoreUnrecognized = JNI_FALSE; + + void *libandroid_runtime_dso = dlopen("libnativehelper.so", RTLD_NOW); + void *libandroid_runtime_dso2 = dlopen("libandroid_runtime.so", RTLD_NOW); + void *jni = NULL; + JniInvocation_ctor_t JniInvocation_ctor; + JniInvocation_dtor_t JniInvocation_dtor; + JniInvocation_Init_t JniInvocation_Init; + JniInvocation_ctor = (JniInvocation_ctor_t)dlsym( + libandroid_runtime_dso, "_ZN17JniInvocationImplC1Ev"); + JniInvocation_dtor = (JniInvocation_dtor_t)dlsym( + libandroid_runtime_dso, "_ZN17JniInvocationImplD1Ev"); + JniInvocation_Init = (JniInvocation_Init_t)dlsym( + libandroid_runtime_dso, "_ZN17JniInvocationImpl4InitEPKc"); + if (JniInvocation_ctor && JniInvocation_dtor && JniInvocation_Init) { jni = calloc(1, 256); if (!jni) { - BMFLOG(BMF_ERROR) << "cannot alloc Memory for JNI Invocation!"; - return JniAllocErr; + BMFLOG(BMF_ERROR) << "cannot alloc Memory for JNI Invocation!"; + return JniAllocErr; } JniInvocation_ctor(jni); JniInvocation_Init(jni, NULL); - } - JNI_CreateJavaVM_t JNI_CreateJavaVM; - JNI_CreateJavaVM = (JNI_CreateJavaVM_t) dlsym(libandroid_runtime_dso, "JNI_CreateJavaVM"); - if (!JNI_CreateJavaVM) { - BMFLOG(BMF_ERROR) << "cannot Find CreateJavaVM Symbol!"; - return NoCreateJavaVMSymbolErr; - } + } + JNI_CreateJavaVM_t JNI_CreateJavaVM; + JNI_CreateJavaVM = + (JNI_CreateJavaVM_t)dlsym(libandroid_runtime_dso, "JNI_CreateJavaVM"); + if (!JNI_CreateJavaVM) { + BMFLOG(BMF_ERROR) << "cannot Find CreateJavaVM Symbol!"; + return NoCreateJavaVMSymbolErr; + } - registerNatives_t registerNatives; - registerNatives = (registerNatives_t) dlsym(libandroid_runtime_dso2, "Java_com_android_internal_util_WithFramework_registerNatives"); - if (!registerNatives) { - // Attempt non-legacy version - registerNatives = (registerNatives_t) dlsym(libandroid_runtime_dso2, "registerFrameworkNatives"); - if(!registerNatives) { - BMFLOG(BMF_ERROR) << "cannot Find RegisterNatives Symbol!"; - return NoRegisterNativesSymbolErr; + registerNatives_t registerNatives; + registerNatives = (registerNatives_t)dlsym( + libandroid_runtime_dso2, + "Java_com_android_internal_util_WithFramework_registerNatives"); + if (!registerNatives) { + // Attempt non-legacy version + registerNatives = (registerNatives_t)dlsym(libandroid_runtime_dso2, + "registerFrameworkNatives"); + if (!registerNatives) { + BMFLOG(BMF_ERROR) << "cannot Find RegisterNatives Symbol!"; + return NoRegisterNativesSymbolErr; + } } - } - if (JNI_CreateJavaVM(&(*p_vm), &(*p_env), &args)) { - BMFLOG(BMF_ERROR) << "Call JNI_CreateJavaVM Func Err!"; - return CreateJavaFuncErr; - } + if (JNI_CreateJavaVM(&(*p_vm), &(*p_env), &args)) { + BMFLOG(BMF_ERROR) << "Call JNI_CreateJavaVM Func Err!"; + return CreateJavaFuncErr; + } - if (registerNatives(*p_env, 0)) { - BMFLOG(BMF_ERROR) << "Call registerNatives Func Err!"; - return RegisterNativesErr; - } + if (registerNatives(*p_env, 0)) { + BMFLOG(BMF_ERROR) << "Call registerNatives Func Err!"; + return RegisterNativesErr; + } - return 0; + return 0; } #endif \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/convert_backend.cpp b/bmf/sdk/cpp_sdk/src/convert_backend.cpp index 64898c40..f45feb08 100644 --- a/bmf/sdk/cpp_sdk/src/convert_backend.cpp +++ b/bmf/sdk/cpp_sdk/src/convert_backend.cpp @@ -7,16 +7,13 @@ namespace bmf_sdk { +static std::unordered_map iConvertors; -static std::unordered_map iConvertors; - -BMF_API void set_convertor(const MediaType &media_type, Convertor* convertor) -{ +BMF_API void set_convertor(const MediaType &media_type, Convertor *convertor) { iConvertors[media_type] = convertor; } -BMF_API Convertor *get_convertor(const MediaType &media_type) -{ +BMF_API Convertor *get_convertor(const MediaType &media_type) { if (iConvertors.find(media_type) == iConvertors.end()) { BMFLOG(BMF_WARNING) << "the media type is not supported by bmf backend"; return NULL; @@ -24,8 +21,7 @@ BMF_API Convertor *get_convertor(const MediaType &media_type) return iConvertors[media_type]; } -BMF_API VideoFrame bmf_convert(VideoFrame& vf, const MediaDesc &dp) -{ +BMF_API VideoFrame bmf_convert(VideoFrame &vf, const MediaDesc &dp) { auto convt = get_convertor(MediaType::kBMFVideoFrame); if (dp.media_type.has_value()) { convt = get_convertor(dp.media_type()); @@ -37,8 +33,8 @@ BMF_API VideoFrame bmf_convert(VideoFrame& vf, const MediaDesc &dp) return device_vf; } -BMF_API VideoFrame bmf_convert_to_videoframe(VideoFrame& vf, const MediaDesc &dp) -{ +BMF_API VideoFrame bmf_convert_to_videoframe(VideoFrame &vf, + const MediaDesc &dp) { VideoFrame frame; auto convt = get_convertor(MediaType::kBMFVideoFrame); if (dp.media_type.has_value()) { @@ -52,15 +48,16 @@ BMF_API VideoFrame bmf_convert_to_videoframe(VideoFrame& vf, const MediaDesc &dp return vf; } -//media type is kBMFVideoFrame +// media type is kBMFVideoFrame bool mt_is_vf(const MediaDesc &dp) { - return !(dp.media_type.has_value() && dp.media_type() != MediaType::kBMFVideoFrame); + return !(dp.media_type.has_value() && + dp.media_type() != MediaType::kBMFVideoFrame); } -BMF_API VideoFrame bmf_convert(VideoFrame& src_vf, const MediaDesc &src_dp, const MediaDesc &dst_dp) -{ +BMF_API VideoFrame bmf_convert(VideoFrame &src_vf, const MediaDesc &src_dp, + const MediaDesc &dst_dp) { VideoFrame frame; - //VideoFrame transfer to other mediatype + // VideoFrame transfer to other mediatype if (mt_is_vf(src_dp)) { frame = bmf_convert(src_vf, dst_dp); @@ -69,27 +66,24 @@ BMF_API VideoFrame bmf_convert(VideoFrame& src_vf, const MediaDesc &src_dp, cons frame = bmf_convert(frame, dst_dp); } else { - BMFLOG(BMF_ERROR) << "can not tranfer from src type: " << static_cast(src_dp.media_type()) - << " to dst type: " << static_cast(dst_dp.media_type()); + BMFLOG(BMF_ERROR) << "can not tranfer from src type: " + << static_cast(src_dp.media_type()) + << " to dst type: " + << static_cast(dst_dp.media_type()); } return frame; } +Convertor::Convertor() {} -Convertor::Convertor() -{ - -} - -VideoFrame Convertor::format_cvt(VideoFrame &src, const MediaDesc &dp) -{ +VideoFrame Convertor::format_cvt(VideoFrame &src, const MediaDesc &dp) { VideoFrame dst = src; // do scale if (dp.width.has_value() || dp.height.has_value()) { int w = 0; int h = 0; - if(!dp.width.has_value()) { + if (!dp.width.has_value()) { h = dp.height(); w = src.width() * h / src.height(); @@ -109,36 +103,33 @@ VideoFrame Convertor::format_cvt(VideoFrame &src, const MediaDesc &dp) if (dp.pixel_format.has_value()) { if (dp.color_space.has_value()) { - dst = bmf_csc_func_with_param(dst, hmp::PixelInfo(dp.pixel_format(), dp.color_space())); + dst = bmf_csc_func_with_param( + dst, hmp::PixelInfo(dp.pixel_format(), dp.color_space())); } else { - dst = bmf_csc_func_with_param(dst, hmp::PixelInfo(dp.pixel_format())); + dst = + bmf_csc_func_with_param(dst, hmp::PixelInfo(dp.pixel_format())); } } return dst; } -VideoFrame Convertor::device_cvt(VideoFrame &src, const MediaDesc &dp) -{ +VideoFrame Convertor::device_cvt(VideoFrame &src, const MediaDesc &dp) { if (dp.device.has_value()) { return src.to(dp.device()); } return src; } -int Convertor::media_cvt(VideoFrame &src, const MediaDesc &dp) -{ - return 0; -} +int Convertor::media_cvt(VideoFrame &src, const MediaDesc &dp) { return 0; } -int Convertor::media_cvt_to_videoframe(VideoFrame &src, const MediaDesc &dp) -{ +int Convertor::media_cvt_to_videoframe(VideoFrame &src, const MediaDesc &dp) { return 0; } -static Convertor* iDefaultBMFConvertor = new Convertor(); +static Convertor *iDefaultBMFConvertor = new Convertor(); BMF_REGISTER_CONVERTOR(MediaType::kBMFVideoFrame, iDefaultBMFConvertor); -} //namespace bmf_sdk +} // namespace bmf_sdk diff --git a/bmf/sdk/cpp_sdk/src/error_define.cpp b/bmf/sdk/cpp_sdk/src/error_define.cpp index 2712d433..58c5acca 100644 --- a/bmf/sdk/cpp_sdk/src/error_define.cpp +++ b/bmf/sdk/cpp_sdk/src/error_define.cpp @@ -19,76 +19,77 @@ const char *BMFErrorStr(int status) { static char buf[256]; switch (status) { - case BMF_StsOk : - return "No Error"; - case BMF_StsBackTrace : - return "Backtrace"; - case BMF_StsError : - return "Unspecified error"; - case BMF_StsInternal : - return "Internal error"; - case BMF_StsNoMem : - return "Insufficient memory"; - case BMF_StsBadArg : - return "Bad argument"; - case BMF_StsNoConv : - return "Iterations do not converge"; - case BMF_StsAutoTrace : - return "Autotrace call"; - case BMF_StsBadSize : - return "Incorrect size of input array"; - case BMF_StsNullPtr : - return "Null pointer"; - case BMF_StsDivByZero : - return "Division by zero occurred"; - case BMF_BadStep : - return "Image step is wrong"; - case BMF_StsInplaceNotSupported : - return "Inplace operation is not supported"; - case BMF_StsObjectNotFound : - return "Requested object was not found"; - case BMF_BadDepth : - return "Input image depth is not supported by function"; - case BMF_StsUnmatchedFormats : - return "Formats of input arguments do not match"; - case BMF_StsUnmatchedSizes : - return "Sizes of input arguments do not match"; - case BMF_StsOutOfRange : - return "One of the arguments\' values is out of range"; - case BMF_StsUnsupportedFormat : - return "Unsupported format or combination of formats"; - case BMF_BadCOI : - return "Input COI is not supported"; - case BMF_BadNumChannels : - return "Bad number of channels"; - case BMF_StsBadFlag : - return "Bad flag (parameter or structure field)"; - case BMF_StsBadPoint : - return "Bad parameter of type BMFPoint"; - case BMF_StsBadMask : - return "Bad type of mask argument"; - case BMF_StsParseError : - return "Parsing error"; - case BMF_StsNotImplemented : - return "The function/feature is not implemented"; - case BMF_StsBadMemBlock : - return "Memory block has been corrupted"; - case BMF_StsAssert : - return "Assertion failed"; - case BMF_GpuNotSupported : - return "No CUDA support"; - case BMF_GpuApiCallError : - return "Gpu API call"; - case BMF_OpenGlNotSupported : - return "No OpenGL support"; - case BMF_OpenGlApiCallError : - return "OpenGL API call"; - case BMF_TranscodeError : - return "BMF Transcode Error"; - case BMF_TranscodeFatalError : - return "BMF Fatal Error During Transcode"; + case BMF_StsOk: + return "No Error"; + case BMF_StsBackTrace: + return "Backtrace"; + case BMF_StsError: + return "Unspecified error"; + case BMF_StsInternal: + return "Internal error"; + case BMF_StsNoMem: + return "Insufficient memory"; + case BMF_StsBadArg: + return "Bad argument"; + case BMF_StsNoConv: + return "Iterations do not converge"; + case BMF_StsAutoTrace: + return "Autotrace call"; + case BMF_StsBadSize: + return "Incorrect size of input array"; + case BMF_StsNullPtr: + return "Null pointer"; + case BMF_StsDivByZero: + return "Division by zero occurred"; + case BMF_BadStep: + return "Image step is wrong"; + case BMF_StsInplaceNotSupported: + return "Inplace operation is not supported"; + case BMF_StsObjectNotFound: + return "Requested object was not found"; + case BMF_BadDepth: + return "Input image depth is not supported by function"; + case BMF_StsUnmatchedFormats: + return "Formats of input arguments do not match"; + case BMF_StsUnmatchedSizes: + return "Sizes of input arguments do not match"; + case BMF_StsOutOfRange: + return "One of the arguments\' values is out of range"; + case BMF_StsUnsupportedFormat: + return "Unsupported format or combination of formats"; + case BMF_BadCOI: + return "Input COI is not supported"; + case BMF_BadNumChannels: + return "Bad number of channels"; + case BMF_StsBadFlag: + return "Bad flag (parameter or structure field)"; + case BMF_StsBadPoint: + return "Bad parameter of type BMFPoint"; + case BMF_StsBadMask: + return "Bad type of mask argument"; + case BMF_StsParseError: + return "Parsing error"; + case BMF_StsNotImplemented: + return "The function/feature is not implemented"; + case BMF_StsBadMemBlock: + return "Memory block has been corrupted"; + case BMF_StsAssert: + return "Assertion failed"; + case BMF_GpuNotSupported: + return "No CUDA support"; + case BMF_GpuApiCallError: + return "Gpu API call"; + case BMF_OpenGlNotSupported: + return "No OpenGL support"; + case BMF_OpenGlApiCallError: + return "OpenGL API call"; + case BMF_TranscodeError: + return "BMF Transcode Error"; + case BMF_TranscodeFatalError: + return "BMF Fatal Error During Transcode"; }; - sprintf(buf, "Unknown %s code %d", status >= 0 ? "status" : "error", status); + sprintf(buf, "Unknown %s code %d", status >= 0 ? "status" : "error", + status); return buf; } diff --git a/bmf/sdk/cpp_sdk/src/exception_factory.cpp b/bmf/sdk/cpp_sdk/src/exception_factory.cpp index fced9d5d..48a4df94 100644 --- a/bmf/sdk/cpp_sdk/src/exception_factory.cpp +++ b/bmf/sdk/cpp_sdk/src/exception_factory.cpp @@ -19,42 +19,44 @@ #include BEGIN_BMF_SDK_NS - std::string format(const char *fmt, ...) { - va_list args; - char buff_size[1024]; - va_start(args, fmt); - vsnprintf(buff_size, 1023, fmt, args); - va_end(args); - std::string result = buff_size; - return result; - } - - Exception::Exception() { - code = 0; - line = 0; - } - - Exception::Exception(int _code, const char *_err, const char *_func, const char *_file, - int _line) - : code(_code), err(_err), func(_func), file(_file), line(_line) { - formatMessage(); - } - - Exception::~Exception() throw() {} +std::string format(const char *fmt, ...) { + va_list args; + char buff_size[1024]; + va_start(args, fmt); + vsnprintf(buff_size, 1023, fmt, args); + va_end(args); + std::string result = buff_size; + return result; +} + +Exception::Exception() { + code = 0; + line = 0; +} + +Exception::Exception(int _code, const char *_err, const char *_func, + const char *_file, int _line) + : code(_code), err(_err), func(_func), file(_file), line(_line) { + formatMessage(); +} + +Exception::~Exception() throw() {} /*! \return the error description and the context as a text string. */ - const char *Exception::what() const throw() { return msg.c_str(); } - - void Exception::formatMessage() { - msg = format("BMF(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", BMF_SDK_VERSION, file.c_str(), line, - code, BMFErrorStr(code), err.c_str(), func.c_str()); - } - - void error(int _code, const char *_err, const char *_func, const char *_file, int _line) { - Exception exception = Exception(_code, _err, _func, _file, _line); - throw exception; - } +const char *Exception::what() const throw() { return msg.c_str(); } + +void Exception::formatMessage() { + msg = format("BMF(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", + BMF_SDK_VERSION, file.c_str(), line, code, BMFErrorStr(code), + err.c_str(), func.c_str()); +} + +void error(int _code, const char *_err, const char *_func, const char *_file, + int _line) { + Exception exception = Exception(_code, _err, _func, _file, _line); + throw exception; +} END_BMF_SDK_NS \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/json_param.cpp b/bmf/sdk/cpp_sdk/src/json_param.cpp index cc2a882f..ce06c0b8 100644 --- a/bmf/sdk/cpp_sdk/src/json_param.cpp +++ b/bmf/sdk/cpp_sdk/src/json_param.cpp @@ -21,134 +21,134 @@ #include #include - BEGIN_BMF_SDK_NS - JsonParam::JsonParam(const JsonParam &json_param) { - json_value_ = json_param.json_value_; - } - - JsonParam::JsonParam(nlohmann::json json_value) { - json_value_ = json_value; - } - - JsonParam::JsonParam(std::string opt_str) { - json_value_ = nlohmann::json::parse(opt_str); - } - - int JsonParam::load(std::string file_name) { - std::ifstream t(file_name); - t >> json_value_; - return 0; - } - - int JsonParam::store(std::string file_name) { - std::ofstream t(file_name); - t << json_value_; - return 0; - } - - int JsonParam::parse(std::string content) { - json_value_ = nlohmann::json::parse(content); +JsonParam::JsonParam(const JsonParam &json_param) { + json_value_ = json_param.json_value_; +} + +JsonParam::JsonParam(nlohmann::json json_value) { json_value_ = json_value; } + +JsonParam::JsonParam(std::string opt_str) { + json_value_ = nlohmann::json::parse(opt_str); +} + +int JsonParam::load(std::string file_name) { + std::ifstream t(file_name); + t >> json_value_; + return 0; +} + +int JsonParam::store(std::string file_name) { + std::ofstream t(file_name); + t << json_value_; + return 0; +} + +int JsonParam::parse(std::string content) { + json_value_ = nlohmann::json::parse(content); + return 0; +} + +bool JsonParam::has_key(std::string name) { + if (json_value_.empty()) { + return false; + } + if (json_value_.count(name) > 0) { + return true; + } else { + return false; + } +} + +int JsonParam::erase(std::string name) { + if (json_value_.empty()) { return 0; } + return json_value_.erase(name); +} - bool JsonParam::has_key(std::string name) { - if (json_value_.empty()) { - return false; - } - if (json_value_.count(name) > 0) { - return true; - } else { - return false; - } +int JsonParam::get_iterated( + std::vector> &group) { + for (const auto &item : json_value_.items()) { + std::string name = item.key(); + std::string val = item.value().is_string() + ? item.value().get() + : item.value().dump(); + group.emplace_back(name, val); } + return 0; +} - int JsonParam::erase(std::string name) { - if (json_value_.empty()) { - return 0; - } - return json_value_.erase(name); - } +void JsonParam::set_value(nlohmann::json &value) { json_value_ = value; } - int JsonParam::get_iterated(std::vector> &group) { - for (const auto &item : json_value_.items()) { - std::string name = item.key(); - std::string val = item.value().is_string() ? item.value().get() : item.value().dump(); - group.emplace_back(name, val); - } +int JsonParam::get_object(std::string name, JsonParam &result) { + if (has_key(name)) { + nlohmann::json value = json_value_[name]; + result.set_value(value); return 0; } + return -1; +} - void JsonParam::set_value(nlohmann::json &value) { - json_value_ = value; - } - - int JsonParam::get_object(std::string name, JsonParam &result) { - if (has_key(name)) { - nlohmann::json value = json_value_[name]; - result.set_value(value); - return 0; - } - return -1; - } - - int JsonParam::get_object_list(std::string name, std::vector &result) { - if (has_key(name)) { - for (auto v:json_value_[name]) { - JsonParam temp_json_param; - temp_json_param.set_value(v); - result.push_back(temp_json_param); - } - return 0; +int JsonParam::get_object_list(std::string name, + std::vector &result) { + if (has_key(name)) { + for (auto v : json_value_[name]) { + JsonParam temp_json_param; + temp_json_param.set_value(v); + result.push_back(temp_json_param); } - return -1; - } - - int JsonParam::get_int(std::string name, int &result) { - result = json_value_[name].get(); - return 0; - } - - int JsonParam::get_long(std::string name, int64_t &result) { - result = json_value_[name].get(); - return 0; - } - - int JsonParam::get_double(std::string name, double &result) { - result = json_value_[name].get(); - return 0; - } - - int JsonParam::get_string(std::string name, std::string &result) { - result = json_value_[name].get(); return 0; } - - int JsonParam::get_int_list(std::string name, std::vector &result) { - for (auto v:json_value_[name]) - result.push_back(v.get()); - return 0; - } - - int JsonParam::get_double_list(std::string name, std::vector &result) { - for (auto v:json_value_[name]) - result.push_back(v.get()); - return 0; - } - - int JsonParam::get_string_list(std::string name, std::vector &result) { - for (auto v:json_value_[name]) - result.push_back(v.get()); - return 0; - } - - std::string JsonParam::dump() const { - std::string result = json_value_.dump(); - return result; - } - - void JsonParam::merge_patch(const JsonParam& json_patch) { - json_value_.merge_patch(json_patch.json_value_); - } + return -1; +} + +int JsonParam::get_int(std::string name, int &result) { + result = json_value_[name].get(); + return 0; +} + +int JsonParam::get_long(std::string name, int64_t &result) { + result = json_value_[name].get(); + return 0; +} + +int JsonParam::get_double(std::string name, double &result) { + result = json_value_[name].get(); + return 0; +} + +int JsonParam::get_string(std::string name, std::string &result) { + result = json_value_[name].get(); + return 0; +} + +int JsonParam::get_int_list(std::string name, std::vector &result) { + for (auto v : json_value_[name]) + result.push_back(v.get()); + return 0; +} + +int JsonParam::get_double_list(std::string name, std::vector &result) { + for (auto v : json_value_[name]) + result.push_back(v.get()); + return 0; +} + +int JsonParam::get_string_list(std::string name, + std::vector &result) { + for (auto v : json_value_[name]) + result.push_back(v.get()); + return 0; +} + +std::string JsonParam::dump() const { + std::string result = json_value_.dump(); + return result; +} + +void JsonParam::merge_patch(const JsonParam &json_patch) { + json_value_.merge_patch(json_patch.json_value_); +} END_BMF_SDK_NS diff --git a/bmf/sdk/cpp_sdk/src/log_buffer.cpp b/bmf/sdk/cpp_sdk/src/log_buffer.cpp index 8b42591d..9b57753b 100644 --- a/bmf/sdk/cpp_sdk/src/log_buffer.cpp +++ b/bmf/sdk/cpp_sdk/src/log_buffer.cpp @@ -18,24 +18,20 @@ #include #include +namespace bmf_sdk { +namespace { -namespace bmf_sdk -{ -namespace -{ - -struct LogBufferPrivate -{ +struct LogBufferPrivate { std::mutex mutex; std::map> log_cb_hooks; int log_cb_idx = 0; bool avlog_cb_set = false; - int avlog_level = 32; //AV_LOG_INFO + int avlog_level = 32; // AV_LOG_INFO std::map log_levels; - void (*av_log_set_callback)(void (*callback)(void *, int, const char *, va_list)) = nullptr; + void (*av_log_set_callback)(void (*callback)(void *, int, const char *, + va_list)) = nullptr; - LogBufferPrivate() - { + LogBufferPrivate() { log_levels = std::map{ {"quiet", -8}, // AV_LOG_QUIET }, {"panic", 0}, // AV_LOG_PANIC }, @@ -49,8 +45,7 @@ struct LogBufferPrivate }; } - static LogBufferPrivate& inst() - { + static LogBufferPrivate &inst() { static LogBufferPrivate p; return p; } @@ -60,8 +55,7 @@ struct LogBufferPrivate } // namespace -void LogBuffer::register_av_log_set_callback(void *func) -{ +void LogBuffer::register_av_log_set_callback(void *func) { std::lock_guard l(self.mutex); self.av_log_set_callback = decltype(self.av_log_set_callback)(func); @@ -70,8 +64,7 @@ void LogBuffer::register_av_log_set_callback(void *func) } } -int LogBuffer::set_cb_hook(std::function cb) -{ +int LogBuffer::set_cb_hook(std::function cb) { std::lock_guard _(self.mutex); if (!self.avlog_cb_set) set_av_log_callback(); @@ -79,14 +72,12 @@ int LogBuffer::set_cb_hook(std::function cb) return self.log_cb_idx++; } -void LogBuffer::remove_cb_hook(int idx) -{ +void LogBuffer::remove_cb_hook(int idx) { std::lock_guard _(self.mutex); self.log_cb_hooks.erase(idx); } -void LogBuffer::lb_callback(void *ptr, int level, const char *fmt, va_list vl) -{ +void LogBuffer::lb_callback(void *ptr, int level, const char *fmt, va_list vl) { std::lock_guard _(self.mutex); if (level > self.avlog_level) return; @@ -98,49 +89,37 @@ void LogBuffer::lb_callback(void *ptr, int level, const char *fmt, va_list vl) cb.second(msg); } -void LogBuffer::set_av_log_callback() -{ - //std::lock_guard _(self.mutex); - if (!self.avlog_cb_set && self.av_log_set_callback != nullptr) - { +void LogBuffer::set_av_log_callback() { + // std::lock_guard _(self.mutex); + if (!self.avlog_cb_set && self.av_log_set_callback != nullptr) { self.av_log_set_callback(lb_callback); self.avlog_cb_set = true; } } -LogBuffer::LogBuffer(std::vector &log_buffer) -{ - hook_idx = set_cb_hook([&log_buffer](std::string const log) -> void - { log_buffer.push_back(log); }); +LogBuffer::LogBuffer(std::vector &log_buffer) { + hook_idx = set_cb_hook([&log_buffer](std::string const log) -> void { + log_buffer.push_back(log); + }); } -LogBuffer::LogBuffer(std::function log_callback, std::string level) -{ +LogBuffer::LogBuffer(std::function log_callback, + std::string level) { if (self.log_levels.count(level) > 0) self.avlog_level = self.log_levels[level]; hook_idx = set_cb_hook(log_callback); } -void LogBuffer::close() -{ - remove_cb_hook(hook_idx); -} - +void LogBuffer::close() { remove_cb_hook(hook_idx); } -bool LogBuffer::avlog_cb_set() -{ +bool LogBuffer::avlog_cb_set() { std::lock_guard _(self.mutex); return self.avlog_cb_set; } - -int LogBuffer::infer_level(const std::string &level_name) -{ +int LogBuffer::infer_level(const std::string &level_name) { return self.log_levels[level_name]; } -LogBuffer::~LogBuffer() -{ - close(); -} -} //namespace bmf_sdk +LogBuffer::~LogBuffer() { close(); } +} // namespace bmf_sdk diff --git a/bmf/sdk/cpp_sdk/src/module_functor.cpp b/bmf/sdk/cpp_sdk/src/module_functor.cpp index 068226fe..f75e05ec 100644 --- a/bmf/sdk/cpp_sdk/src/module_functor.cpp +++ b/bmf/sdk/cpp_sdk/src/module_functor.cpp @@ -2,29 +2,26 @@ #include #include -namespace bmf_sdk{ +namespace bmf_sdk { - -struct ModuleFunctor::Private -{ +struct ModuleFunctor::Private { std::shared_ptr module; std::vector iids; std::vector oids; std::vector eofs; Task task; - ~Private(){ - try{ + ~Private() { + try { module->close(); - } - catch(std::exception &e){ + } catch (std::exception &e) { HMP_WRN("Exception {} when do module close", e.what()); } } }; -ModuleFunctor::ModuleFunctor(const std::shared_ptr &m, int ninputs, int noutputs) -{ +ModuleFunctor::ModuleFunctor(const std::shared_ptr &m, int ninputs, + int noutputs) { HMP_REQUIRE(m, "Null module ptr detected"); HMP_REQUIRE(ninputs >= 0, "Invalid ninputs = {}", ninputs); HMP_REQUIRE(noutputs >= 0, "Invalid noutputs = {}", noutputs); @@ -35,10 +32,10 @@ ModuleFunctor::ModuleFunctor(const std::shared_ptr &m, int ninputs, int self = std::make_shared(); self->module = m; - for(int i = 0; i < ninputs; ++i){ + for (int i = 0; i < ninputs; ++i) { self->iids.push_back(i); } - for(int i = 0; i < noutputs; ++i){ + for (int i = 0; i < noutputs; ++i) { self->oids.push_back(i); self->eofs.push_back(false); } @@ -46,44 +43,42 @@ ModuleFunctor::ModuleFunctor(const std::shared_ptr &m, int ninputs, int self->task = Task(self->module->node_id_, self->iids, self->oids); } +ModuleFunctor::~ModuleFunctor() {} -ModuleFunctor::~ModuleFunctor() -{ -} - - -ModuleFunctor& ModuleFunctor::execute(const std::vector &inputs, bool cleanup) -{ +ModuleFunctor &ModuleFunctor::execute(const std::vector &inputs, + bool cleanup) { HMP_REQUIRE(inputs.size() == self->iids.size(), - "Expect {} inputs, got {} inputs", self->iids.size(), inputs.size()); - for(size_t i = 0; i < self->iids.size(); ++i){ - if(inputs[i]){ + "Expect {} inputs, got {} inputs", self->iids.size(), + inputs.size()); + for (size_t i = 0; i < self->iids.size(); ++i) { + if (inputs[i]) { self->task.fill_input_packet(self->iids[i], inputs[i]); } } // - if(self->task.timestamp() == DONE){ + if (self->task.timestamp() == DONE) { throw ProcessDone("Task done"); } - if(cleanup){ + if (cleanup) { // clear all un-fetch results - for(auto &it : self->task.get_outputs()){ - while(!it.second->empty()){ + for (auto &it : self->task.get_outputs()) { + while (!it.second->empty()) { it.second->pop(); } } } auto rc = self->module->process(self->task); - if(rc != 0){ - throw std::runtime_error(fmt::format("Process failed with error {}", rc)); + if (rc != 0) { + throw std::runtime_error( + fmt::format("Process failed with error {}", rc)); } - if(self->task.timestamp() == DONE){ - for(size_t i = 0; i < self->oids.size(); ++i){ - if(!self->task.output_queue_empty(self->oids[i])){ + if (self->task.timestamp() == DONE) { + for (size_t i = 0; i < self->oids.size(); ++i) { + if (!self->task.output_queue_empty(self->oids[i])) { return *this; } } @@ -95,101 +90,83 @@ ModuleFunctor& ModuleFunctor::execute(const std::vector &inputs, bool cl return *this; } - -std::vector ModuleFunctor::fetch(int idx) -{ +std::vector ModuleFunctor::fetch(int idx) { std::vector pkts; auto oid = self->oids[idx]; - while(!self->task.output_queue_empty(oid)){ + while (!self->task.output_queue_empty(oid)) { Packet pkt; self->task.pop_packet_from_out_queue(oid, pkt); - if(pkt && pkt.timestamp() == BMF_EOF){ + if (pkt && pkt.timestamp() == BMF_EOF) { self->eofs[idx] = true; break; } - + pkts.push_back(pkt); } - if(self->eofs[idx] && pkts.size() == 0){ + if (self->eofs[idx] && pkts.size() == 0) { throw ProcessDone("Receive EOF packet"); } return pkts; } - -std::vector ModuleFunctor::operator()(const std::vector &inputs) -{ +std::vector ModuleFunctor:: +operator()(const std::vector &inputs) { execute(inputs); std::vector outputs; int neof = 0; - for(size_t i = 0; i < self->oids.size(); ++i){ - if(self->eofs[i]){ + for (size_t i = 0; i < self->oids.size(); ++i) { + if (self->eofs[i]) { neof += 1; continue; } // std::vector opkts; - try{ + try { opkts = fetch(i); - } - catch(ProcessDone &e){ + } catch (ProcessDone &e) { self->eofs[i] = true; neof += 1; continue; } // - HMP_REQUIRE(opkts.size() <= 1, - "ModuleFunctor: more than one output packet is not supported, got {}", opkts.size()); - if(opkts.size()){ + HMP_REQUIRE(opkts.size() <= 1, "ModuleFunctor: more than one output " + "packet is not supported, got {}", + opkts.size()); + if (opkts.size()) { outputs.push_back(opkts[0]); - } - else{ + } else { outputs.push_back(Packet()); } } - if(neof == self->oids.size() && self->oids.size() > 0){ + if (neof == self->oids.size() && self->oids.size() > 0) { throw ProcessDone("Receive EOF packet"); } return outputs; } +Module &ModuleFunctor::module() const { return *self->module; } -Module &ModuleFunctor::module() const -{ - return *self->module; -} +int ModuleFunctor::ninputs() const { return self->iids.size(); } +int ModuleFunctor::noutputs() const { return self->oids.size(); } -int ModuleFunctor::ninputs() const -{ - return self->iids.size(); -} - -int ModuleFunctor::noutputs() const -{ - return self->oids.size(); -} - - -ModuleFunctor make_sync_func(const ModuleInfo &info, int32_t ninputs, int32_t noutputs, - const JsonParam &option, int32_t node_id) -{ +ModuleFunctor make_sync_func(const ModuleInfo &info, int32_t ninputs, + int32_t noutputs, const JsonParam &option, + int32_t node_id) { auto &M = ModuleManager::instance(); auto factory = M.load_module(info); - if(factory == nullptr){ + if (factory == nullptr) { throw std::runtime_error("Load module " + info.module_name + " failed"); } return ModuleFunctor(factory->make(node_id, option), ninputs, noutputs); } - - -} //namespace bmf_sdk \ No newline at end of file +} // namespace bmf_sdk \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/module_manager.cpp b/bmf/sdk/cpp_sdk/src/module_manager.cpp index 255de8ec..7037a5fb 100644 --- a/bmf/sdk/cpp_sdk/src/module_manager.cpp +++ b/bmf/sdk/cpp_sdk/src/module_manager.cpp @@ -7,8 +7,7 @@ #include #include - -namespace bmf_sdk{ +namespace bmf_sdk { #ifdef _WIN32 const fs::path s_bmf_repo_root = "C:\\Users\\Public\\bmf_mods"; @@ -17,42 +16,40 @@ const fs::path s_bmf_repo_root = "/usr/local/share/bmf_mods/"; #endif static void string_split(std::vector &tokens, - const std::string &str, const std::string &seps) -{ + const std::string &str, const std::string &seps) { size_t j = 0; - for(size_t i = 0; i < str.size(); ++i){ - if(seps.find(str[i]) != std::string::npos){ - if(i > j){ + for (size_t i = 0; i < str.size(); ++i) { + if (seps.find(str[i]) != std::string::npos) { + if (i > j) { tokens.push_back(str.substr(j, i - j)); } j = i + 1; } } - if(j < str.size()){ + if (j < str.size()) { tokens.push_back(str.substr(j)); } } - -static std::string unique_name(const ModuleInfo &info) -{ - return fmt::format("{}:{}:{}:{}", info.module_type, info.module_path, info.module_entry, info.module_revision); +static std::string unique_name(const ModuleInfo &info) { + return fmt::format("{}:{}:{}:{}", info.module_type, info.module_path, + info.module_entry, info.module_revision); } -class CPPModuleFactory : public ModuleFactoryI -{ +class CPPModuleFactory : public ModuleFactoryI { SharedLibrary lib_; std::string class_name_; std::string sdk_version_; -public: + + public: CPPModuleFactory(const std::string &so, const std::string &class_name) - : class_name_(class_name) - { - if(!so.empty()){ //in-app module have no .so file - lib_ = SharedLibrary(so, SharedLibrary::LAZY | SharedLibrary::GLOBAL); + : class_name_(class_name) { + if (!so.empty()) { // in-app module have no .so file + lib_ = + SharedLibrary(so, SharedLibrary::LAZY | SharedLibrary::GLOBAL); } - if (!ModuleRegistry::Registry().count(class_name)){ + if (!ModuleRegistry::Registry().count(class_name)) { auto msg = "Cannot find specified C++ module class: " + class_name; BMFLOG(BMF_ERROR) << msg << std::endl; throw std::logic_error(msg); @@ -61,16 +58,13 @@ class CPPModuleFactory : public ModuleFactoryI sdk_version_ = ModuleRegistry::GetModuleUsingSDKVersion(class_name_); } - const std::string &sdk_version() const override - { - return sdk_version_; - } + const std::string &sdk_version() const override { return sdk_version_; } - const bool module_info(ModuleInfo &info) const override - { + const bool module_info(ModuleInfo &info) const override { std::string dump_func_symbol = "register_" + class_name_ + "_info"; if (lib_.has(dump_func_symbol)) { - auto dump_func = lib_.symbol(dump_func_symbol); + auto dump_func = + lib_.symbol(dump_func_symbol); dump_func(info); return true; } @@ -78,17 +72,16 @@ class CPPModuleFactory : public ModuleFactoryI } std::shared_ptr make(int32_t node_id = -1, - const JsonParam &json_param = {}) override - { + const JsonParam &json_param = {}) override { BMFLOG(BMF_INFO) << "Constructing c++ module" << std::endl; - auto module = ModuleRegistry::ConstructModule(class_name_, node_id, json_param); + auto module = + ModuleRegistry::ConstructModule(class_name_, node_id, json_param); BMFLOG(BMF_INFO) << "c++ module constructed" << std::endl; return module; } }; -struct ModuleManager::Private -{ +struct ModuleManager::Private { nlohmann::json builtin_config; std::string builtin_root; std::vector repo_roots; @@ -100,19 +93,17 @@ struct ModuleManager::Private std::map> factories; // supported module loaders - std::map> loaders; + std::map> + loaders; }; - -ModuleManager::ModuleManager() -{ +ModuleManager::ModuleManager() { if (false == inited) { init(); } } -bool ModuleManager::set_repo_root(const std::string &path) -{ +bool ModuleManager::set_repo_root(const std::string &path) { std::lock_guard guard(m_mutex); if (fs::exists(path)) { self->repo_roots.push_back(path); @@ -120,36 +111,36 @@ bool ModuleManager::set_repo_root(const std::string &path) return true; } -std::function ModuleManager::get_loader(const std::string module_type) -{ - if(self->loaders.find(module_type) == self->loaders.end()){ +std::function +ModuleManager::get_loader(const std::string module_type) { + if (self->loaders.find(module_type) == self->loaders.end()) { throw std::runtime_error("loader not found."); } return self->loaders.at(module_type); } -const ModuleInfo* ModuleManager::resolve_module_info(const std::string &module_name) -{ +const ModuleInfo * +ModuleManager::resolve_module_info(const std::string &module_name) { std::lock_guard guard(m_mutex); #if defined(__APPLE__) - BMFLOG(BMF_INFO) << "if APPLE, Module Mananger resolve_module_info, return nullptr.\n"; + BMFLOG(BMF_INFO) + << "if APPLE, Module Mananger resolve_module_info, return nullptr.\n"; return nullptr; #endif // check if it has already cached - if(self->known_modules.find(module_name) != self->known_modules.end()){ + if (self->known_modules.find(module_name) != self->known_modules.end()) { return &self->known_modules.at(module_name); } // resolvers std::vector resolvers{ &ModuleManager::resolve_from_builtin, - &ModuleManager::resolve_from_meta - }; + &ModuleManager::resolve_from_meta}; ModuleInfo info; - for(auto resolver : resolvers){ - if((this->*resolver)(module_name, info)){ + for (auto resolver : resolvers) { + if ((this->*resolver)(module_name, info)) { self->known_modules[module_name] = info; return &self->known_modules.at(module_name); } @@ -158,85 +149,81 @@ const ModuleInfo* ModuleManager::resolve_module_info(const std::string &module_n return nullptr; } -const std::map ModuleManager::resolve_all_modules() -{ +const std::map ModuleManager::resolve_all_modules() { std::lock_guard guard(m_mutex); load_all_modules(); return self->known_modules; } - -std::shared_ptr ModuleManager::load_module(const ModuleInfo &info, ModuleInfo *info_out) -{ - return load_module(info.module_name, info.module_type, - info.module_path, info.module_entry, info_out); +std::shared_ptr +ModuleManager::load_module(const ModuleInfo &info, ModuleInfo *info_out) { + return load_module(info.module_name, info.module_type, info.module_path, + info.module_entry, info_out); } - -std::shared_ptr ModuleManager::load_module( - const std::string &module_name, - const std::string &module_type, - const std::string &module_path, - const std::string &module_entry, - ModuleInfo *info) -{ +std::shared_ptr +ModuleManager::load_module(const std::string &module_name, + const std::string &module_type, + const std::string &module_path, + const std::string &module_entry, ModuleInfo *info) { // resolve module info auto tmp_module_info = resolve_module_info(module_name); ModuleInfo module_info; - if(tmp_module_info == nullptr){ - //try load from local + if (tmp_module_info == nullptr) { + // try load from local module_info.module_name = module_name; module_info.module_entry = module_name + "." + module_name; - module_info.module_type = module_type.empty() ? infer_module_type(module_path) : module_type; - if(module_info.module_type == "python"){ + module_info.module_type = + module_type.empty() ? infer_module_type(module_path) : module_type; + if (module_info.module_type == "python") { module_info.module_path = fs::current_path(); } - } - else{ + } else { module_info = *tmp_module_info; } std::lock_guard guard(m_mutex); // merge module info - if(!module_type.empty()){ + if (!module_type.empty()) { module_info.module_type = module_type; } - if(!module_entry.empty()){ + if (!module_entry.empty()) { module_info.module_entry = module_entry; } - if(!module_path.empty()){ + if (!module_path.empty()) { module_info.module_path = module_path; } // check if it is cached auto module_id = unique_name(module_info); - if(self->factories.find(module_id) != self->factories.end()){ + if (self->factories.find(module_id) != self->factories.end()) { return self->factories.at(module_id); } - BMFLOG(BMF_INFO) << "Module info " << module_info.module_name << " " << module_info.module_type << " " - << module_info.module_entry << " " << module_info.module_path << std::endl; + BMFLOG(BMF_INFO) << "Module info " << module_info.module_name << " " + << module_info.module_type << " " + << module_info.module_entry << " " + << module_info.module_path << std::endl; - if(!initialize_loader(module_info.module_type)){ - throw std::invalid_argument( - fmt::format("Module type {} is not supported", module_info.module_type)); + if (!initialize_loader(module_info.module_type)) { + throw std::invalid_argument(fmt::format( + "Module type {} is not supported", module_info.module_type)); } auto &loader = self->loaders.at(module_info.module_type); auto factory = std::shared_ptr(loader(module_info)); - //python/go factory must deconstrut before main() return - if(module_info.module_type == "c++"){ + // python/go factory must deconstrut before main() return + if (module_info.module_type == "c++") { self->factories[module_id] = factory; } - if(info){ + if (info) { *info = module_info; } return factory; } -void ModuleManager::load_all_modules() -{ +void ModuleManager::load_all_modules() { std::vector keys; for (const auto &item : self->builtin_config.items()) { keys.emplace_back(item.key()); @@ -249,12 +236,14 @@ void ModuleManager::load_all_modules() } } - for(auto &root : self->repo_roots) { + for (auto &root : self->repo_roots) { auto r = fs::path(root); std::string module_prefix = (r / "Module_").string(); for (const auto &dir_entry : fs::directory_iterator(r)) { - if (fs::is_directory(dir_entry) and dir_entry.path().string().rfind(module_prefix, 0) == 0) { - std::string module_name = dir_entry.path().string().erase(0, module_prefix.length()); + if (fs::is_directory(dir_entry) and + dir_entry.path().string().rfind(module_prefix, 0) == 0) { + std::string module_name = + dir_entry.path().string().erase(0, module_prefix.length()); if (resolve_from_meta(module_name, info)) { self->known_modules[info.module_name] = info; } @@ -263,15 +252,14 @@ void ModuleManager::load_all_modules() } } - -bool ModuleManager::resolve_from_builtin(const std::string &module_name, ModuleInfo &info) const -{ - if(!self->builtin_config.contains(module_name)){ +bool ModuleManager::resolve_from_builtin(const std::string &module_name, + ModuleInfo &info) const { + if (!self->builtin_config.contains(module_name)) { return false; } auto &vinfo = self->builtin_config[module_name]; - auto vget = [&](const std::string &key, const std::string &def){ + auto vget = [&](const std::string &key, const std::string &def) { return vinfo.contains(key) ? vinfo[key].get() : def; }; auto module_path = vget("path", ""); @@ -279,40 +267,46 @@ bool ModuleManager::resolve_from_builtin(const std::string &module_name, ModuleI auto module_class = vget("class", ""); auto module_revision = vget("revision", ""); std::string module_file; - if (module_type.empty()) - { + if (module_type.empty()) { throw std::invalid_argument("missing type in builtin config"); } - if (module_type != "python" && module_type != "c++" && module_type != "go") - { - throw std::invalid_argument("unsupported builtin module type.(must be c++/python/go"); - } - - if (module_path.empty()) - { - if (module_type == "c++") - { - module_path = (fs::path(self->builtin_root) / std::string(SharedLibrary::default_shared_dir()) / (std::string(SharedLibrary::default_prefix()) + "builtin_modules" + SharedLibrary::default_extension())).string(); - module_file = std::string(SharedLibrary::default_prefix()) + "builtin_modules"; - } - else if (module_type == "python") - { - module_path = fs::path(self->builtin_root) / std::string("python_builtins"); + if (module_type != "python" && module_type != "c++" && + module_type != "go") { + throw std::invalid_argument( + "unsupported builtin module type.(must be c++/python/go"); + } + + if (module_path.empty()) { + if (module_type == "c++") { + module_path = + (fs::path(self->builtin_root) / + std::string(SharedLibrary::default_shared_dir()) / + (std::string(SharedLibrary::default_prefix()) + + "builtin_modules" + SharedLibrary::default_extension())) + .string(); + module_file = std::string(SharedLibrary::default_prefix()) + + "builtin_modules"; + } else if (module_type == "python") { + module_path = + fs::path(self->builtin_root) / std::string("python_builtins"); if (!module_class.empty()) module_file = module_class; else module_file = module_name; - } - else if (module_type == "go") - { - if (!module_class.empty()) - { - module_path = (fs::path(self->builtin_root) / std::string(SharedLibrary::default_shared_dir()) / (module_class + SharedLibrary::default_extension())).string(); + } else if (module_type == "go") { + if (!module_class.empty()) { + module_path = + (fs::path(self->builtin_root) / + std::string(SharedLibrary::default_shared_dir()) / + (module_class + SharedLibrary::default_extension())) + .string(); module_file = module_class; - } - else - { - module_path = (fs::path(self->builtin_root) / std::string(SharedLibrary::default_shared_dir()) / (module_name + SharedLibrary::default_extension())).string(); + } else { + module_path = + (fs::path(self->builtin_root) / + std::string(SharedLibrary::default_shared_dir()) / + (module_name + SharedLibrary::default_extension())) + .string(); module_file = module_name; } } @@ -321,26 +315,27 @@ bool ModuleManager::resolve_from_builtin(const std::string &module_name, ModuleI module_class = module_name; auto module_entry = module_file + "." + module_class; - BMFLOG(BMF_INFO) << module_name << " " << module_type << " " << module_path << " " << module_entry - << std::endl; + BMFLOG(BMF_INFO) << module_name << " " << module_type << " " << module_path + << " " << module_entry << std::endl; - info = ModuleInfo(module_name, module_type, module_entry, module_path, module_revision); + info = ModuleInfo(module_name, module_type, module_entry, module_path, + module_revision); return true; } - -bool ModuleManager::resolve_from_meta(const std::string &module_name, ModuleInfo &info) const -{ - for(auto &r : self->repo_roots) { +bool ModuleManager::resolve_from_meta(const std::string &module_name, + ModuleInfo &info) const { + for (auto &r : self->repo_roots) { std::string meta_path; - auto p = fs::path(r) / fmt::format("Module_{}", module_name) / std::string("meta.info"); - if(fs::exists(p)){ + auto p = fs::path(r) / fmt::format("Module_{}", module_name) / + std::string("meta.info"); + if (fs::exists(p)) { meta_path = p.string(); } else { continue; } - //read meta file + // read meta file JsonParam meta; meta.load(meta_path); @@ -349,61 +344,80 @@ bool ModuleManager::resolve_from_meta(const std::string &module_name, ModuleInfo }; // module_name - if (info.module_name = vget("name", ""); module_name != info.module_name) { - BMFLOG(BMF_WARNING) << "The module_name in meta is: " << info.module_name << ", which is different from the actual module_name:" << module_name << std::endl; + if (info.module_name = vget("name", ""); + module_name != info.module_name) { + BMFLOG(BMF_WARNING) + << "The module_name in meta is: " << info.module_name + << ", which is different from the actual module_name:" + << module_name << std::endl; } // module_type auto meta_module_type = vget("type", ""); - if (meta_module_type == "python" || meta_module_type == "PYTHON" || meta_module_type == "python3") { - info.module_type = "python"; + if (meta_module_type == "python" || meta_module_type == "PYTHON" || + meta_module_type == "python3") { + info.module_type = "python"; } else if (meta_module_type == "binary" || meta_module_type == "c++") { - info.module_type = "c++"; + info.module_type = "c++"; } else if (meta_module_type == "golang" || meta_module_type == "go") { - info.module_type = "go"; + info.module_type = "go"; } else { - throw std::invalid_argument("unsupported module type.(must be c++/python/go"); + throw std::invalid_argument( + "unsupported module type.(must be c++/python/go"); } // module_class, module_entry auto meta_module_class = vget("class", ""); info.module_entry = vget("entry", ""); if (meta_module_class == "" && info.module_entry == "") { - throw std::invalid_argument("one of class or entry should be provided"); + throw std::invalid_argument( + "one of class or entry should be provided"); } if (info.module_entry == "") { if (info.module_type == "c++") { - info.module_entry = std::string(SharedLibrary::default_prefix()) + info.module_name + "." + meta_module_class; - }else if(info.module_type == "python") { + info.module_entry = + std::string(SharedLibrary::default_prefix()) + + info.module_name + "." + meta_module_class; + } else if (info.module_type == "python") { info.module_entry = meta_module_class + "." + meta_module_class; - }else if(info.module_type == "go") { + } else if (info.module_type == "go") { info.module_entry = info.module_name + "." + meta_module_class; } - //BMFLOG(BMF_WARNING) << "Can not find entry from meta file, using default: " << info.module_entry << std::endl; + // BMFLOG(BMF_WARNING) << "Can not find entry from meta file, using + // default: " << info.module_entry << std::endl; } std::vector entry_path; string_split(entry_path, info.module_entry, ".:"); - if (entry_path.size() < 2){ - BMF_Error_(BMF_StsBadArg, "module_entry: ", info.module_entry.c_str(), "is not satisfy"); + if (entry_path.size() < 2) { + BMF_Error_(BMF_StsBadArg, "module_entry: ", + info.module_entry.c_str(), "is not satisfy"); } - if (auto entry_module_class = entry_path[entry_path.size() - 1]; meta_module_class == "") { + if (auto entry_module_class = entry_path[entry_path.size() - 1]; + meta_module_class == "") { meta_module_class = entry_module_class; } else if (meta_module_class != entry_module_class) { - BMFLOG(BMF_WARNING) << "The module class in meta is: " << meta_module_class << ", which is different from the entry field:" << entry_module_class << std::endl; + BMFLOG(BMF_WARNING) + << "The module class in meta is: " << meta_module_class + << ", which is different from the entry field:" + << entry_module_class << std::endl; } entry_path.pop_back(); - info.module_entry = entry_path[entry_path.size() - 1] + "." + meta_module_class; + info.module_entry = + entry_path[entry_path.size() - 1] + "." + meta_module_class; auto entry_module_path = fs::path(meta_path).parent_path(); - for(auto &e : entry_path){ + for (auto &e : entry_path) { entry_module_path /= e; } // module_path - if (info.module_path = vget("path", ""); info.module_path.empty()) { // builtin modules + if (info.module_path = vget("path", ""); + info.module_path.empty()) { // builtin modules if (info.module_type == "c++" || info.module_type == "go") { - info.module_path = entry_module_path.parent_path() / - entry_module_path.filename().replace_extension(SharedLibrary::default_extension()); - }else if(info.module_type == "python") { + info.module_path = + entry_module_path.parent_path() / + entry_module_path.filename().replace_extension( + SharedLibrary::default_extension()); + } else if (info.module_type == "python") { info.module_path = entry_module_path.parent_path(); } } @@ -412,43 +426,50 @@ bool ModuleManager::resolve_from_meta(const std::string &module_name, ModuleInfo // XXX: other attributes, such as envs... - BMFLOG(BMF_INFO) << info.module_name << " " << info.module_type << " " << info.module_path << " " << info.module_entry + BMFLOG(BMF_INFO) << info.module_name << " " << info.module_type << " " + << info.module_path << " " << info.module_entry << std::endl; return true; } return false; } - -bool ModuleManager::initialize_loader(const std::string &module_type) -{ - if(self->loaders.find(module_type) != self->loaders.end()){ +bool ModuleManager::initialize_loader(const std::string &module_type) { + if (self->loaders.find(module_type) != self->loaders.end()) { return true; } - if(module_type == "c++"){ - self->loaders["c++"] = [&](const ModuleInfo &info) -> ModuleFactoryI*{ + if (module_type == "c++") { + self->loaders["c++"] = [&](const ModuleInfo &info) -> ModuleFactoryI * { std::string _, class_name; std::tie(_, class_name) = parse_entry(info.module_entry, false); return new CPPModuleFactory(info.module_path, class_name); }; return true; } - if(module_type == "python"){ - auto lib_name = std::string(SharedLibrary::default_prefix()) + "bmf_py_loader" + SharedLibrary::default_extension(); - auto loader_path = fs::path(SharedLibrary::this_line_location()).parent_path() / lib_name; - auto lib = std::make_shared(loader_path, - SharedLibrary::LAZY | SharedLibrary::GLOBAL); - - self->loaders["python"] = [=](const ModuleInfo &info) -> ModuleFactoryI*{ + if (module_type == "python") { + auto lib_name = std::string(SharedLibrary::default_prefix()) + + "bmf_py_loader" + SharedLibrary::default_extension(); + auto loader_path = + fs::path(SharedLibrary::this_line_location()).parent_path() / + lib_name; + auto lib = std::make_shared( + loader_path, SharedLibrary::LAZY | SharedLibrary::GLOBAL); + + self->loaders["python"] = + [=](const ModuleInfo &info) -> ModuleFactoryI * { std::string module_file, class_name; - std::tie(module_file, class_name) = parse_entry(info.module_entry, false); - auto import_func = lib->symbol( - "bmf_import_py_module"); + std::tie(module_file, class_name) = + parse_entry(info.module_entry, false); + auto import_func = + lib->symbol( + "bmf_import_py_module"); char *errstr = nullptr; - auto mptr = import_func(info.module_path.c_str(), - module_file.c_str(), class_name.c_str(), &errstr); - if(errstr != nullptr){ + auto mptr = + import_func(info.module_path.c_str(), module_file.c_str(), + class_name.c_str(), &errstr); + if (errstr != nullptr) { auto err = std::string(errstr); free(errstr); throw std::runtime_error(err); @@ -456,18 +477,24 @@ bool ModuleManager::initialize_loader(const std::string &module_type) return mptr; }; return true; - } - else if(module_type == "go"){ - auto lib_name = std::string(SharedLibrary::default_prefix()) + "bmf_go_loader" + SharedLibrary::default_extension(); - auto loader_path = fs::path(SharedLibrary::this_line_location()).parent_path() / lib_name; - auto lib = std::make_shared(loader_path, - SharedLibrary::LAZY | SharedLibrary::GLOBAL); - - self->loaders["go"] = [=](const ModuleInfo &info) -> ModuleFactoryI*{ - auto import_func = lib->symbol("bmf_import_go_module"); + } else if (module_type == "go") { + auto lib_name = std::string(SharedLibrary::default_prefix()) + + "bmf_go_loader" + SharedLibrary::default_extension(); + auto loader_path = + fs::path(SharedLibrary::this_line_location()).parent_path() / + lib_name; + auto lib = std::make_shared( + loader_path, SharedLibrary::LAZY | SharedLibrary::GLOBAL); + + self->loaders["go"] = [=](const ModuleInfo &info) -> ModuleFactoryI * { + auto import_func = + lib->symbol( + "bmf_import_go_module"); char *errstr = nullptr; - auto mptr = import_func(info.module_path.c_str(), info.module_name.c_str(), &errstr); - if(errstr != nullptr){ + auto mptr = import_func(info.module_path.c_str(), + info.module_name.c_str(), &errstr); + if (errstr != nullptr) { auto err = std::string(errstr); free(errstr); throw std::runtime_error(err); @@ -475,89 +502,91 @@ bool ModuleManager::initialize_loader(const std::string &module_type) return mptr; }; return true; - } - else{ + } else { return false; } } - -std::tuple ModuleManager::parse_entry(const std::string &module_entry, bool file_system) -{ +std::tuple +ModuleManager::parse_entry(const std::string &module_entry, bool file_system) { std::vector entry_path; string_split(entry_path, module_entry, ".:"); - if (entry_path.size() < 2){ - BMF_Error_(BMF_StsBadArg, "module_entry: ", module_entry.c_str(), "is not satisfy"); + if (entry_path.size() < 2) { + BMF_Error_(BMF_StsBadArg, "module_entry: ", module_entry.c_str(), + "is not satisfy"); } auto sep = file_system ? std::string{fs::path::preferred_separator} : "."; auto module_file = entry_path[0]; - for (int i = 1; i < entry_path.size() - 1; i++) - { + for (int i = 1; i < entry_path.size() - 1; i++) { module_file += sep + entry_path[i]; } auto module_class = entry_path[entry_path.size() - 1]; return std::make_tuple(module_file, module_class); } - -std::string ModuleManager::infer_module_type(const std::string &path) -{ - if (fs::path(path).extension() == SharedLibrary::default_extension()){ - if (SharedLibrary(path).raw_symbol("ConstructorRegister")){ //FIXME: +std::string ModuleManager::infer_module_type(const std::string &path) { + if (fs::path(path).extension() == SharedLibrary::default_extension()) { + if (SharedLibrary(path).raw_symbol("ConstructorRegister")) { // FIXME: return "go"; - } - else{ + } else { return "c++"; } } return "python"; } -void ModuleManager::init() -{ +void ModuleManager::init() { { std::lock_guard guard(m_mutex); self = std::make_unique(); - //locate BUILTIN_CONFIG.json + // locate BUILTIN_CONFIG.json std::vector roots; - auto lib_path = fs::path(SharedLibrary::this_line_location()).parent_path(); + auto lib_path = + fs::path(SharedLibrary::this_line_location()).parent_path(); roots.push_back(lib_path.string()); roots.push_back(lib_path.parent_path().string()); roots.push_back(fs::current_path().string()); auto fn = std::string("BUILTIN_CONFIG.json"); - for(auto &p : roots){ + for (auto &p : roots) { auto fp = fs::path(p) / fn; - if(fs::exists(fp) && !fs::is_directory(fp)){ + if (fs::exists(fp) && !fs::is_directory(fp)) { self->builtin_root = p; break; } } fn = (fs::path(self->builtin_root) / fn).string(); - if(fs::exists(fn)){ + if (fs::exists(fn)) { std::ifstream fp(fn); fp >> self->builtin_config; } else { BMFLOG(BMF_ERROR) << "Module Mananger can not find:" << fn << "\n"; } - inited = true; // initialize cpp/py/go loader lazily } - set_repo_root(fs::path(SharedLibrary::this_line_location()).parent_path().parent_path() / "cpp_modules"); - set_repo_root(fs::path(SharedLibrary::this_line_location()).parent_path().parent_path() / "python_modules"); - set_repo_root(fs::path(SharedLibrary::this_line_location()).parent_path().parent_path() / "go_modules"); + set_repo_root(fs::path(SharedLibrary::this_line_location()) + .parent_path() + .parent_path() / + "cpp_modules"); + set_repo_root(fs::path(SharedLibrary::this_line_location()) + .parent_path() + .parent_path() / + "python_modules"); + set_repo_root(fs::path(SharedLibrary::this_line_location()) + .parent_path() + .parent_path() / + "go_modules"); set_repo_root(s_bmf_repo_root.string()); set_repo_root(fs::current_path().string()); } -ModuleManager &ModuleManager::instance() -{ +ModuleManager &ModuleManager::instance() { static ModuleManager m; - return m; + return m; } -} //namespace bmf_sdk +} // namespace bmf_sdk diff --git a/bmf/sdk/cpp_sdk/src/module_registry.cpp b/bmf/sdk/cpp_sdk/src/module_registry.cpp index 61f37974..b0cbbb19 100644 --- a/bmf/sdk/cpp_sdk/src/module_registry.cpp +++ b/bmf/sdk/cpp_sdk/src/module_registry.cpp @@ -17,35 +17,40 @@ #include BEGIN_BMF_SDK_NS - ModuleRegistry::ConstructorRegistry &ModuleRegistry::Registry() { - static ConstructorRegistry *real_registry = new ConstructorRegistry(); - return *real_registry; - } +ModuleRegistry::ConstructorRegistry &ModuleRegistry::Registry() { + static ConstructorRegistry *real_registry = new ConstructorRegistry(); + return *real_registry; +} - void ModuleRegistry::AddConstructor(std::string const &module_name, std::string const &sdk_version, - Constructor constructor) { - ConstructorRegistry ®istry = Registry(); - registry[module_name] = {sdk_version, constructor}; - } +void ModuleRegistry::AddConstructor(std::string const &module_name, + std::string const &sdk_version, + Constructor constructor) { + ConstructorRegistry ®istry = Registry(); + registry[module_name] = {sdk_version, constructor}; +} - std::shared_ptr - ModuleRegistry::ConstructModule(std::string const &module_name, int node_id, JsonParam json_param) { - ConstructorRegistry ®istry = Registry(); - return registry[module_name].second(node_id, json_param); - } +std::shared_ptr +ModuleRegistry::ConstructModule(std::string const &module_name, int node_id, + JsonParam json_param) { + ConstructorRegistry ®istry = Registry(); + return registry[module_name].second(node_id, json_param); +} - std::string ModuleRegistry::GetModuleUsingSDKVersion(const std::string &module_name) { - ConstructorRegistry ®istry = Registry(); - return registry[module_name].first; - } +std::string +ModuleRegistry::GetModuleUsingSDKVersion(const std::string &module_name) { + ConstructorRegistry ®istry = Registry(); + return registry[module_name].first; +} - ModuleRegister::ModuleRegister(std::string const &module_name, std::string const &sdk_version, - std::shared_ptr (*constructor)(int node_id, JsonParam json_param)) { - ModuleRegistry::AddConstructor(module_name, sdk_version, constructor); - } +ModuleRegister::ModuleRegister( + std::string const &module_name, std::string const &sdk_version, + std::shared_ptr (*constructor)(int node_id, JsonParam json_param)) { + ModuleRegistry::AddConstructor(module_name, sdk_version, constructor); +} - ModuleRegister::ModuleRegister(const std::string &module_name, - std::shared_ptr (*constructor)(int, JsonParam)) { - ModuleRegistry::AddConstructor(module_name, "V0.0.1", constructor); - } +ModuleRegister::ModuleRegister( + const std::string &module_name, + std::shared_ptr (*constructor)(int, JsonParam)) { + ModuleRegistry::AddConstructor(module_name, "V0.0.1", constructor); +} END_BMF_SDK_NS \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/module_tag.cpp b/bmf/sdk/cpp_sdk/src/module_tag.cpp index 15e70cc2..68579271 100644 --- a/bmf/sdk/cpp_sdk/src/module_tag.cpp +++ b/bmf/sdk/cpp_sdk/src/module_tag.cpp @@ -7,45 +7,46 @@ namespace bmf_sdk { ModuleTag operator|(ModuleTag tag1, ModuleTag tag2) { - if (tag1 == ModuleTag::BMF_TAG_NONE || tag1 == ModuleTag::BMF_TAG_DONE || - tag2 == ModuleTag::BMF_TAG_NONE || tag2 == ModuleTag::BMF_TAG_DONE) - throw std::runtime_error("invalid value"); - return static_cast(static_cast(tag1) | - static_cast(tag2)); + if (tag1 == ModuleTag::BMF_TAG_NONE || tag1 == ModuleTag::BMF_TAG_DONE || + tag2 == ModuleTag::BMF_TAG_NONE || tag2 == ModuleTag::BMF_TAG_DONE) + throw std::runtime_error("invalid value"); + return static_cast(static_cast(tag1) | + static_cast(tag2)); } ModuleTag operator|=(ModuleTag &tag1, ModuleTag tag2) { - if (tag1 == ModuleTag::BMF_TAG_NONE || tag1 == ModuleTag::BMF_TAG_DONE || - tag2 == ModuleTag::BMF_TAG_NONE || tag2 == ModuleTag::BMF_TAG_DONE) - throw std::runtime_error("invalid value"); - tag1 = static_cast(static_cast(tag1) | - static_cast(tag2)); - return tag1; + if (tag1 == ModuleTag::BMF_TAG_NONE || tag1 == ModuleTag::BMF_TAG_DONE || + tag2 == ModuleTag::BMF_TAG_NONE || tag2 == ModuleTag::BMF_TAG_DONE) + throw std::runtime_error("invalid value"); + tag1 = static_cast(static_cast(tag1) | + static_cast(tag2)); + return tag1; } std::ostream &operator<<(std::ostream &os, const ModuleTag &tag) { - static std::map m = { - {ModuleTag::BMF_TAG_DECODER, "BMF_TAG_DECODER"}, - {ModuleTag::BMF_TAG_ENCODER, "BMF_TAG_ENCODER"}, - {ModuleTag::BMF_TAG_FILTER, "BMF_TAG_FILTER"}, - {ModuleTag::BMF_TAG_MUXER, "BMF_TAG_MUXER"}, - {ModuleTag::BMF_TAG_DEMUXER, "BMF_TAG_DEMUXER"}, - {ModuleTag::BMF_TAG_IMAGE_PROCESSOR, "BMF_TAG_IMAGE_PROCESSOR"}, - {ModuleTag::BMF_TAG_AUDIO_PROCESSOR, "BMF_TAG_AUDIO_PROCESSOR"}, - {ModuleTag::BMF_TAG_VIDEO_PROCESSOR, "BMF_TAG_VIDEO_PROCESSOR"}, - {ModuleTag::BMF_TAG_DEVICE_HWACCEL, "BMF_TAG_DEVICE_HWACCEL"}, - {ModuleTag::BMF_TAG_AI, "BMF_TAG_AI"}, - {ModuleTag::BMF_TAG_UTILS, "BMF_TAG_UTILS"}, - }; - std::string str; - for (const auto &[k, v] : m) { - if (static_cast(tag) & static_cast(k)) { - str += (str.size() == 0 ? "" : "|"); - str += v; + static std::map m = { + {ModuleTag::BMF_TAG_DECODER, "BMF_TAG_DECODER"}, + {ModuleTag::BMF_TAG_ENCODER, "BMF_TAG_ENCODER"}, + {ModuleTag::BMF_TAG_FILTER, "BMF_TAG_FILTER"}, + {ModuleTag::BMF_TAG_MUXER, "BMF_TAG_MUXER"}, + {ModuleTag::BMF_TAG_DEMUXER, "BMF_TAG_DEMUXER"}, + {ModuleTag::BMF_TAG_IMAGE_PROCESSOR, "BMF_TAG_IMAGE_PROCESSOR"}, + {ModuleTag::BMF_TAG_AUDIO_PROCESSOR, "BMF_TAG_AUDIO_PROCESSOR"}, + {ModuleTag::BMF_TAG_VIDEO_PROCESSOR, "BMF_TAG_VIDEO_PROCESSOR"}, + {ModuleTag::BMF_TAG_DEVICE_HWACCEL, "BMF_TAG_DEVICE_HWACCEL"}, + {ModuleTag::BMF_TAG_AI, "BMF_TAG_AI"}, + {ModuleTag::BMF_TAG_UTILS, "BMF_TAG_UTILS"}, + }; + std::string str; + for (const auto & [ k, v ] : m) { + if (static_cast(tag) & + static_cast(k)) { + str += (str.size() == 0 ? "" : "|"); + str += v; + } } - } - str = (str.size() == 0 ? "BMF_TAG_NONE" : str); - return os << str; + str = (str.size() == 0 ? "BMF_TAG_NONE" : str); + return os << str; } } // namespace bmf_sdk diff --git a/bmf/sdk/cpp_sdk/src/packet.cpp b/bmf/sdk/cpp_sdk/src/packet.cpp index 8ec8f749..d69fa28c 100644 --- a/bmf/sdk/cpp_sdk/src/packet.cpp +++ b/bmf/sdk/cpp_sdk/src/packet.cpp @@ -1,88 +1,64 @@ #include -namespace bmf_sdk{ +namespace bmf_sdk { -PacketImpl::PacketImpl(void *obj, const TypeInfo *type_info, - const std::function &del) - : obj_(obj), type_info_(type_info), del_(del) -{ +PacketImpl::PacketImpl(void *obj, const TypeInfo *type_info, + const std::function &del) + : obj_(obj), type_info_(type_info), del_(del) { HMP_REQUIRE(obj_, "PacketImpl: null object detected"); HMP_REQUIRE(type_info_, "PacketImpl: null type_info detected"); } - -PacketImpl::~PacketImpl() -{ - if(del_){ +PacketImpl::~PacketImpl() { + if (del_) { del_(obj_); } } +PacketImpl *Packet::unsafe_self() { return self.get(); } -PacketImpl* Packet::unsafe_self() -{ - return self.get(); -} - -const PacketImpl* Packet::unsafe_self() const -{ - return self.get(); -} - +const PacketImpl *Packet::unsafe_self() const { return self.get(); } -const TypeInfo& Packet::type_info() const -{ +const TypeInfo &Packet::type_info() const { HMP_REQUIRE(*this, "Packet: null packet"); return self->type_info(); } - // -void Packet::set_timestamp(int64_t timestamp) -{ +// +void Packet::set_timestamp(int64_t timestamp) { HMP_REQUIRE(*this, "Packet: null packet"); self->set_timestamp(timestamp); } - // -void Packet::set_time(double time) -{ +// +void Packet::set_time(double time) { HMP_REQUIRE(*this, "Packet: null packet"); self->set_time(time); } -int64_t Packet::timestamp() const -{ +int64_t Packet::timestamp() const { HMP_REQUIRE(*this, "Packet: null packet"); return self->timestamp(); } -double Packet::time() const -{ +double Packet::time() const { HMP_REQUIRE(*this, "Packet: null packet"); return self->time(); } - -Packet Packet::generate_eos_packet() -{ +Packet Packet::generate_eos_packet() { Packet pkt = Packet(0); pkt.set_timestamp(EOS); return pkt; } -Packet Packet::generate_eof_packet() -{ +Packet Packet::generate_eof_packet() { Packet pkt = Packet(0); pkt.set_timestamp(BMF_EOF); return pkt; } - - -std::size_t string_hash(const char *str) -{ +std::size_t string_hash(const char *str) { return std::hash{}(str); } - -} //namespace bmf_sdk - +} // namespace bmf_sdk diff --git a/bmf/sdk/cpp_sdk/src/sdk_interface.cpp b/bmf/sdk/cpp_sdk/src/sdk_interface.cpp index 4ce60142..6ea46272 100644 --- a/bmf/sdk/cpp_sdk/src/sdk_interface.cpp +++ b/bmf/sdk/cpp_sdk/src/sdk_interface.cpp @@ -6,118 +6,90 @@ #include #endif -namespace bmf_sdk{ +namespace bmf_sdk { - -void OpaqueDataSet::set_private_data(int key, const OpaqueData &data) -{ - HMP_REQUIRE(key < OpaqueDataKey::kNumKeys, - "Private key {} is out of range, need less than {}", key, OpaqueDataKey::kNumKeys); +void OpaqueDataSet::set_private_data(int key, const OpaqueData &data) { + HMP_REQUIRE(key < OpaqueDataKey::kNumKeys, + "Private key {} is out of range, need less than {}", key, + OpaqueDataKey::kNumKeys); opaque_set_[key] = data; } -const OpaqueData& OpaqueDataSet::private_data(int key) const -{ - HMP_REQUIRE(key < OpaqueDataKey::kNumKeys, - "Private key {} is out of range, need less than {}", key, OpaqueDataKey::kNumKeys); +const OpaqueData &OpaqueDataSet::private_data(int key) const { + HMP_REQUIRE(key < OpaqueDataKey::kNumKeys, + "Private key {} is out of range, need less than {}", key, + OpaqueDataKey::kNumKeys); return opaque_set_[key]; } - -void OpaqueDataSet::private_merge(const OpaqueDataSet &from) -{ - for(int i = 0; i < OpaqueDataKey::kNumKeys; ++i){ - if(from.opaque_set_[i]){ +void OpaqueDataSet::private_merge(const OpaqueDataSet &from) { + for (int i = 0; i < OpaqueDataKey::kNumKeys; ++i) { + if (from.opaque_set_[i]) { opaque_set_[i] = from.opaque_set_[i]; } } } - -OpaqueDataSet& OpaqueDataSet::copy_props(const OpaqueDataSet& from) -{ +OpaqueDataSet &OpaqueDataSet::copy_props(const OpaqueDataSet &from) { private_merge(from); return *this; } - -SequenceData& SequenceData::copy_props(const SequenceData& from) -{ +SequenceData &SequenceData::copy_props(const SequenceData &from) { set_time_base(from.time_base()); set_pts(from.pts()); return *this; } - -struct Future::Private{ +struct Future::Private { uint64_t stream = 0; #ifdef HMP_ENABLE_CUDA hmp::cuda::Event event; #endif }; +Future::Future() { self = std::make_shared(); } -Future::Future() -{ - self = std::make_shared(); -} - +void Future::set_stream(uint64_t stream) { self->stream = stream; } -void Future::set_stream(uint64_t stream) -{ - self->stream = stream; -} +uint64_t Future::stream() const { return self->stream; } - -uint64_t Future::stream() const -{ - return self->stream; -} - -bool Future::ready() const -{ +bool Future::ready() const { auto d = device(); - if(d.type() == kCUDA || d.type() == kCPU){ + if (d.type() == kCUDA || d.type() == kCPU) { #ifdef HMP_ENABLE_CUDA return !self->event.is_created() || self->event.query(); #else return true; #endif - } - else{ - HMP_REQUIRE(false, - "Future::ready: Not Implemented for device {}", d); + } else { + HMP_REQUIRE(false, "Future::ready: Not Implemented for device {}", d); } } - -void Future::record(bool use_current) -{ +void Future::record(bool use_current) { auto d = device(); #ifdef HMP_ENABLE_CUDA - if(d.type() == kCUDA || d.type() == kCPU){ + if (d.type() == kCUDA || d.type() == kCPU) { DeviceGuard guard(d); auto stream = use_current ? hmp::current_stream(kCUDA) : hmp::cuda::wrap_stream(self->stream, false); self->event.record(stream); - if(use_current){ + if (use_current) { self->stream = stream->handle(); } } #endif } - -void Future::synchronize() -{ +void Future::synchronize() { auto d = device(); #ifdef HMP_ENABLE_CUDA - if(d.type() == kCUDA || d.type() == kCPU){ - if(self->event.is_created()){ + if (d.type() == kCUDA || d.type() == kCPU) { + if (self->event.is_created()) { self->event.synchronize(); - } - else{ + } else { DeviceGuard guard(d); auto stream = hmp::cuda::wrap_stream(self->stream, false); stream.synchronize(); @@ -126,10 +98,9 @@ void Future::synchronize() #endif } -Future& Future::copy_props(const Future& from) -{ +Future &Future::copy_props(const Future &from) { set_stream(from.stream()); return *this; } -} //namespace bmf_sdk \ No newline at end of file +} // namespace bmf_sdk \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/src/task.cpp b/bmf/sdk/cpp_sdk/src/task.cpp index bd57eb98..d9bbaef3 100644 --- a/bmf/sdk/cpp_sdk/src/task.cpp +++ b/bmf/sdk/cpp_sdk/src/task.cpp @@ -20,159 +20,145 @@ #include BEGIN_BMF_SDK_NS - Task::Task(int node_id, std::vector input_stream_id_list, std::vector output_stream_id_list) { - init(node_id, input_stream_id_list, output_stream_id_list); - } - - Task::Task(const Task &rhs) { - this->node_id_ = rhs.node_id_; - this->timestamp_ = rhs.timestamp_; - this->inputs_queue_ = rhs.inputs_queue_; - this->outputs_queue_ = rhs.outputs_queue_; - } - - Task::Task(Task &&rhs) : Task() { - swap(*this, rhs); - } - - Task &Task::operator=(Task rhs) { - swap(*this, rhs); - return *this; - } - - BMF_API void swap(Task &target, Task &source) { - using std::swap; - - std::swap(target.node_id_, source.node_id_); - std::swap(target.timestamp_, source.timestamp_); - auto itp = std::move(source.inputs_queue_); - source.inputs_queue_ = std::move(target.inputs_queue_); - target.inputs_queue_ = std::move(itp); - auto otp = std::move(source.outputs_queue_); - source.outputs_queue_ = std::move(target.outputs_queue_); - target.outputs_queue_ = std::move(otp); - } - - void Task::init(int node_id, std::vector input_stream_id_list, std::vector output_stream_id_list) { - node_id_ = node_id; - timestamp_ = 0; - for (int i = 0; i < input_stream_id_list.size(); i++) { - std::shared_ptr> - tmp_queue = std::make_shared >(); - inputs_queue_.insert( - std::pair>>( - input_stream_id_list[i], tmp_queue) - ); - } - for (int i = 0; i < output_stream_id_list.size(); i++) { - std::shared_ptr> - tmp_queue = std::make_shared >(); - outputs_queue_.insert( - std::pair>>( - output_stream_id_list[i], tmp_queue) - ); - } - } - - bool Task::fill_input_packet(int stream_id, Packet packet) { - PacketQueueMap::iterator it = inputs_queue_.find(stream_id); - if (it == inputs_queue_.end()) { - return false; - } - it->second->push(packet); +Task::Task(int node_id, std::vector input_stream_id_list, + std::vector output_stream_id_list) { + init(node_id, input_stream_id_list, output_stream_id_list); +} + +Task::Task(const Task &rhs) { + this->node_id_ = rhs.node_id_; + this->timestamp_ = rhs.timestamp_; + this->inputs_queue_ = rhs.inputs_queue_; + this->outputs_queue_ = rhs.outputs_queue_; +} + +Task::Task(Task &&rhs) : Task() { swap(*this, rhs); } + +Task &Task::operator=(Task rhs) { + swap(*this, rhs); + return *this; +} + +BMF_API void swap(Task &target, Task &source) { + using std::swap; + + std::swap(target.node_id_, source.node_id_); + std::swap(target.timestamp_, source.timestamp_); + auto itp = std::move(source.inputs_queue_); + source.inputs_queue_ = std::move(target.inputs_queue_); + target.inputs_queue_ = std::move(itp); + auto otp = std::move(source.outputs_queue_); + source.outputs_queue_ = std::move(target.outputs_queue_); + target.outputs_queue_ = std::move(otp); +} + +void Task::init(int node_id, std::vector input_stream_id_list, + std::vector output_stream_id_list) { + node_id_ = node_id; + timestamp_ = 0; + for (int i = 0; i < input_stream_id_list.size(); i++) { + std::shared_ptr> tmp_queue = + std::make_shared>(); + inputs_queue_.insert( + std::pair>>( + input_stream_id_list[i], tmp_queue)); + } + for (int i = 0; i < output_stream_id_list.size(); i++) { + std::shared_ptr> tmp_queue = + std::make_shared>(); + outputs_queue_.insert( + std::pair>>( + output_stream_id_list[i], tmp_queue)); + } +} + +bool Task::fill_input_packet(int stream_id, Packet packet) { + PacketQueueMap::iterator it = inputs_queue_.find(stream_id); + if (it == inputs_queue_.end()) { + return false; + } + it->second->push(packet); + return true; +} + +bool Task::fill_output_packet(int stream_id, Packet packet) { + PacketQueueMap::iterator it = outputs_queue_.find(stream_id); + if (it == outputs_queue_.end()) { + return false; + } + it->second->push(packet); + return true; +} + +bool Task::pop_packet_from_input_queue(int stream_id, Packet &packet) { + PacketQueueMap::iterator it = inputs_queue_.find(stream_id); + if (it == inputs_queue_.end()) { + return false; + } + std::shared_ptr> q = it->second; + if (q->empty()) { + return false; + } + packet = q->front(); + q->pop(); + BMF_TRACE_THROUGHPUT(stream_id, node_id_, q->size()); + return true; +} + +bool Task::pop_packet_from_out_queue(int stream_id, Packet &packet) { + auto it = outputs_queue_.find(stream_id); + if (it == outputs_queue_.end()) { + return false; + } + std::shared_ptr> q = it->second; + if (q->empty()) { + return false; + } + packet = q->front(); + q->pop(); + return true; +} + +bool Task::input_queue_empty(int stream_id) { + auto it = inputs_queue_.find(stream_id); + if (it == inputs_queue_.end()) { return true; } + return it->second->empty(); +} - bool Task::fill_output_packet(int stream_id, Packet packet) { - PacketQueueMap::iterator it = outputs_queue_.find(stream_id); - if (it == outputs_queue_.end()) { - return false; - } - it->second->push(packet); +bool Task::output_queue_empty(int stream_id) { + auto it = outputs_queue_.find(stream_id); + if (it == outputs_queue_.end()) { return true; } + return it->second->empty(); +} - bool Task::pop_packet_from_input_queue(int stream_id, Packet &packet) { - PacketQueueMap::iterator it = inputs_queue_.find(stream_id); - if (it == inputs_queue_.end()) { - return false; - } - std::shared_ptr > q = it->second; - if (q->empty()) { - return false; - } - packet = q->front(); - q->pop(); - BMF_TRACE_THROUGHPUT(stream_id, node_id_, q->size()); - return true; - } +int64_t Task::timestamp() const { return timestamp_; } - bool Task::pop_packet_from_out_queue(int stream_id, Packet &packet) { - auto it = outputs_queue_.find(stream_id); - if (it == outputs_queue_.end()) { - return false; - } - std::shared_ptr > q = it->second; - if (q->empty()) { - return false; - } - packet = q->front(); - q->pop(); - return true; - } +void Task::set_timestamp(int64_t t) { timestamp_ = t; } - bool Task::input_queue_empty(int stream_id) - { - auto it = inputs_queue_.find(stream_id); - if (it == inputs_queue_.end()) { - return true; - } - return it->second->empty(); +std::vector Task::get_input_stream_ids() { + std::vector input_stream_ids; + for (auto input : inputs_queue_) { + input_stream_ids.push_back(input.first); } + return input_stream_ids; +} - bool Task::output_queue_empty(int stream_id) - { - auto it = outputs_queue_.find(stream_id); - if (it == outputs_queue_.end()) { - return true; - } - return it->second->empty(); +std::vector Task::get_output_stream_ids() { + std::vector output_stream_ids; + for (auto output : outputs_queue_) { + output_stream_ids.push_back(output.first); } + return output_stream_ids; +} - int64_t Task::timestamp() const { - return timestamp_; - } +PacketQueueMap &Task::get_inputs() { return inputs_queue_; } - void Task::set_timestamp(int64_t t) { - timestamp_ = t; - } +PacketQueueMap &Task::get_outputs() { return outputs_queue_; } - std::vector Task::get_input_stream_ids() { - std::vector input_stream_ids; - for (auto input :inputs_queue_) { - input_stream_ids.push_back(input.first); - } - return input_stream_ids; - } - - std::vector Task::get_output_stream_ids() { - std::vector output_stream_ids; - for (auto output :outputs_queue_) { - output_stream_ids.push_back(output.first); - } - return output_stream_ids; - } - - PacketQueueMap &Task::get_inputs() { - return inputs_queue_; - } - - PacketQueueMap &Task::get_outputs() { - return outputs_queue_; - } - - int Task::get_node() { - return node_id_; - } +int Task::get_node() { return node_id_; } END_BMF_SDK_NS diff --git a/bmf/sdk/cpp_sdk/src/trace.cpp b/bmf/sdk/cpp_sdk/src/trace.cpp index 35fc26bd..669c1554 100644 --- a/bmf/sdk/cpp_sdk/src/trace.cpp +++ b/bmf/sdk/cpp_sdk/src/trace.cpp @@ -8,76 +8,197 @@ BEGIN_BMF_SDK_NS #ifndef NO_TRACE - TraceEvent::TraceEvent() {} - - void TraceBuffer::push_event(const TraceEvent &event) { - total_count_++; - // Handle overflow - if (is_full()) { - overflow_count_++; - // Do not write anymore at limit - return; - } - buffer_[next_write_index_] = event; - next_write_index_.store( - get_next_index(next_write_index_), - std::memory_order_relaxed - ); - buffer_occupancy_++; +TraceEvent::TraceEvent() {} + +void TraceBuffer::push_event(const TraceEvent &event) { + total_count_++; + // Handle overflow + if (is_full()) { + overflow_count_++; + // Do not write anymore at limit + return; } - - TraceEvent TraceBuffer::pop_event() { - // Assumes that is_empty() has been checked prior to Read - TraceEvent event = buffer_[next_read_index_]; - next_read_index_.store( - get_next_index(next_read_index_), - std::memory_order_relaxed - ); - buffer_occupancy_--; - return event; + buffer_[next_write_index_] = event; + next_write_index_.store(get_next_index(next_write_index_), + std::memory_order_relaxed); + buffer_occupancy_++; +} + +TraceEvent TraceBuffer::pop_event() { + // Assumes that is_empty() has been checked prior to Read + TraceEvent event = buffer_[next_read_index_]; + next_read_index_.store(get_next_index(next_read_index_), + std::memory_order_relaxed); + buffer_occupancy_--; + return event; +} + +int64_t TraceBuffer::get_next_timestamp() const { + return buffer_[next_read_index_].timestamp; +} + +bool TraceBuffer::is_not_time_to_log(int64_t time_limit) { + return get_next_timestamp() > time_limit; +} + +bool TraceBuffer::is_empty() const { + return next_read_index_.load(std::memory_order_relaxed) == + next_write_index_.load(std::memory_order_relaxed); +} + +bool TraceBuffer::is_full() const { + return get_next_index(next_write_index_.load(std::memory_order_relaxed)) == + next_read_index_.load(std::memory_order_relaxed); +} + +int TraceBuffer::overflowed() const { return overflow_count_; } + +uint64_t TraceBuffer::total_count() const { + return total_count_.load(std::memory_order_relaxed); +} + +void TraceBuffer::reset_count() { + overflow_count_.store(0, std::memory_order_relaxed); + total_count_.store(0, std::memory_order_release); +} + +int TraceBuffer::get_next_index(int counter) const { + counter++; + if (counter >= buffer_.size()) { + counter = 0; } - - int64_t TraceBuffer::get_next_timestamp() const { - return buffer_[next_read_index_].timestamp; + return counter; +} + +TraceLogger::TraceLogger(int queue_size, bool loop_mode) + : queue_map_(queue_size) { + // Set the thread name + std::thread::id tid = std::this_thread::get_id(); + std::stringstream tss; + tss << tid; + thread_name_ = tss.str(); + + // Set the process name + pid_t pid = getpid(); + std::stringstream pss; + pss << pid; + process_name_ = pss.str(); + + // Set the trace settings + if (getenv("BMF_TRACE_PRINTING") && + std::strcmp(getenv("BMF_TRACE_PRINTING"), "DISABLE") == 0) + enable_printing = false; + if (getenv("BMF_TRACE_LOGGING") && + std::strcmp(getenv("BMF_TRACE_LOGGING"), "DISABLE") == 0) + enable_format_log = false; + + // Start the execution loop for logger + if (loop_mode) { + start(); } +} - bool TraceBuffer::is_not_time_to_log(int64_t time_limit) { - return get_next_timestamp() > time_limit; +void TraceLogger::start() { + if (TRACE_ENABLED) { + file_thread_ = std::thread(&TraceLogger::loop, this); } +} - bool TraceBuffer::is_empty() const { - return next_read_index_.load(std::memory_order_relaxed) - == next_write_index_.load(std::memory_order_relaxed); +void TraceLogger::end() { + if (TRACE_ENABLED) { + thread_quit_ = true; + file_thread_.join(); } - - bool TraceBuffer::is_full() const { - return get_next_index(next_write_index_.load(std::memory_order_relaxed)) - == next_read_index_.load(std::memory_order_relaxed); +} + +int TraceLogger::register_queue(std::string process_name, + std::string thread_name) { + // Assign buffer for the thread + queue_map_[thread_count_].process_name = process_name; + queue_map_[thread_count_].thread_name = thread_name; + running_count_++; + if (thread_count_ == queue_map_.size() - 1) + thread_count_ = 0; // Back to first buffer to reuse buffer + return thread_count_++; +} + +void TraceLogger::close_queue(int thread_id) { + running_count_--; + if (!running_count_) { + end(); } - - int TraceBuffer::overflowed() const { - return overflow_count_; +} + +void TraceLogger::push(int thread_id, TraceEvent &event) { + queue_map_[thread_id].push_event(event); +} + +TraceEvent TraceLogger::pop(int thread_id) { + return queue_map_[thread_id].pop_event(); +} + +std::string TraceLogger::get_log_name(int index) { + return "log" + std::to_string(index) + ".txt"; +} + +void TraceLogger::create_log() { + ofs_.open(get_log_name(log_index_), + std::ofstream::out | std::ofstream::trunc); +} + +void TraceLogger::close_log() { + ofs_.close(); + log_index_++; +} + +void TraceLogger::process_queues() { + bool break_file = get_duration() > current_limit_; + + for (int i = 0; i < queue_map_.size(); i++) { + while (!queue_map_[i].is_empty()) { + TraceEvent event = pop(i); + ofs_ << queue_map_[i].process_name << "," + << queue_map_[i].thread_name << "," << event.timestamp << "," + << event.name << ":" << event.subname << "," << event.category + << "," << event.phase << event.info << std::endl; + } } - uint64_t TraceBuffer::total_count() const { - return total_count_.load(std::memory_order_relaxed); + // Triggered the splitting of new log file for next batch of events + if (break_file) { + close_log(); + current_limit_ += TRACE_BINLOG_INTERVAL; + create_log(); } +} - void TraceBuffer::reset_count() { - overflow_count_.store(0, std::memory_order_relaxed); - total_count_.store(0, std::memory_order_release); - } +void TraceLogger::loop() { + create_log(); - int TraceBuffer::get_next_index(int counter) const { - counter++; - if (counter >= buffer_.size()) { - counter = 0; - } - return counter; + // Start execute logging + while (!thread_quit_) { + process_queues(); + usleep(1); } - TraceLogger::TraceLogger(int queue_size, bool loop_mode) - : queue_map_(queue_size) { + // Perform a final clear of pending events to process + process_queues(); + + // Handle log close + close_log(); + + // Print out overflowed buffers + show_overflow(); + + // Format binary logs into JSON log + BMF_TRACE_DONE(); +} + +ThreadTrace::ThreadTrace() { + // Check the environment variable "BMF_TRACE", as long as it has been set, + // trace is enabled. To skip trace, unset "BMF_TRACE" + if (TRACE_ENABLED) { + // Set the thread name std::thread::id tid = std::this_thread::get_id(); std::stringstream tss; @@ -90,625 +211,488 @@ BEGIN_BMF_SDK_NS pss << pid; process_name_ = pss.str(); - // Set the trace settings - if (getenv("BMF_TRACE_PRINTING") && std::strcmp(getenv("BMF_TRACE_PRINTING"), "DISABLE") == 0) - enable_printing = false; - if (getenv("BMF_TRACE_LOGGING") && std::strcmp(getenv("BMF_TRACE_LOGGING"), "DISABLE") == 0) - enable_format_log = false; - - // Start the execution loop for logger - if (loop_mode) { - start(); - } - } - - void TraceLogger::start() { - if (TRACE_ENABLED) { - file_thread_ = std::thread(&TraceLogger::loop, this); - } - } - - void TraceLogger::end() { - if (TRACE_ENABLED) { - thread_quit_ = true; - file_thread_.join(); - } - } - - int TraceLogger::register_queue( - std::string process_name, - std::string thread_name - ) { - // Assign buffer for the thread - queue_map_[thread_count_].process_name = process_name; - queue_map_[thread_count_].thread_name = thread_name; - running_count_++; - if (thread_count_ == queue_map_.size() - 1) - thread_count_ = 0; // Back to first buffer to reuse buffer - return thread_count_++; - } - - void TraceLogger::close_queue(int thread_id) { - running_count_--; - if (!running_count_) { - end(); - } - } - - void TraceLogger::push(int thread_id, TraceEvent& event) { - queue_map_[thread_id].push_event(event); - } - - TraceEvent TraceLogger::pop(int thread_id) { - return queue_map_[thread_id].pop_event(); - } - - std::string TraceLogger::get_log_name(int index) { - return "log" + std::to_string(index) + ".txt"; - } - - void TraceLogger::create_log() { - ofs_.open( - get_log_name(log_index_), - std::ofstream::out | std::ofstream::trunc - ); - } - - void TraceLogger::close_log() { - ofs_.close(); - log_index_++; - } - - void TraceLogger::process_queues() { - bool break_file = get_duration() > current_limit_; - - for (int i = 0; i < queue_map_.size(); i++) { - while (!queue_map_[i].is_empty()) { - TraceEvent event = pop(i); - ofs_ << queue_map_[i].process_name << "," \ - << queue_map_[i].thread_name << "," \ - << event.timestamp << "," \ - << event.name << ":" << event.subname << "," \ - << event.category << "," \ - << event.phase \ - << event.info \ - << std::endl; - } - } - - // Triggered the splitting of new log file for next batch of events - if (break_file) { - close_log(); - current_limit_ += TRACE_BINLOG_INTERVAL; - create_log(); - } - } - - void TraceLogger::loop() { - create_log(); - - // Start execute logging - while (!thread_quit_) { - process_queues(); - usleep(1); - } - - // Perform a final clear of pending events to process - process_queues(); - - // Handle log close - close_log(); - - // Print out overflowed buffers - show_overflow(); - - // Format binary logs into JSON log - BMF_TRACE_DONE(); - } - - ThreadTrace::ThreadTrace() { - // Check the environment variable "BMF_TRACE", as long as it has been set, - // trace is enabled. To skip trace, unset "BMF_TRACE" - if (TRACE_ENABLED) { - - // Set the thread name - std::thread::id tid = std::this_thread::get_id(); - std::stringstream tss; - tss << tid; - thread_name_ = tss.str(); - - // Set the process name - pid_t pid = getpid(); - std::stringstream pss; - pss << pid; - process_name_ = pss.str(); - - // Register with Tracer - thread_id_ = TraceLogger::instance()->register_queue( - process_name_, - thread_name_ - ); - } - } - - ThreadTrace::~ThreadTrace() { - if (TRACE_ENABLED) { - TraceLogger::instance()->close_queue(thread_id_); - } + // Register with Tracer + thread_id_ = TraceLogger::instance()->register_queue(process_name_, + thread_name_); } +} - void ThreadTrace::trace( - TraceType category, - const char* name, - TracePhase phase, - const char* src - ) { - // Get the current timestamp - int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; - - // Create a trace event - TraceEvent event = TraceEvent( - timestamp, - name, - src, - category, - phase - ); - - // Send the event to buffer - TraceLogger::instance()->push(thread_id_, event); +ThreadTrace::~ThreadTrace() { + if (TRACE_ENABLED) { + TraceLogger::instance()->close_queue(thread_id_); } +} + +void ThreadTrace::trace(TraceType category, const char *name, TracePhase phase, + const char *src) { + // Get the current timestamp + int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; + + // Create a trace event + TraceEvent event = TraceEvent(timestamp, name, src, category, phase); + + // Send the event to buffer + TraceLogger::instance()->push(thread_id_, event); +} + +void ThreadTrace::trace_info(TraceType category, const char *name, + TracePhase phase, std::string info, + const char *src) { + // Get the current timestamp + int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; + + // Create a trace event + TraceEvent event = TraceEvent(timestamp, name, src, category, phase, info); + + // Send the event to buffer + TraceLogger::instance()->push(thread_id_, event); +} + +void ThreadTrace::trace_process(const char *name, const char *subname, + TracePhase phase) { + // Get the current timestamp + int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; + + // Create a trace event + TraceEvent event = TraceEvent(timestamp, name, subname, PROCESSING, phase); + + // Send the event to buffer + TraceLogger::instance()->push(thread_id_, event); +} + +void TraceLogger::format_logs(bool include_info) { + if (!enable_format_log) + return; + + std::string categories[] = {"INTERLATENCY", "PROCESSING", "SCHEDULE", + "QUEUE_INFO", "THROUGHPUT", "CUSTOM", + "TRACE_START", "GRAPH_START"}; + + std::string phases[] = {"i", "B", "E"}; + + // Hold the timestamp of duration event with phase 'B' + std::map previous_ts; + + // Count the additional number of duration event with 'B' phase to add + std::map> ts_completed; + + // Count the occurrence of each event + std::map occurrence; + std::map> timings; + std::map> queue_info; + std::map>> + throughput; + + nlohmann::json flog; + char line[1024]; + long long init_time = LLONG_MAX; + long long start_time = LLONG_MAX; + long long final_time = 0; + + for (const auto &entry : std::filesystem::directory_iterator(".")) { + // Proceed if is a log file + std::string filename = entry.path().filename().u8string(); + if (filename.size() > 7 && filename.find("log") == 0 && + filename.compare(filename.size() - 4, 4, ".txt") == 0) { + FILE *fp = fopen(filename.c_str(), "r"); + + while (fgets(line, sizeof(line), fp)) { + nlohmann::json linelog; + + // Line by line decoding + std::stringstream ss(line); + int term_count = 0; + int cat_index = 0; + + while (ss.good()) { + std::string term; + getline(ss, term, ','); + + if (term_count == 0) { + // Process ID + linelog["pid"] = term; + } else if (term_count == 1) { + // Thread ID + linelog["tid"] = term; + } else if (term_count == 2) { + // Timestamp + char *result; + linelog["ts"] = strtoll(term.c_str(), &result, 10); + } else if (term_count == 3) { + // Name + linelog["name"] = term; + } else if (term_count == 4) { + // Category + cat_index = strtoll(term.c_str(), NULL, 10); + linelog["cat"] = categories[cat_index]; + if (cat_index == 6) { + // Graph start + init_time = linelog["ts"]; + } else if (enable_printing && cat_index == 4) { + // Throughput + std::string line_name = linelog["name"]; + std::string stream_name = + line_name.substr(0, line_name.find(":")); + std::string node_name = line_name.substr( + line_name.find(":") + 1, line_name.length()); + if (throughput.count(node_name)) { + if (!throughput[node_name].count(stream_name)) { + throughput[node_name][stream_name] = + std::make_pair(0, 0); + } + throughput[node_name][stream_name].second += 1; + } + } else { + if (linelog["ts"] < start_time) + start_time = linelog["ts"]; + if (linelog["ts"] > final_time) + final_time = linelog["ts"]; + } - void ThreadTrace::trace_info( - TraceType category, - const char* name, - TracePhase phase, - std::string info, - const char* src - ) { - // Get the current timestamp - int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; - - // Create a trace event - TraceEvent event = TraceEvent( - timestamp, - name, - src, - category, - phase, - info - ); - - // Send the event to buffer - TraceLogger::instance()->push(thread_id_, event); - } + if (enable_printing && cat_index > 0) { + occurrence[linelog["name"]]++; + } + } else if (term_count == 5) { + // Phase + linelog["ph"] = phases[strtoll(term.c_str(), NULL, 10)]; - void ThreadTrace::trace_process( - const char* name, - const char* subname, - TracePhase phase - ) { - // Get the current timestamp - int64_t timestamp = BMF_TRACE_CLOCK() - BMF_TRACE_CLOCK_START; - - // Create a trace event - TraceEvent event = TraceEvent( - timestamp, - name, - subname, - PROCESSING, - phase - ); - - // Send the event to buffer - TraceLogger::instance()->push(thread_id_, event); - } + // Duration event with phase 'B' will be recorded + if (linelog["ph"] == "B") { + previous_ts[linelog["name"]] = linelog["ts"]; - void TraceLogger::format_logs(bool include_info) { - if (!enable_format_log) - return; - - std::string categories[] = { - "INTERLATENCY", - "PROCESSING", - "SCHEDULE", - "QUEUE_INFO", - "THROUGHPUT", - "CUSTOM", - "TRACE_START", - "GRAPH_START" - }; - - std::string phases[] = { - "i", - "B", - "E" - }; - - // Hold the timestamp of duration event with phase 'B' - std::map previous_ts; - - // Count the additional number of duration event with 'B' phase to add - std::map > ts_completed; - - // Count the occurrence of each event - std::map occurrence; - std::map > timings; - std::map > queue_info; - std::map > > throughput; - - nlohmann::json flog; - char line[1024]; - long long init_time = LLONG_MAX; - long long start_time = LLONG_MAX; - long long final_time = 0; - - for (const auto &entry : std::filesystem::directory_iterator(".")) { - // Proceed if is a log file - std::string filename = entry.path().filename().u8string(); - if (filename.size() > 7 && filename.find("log") == 0 - && filename.compare(filename.size() - 4, 4, ".txt") == 0) { - FILE* fp = fopen(filename.c_str(), "r"); - - while (fgets(line, sizeof(line), fp)) { - nlohmann::json linelog; - - // Line by line decoding - std::stringstream ss(line); - int term_count = 0; - int cat_index = 0; - - while (ss.good()) { - std::string term; - getline(ss, term, ','); - - if (term_count == 0) { - // Process ID - linelog["pid"] = term; - } else if (term_count == 1) { - // Thread ID - linelog["tid"] = term; - } else if (term_count == 2) { - // Timestamp - char *result; - linelog["ts"] = strtoll(term.c_str(), &result, 10); - } else if (term_count == 3) { - // Name - linelog["name"] = term; - } else if (term_count == 4) { - // Category - cat_index = strtoll(term.c_str(), NULL, 10); - linelog["cat"] = categories[cat_index]; - if (cat_index == 6) { - // Graph start - init_time = linelog["ts"]; - } else if (enable_printing && cat_index == 4) { - // Throughput + if (enable_printing) { + // throughput std::string line_name = linelog["name"]; - std::string stream_name = line_name.substr(0, line_name.find(":")); - std::string node_name = line_name.substr(line_name.find(":") + 1, line_name.length()); - if (throughput.count(node_name)) { - if (!throughput[node_name].count(stream_name)) { - throughput[node_name][stream_name] = std::make_pair(0, 0); - } - throughput[node_name][stream_name].second += 1; + std::string node_name = + line_name.substr(0, line_name.find(":")); + if (!throughput.count(node_name)) { + throughput[node_name] = std::map< + std::string, + std::pair>(); } - } else { - if (linelog["ts"] < start_time) - start_time = linelog["ts"]; - if (linelog["ts"] > final_time) - final_time = linelog["ts"]; - } - - if (enable_printing && cat_index > 0) { - occurrence[linelog["name"]]++; } - } else if (term_count == 5) { - // Phase - linelog["ph"] = phases[ - strtoll(term.c_str(), NULL, 10) - ]; - - // Duration event with phase 'B' will be recorded - if (linelog["ph"] == "B") { - previous_ts[linelog["name"]] = linelog["ts"]; - - if (enable_printing) { - // throughput - std::string line_name = linelog["name"]; - std::string node_name = line_name.substr(0, line_name.find(":")); - if (!throughput.count(node_name)) { - throughput[node_name] - = std::map >(); - } + } else if (linelog["ph"] == "E") { + // Duration event with phase 'E' will be checked + // against 'E' + if (previous_ts.count(linelog["name"])) { + long long last_ts = + previous_ts[linelog["name"]]; + // Assume 'B' only occur once, while 'E' can + // occur multiple times + if (ts_completed.count(linelog["name"]) && + ts_completed[linelog["name"]].count( + last_ts)) { + // Duplicate an event for "B" and slot in + nlohmann::json duplog; + duplog["pid"] = linelog["pid"]; + duplog["tid"] = linelog["tid"]; + duplog["ts"] = last_ts; + duplog["name"] = linelog["name"]; + duplog["cat"] = linelog["cat"]; + duplog["ph"] = "B"; + flog.push_back(duplog); + } else { + ts_completed[linelog["name"]][last_ts] = + true; } - } else if (linelog["ph"] == "E") { - // Duration event with phase 'E' will be checked against 'E' - if (previous_ts.count(linelog["name"])) { - long long last_ts = previous_ts[linelog["name"]]; - // Assume 'B' only occur once, while 'E' can occur multiple times - if (ts_completed.count(linelog["name"]) - && ts_completed[linelog["name"]].count(last_ts)) { - // Duplicate an event for "B" and slot in - nlohmann::json duplog; - duplog["pid"] = linelog["pid"]; - duplog["tid"] = linelog["tid"]; - duplog["ts"] = last_ts; - duplog["name"] = linelog["name"]; - duplog["cat"] = linelog["cat"]; - duplog["ph"] = "B"; - flog.push_back(duplog); - } else { - ts_completed[linelog["name"]][last_ts] = true; + + // Record the event duration + if (enable_printing && cat_index > 0) { + if (!timings.count(linelog["name"])) { + timings[linelog["name"]]["total"] = 0; + timings[linelog["name"]]["count"] = 0; + timings[linelog["name"]]["ave"] = 0; + timings[linelog["name"]]["min"] = + LLONG_MAX; + timings[linelog["name"]]["max"] = 0; } - - // Record the event duration - if (enable_printing && cat_index > 0) { - if (!timings.count(linelog["name"])) { - timings[linelog["name"]]["total"] = 0; - timings[linelog["name"]]["count"] = 0; - timings[linelog["name"]]["ave"] = 0; - timings[linelog["name"]]["min"] = LLONG_MAX; - timings[linelog["name"]]["max"] = 0; - } - long long event_ts = linelog["ts"]; - long long duration = event_ts - last_ts; - timings[linelog["name"]]["total"] += duration; - timings[linelog["name"]]["count"]++; - timings[linelog["name"]]["ave"] - = timings[linelog["name"]]["total"] / timings[linelog["name"]]["count"]; - timings[linelog["name"]]["min"] - = std::min(timings[linelog["name"]]["min"], duration); - timings[linelog["name"]]["max"] - = std::max(timings[linelog["name"]]["max"], duration); - - std::string line_name = linelog["name"]; - std::string node_name = line_name.substr(0, line_name.find(":")); - std::string cat_name = linelog["cat"]; - if (cat_index == 1) { - // Handle throughput event - only end of processing will be checked - std::string func_name = line_name.substr( - line_name.find(":") + 1, line_name.length() - ); - if (strcmp(func_name.c_str(), "process_node") == 0) { - for (auto &it : throughput[node_name]) { - it.second.first += duration; - } + long long event_ts = linelog["ts"]; + long long duration = event_ts - last_ts; + timings[linelog["name"]]["total"] += + duration; + timings[linelog["name"]]["count"]++; + timings[linelog["name"]]["ave"] = + timings[linelog["name"]]["total"] / + timings[linelog["name"]]["count"]; + timings[linelog["name"]]["min"] = std::min( + timings[linelog["name"]]["min"], + duration); + timings[linelog["name"]]["max"] = std::max( + timings[linelog["name"]]["max"], + duration); + + std::string line_name = linelog["name"]; + std::string node_name = line_name.substr( + 0, line_name.find(":")); + std::string cat_name = linelog["cat"]; + if (cat_index == 1) { + // Handle throughput event - only end of + // processing will be checked + std::string func_name = + line_name.substr( + line_name.find(":") + 1, + line_name.length()); + if (strcmp(func_name.c_str(), + "process_node") == 0) { + for (auto &it : + throughput[node_name]) { + it.second.first += duration; } } } } } - } else { - // Create user info for first occurrence of user info - // within the event log - if (term_count == 6) { - nlohmann::json user_info; - linelog["args"] = user_info; - } + } + } else { + // Create user info for first occurrence of user info + // within the event log + if (term_count == 6) { + nlohmann::json user_info; + linelog["args"] = user_info; + } - // Add user info - size_t pos = 0; - std::string arg, key, valtype; - while ((pos = term.find(":")) != std::string::npos) { - arg = term.substr(0, pos); - if (key.empty()) { - // Handle key - key = arg; + // Add user info + size_t pos = 0; + std::string arg, key, valtype; + while ((pos = term.find(":")) != std::string::npos) { + arg = term.substr(0, pos); + if (key.empty()) { + // Handle key + key = arg; + } else { + // Handle string type value + valtype = arg; + arg = term.substr(pos + 1, term.length()); + if (!arg.empty() && + arg[arg.length() - 1] == '\n') { + arg.erase(arg.length() - 1); + } + if (valtype == "1") { + // Handle int type value (decimal string) + linelog["args"][key] = + strtoll(arg.c_str(), NULL, 10); + } else if (valtype == "2") { + // Handle double type value (decimal string) + linelog["args"][key] = atof(arg.c_str()); } else { - // Handle string type value - valtype = arg; - arg = term.substr(pos + 1, term.length()); - if (!arg.empty() && arg[arg.length() - 1] == '\n') { - arg.erase(arg.length() - 1); - } - if (valtype == "1") { - // Handle int type value (decimal string) - linelog["args"][key] = strtoll(arg.c_str(), NULL, 10); - } else if (valtype == "2") { - // Handle double type value (decimal string) - linelog["args"][key] = atof(arg.c_str()); - } else { - // Handle string type (default) value - linelog["args"][key] = arg; - } + // Handle string type (default) value + linelog["args"][key] = arg; } - term.erase(0, pos + 1); } + term.erase(0, pos + 1); } - term_count++; } + term_count++; + } - // Handle queue info - if (enable_printing) { - if (cat_index == 3) { - std::string queue_name = linelog["name"]; - queue_name = queue_name.substr(0, queue_name.find(":")); - if (!queue_info.count(queue_name)) { - queue_info[queue_name]["limit"] = linelog["args"]["max"]; - queue_info[queue_name]["max"] = 0; - queue_info[queue_name]["ave"] = 0; - queue_info[queue_name]["total"] = 0; - queue_info[queue_name]["count"] = 0; - } - if (linelog["args"]["size"] > queue_info[queue_name]["max"]) - queue_info[queue_name]["max"] = linelog["args"]["size"]; - int curr_size = linelog["args"]["size"]; - queue_info[queue_name]["total"] += curr_size; - queue_info[queue_name]["count"]++; - queue_info[queue_name]["ave"] - = queue_info[queue_name]["total"] / queue_info[queue_name]["count"]; + // Handle queue info + if (enable_printing) { + if (cat_index == 3) { + std::string queue_name = linelog["name"]; + queue_name = queue_name.substr(0, queue_name.find(":")); + if (!queue_info.count(queue_name)) { + queue_info[queue_name]["limit"] = + linelog["args"]["max"]; + queue_info[queue_name]["max"] = 0; + queue_info[queue_name]["ave"] = 0; + queue_info[queue_name]["total"] = 0; + queue_info[queue_name]["count"] = 0; } + if (linelog["args"]["size"] > + queue_info[queue_name]["max"]) + queue_info[queue_name]["max"] = + linelog["args"]["size"]; + int curr_size = linelog["args"]["size"]; + queue_info[queue_name]["total"] += curr_size; + queue_info[queue_name]["count"]++; + queue_info[queue_name]["ave"] = + queue_info[queue_name]["total"] / + queue_info[queue_name]["count"]; } - - flog.push_back(linelog); } - fclose(fp); - - // Handle removal of old binary log - // Binary log that has been formatted is no longer needed - try { - std::filesystem::remove(filename.c_str()); - } catch (const std::filesystem::filesystem_error& err) { - std::cerr << "Filesystem Error: "<< err.what() << std::endl; - } + flog.push_back(linelog); } - } - - // Short-circuit if empty log - if (!flog.size()) - return; - // Sort the JSON list - using json_it_type = decltype(*flog.begin()); - std::sort(flog.begin(), flog.end(), [](const json_it_type a, const json_it_type b) { - return a["ts"] < b["ts"]; - }); + fclose(fp); - // Process and print statistics - if (enable_printing) { - std::cout << "\n\n- - - - - - - - - - - RUNTIME INFORMATION - - - - - - - - - - - -"; - - if (init_time < LLONG_MAX) { - auto init_diff = final_time - init_time; - std::cout << "\nTotal execution time (from TRACE_START): " << init_diff << " us"; + // Handle removal of old binary log + // Binary log that has been formatted is no longer needed + try { + std::filesystem::remove(filename.c_str()); + } catch (const std::filesystem::filesystem_error &err) { + std::cerr << "Filesystem Error: " << err.what() << std::endl; } + } + } - auto trace_diff = final_time - start_time; - std::cout << "\nTotal graph execution time: " << trace_diff << " us"; + // Short-circuit if empty log + if (!flog.size()) + return; + + // Sort the JSON list + using json_it_type = decltype(*flog.begin()); + std::sort(flog.begin(), flog.end(), + [](const json_it_type a, const json_it_type b) { + return a["ts"] < b["ts"]; + }); + + // Process and print statistics + if (enable_printing) { + std::cout << "\n\n- - - - - - - - - - - RUNTIME INFORMATION - - - - - " + "- - - - - - -"; + + if (init_time < LLONG_MAX) { + auto init_diff = final_time - init_time; + std::cout << "\nTotal execution time (from TRACE_START): " + << init_diff << " us"; + } - std::cout << "\n\n- - - - - - - - - - - - EVENTS FREQUENCY - - - - - - - - - - - - -" - << std::endl << std::left << std::setw(30) << "Event Name" - << std::setw(10) << "Total Count"; - std::vector > sorted_occurrence; - for (auto &it : occurrence) { - sorted_occurrence.push_back(it); - } - sort(sorted_occurrence.begin(), sorted_occurrence.end(), [](const auto &a, const auto &b) { - return a.second > b.second; - }); - for (auto &it : sorted_occurrence) { - std::cout << std::endl << std::left << std::setw(30) << it.first << std::setw(10) << it.second; - } + auto trace_diff = final_time - start_time; + std::cout << "\nTotal graph execution time: " << trace_diff << " us"; + + std::cout << "\n\n- - - - - - - - - - - - EVENTS FREQUENCY - - - - - - " + "- - - - - - -" + << std::endl + << std::left << std::setw(30) << "Event Name" << std::setw(10) + << "Total Count"; + std::vector> sorted_occurrence; + for (auto &it : occurrence) { + sorted_occurrence.push_back(it); + } + sort(sorted_occurrence.begin(), sorted_occurrence.end(), + [](const auto &a, const auto &b) { return a.second > b.second; }); + for (auto &it : sorted_occurrence) { + std::cout << std::endl + << std::left << std::setw(30) << it.first << std::setw(10) + << it.second; + } - std::cout << "\n\n- - - - - - - - - - - - EVENTS DURATION - - - - - - - - - - - - -" - << std::endl << std::left << std::setw(30) << "Event Name" - << std::setw(10) << "Total (us)" - << std::setw(10) << "Total (%)" - << std::setw(10) << "Ave (us)" - << std::setw(10) << "Min (us)" - << std::setw(10) << "Max (us)"; - for (auto &it : timings) { - float perc = it.second["total"] * 100 / trace_diff; - std::cout << std::endl << std::left << std::setw(30) << it.first - << std::setw(10) << it.second["total"] - << std::setw(10) << std::fixed << std::setprecision(1) << perc - << std::setw(10) << it.second["ave"] - << std::setw(10) << it.second["min"] - << std::setw(10) << it.second["max"]; - } + std::cout << "\n\n- - - - - - - - - - - - EVENTS DURATION - - - - - - " + "- - - - - - -" + << std::endl + << std::left << std::setw(30) << "Event Name" << std::setw(10) + << "Total (us)" << std::setw(10) << "Total (%)" + << std::setw(10) << "Ave (us)" << std::setw(10) << "Min (us)" + << std::setw(10) << "Max (us)"; + for (auto &it : timings) { + float perc = it.second["total"] * 100 / trace_diff; + std::cout << std::endl + << std::left << std::setw(30) << it.first << std::setw(10) + << it.second["total"] << std::setw(10) << std::fixed + << std::setprecision(1) << perc << std::setw(10) + << it.second["ave"] << std::setw(10) << it.second["min"] + << std::setw(10) << it.second["max"]; + } - std::cout << "\n\n- - - - - - - - - - - - QUEUE INFORMATION - - - - - - - - - - - -" - << std::endl << std::left << std::setw(30) << "Queue Name" - << std::setw(10) << "Limit" - << std::setw(10) << "Ave" - << std::setw(10) << "Max"; - - for (auto &it : queue_info) { - std::cout << std::endl << std::left << std::setw(30) << it.first - << std::setw(10) << it.second["limit"] - << std::setw(10) << it.second["ave"] - << std::setw(10) << it.second["max"]; - } + std::cout << "\n\n- - - - - - - - - - - - QUEUE INFORMATION - - - - - " + "- - - - - - -" + << std::endl + << std::left << std::setw(30) << "Queue Name" << std::setw(10) + << "Limit" << std::setw(10) << "Ave" << std::setw(10) + << "Max"; + + for (auto &it : queue_info) { + std::cout << std::endl + << std::left << std::setw(30) << it.first << std::setw(10) + << it.second["limit"] << std::setw(10) << it.second["ave"] + << std::setw(10) << it.second["max"]; + } - std::cout << "\n\n- - - - - - - - - - - THROUGHPUT INFORMATION - - - - - - - - - - -" - << std::endl << std::left << std::setw(10) << "Node" - << std::setw(10) << "Stream" - << std::setw(10) << "Packets/second"; - - for (auto &node : throughput) { - for (auto &stream : throughput[node.first]) { - auto stream_rate = stream.second.second * 1000000 / stream.second.first; - std::cout << std::endl << std::left << std::setw(30) << node.first - << std::setw(10) << stream.first - << std::setw(10) << stream_rate; - } + std::cout << "\n\n- - - - - - - - - - - THROUGHPUT INFORMATION - - - - " + "- - - - - - -" + << std::endl + << std::left << std::setw(10) << "Node" << std::setw(10) + << "Stream" << std::setw(10) << "Packets/second"; + + for (auto &node : throughput) { + for (auto &stream : throughput[node.first]) { + auto stream_rate = + stream.second.second * 1000000 / stream.second.first; + std::cout << std::endl + << std::left << std::setw(30) << node.first + << std::setw(10) << stream.first << std::setw(10) + << stream_rate; } - - std::cout << "\n\n- - - - - - - - - - - - TRACE INFORMATION - - - - - - - - - - - -"; } - // Sort the JSON list - using json_it_type = decltype(*flog.begin()); - std::sort(flog.begin(), flog.end(), [](const json_it_type a, const json_it_type b) { - return a["ts"] < b["ts"]; - }); - - // Output Trace statistics - if (include_info) { - nlohmann::json logstats; - logstats["ts"] = get_duration(); - logstats["name"] = "Trace Log"; - logstats["pid"] = process_name_; - logstats["tid"] = thread_name_; - logstats["cat"] = categories[2]; - logstats["ph"] = phases[0]; - logstats["args"] = nlohmann::json::object(); - logstats["args"]["buffer_stats"] = nlohmann::json::array(); - logstats["args"]["buffer_size"] = trace_get_buffer_size(); - logstats["args"]["buffer_count"] = queue_map_.size(); - - int buffer_allocated = 0; - - for (int i = 0; i < queue_map_.size(); i++) { - nlohmann::json queue_info; - queue_info["tid"] = queue_map_[i].thread_name; - queue_info["overflowed_events"] = queue_map_[i].overflowed(); - queue_info["total_events"] = queue_map_[i].total_count(); - queue_map_[i].reset_count(); - queue_info["buffer_size"] = queue_map_[i].get_buffer_size(); - logstats["args"]["buffer_stats"].push_back(queue_info); - - // Print individual buffer info - if (enable_printing) { - if (queue_info["total_events"] > 0) { - std::cout - << "\nThread: " << queue_info["tid"] - << "\tTotal Events: " << queue_info["total_events"] - << " (" << queue_info["overflowed_events"] << " overflowed)"; - buffer_allocated++; - } - } - } + std::cout << "\n\n- - - - - - - - - - - - TRACE INFORMATION - - - - - " + "- - - - - - -"; + } - // Print trace info + // Sort the JSON list + using json_it_type = decltype(*flog.begin()); + std::sort(flog.begin(), flog.end(), + [](const json_it_type a, const json_it_type b) { + return a["ts"] < b["ts"]; + }); + + // Output Trace statistics + if (include_info) { + nlohmann::json logstats; + logstats["ts"] = get_duration(); + logstats["name"] = "Trace Log"; + logstats["pid"] = process_name_; + logstats["tid"] = thread_name_; + logstats["cat"] = categories[2]; + logstats["ph"] = phases[0]; + logstats["args"] = nlohmann::json::object(); + logstats["args"]["buffer_stats"] = nlohmann::json::array(); + logstats["args"]["buffer_size"] = trace_get_buffer_size(); + logstats["args"]["buffer_count"] = queue_map_.size(); + + int buffer_allocated = 0; + + for (int i = 0; i < queue_map_.size(); i++) { + nlohmann::json queue_info; + queue_info["tid"] = queue_map_[i].thread_name; + queue_info["overflowed_events"] = queue_map_[i].overflowed(); + queue_info["total_events"] = queue_map_[i].total_count(); + queue_map_[i].reset_count(); + queue_info["buffer_size"] = queue_map_[i].get_buffer_size(); + logstats["args"]["buffer_stats"].push_back(queue_info); + + // Print individual buffer info if (enable_printing) { - std::cout - << "\n\nTotal number of thread buffers allocated: " - << buffer_allocated << " / " << logstats["args"]["buffer_count"] - << "\nAllocated buffer size (individual): " << logstats["args"]["buffer_size"]; + if (queue_info["total_events"] > 0) { + std::cout + << "\nThread: " << queue_info["tid"] + << "\tTotal Events: " << queue_info["total_events"] + << " (" << queue_info["overflowed_events"] + << " overflowed)"; + buffer_allocated++; + } } - - flog.push_back(logstats); } - // Write formatted log file - char tracelog_name[TRACELOG_NAME_SIZE]; - time_t now = time(0); - strftime(tracelog_name, sizeof(tracelog_name), TRACELOG_NAME_FORMAT, localtime(&now)); - std::ofstream flog_file(tracelog_name); - flog_file << std::setw(4) << flog << std::endl; - flog_file.close(); - + // Print trace info if (enable_printing) { - auto log_time = get_duration() - final_time; - std::cout - << "\nTracelog formatting duration: " << log_time << " us" - << "\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n"; + std::cout << "\n\nTotal number of thread buffers allocated: " + << buffer_allocated << " / " + << logstats["args"]["buffer_count"] + << "\nAllocated buffer size (individual): " + << logstats["args"]["buffer_size"]; } + + flog.push_back(logstats); } + // Write formatted log file + char tracelog_name[TRACELOG_NAME_SIZE]; + time_t now = time(0); + strftime(tracelog_name, sizeof(tracelog_name), TRACELOG_NAME_FORMAT, + localtime(&now)); + std::ofstream flog_file(tracelog_name); + flog_file << std::setw(4) << flog << std::endl; + flog_file.close(); + + if (enable_printing) { + auto log_time = get_duration() - final_time; + std::cout << "\nTracelog formatting duration: " << log_time << " us" + << "\n- - - - - - - - - - - - - - - - - - - - - - - - - - - " + "- - - - - -\n\n"; + } +} #endif diff --git a/bmf/sdk/cpp_sdk/src/video_filter.cpp b/bmf/sdk/cpp_sdk/src/video_filter.cpp index 3d173ecf..b1d69220 100644 --- a/bmf/sdk/cpp_sdk/src/video_filter.cpp +++ b/bmf/sdk/cpp_sdk/src/video_filter.cpp @@ -5,20 +5,21 @@ BEGIN_BMF_SDK_NS -#define GET_OR_RETURN(key, value, key_type, return_value) \ - do { \ - if (!(param.has_key(key))) { \ - BMFLOG(BMF_ERROR) << "get " << key << " failed"; \ - return return_value; \ - } \ - param.get_##key_type(key, value); \ +#define GET_OR_RETURN(key, value, key_type, return_value) \ + do { \ + if (!(param.has_key(key))) { \ + BMFLOG(BMF_ERROR) << "get " << key << " failed"; \ + return return_value; \ + } \ + param.get_##key_type(key, value); \ } while (0) -VideoFrame bmf_scale_func_with_param(VideoFrame& src_vf, int w, int h, int mode) { +VideoFrame bmf_scale_func_with_param(VideoFrame &src_vf, int w, int h, + int mode) { VideoFrame frame; PixelInfo pix_info = src_vf.frame().pix_info(); - if(src_vf.width() == w && src_vf.height() == h) { + if (src_vf.width() == w && src_vf.height() == h) { return src_vf; } @@ -26,28 +27,30 @@ VideoFrame bmf_scale_func_with_param(VideoFrame& src_vf, int w, int h, int mode) auto scale_mode = static_cast(mode); - //check support - if(src_vf.frame().pix_info().is_rgbx()) { + // check support + if (src_vf.frame().pix_info().is_rgbx()) { hmp::Tensor dst_tensor = frame.frame().data()[0]; - hmp::img::resize(dst_tensor, src_vf.frame().data()[0], scale_mode, kNHWC); + hmp::img::resize(dst_tensor, src_vf.frame().data()[0], scale_mode, + kNHWC); } else { hmp::TensorList dst_tensor = frame.frame().data(); - hmp::img::yuv_resize(dst_tensor, src_vf.frame().data(), pix_info, scale_mode); + hmp::img::yuv_resize(dst_tensor, src_vf.frame().data(), pix_info, + scale_mode); } - //copy + // copy frame.copy_props(src_vf); return frame; } -/** @addtogroup bmf_video_filter +/** @addtogroup bmf_video_filter * @{ * @arg width: dst frame width * @arg height: dst frame height * @arg mode: 0 is Nearest, 1 is Bilinear, 2 is Bicubic * @} */ -VideoFrame bmf_scale_func(VideoFrame& src_vf, JsonParam param) { +VideoFrame bmf_scale_func(VideoFrame &src_vf, JsonParam param) { VideoFrame frame; int width; int height; @@ -61,20 +64,18 @@ VideoFrame bmf_scale_func(VideoFrame& src_vf, JsonParam param) { return bmf_scale_func_with_param(src_vf, width, height, mode); } - -VideoFrame bmf_csc_func_with_param(VideoFrame &src_vf, const hmp::PixelInfo& pixel_info) { - //reformat +VideoFrame bmf_csc_func_with_param(VideoFrame &src_vf, + const hmp::PixelInfo &pixel_info) { + // reformat return src_vf.reformat(pixel_info); } - - -/** @addtogroup bmf_video_filter +/** @addtogroup bmf_video_filter * @{ * @arg pixfmt: dst frame pixfmt * @} */ -VideoFrame bmf_csc_func(VideoFrame& src_vf, JsonParam param) { - //use reformat +VideoFrame bmf_csc_func(VideoFrame &src_vf, JsonParam param) { + // use reformat VideoFrame frame; std::string pixfmt; GET_OR_RETURN("pixfmt", pixfmt, string, frame); @@ -84,7 +85,6 @@ VideoFrame bmf_csc_func(VideoFrame& src_vf, JsonParam param) { } REGISTER_VFFILTER(bmf_scale, bmf_scale_func) -REGISTER_VFFILTER(bmf_csc, bmf_csc_func) - +REGISTER_VFFILTER(bmf_csc, bmf_csc_func) END_BMF_SDK_NS diff --git a/bmf/sdk/cpp_sdk/src/video_frame.cpp b/bmf/sdk/cpp_sdk/src/video_frame.cpp index d9d3f300..cc760042 100644 --- a/bmf/sdk/cpp_sdk/src/video_frame.cpp +++ b/bmf/sdk/cpp_sdk/src/video_frame.cpp @@ -1,69 +1,41 @@ #include #include -namespace bmf_sdk{ +namespace bmf_sdk { - -struct VideoFrame::Private -{ - Private(const Frame &frame_) - : frame(frame_) - { - } +struct VideoFrame::Private { + Private(const Frame &frame_) : frame(frame_) {} Private(const Private &other) = default; Frame frame; }; - -VideoFrame::VideoFrame() -{ - //not defined +VideoFrame::VideoFrame() { + // not defined } -VideoFrame::VideoFrame(const Frame &frame) -{ +VideoFrame::VideoFrame(const Frame &frame) { self = std::make_shared(frame); } -VideoFrame::VideoFrame(int width, int height, const PixelInfo &pix_info, const Device &device) - : VideoFrame(Frame(width, height, pix_info, device)) -{ -} +VideoFrame::VideoFrame(int width, int height, const PixelInfo &pix_info, + const Device &device) + : VideoFrame(Frame(width, height, pix_info, device)) {} -VideoFrame::VideoFrame(const std::shared_ptr &other) - : self(other) -{ -} +VideoFrame::VideoFrame(const std::shared_ptr &other) : self(other) {} -VideoFrame::operator bool() const -{ - return self.get() != nullptr; -} +VideoFrame::operator bool() const { return self.get() != nullptr; } -int VideoFrame::width() const -{ - return self->frame.width(); -} +int VideoFrame::width() const { return self->frame.width(); } -int VideoFrame::height() const -{ - return self->frame.height(); -} +int VideoFrame::height() const { return self->frame.height(); } -ScalarType VideoFrame::dtype() const -{ - return self->frame.dtype(); -} +ScalarType VideoFrame::dtype() const { return self->frame.dtype(); } -const VideoFrame::Frame& VideoFrame::frame() const -{ - return self->frame; -} +const VideoFrame::Frame &VideoFrame::frame() const { return self->frame; } -VideoFrame VideoFrame::crop(int x, int y, int w, int h) const -{ +VideoFrame VideoFrame::crop(int x, int y, int w, int h) const { VideoFrame vf; auto frame = self->frame.crop(x, y, w, h); vf = VideoFrame(frame); @@ -71,15 +43,9 @@ VideoFrame VideoFrame::crop(int x, int y, int w, int h) const return vf; } +const Device &VideoFrame::device() const { return self->frame.device(); } -const Device& VideoFrame::device() const -{ - return self->frame.device(); -} - - -VideoFrame VideoFrame::cpu(bool non_blocking) const -{ +VideoFrame VideoFrame::cpu(bool non_blocking) const { VideoFrame vf; auto frame = self->frame.to(kCPU, non_blocking); vf = VideoFrame(frame); @@ -88,9 +54,7 @@ VideoFrame VideoFrame::cpu(bool non_blocking) const return vf; } - -VideoFrame VideoFrame::VideoFrame::cuda() const -{ +VideoFrame VideoFrame::VideoFrame::cuda() const { VideoFrame vf; auto frame = self->frame.to(kCUDA); vf = VideoFrame(frame); @@ -99,14 +63,12 @@ VideoFrame VideoFrame::VideoFrame::cuda() const return vf; } -VideoFrame& VideoFrame::copy_(const VideoFrame &from) -{ +VideoFrame &VideoFrame::copy_(const VideoFrame &from) { self->frame.copy_(from.frame()); return *this; } -VideoFrame VideoFrame::to(const Device &device, bool non_blocking) const -{ +VideoFrame VideoFrame::to(const Device &device, bool non_blocking) const { VideoFrame vf; auto frame = self->frame.to(device, non_blocking); vf = VideoFrame(frame); @@ -115,18 +77,16 @@ VideoFrame VideoFrame::to(const Device &device, bool non_blocking) const return vf; } -VideoFrame& VideoFrame::copy_props(const VideoFrame &from) -{ +VideoFrame &VideoFrame::copy_props(const VideoFrame &from) { OpaqueDataSet::copy_props(from); SequenceData::copy_props(from); Future::copy_props(from); return *this; } -VideoFrame VideoFrame::reformat(const PixelInfo &pix_info) -{ +VideoFrame VideoFrame::reformat(const PixelInfo &pix_info) { auto frame = self->frame.reformat(pix_info); return VideoFrame(frame); } -} //namespacebmf_sdk +} // namespacebmf_sdk diff --git a/bmf/sdk/cpp_sdk/test/test_audio_frame.cpp b/bmf/sdk/cpp_sdk/test/test_audio_frame.cpp index 3088ea8f..04d2adc6 100644 --- a/bmf/sdk/cpp_sdk/test/test_audio_frame.cpp +++ b/bmf/sdk/cpp_sdk/test/test_audio_frame.cpp @@ -5,61 +5,66 @@ #endif #include - using namespace bmf_sdk; - -TEST(audio_frame, constructors) -{ +TEST(audio_frame, constructors) { AudioFrame af0; EXPECT_FALSE(af0); - auto af1 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, kInt16); - EXPECT_TRUE(af1); + auto af1 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, + kInt16); + EXPECT_TRUE(af1); EXPECT_EQ(af1.layout(), AudioChannelLayout::kLAYOUT_STEREO); EXPECT_EQ(af1.dtype(), kInt16); EXPECT_EQ(af1.planer(), false); EXPECT_EQ(af1.nsamples(), 8192); EXPECT_EQ(af1.nchannels(), 2); - EXPECT_EQ(af1.sample_rate(), 1); //default - EXPECT_EQ(af1.nplanes(), 1); //interleave + EXPECT_EQ(af1.sample_rate(), 1); // default + EXPECT_EQ(af1.nplanes(), 1); // interleave EXPECT_NO_THROW(af1[0]); EXPECT_THROW(af1[1], std::runtime_error); - auto af2 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, true, kInt16); + auto af2 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, true, + kInt16); EXPECT_TRUE(af2); EXPECT_TRUE(af2.planer()); EXPECT_EQ(af2.nplanes(), 2); - auto af3 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_HEXADECAGONAL, true, kInt16); + auto af3 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_HEXADECAGONAL, + true, kInt16); EXPECT_TRUE(af3); EXPECT_TRUE(af3.planer()); EXPECT_EQ(af3.nplanes(), 16); TensorList ad0; - EXPECT_THROW(AudioFrame::make(ad0, AudioChannelLayout::kLAYOUT_STEREO, true), - std::runtime_error); - - TensorList ad1{empty({8192, 2}, kInt16)}; //interleave stereo data - EXPECT_THROW(AudioFrame::make(ad1, AudioChannelLayout::kLAYOUT_STEREO, true), - std::runtime_error); - EXPECT_NO_THROW(AudioFrame::make(ad1, AudioChannelLayout::kLAYOUT_STEREO, false)); - - - TensorList ad2{empty({8192}, kInt16), empty({8192}, kInt16)}; //planer stereo data - EXPECT_THROW(AudioFrame::make(ad2, AudioChannelLayout::kLAYOUT_STEREO, false), - std::runtime_error); - EXPECT_NO_THROW(AudioFrame::make(ad2, AudioChannelLayout::kLAYOUT_STEREO, true)); + EXPECT_THROW( + AudioFrame::make(ad0, AudioChannelLayout::kLAYOUT_STEREO, true), + std::runtime_error); + + TensorList ad1{empty({8192, 2}, kInt16)}; // interleave stereo data + EXPECT_THROW( + AudioFrame::make(ad1, AudioChannelLayout::kLAYOUT_STEREO, true), + std::runtime_error); + EXPECT_NO_THROW( + AudioFrame::make(ad1, AudioChannelLayout::kLAYOUT_STEREO, false)); + + TensorList ad2{empty({8192}, kInt16), + empty({8192}, kInt16)}; // planer stereo data + EXPECT_THROW( + AudioFrame::make(ad2, AudioChannelLayout::kLAYOUT_STEREO, false), + std::runtime_error); + EXPECT_NO_THROW( + AudioFrame::make(ad2, AudioChannelLayout::kLAYOUT_STEREO, true)); } #ifdef BMF_ENABLE_FFMPEG -TEST(audio_frame, ffmpeg_interop) -{ - //planer +TEST(audio_frame, ffmpeg_interop) { + // planer { - auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, true, kInt16); + auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, + true, kInt16); - AVFrame* aaf0; + AVFrame *aaf0; ASSERT_NO_THROW(aaf0 = bmf_sdk::ffmpeg::from_audio_frame(af0, false)); ASSERT_NE(aaf0, nullptr); @@ -67,13 +72,13 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(aaf0->channel_layout, AV_CH_LAYOUT_STEREO); EXPECT_EQ(aaf0->nb_samples, 8192); EXPECT_EQ(aaf0->channels, 2); - EXPECT_EQ(aaf0->linesize[0], 8192*sizeof(short)); + EXPECT_EQ(aaf0->linesize[0], 8192 * sizeof(short)); EXPECT_EQ(aaf0->nb_extended_buf, 0); - for(int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i){ + for (int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i) { EXPECT_EQ(aaf0->data[i], aaf0->extended_data[i]); } //--> refcount check - EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 2); //af0, aaf0 + EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 2); // af0, aaf0 { AudioFrame af1; @@ -83,19 +88,20 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(af0.planer(), af1.planer()); EXPECT_EQ(af0.nsamples(), af1.nsamples()); EXPECT_EQ(af0.nchannels(), af1.nchannels()); - EXPECT_EQ(af0.nplanes(), af1.nplanes()); //interleave + EXPECT_EQ(af0.nplanes(), af1.nplanes()); // interleave av_frame_free(&aaf0); - EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 2); //af0, af1 + EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 2); // af0, af1 } - EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 1); //af0 + EXPECT_EQ(af0.planes()[0].tensorInfo().refcount(), 1); // af0 } - //interleave + // interleave { - auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, kInt16); + auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, + false, kInt16); - AVFrame* aaf0; + AVFrame *aaf0; ASSERT_NO_THROW(aaf0 = bmf_sdk::ffmpeg::from_audio_frame(af0, false)); ASSERT_NE(aaf0, nullptr); @@ -103,9 +109,9 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(aaf0->channel_layout, AV_CH_LAYOUT_STEREO); EXPECT_EQ(aaf0->nb_samples, 8192); EXPECT_EQ(aaf0->channels, 2); - EXPECT_EQ(aaf0->linesize[0], 8192*sizeof(short)*2); + EXPECT_EQ(aaf0->linesize[0], 8192 * sizeof(short) * 2); EXPECT_EQ(aaf0->nb_extended_buf, 0); - for(int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i){ + for (int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i) { EXPECT_EQ(aaf0->data[i], aaf0->extended_data[i]); } @@ -117,17 +123,18 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(af0.planer(), af1.planer()); EXPECT_EQ(af0.nsamples(), af1.nsamples()); EXPECT_EQ(af0.nchannels(), af1.nchannels()); - EXPECT_EQ(af0.nplanes(), af1.nplanes()); //interleave + EXPECT_EQ(af0.nplanes(), af1.nplanes()); // interleave av_frame_free(&aaf0); } } // - //channels > 8 + // channels > 8 { - auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_HEXADECAGONAL, true, kInt16); + auto af0 = AudioFrame::make( + 8192, AudioChannelLayout::kLAYOUT_HEXADECAGONAL, true, kInt16); - AVFrame* aaf0; + AVFrame *aaf0; ASSERT_NO_THROW(aaf0 = bmf_sdk::ffmpeg::from_audio_frame(af0, false)); ASSERT_NE(aaf0, nullptr); @@ -135,9 +142,9 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(aaf0->channel_layout, AV_CH_LAYOUT_HEXADECAGONAL); EXPECT_EQ(aaf0->nb_samples, 8192); EXPECT_EQ(aaf0->channels, 16); - EXPECT_EQ(aaf0->linesize[0], 8192*sizeof(short)); - EXPECT_EQ(aaf0->nb_extended_buf, 16-FF_ARRAY_ELEMS(aaf0->buf)); - for(int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i){ + EXPECT_EQ(aaf0->linesize[0], 8192 * sizeof(short)); + EXPECT_EQ(aaf0->nb_extended_buf, 16 - FF_ARRAY_ELEMS(aaf0->buf)); + for (int i = 0; i < FF_ARRAY_ELEMS(aaf0->data); ++i) { EXPECT_EQ(aaf0->data[i], aaf0->extended_data[i]); } @@ -149,26 +156,23 @@ TEST(audio_frame, ffmpeg_interop) EXPECT_EQ(af0.planer(), af1.planer()); EXPECT_EQ(af0.nsamples(), af1.nsamples()); EXPECT_EQ(af0.nchannels(), af1.nchannels()); - EXPECT_EQ(af0.nplanes(), af1.nplanes()); //interleave + EXPECT_EQ(af0.nplanes(), af1.nplanes()); // interleave av_frame_free(&aaf0); } } // - - } #endif - - -TEST(audio_frame, copy_props) -{ - auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, kInt16); +TEST(audio_frame, copy_props) { + auto af0 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, + kInt16); af0.set_time_base(Rational(1, 2)); af0.set_pts(100); af0.set_sample_rate(44100); - auto af1 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, kInt16); + auto af1 = AudioFrame::make(8192, AudioChannelLayout::kLAYOUT_STEREO, false, + kInt16); af1.copy_props(af0); EXPECT_EQ(af1.pts(), 100); diff --git a/bmf/sdk/cpp_sdk/test/test_bmf_av_packet.cpp b/bmf/sdk/cpp_sdk/test/test_bmf_av_packet.cpp index c6a8084a..790ce154 100644 --- a/bmf/sdk/cpp_sdk/test/test_bmf_av_packet.cpp +++ b/bmf/sdk/cpp_sdk/test/test_bmf_av_packet.cpp @@ -2,17 +2,14 @@ #include #include - using namespace bmf_sdk; - -TEST(bmf_av_packet, constructors) -{ +TEST(bmf_av_packet, constructors) { BMFAVPacket pkt0; EXPECT_FALSE(pkt0); EXPECT_THROW(pkt0 = BMFAVPacket(Tensor()), std::runtime_error); - auto d0 = hmp::empty({1024}).slice(0, 0, -1, 2); //non-contiguous + auto d0 = hmp::empty({1024}).slice(0, 0, -1, 2); // non-contiguous EXPECT_THROW(pkt0 = BMFAVPacket(d0), std::runtime_error); auto pkt1 = BMFAVPacket::make(1024); @@ -23,9 +20,7 @@ TEST(bmf_av_packet, constructors) EXPECT_TRUE(pkt1.data_ptr() != nullptr); } - -TEST(bmf_av_packet, copy_props) -{ +TEST(bmf_av_packet, copy_props) { auto pkt0 = BMFAVPacket::make(1024); pkt0.set_time_base(Rational(1, 2)); pkt0.set_pts(100); diff --git a/bmf/sdk/cpp_sdk/test/test_convert_backend.cpp b/bmf/sdk/cpp_sdk/test/test_convert_backend.cpp index 8df09fa6..d2a62b0c 100644 --- a/bmf/sdk/cpp_sdk/test/test_convert_backend.cpp +++ b/bmf/sdk/cpp_sdk/test/test_convert_backend.cpp @@ -8,10 +8,13 @@ using namespace bmf_sdk; -TEST(media_description, construct) -{ +TEST(media_description, construct) { MediaDesc dp; - dp.width(1920).height(1080).device(hmp::Device("cpu")).pixel_format(hmp::PF_YUV420P).media_type(MediaType::kAVFrame); + dp.width(1920) + .height(1080) + .device(hmp::Device("cpu")) + .pixel_format(hmp::PF_YUV420P) + .media_type(MediaType::kAVFrame); EXPECT_EQ(dp.width(), 1920); EXPECT_EQ(dp.height(), 1080); @@ -20,8 +23,7 @@ TEST(media_description, construct) EXPECT_EQ(dp.media_type(), MediaType::kAVFrame); } -TEST(media_description, has_value) -{ +TEST(media_description, has_value) { MediaDesc dp; dp.width(1920).device(hmp::Device("cpu")).pixel_format(hmp::PF_YUV420P); EXPECT_TRUE(dp.width.has_value()); @@ -31,31 +33,33 @@ TEST(media_description, has_value) EXPECT_FALSE(dp.media_type.has_value()); } -TEST(convert_backend, format_cvt) -{ +TEST(convert_backend, format_cvt) { MediaDesc dp; dp.width(1920).pixel_format(hmp::PF_YUV420P); auto rgbformat = hmp::PixelInfo(hmp::PF_RGB24); auto src_vf = VideoFrame::make(640, 320, rgbformat); - auto dst_vf = bmf_convert(src_vf, MediaDesc{}, dp); + auto dst_vf = bmf_convert(src_vf, MediaDesc{}, dp); EXPECT_EQ(dst_vf.width(), 1920); EXPECT_EQ(dst_vf.height(), 960); EXPECT_EQ(dst_vf.frame().format(), hmp::PF_YUV420P); } #ifdef BMF_ENABLE_FFMPEG -//use for register +// use for register #include TEST(convert_backend, convert_AVFrame) { MediaDesc dp; - dp.width(1920).height(1080).pixel_format(hmp::PF_RGB24).media_type(MediaType::kAVFrame); + dp.width(1920) + .height(1080) + .pixel_format(hmp::PF_RGB24) + .media_type(MediaType::kAVFrame); auto yuvformat = hmp::PixelInfo(hmp::PF_YUV420P); auto src_vf = VideoFrame::make(640, 320, yuvformat); auto dst_vf = bmf_convert(src_vf, MediaDesc{}, dp); EXPECT_TRUE(static_cast(dst_vf)); - const AVFrame* frame = dst_vf.private_get(); + const AVFrame *frame = dst_vf.private_get(); EXPECT_EQ(frame->width, 1920); EXPECT_EQ(frame->height, 1080); EXPECT_EQ(frame->format, AV_PIX_FMT_RGB24); @@ -79,7 +83,10 @@ TEST(convert_backend, convert_AVFrame) { #include TEST(convert_backend, convert_OCV) { MediaDesc dp; - dp.width(1920).height(1080).pixel_format(hmp::PF_RGB24).media_type(MediaType::kCVMat); + dp.width(1920) + .height(1080) + .pixel_format(hmp::PF_RGB24) + .media_type(MediaType::kCVMat); auto yuvformat = hmp::PixelInfo(hmp::PF_YUV420P); auto src_vf = VideoFrame::make(640, 320, yuvformat); @@ -94,7 +101,7 @@ TEST(convert_backend, convert_OCV) { EXPECT_EQ(mat->size[0], 1080); EXPECT_EQ(mat->size[1], 1920); - cv::Mat *roi_mat = new cv::Mat((*mat)({0,0,1280,720})); + cv::Mat *roi_mat = new cv::Mat((*mat)({0, 0, 1280, 720})); VideoFrame src_with_ocv; src_with_ocv.private_attach(roi_mat); @@ -105,7 +112,7 @@ TEST(convert_backend, convert_OCV) { EXPECT_EQ(vf.height(), 720); EXPECT_EQ(vf.frame().format(), hmp::PF_RGB24); - cv::Mat *roi_mat2 = new cv::Mat((*mat)({0,0,1440,720})); + cv::Mat *roi_mat2 = new cv::Mat((*mat)({0, 0, 1440, 720})); VideoFrame src_with_ocv2; src_with_ocv2.private_attach(roi_mat2); MediaDesc dst_dp; @@ -121,7 +128,10 @@ TEST(convert_backend, convert_OCV) { #ifdef BMF_ENABLE_TORCH TEST(convert_backend, convert_torch) { MediaDesc dp; - dp.width(1920).height(1080).pixel_format(hmp::PF_RGB24).media_type(MediaType::kATTensor); + dp.width(1920) + .height(1080) + .pixel_format(hmp::PF_RGB24) + .media_type(MediaType::kATTensor); auto yuvformat = hmp::PixelInfo(hmp::PF_YUV420P); auto src_vf = VideoFrame::make(640, 320, yuvformat); @@ -147,7 +157,11 @@ TEST(convert_backend, convert_torch) { #if defined(BMF_ENABLE_TORCH) && defined(BMF_ENABLE_CUDA) TEST(convert_backend, convert_torch_cuda) { MediaDesc dp; - dp.width(1920).height(1080).pixel_format(hmp::PF_RGB24).device("cuda").media_type(MediaType::kATTensor); + dp.width(1920) + .height(1080) + .pixel_format(hmp::PF_RGB24) + .device("cuda") + .media_type(MediaType::kATTensor); auto yuvformat = hmp::PixelInfo(hmp::PF_YUV420P); auto src_vf = VideoFrame::make(640, 320, yuvformat); diff --git a/bmf/sdk/cpp_sdk/test/test_exception.cpp b/bmf/sdk/cpp_sdk/test/test_exception.cpp index a6fa09d9..0b9f349a 100644 --- a/bmf/sdk/cpp_sdk/test/test_exception.cpp +++ b/bmf/sdk/cpp_sdk/test/test_exception.cpp @@ -19,9 +19,7 @@ USE_BMF_SDK_NS -void test_bmf_error() { - BMF_Error(-2, "some error happen"); -} +void test_bmf_error() { BMF_Error(-2, "some error happen"); } void test_bmf_error_(std::string error_str) { BMF_Error_(-1, "some error happen %s\n", error_str.c_str()); @@ -31,15 +29,13 @@ TEST(exception, simple_exception) { Exception e; try { test_bmf_error(); - } - catch (Exception e) { + } catch (Exception e) { std::cout << e.what() << std::endl; } try { std::string test_error_info = "hello_world"; test_bmf_error_(test_error_info); - } - catch (Exception e) { + } catch (Exception e) { std::cout << e.what() << std::endl; } } \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/test/test_json_param.cpp b/bmf/sdk/cpp_sdk/test/test_json_param.cpp index 88f4831f..e014fa5e 100644 --- a/bmf/sdk/cpp_sdk/test/test_json_param.cpp +++ b/bmf/sdk/cpp_sdk/test/test_json_param.cpp @@ -21,26 +21,26 @@ USE_BMF_SDK_NS TEST(json_param, parse_json) { - JsonParam json_param; - std::string path = getcwd(NULL,0); - std::string file_name = "../../test/run_by_config/config.json"; - json_param.load(file_name); - std::string mode; - json_param.get_string("mode", mode); - EXPECT_EQ(mode, "normal"); - std::vector node_config_list; - json_param.get_object_list("nodes", node_config_list); - JsonParam json_param2; - json_param2 = json_param; - EXPECT_EQ(node_config_list.size(), 4); - JsonParam module_info; - std::string module_name; - node_config_list[0].get_object("module_info", module_info); - module_info.get_string("name", module_name); - EXPECT_EQ(module_name, "c_ffmpeg_decoder"); + JsonParam json_param; + std::string path = getcwd(NULL, 0); + std::string file_name = "../../test/run_by_config/config.json"; + json_param.load(file_name); + std::string mode; + json_param.get_string("mode", mode); + EXPECT_EQ(mode, "normal"); + std::vector node_config_list; + json_param.get_object_list("nodes", node_config_list); + JsonParam json_param2; + json_param2 = json_param; + EXPECT_EQ(node_config_list.size(), 4); + JsonParam module_info; + std::string module_name; + node_config_list[0].get_object("module_info", module_info); + module_info.get_string("name", module_name); + EXPECT_EQ(module_name, "c_ffmpeg_decoder"); } -TEST(json_param, basic_type){ +TEST(json_param, basic_type) { std::string str = "{\"double\":0.01,\"int\":100,\"long\":999999999}"; JsonParam json_param = JsonParam(str); @@ -59,8 +59,10 @@ TEST(json_param, basic_type){ EXPECT_EQ(value, str); } -TEST(json_param, basic_list_type){ - std::string str = "{\"int_list\":[1,2,3,4,5,6],\"double_list\":[0.001,0.002,0.003],\"string_list\":[\"test_str_001\",\"test_str_002\"]}"; +TEST(json_param, basic_list_type) { + std::string str = "{\"int_list\":[1,2,3,4,5,6],\"double_list\":[0.001,0." + "002,0.003],\"string_list\":[\"test_str_001\",\"test_str_" + "002\"]}"; nlohmann::json json_value = nlohmann::json::parse(str); JsonParam json_param = JsonParam(json_value); @@ -77,7 +79,7 @@ TEST(json_param, basic_list_type){ EXPECT_EQ(string_list.size(), 2); } -TEST(json_param, remove_element){ +TEST(json_param, remove_element) { std::string str = "{\"id1\":\"100\",\"id2\":\"200\", \"id3\":\"300\"}"; JsonParam json_param; json_param.parse(str); @@ -85,12 +87,12 @@ TEST(json_param, remove_element){ std::vector> group; json_param.get_iterated(group); EXPECT_EQ(group.size(), 3); - for (auto &it: group){ - if(it.first == "id1"){ + for (auto &it : group) { + if (it.first == "id1") { EXPECT_EQ(it.second, "100"); - }else if(it.first == "id2"){ + } else if (it.first == "id2") { EXPECT_EQ(it.second, "200"); - }else{ + } else { EXPECT_EQ(it.first, "id3"); EXPECT_EQ(it.second, "300"); } @@ -100,10 +102,10 @@ TEST(json_param, remove_element){ group.clear(); json_param.get_iterated(group); EXPECT_EQ(group.size(), 2); - for (auto &it: group){ - if (it.first == "id2"){ + for (auto &it : group) { + if (it.first == "id2") { EXPECT_EQ(it.second, "200"); - }else if (it.first == "id3"){ + } else if (it.first == "id3") { EXPECT_EQ(it.second, "300"); } } diff --git a/bmf/sdk/cpp_sdk/test/test_log_buffer.cpp b/bmf/sdk/cpp_sdk/test/test_log_buffer.cpp index 99788ad4..ced00251 100644 --- a/bmf/sdk/cpp_sdk/test/test_log_buffer.cpp +++ b/bmf/sdk/cpp_sdk/test/test_log_buffer.cpp @@ -23,16 +23,13 @@ extern "C" { USE_BMF_SDK_NS -void register_av_log_set_callback() -{ +void register_av_log_set_callback() { static std::once_flag flag; - std::call_once(flag, [](){ - LogBuffer::register_av_log_set_callback((void*)av_log_set_callback); + std::call_once(flag, []() { + LogBuffer::register_av_log_set_callback((void *)av_log_set_callback); }); } - - TEST(log_buffer, init_by_string_vector) { register_av_log_set_callback(); @@ -52,9 +49,8 @@ TEST(log_buffer, init_by_function) { register_av_log_set_callback(); std::vector buffer_str; - std::function log_callback = [&buffer_str](std::string const log) -> void { - buffer_str.push_back(log); - }; + std::function log_callback = [&buffer_str]( + std::string const log) -> void { buffer_str.push_back(log); }; std::string log_level = "info"; LogBuffer log_buffer = LogBuffer(log_callback, log_level); EXPECT_EQ(buffer_str.size(), 0); diff --git a/bmf/sdk/cpp_sdk/test/test_module_functor.cpp b/bmf/sdk/cpp_sdk/test/test_module_functor.cpp index 1327f629..d429974c 100644 --- a/bmf/sdk/cpp_sdk/test/test_module_functor.cpp +++ b/bmf/sdk/cpp_sdk/test/test_module_functor.cpp @@ -8,44 +8,38 @@ namespace fs = std::filesystem; namespace { - // two output streams -class FunctorSource : public Module -{ +class FunctorSource : public Module { int ivalue_ = 0; int close_time_ = 0; bool done_ = false; int npkts_[2] = {1, 1}; -public: - FunctorSource(int node_id, const JsonParam &option) - : Module(node_id, option) - { - if(option.json_value_.contains("ivalue")){ + + public: + FunctorSource(int node_id, const JsonParam &option) + : Module(node_id, option) { + if (option.json_value_.contains("ivalue")) { ivalue_ = option.get("ivalue"); } - if(option.json_value_.contains("npkts_0")){ + if (option.json_value_.contains("npkts_0")) { npkts_[0] = option.get("npkts_0"); } - if(option.json_value_.contains("npkts_1")){ + if (option.json_value_.contains("npkts_1")) { npkts_[1] = option.get("npkts_1"); } } - void mark_done() - { - done_ = true; - } + void mark_done() { done_ = true; } - int process(Task &task) override - { - if(done_){ + int process(Task &task) override { + if (done_) { task.set_timestamp(DONE); } - for(int i = 0; i < 2; ++i){ - for(int j = 0; j < npkts_[i]; ++j){ + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < npkts_[i]; ++j) { task.fill_output_packet(i, ivalue_ + i + j); } } @@ -53,29 +47,26 @@ class FunctorSource : public Module ivalue_ += 2; return 0; } - int close() override - { + int close() override { close_time_++; - HMP_REQUIRE(close_time_ < 2, "close module more than once. close time = {}", close_time_); + HMP_REQUIRE(close_time_ < 2, + "close module more than once. close time = {}", + close_time_); return 0; } }; // two input streams and one output stream -class FunctorAdd : public Module -{ +class FunctorAdd : public Module { bool done_ = false; -public: + + public: using Module::Module; - void mark_done() - { - done_ = true; - } + void mark_done() { done_ = true; } - int process(Task &task) override - { - if(done_){ + int process(Task &task) override { + if (done_) { task.set_timestamp(DONE); } @@ -91,26 +82,21 @@ class FunctorAdd : public Module } }; - REGISTER_MODULE_CLASS(FunctorSource) REGISTER_MODULE_CLASS(FunctorAdd) -} //namespace - - +} // namespace -TEST(module_functor, source_add) -{ +TEST(module_functor, source_add) { JsonParam json; auto ivalue = 10; json.parse("{\"ivalue\": 10}"); auto source = make_sync_func, std::tuple>( - ModuleInfo("FunctorSource", "c++", ""), - json); + ModuleInfo("FunctorSource", "c++", ""), json); auto add = make_sync_func, std::tuple>( - ModuleInfo("FunctorAdd", "c++", "")); + ModuleInfo("FunctorAdd", "c++", "")); - for(int i = 0; i < 10; ++i){ + for (int i = 0; i < 10; ++i) { int a, b; std::tie(a, b) = source(); EXPECT_EQ(a, ivalue); @@ -123,17 +109,14 @@ TEST(module_functor, source_add) } }; - -TEST(module_functor, process_done) -{ +TEST(module_functor, process_done) { JsonParam json; auto ivalue = 10; json.parse("{\"ivalue\": 10}"); auto source = make_sync_func, std::tuple>( - ModuleInfo("FunctorSource", "c++", ""), - json); + ModuleInfo("FunctorSource", "c++", ""), json); - for(int i = 0; i < 10; ++i){ + for (int i = 0; i < 10; ++i) { int a, b; std::tie(a, b) = source(); EXPECT_EQ(a, ivalue); @@ -146,30 +129,23 @@ TEST(module_functor, process_done) EXPECT_NO_THROW(source()); // EXPECT_THROW(source(), ProcessDone); } - }; - -TEST(module_functor, irregular_outputs) -{ - //irregular outputs +TEST(module_functor, irregular_outputs) { + // irregular outputs { std::vector> configs{ - {0, 0}, - {0, 2}, - {2, 0}, - {2, 2}, + {0, 0}, {0, 2}, {2, 0}, {2, 2}, }; - for (auto &config : configs) - { + for (auto &config : configs) { JsonParam json; int n0, n1; std::tie(n0, n1) = config; - json.parse(fmt::format("{{\"npkts_0\": {}, \"npkts_1\": {}}}", n0, n1)); + json.parse( + fmt::format("{{\"npkts_0\": {}, \"npkts_1\": {}}}", n0, n1)); auto source = make_sync_func, std::tuple>( - ModuleInfo("FunctorSource", "c++", ""), - json); + ModuleInfo("FunctorSource", "c++", ""), json); source.execute(); auto outs_0 = source.fetch<0>(); @@ -185,8 +161,7 @@ TEST(module_functor, irregular_outputs) JsonParam json; json.parse(fmt::format("{{\"npkts_0\": {}, \"npkts_1\": {}}}", 1, 2)); auto source = make_sync_func, std::tuple>( - ModuleInfo("FunctorSource", "c++", ""), - json); + ModuleInfo("FunctorSource", "c++", ""), json); // with cleanup source.execute(true); @@ -208,5 +183,4 @@ TEST(module_functor, irregular_outputs) EXPECT_EQ(2, outs_0.size()); EXPECT_EQ(4, outs_1.size()); } - } diff --git a/bmf/sdk/cpp_sdk/test/test_module_manager.cpp b/bmf/sdk/cpp_sdk/test/test_module_manager.cpp index 6a2a2782..b7c50e4d 100644 --- a/bmf/sdk/cpp_sdk/test/test_module_manager.cpp +++ b/bmf/sdk/cpp_sdk/test/test_module_manager.cpp @@ -4,30 +4,23 @@ #include using namespace bmf_sdk; -namespace{ +namespace { -class InAppModuleDemo : public Module -{ -public: +class InAppModuleDemo : public Module { + public: using Module::Module; - int32_t process(Task &task) override - { - return 0; - } + int32_t process(Task &task) override { return 0; } }; - REGISTER_MODULE_CLASS(InAppModuleDemo) - }; -TEST(module_manager, test_compat_path) -{ +TEST(module_manager, test_compat_path) { auto p0 = fs::path("/home/foo"); ASSERT_EQ(p0.string(), "/home/foo"); ASSERT_EQ(std::string(p0), "/home/foo"); - + auto p1 = p0 / std::string("a.out"); p0 /= std::string("a.out"); EXPECT_EQ(p0.string(), p0.string()); @@ -39,7 +32,8 @@ TEST(module_manager, test_compat_path) EXPECT_EQ(p3.string(), "./foo/b.exe"); EXPECT_EQ(fs::path("/home/foo").extension(), std::string("")); - EXPECT_EQ(fs::path("/home/foo").replace_extension(".jpeg").string(), std::string("/home/foo.jpeg")); + EXPECT_EQ(fs::path("/home/foo").replace_extension(".jpeg").string(), + std::string("/home/foo.jpeg")); auto p4 = fs::path("/home/foo/a.out"); EXPECT_EQ(p4.parent_path().string(), "/home/foo"); @@ -53,14 +47,12 @@ TEST(module_manager, test_compat_path) EXPECT_FALSE(fs::exists("not_exists")); } - #ifndef BMF_ENABLE_MOBILE // -TEST(module_manager, resolve_module_info) -{ +TEST(module_manager, resolve_module_info) { auto &M = ModuleManager::instance(); - //resolve module info from builtin(ffmpeg-based) + // resolve module info from builtin(ffmpeg-based) { auto info = M.resolve_module_info("c_ffmpeg_decoder"); ASSERT_TRUE(info != nullptr); @@ -80,7 +72,7 @@ TEST(module_manager, resolve_module_info) EXPECT_EQ(info->module_type, "c++"); } - //resolve module info from builtin(python) + // resolve module info from builtin(python) { auto info = M.resolve_module_info("cpu_gpu_trans_module"); ASSERT_TRUE(info != nullptr); @@ -121,12 +113,10 @@ TEST(module_manager, resolve_module_info) } } - -TEST(module_manager, load_module) -{ +TEST(module_manager, load_module) { auto &M = ModuleManager::instance(); - //load builtin module(ffmpeg-based) + // load builtin module(ffmpeg-based) { auto facotry = M.load_module("c_ffmpeg_decoder"); ASSERT_TRUE(facotry != nullptr); @@ -134,7 +124,7 @@ TEST(module_manager, load_module) EXPECT_TRUE(module != nullptr); } - //load builtin module(c++) + // load builtin module(c++) { auto facotry = M.load_module("pass_through"); ASSERT_TRUE(facotry != nullptr); @@ -176,10 +166,9 @@ TEST(module_manager, load_module) } -#endif //BMF_ENABLE_MOBILE +#endif // BMF_ENABLE_MOBILE -TEST(module_manager, in_app_module) -{ +TEST(module_manager, in_app_module) { auto &M = ModuleManager::instance(); auto factory = M.load_module("InAppModuleDemo", "c++"); ASSERT_TRUE(factory != nullptr); diff --git a/bmf/sdk/cpp_sdk/test/test_module_registry.cpp b/bmf/sdk/cpp_sdk/test/test_module_registry.cpp index 35ffddf9..5306b6e6 100644 --- a/bmf/sdk/cpp_sdk/test/test_module_registry.cpp +++ b/bmf/sdk/cpp_sdk/test/test_module_registry.cpp @@ -18,14 +18,12 @@ //#include #include - USE_BMF_SDK_NS class CFFTestmodule : public Module { - public: - CFFTestmodule(int node_id, JsonParam option) - : Module(node_id,option) {} - int32_t process(Task &task) {return 0;} + public: + CFFTestmodule(int node_id, JsonParam option) : Module(node_id, option) {} + int32_t process(Task &task) { return 0; } }; REGISTER_MODULE_CLASS(CFFTestmodule) @@ -35,8 +33,10 @@ TEST(module_registry, construct_module) { int node_id = 1; std::string option_str = "{\"name\":\"mock_test_module\"}"; JsonParam json_param = JsonParam(option_str); - std::shared_ptr test_module = ModuleRegistry::ConstructModule(module_name, node_id, json_param); - std::string sdk_version = ModuleRegistry::GetModuleUsingSDKVersion(module_name); + std::shared_ptr test_module = + ModuleRegistry::ConstructModule(module_name, node_id, json_param); + std::string sdk_version = + ModuleRegistry::GetModuleUsingSDKVersion(module_name); EXPECT_EQ(sdk_version, BMF_SDK_VERSION); } @@ -46,7 +46,8 @@ TEST(module_registry, init_by_module_name) { std::string option_str = "{\"name\":\"mock_test_module\"}"; JsonParam json_param = JsonParam(option_str); ModuleRegister module_registry = ModuleRegister(module_name, nullptr); - std::string sdk_version = ModuleRegistry::GetModuleUsingSDKVersion(module_name); + std::string sdk_version = + ModuleRegistry::GetModuleUsingSDKVersion(module_name); EXPECT_EQ(sdk_version, "V0.0.1"); } @@ -56,8 +57,9 @@ TEST(module_registry, init_by_module_name_and_version) { int node_id = 1; std::string option_str = "{\"name\":\"mock_test_module\"}"; JsonParam json_param = JsonParam(option_str); - ModuleRegister module_registry = ModuleRegister(module_name, version, nullptr); - std::string sdk_version = ModuleRegistry::GetModuleUsingSDKVersion(module_name); + ModuleRegister module_registry = + ModuleRegister(module_name, version, nullptr); + std::string sdk_version = + ModuleRegistry::GetModuleUsingSDKVersion(module_name); EXPECT_EQ(sdk_version, "V0.0.3"); } - diff --git a/bmf/sdk/cpp_sdk/test/test_packet.cpp b/bmf/sdk/cpp_sdk/test/test_packet.cpp index 8c196df3..fcd8adab 100644 --- a/bmf/sdk/cpp_sdk/test/test_packet.cpp +++ b/bmf/sdk/cpp_sdk/test/test_packet.cpp @@ -10,51 +10,47 @@ using namespace bmf_sdk; namespace { -struct A{ -}; +struct A {}; -struct B{ -}; +struct B {}; -namespace test{ +namespace test { -struct C{ //copyable, moveable +struct C { // copyable, moveable int value = 0; }; -struct D : public C{ //moveable only - D(D&&) = default; +struct D : public C { // moveable only + D(D &&) = default; std::unique_ptr v_ptr; int *u_ptr = nullptr; - ~D() - { - if(u_ptr){ + ~D() { + if (u_ptr) { *u_ptr = 0x42; } } }; -} //namespace test +} // namespace test -} //namespace +} // namespace -//register in global namespace +// register in global namespace BMF_DEFINE_TYPE(test::C) BMF_DEFINE_TYPE(test::D) -TEST(type_info, type_info) -{ - //default using type_id +TEST(type_info, type_info) { + // default using type_id EXPECT_TRUE(type_info() == type_info()); - EXPECT_TRUE(type_info() == type_info()); - EXPECT_TRUE(type_info() == type_info()); - EXPECT_TRUE(type_info() == type_info()); + EXPECT_TRUE(type_info() == type_info()); + EXPECT_TRUE(type_info() == type_info()); + EXPECT_TRUE(type_info() == type_info()); EXPECT_TRUE(type_info() != type_info()); - //register by BMF_DEFINE_TYPE + // register by BMF_DEFINE_TYPE auto &c_info = type_info(); auto &d_info = type_info(); EXPECT_TRUE(type_info() != c_info); @@ -62,18 +58,14 @@ TEST(type_info, type_info) EXPECT_EQ(c_info.name, std::string("test::C")); EXPECT_EQ(d_info.name, std::string("test::D")); - //pre-define types + // pre-define types EXPECT_EQ(type_info().name, std::string("std::string")); EXPECT_EQ(type_info().name, std::string("hmp::Tensor")); EXPECT_EQ(type_info().name, std::string("bmf_sdk::VideoFrame")); EXPECT_EQ(type_info().name, std::string("bmf_sdk::AudioFrame")); } - - - -TEST(packet, constructors) -{ +TEST(packet, constructors) { Packet pkt0; EXPECT_FALSE(pkt0); @@ -82,10 +74,10 @@ TEST(packet, constructors) int d_destroy_flag = 0x0; { - //type cast - auto pkt_c = Packet(c); //copy c + // type cast + auto pkt_c = Packet(c); // copy c Packet pkt_cc = pkt_c; - //auto pkt_d = Packet(d); //compile error, as d is not copyable + // auto pkt_d = Packet(d); //compile error, as d is not copyable auto pkt_d = Packet(std::move(d)); ASSERT_EQ(pkt_c.unsafe_self(), pkt_cc.unsafe_self()); @@ -104,7 +96,7 @@ TEST(packet, constructors) EXPECT_TRUE(pkt_d.is()); EXPECT_FALSE(pkt_d.is()); - //timestamp + // timestamp EXPECT_EQ(pkt_c.timestamp(), UNSET); pkt_c.set_timestamp(111); EXPECT_EQ(pkt_c.timestamp(), 111); @@ -112,7 +104,7 @@ TEST(packet, constructors) pkt_d.get().u_ptr = &d_destroy_flag; EXPECT_EQ(d_destroy_flag, 0); } - EXPECT_EQ(d_destroy_flag, 0x42); //check if d is destroyed + EXPECT_EQ(d_destroy_flag, 0x42); // check if d is destroyed auto pkt_eos = Packet::generate_eos_packet(); EXPECT_EQ(pkt_eos.timestamp(), EOS); @@ -123,5 +115,4 @@ TEST(packet, constructors) // auto rgb = hmp::PixelInfo(hmp::PF_RGB24); EXPECT_NO_THROW(Packet(VideoFrame::make(720, 1280, rgb))); - } diff --git a/bmf/sdk/cpp_sdk/test/test_task.cpp b/bmf/sdk/cpp_sdk/test/test_task.cpp index 1acaa78e..cdc6c160 100644 --- a/bmf/sdk/cpp_sdk/test/test_task.cpp +++ b/bmf/sdk/cpp_sdk/test/test_task.cpp @@ -32,7 +32,7 @@ TEST(task, task) { EXPECT_EQ(task.get_input_stream_ids().size(), 2); EXPECT_EQ(task.get_output_stream_ids().size(), 1); - //TEST input stream + // TEST input stream { Packet pkt0(0); pkt0.set_timestamp(9); @@ -41,26 +41,25 @@ TEST(task, task) { Packet pkt1(0); pkt1.set_timestamp(9); task.fill_input_packet(1, pkt1); - + Packet pkt_output; - std::cout << task.pop_packet_from_input_queue(0, pkt_output) << std::endl; + std::cout << task.pop_packet_from_input_queue(0, pkt_output) + << std::endl; EXPECT_EQ(pkt_output.timestamp(), 9); - + PacketQueueMap input_stream_map = task.get_inputs(); EXPECT_EQ(input_stream_map[0]->size(), 0); EXPECT_EQ(input_stream_map[1]->size(), 1); - } - //TEST output stream + // TEST output stream { Packet pkt(0); pkt.set_timestamp(88); - task.fill_output_packet(0,pkt); + task.fill_output_packet(0, pkt); Packet pkt_output; task.pop_packet_from_out_queue(0, pkt_output); EXPECT_EQ(pkt_output.timestamp(), 88); PacketQueueMap output_stream_map = task.get_outputs(); EXPECT_EQ(output_stream_map[0]->size(), 0); } - } \ No newline at end of file diff --git a/bmf/sdk/cpp_sdk/test/test_video_frame.cpp b/bmf/sdk/cpp_sdk/test/test_video_frame.cpp index 2e40dbae..25b8e4dd 100644 --- a/bmf/sdk/cpp_sdk/test/test_video_frame.cpp +++ b/bmf/sdk/cpp_sdk/test/test_video_frame.cpp @@ -9,34 +9,34 @@ #include #include - using namespace bmf_sdk; -//NOTE: all correctness of tensor operations are tested in hml/tests +// NOTE: all correctness of tensor operations are tested in hml/tests -template -static bool check_pixel_value(const VideoFrame &vf, const T &v) -{ - //ASSERT_TRUE(vf.is_image()); - //ASSERT_TRUE(vf.device() == kCPU); +template +static bool check_pixel_value(const VideoFrame &vf, const T &v) { + // ASSERT_TRUE(vf.is_image()); + // ASSERT_TRUE(vf.device() == kCPU); - //RGB HWC + // RGB HWC auto frame = vf.frame(); - //only one plane + // only one plane auto &data = frame.plane(0); int64_t channels = data.size(hmp::HWC_C); // int64_t w = data.size(hmp::HWC_W); int64_t h = data.size(hmp::HWC_H); - const T* ptr = data.data(); + const T *ptr = data.data(); - for (int64_t c = 0; c < channels; ++c){ - for (int64_t y = 0; y < h; ++y){ - for (int64_t x = 0; x < w; ++x){ - auto idx = c * data.stride(hmp::HWC_C) + y * data.stride(hmp::HWC_H) + x * data.stride(hmp::HWC_W); - if(ptr[idx] != v){ + for (int64_t c = 0; c < channels; ++c) { + for (int64_t y = 0; y < h; ++y) { + for (int64_t x = 0; x < w; ++x) { + auto idx = c * data.stride(hmp::HWC_C) + + y * data.stride(hmp::HWC_H) + + x * data.stride(hmp::HWC_W); + if (ptr[idx] != v) { return false; } } @@ -46,27 +46,25 @@ static bool check_pixel_value(const VideoFrame &vf, const T &v) return true; } -static VideoFrame decode_one_frame(const std::string &path) -{ +static VideoFrame decode_one_frame(const std::string &path) { JsonParam option; option.parse(fmt::format("{{\"input_path\": \"{}\"}}", path)); auto decoder = make_sync_func, std::tuple>( - ModuleInfo("c_ffmpeg_decoder"), option); + ModuleInfo("c_ffmpeg_decoder"), option); VideoFrame vf; std::tie(vf) = decoder(); return vf; } -TEST(video_frame, frame_constructors) -{ +TEST(video_frame, frame_constructors) { int width = 1920, height = 1080; // default constructor VideoFrame undefined; // EXPECT_FALSE(undefined); - //create with default TensorOptions + // create with default TensorOptions auto H420 = PixelInfo(hmp::PF_YUV420P, hmp::CS_BT709); auto vf0 = VideoFrame::make(width, height, H420); // EXPECT_EQ(vf0.width(), width); @@ -76,52 +74,49 @@ TEST(video_frame, frame_constructors) EXPECT_NO_THROW(vf0.frame()); EXPECT_EQ(vf0.frame().format(), hmp::PF_YUV420P); - // With dtype specified, not support +// With dtype specified, not support #ifdef HMP_ENABLE_CUDA - //with device specifed + // with device specifed auto vf2 = VideoFrame::make(1920, 1080, H420, - "cuda:0" //cuda device + "cuda:0" // cuda device ); EXPECT_TRUE(vf2.device() == Device(kCUDA, 0)); EXPECT_TRUE(vf2.dtype() == kUInt8); - auto vf3 = VideoFrame::make(1920, 1080, H420, - Device(kCUDA, 0) //cuda device - ); + auto vf3 = + VideoFrame::make(1920, 1080, H420, Device(kCUDA, 0) // cuda device + ); EXPECT_TRUE(vf3.device() == Device(kCUDA, 0)); auto vf4 = VideoFrame::make(1920, 1080, H420, - kCUDA //cuda device + kCUDA // cuda device ); EXPECT_TRUE(vf4.device() == Device(kCUDA, 0)); #endif - } -TEST(video_frame, crop_test) -{ +TEST(video_frame, crop_test) { int width = 1920, height = 1080; - //frame + // frame auto H420 = PixelInfo(hmp::PF_YUV420P, hmp::CS_BT709); auto vf0 = VideoFrame::make(width, height, H420); // auto vf0_sub = vf0.crop(50, 100, 1280, 720); EXPECT_EQ(vf0_sub.width(), 1280); EXPECT_EQ(vf0_sub.height(), 720); auto &vf0_sub_data = vf0_sub.frame().plane(0); - EXPECT_EQ(vf0_sub_data.stride(0), 1920); //(H, W, 1) layout, stride(0) == line width + EXPECT_EQ(vf0_sub_data.stride(0), + 1920); //(H, W, 1) layout, stride(0) == line width } - #ifdef HMP_ENABLE_CUDA -TEST(video_frame, copy_test) -{ +TEST(video_frame, copy_test) { int width = 1920, height = 1080; - //frame + // frame auto H420 = PixelInfo(hmp::PF_YUV420P, hmp::CS_BT709); auto vf0 = VideoFrame::make(width, height, H420); // EXPECT_TRUE(vf0.device() == kCPU); @@ -131,19 +126,18 @@ TEST(video_frame, copy_test) EXPECT_TRUE(vf0_cpu.device() == kCPU); } -TEST(video_frame, async_execution) -{ +TEST(video_frame, async_execution) { int width = 1920, height = 1080; auto RGB = PixelInfo(hmp::PF_RGB24, hmp::CS_BT709); auto vf0 = VideoFrame::make(width, height, RGB, kCPU); // - auto vf1 = VideoFrame::make(width, height, RGB, kCUDA); - + auto vf1 = VideoFrame::make(width, height, RGB, kCUDA); + VideoFrame vf2; // - auto data = vf0.frame().data()[0]; //shadow copy, remove const - data.fill_(1); //(1, 1, 1, 1, .....) + auto data = vf0.frame().data()[0]; // shadow copy, remove const + data.fill_(1); //(1, 1, 1, 1, .....) - //with cuda stream support + // with cuda stream support auto stream = hmp::create_stream(kCUDA); { hmp::StreamGuard guard(stream); @@ -154,13 +148,13 @@ TEST(video_frame, async_execution) auto data = vf1.frame().data()[0]; data += 2; // (3, 3, 3, 3, ....) - vf2 = vf1.cpu(true); //async copy to cpu + vf2 = vf1.cpu(true); // async copy to cpu vf2.record(); EXPECT_FALSE(vf2.ready()); vf2.synchronize(); - //stream.synchronize(); + // stream.synchronize(); EXPECT_TRUE(vf2.ready()); } @@ -169,20 +163,19 @@ TEST(video_frame, async_execution) EXPECT_TRUE(check_pixel_value(vf2, 3)); } -TEST(video_frame, from_hardware_avframe) -{ +TEST(video_frame, from_hardware_avframe) { int width = 1920, height = 1080; auto NV12 = PixelInfo(hmp::PF_NV12, hmp::CS_BT709); - AVFrame* avfrm = hmp::ffmpeg::hw_avframe_from_device(kCUDA, width, height, NV12); + AVFrame *avfrm = + hmp::ffmpeg::hw_avframe_from_device(kCUDA, width, height, NV12); VideoFrame vf = ffmpeg::to_video_frame(avfrm); EXPECT_TRUE(vf.device() == kCUDA); auto from_video_frame = ffmpeg::from_video_frame(vf); EXPECT_TRUE(from_video_frame->hw_frames_ctx != NULL); } -TEST(video_frame, gpu_frame_to_avframe) -{ +TEST(video_frame, gpu_frame_to_avframe) { int width = 1920, height = 1080; auto NV12 = PixelInfo(hmp::PF_NV12, hmp::CS_BT709); @@ -191,15 +184,14 @@ TEST(video_frame, gpu_frame_to_avframe) EXPECT_TRUE(from_video_frame->hw_frames_ctx != NULL); } - -TEST(video_frame, hardware_avframe_csc_resize) -{ +TEST(video_frame, hardware_avframe_csc_resize) { int width = 1920, height = 1080; auto NV12 = PixelInfo(hmp::PF_NV12, hmp::CS_BT470BG); auto H420 = PixelInfo(hmp::PF_YUV420P, hmp::CS_BT709); - //auto RGB24 = PixelInfo(hmp::PF_BGR24, hmp::CS_BT709); - AVFrame* avfrm = hmp::ffmpeg::hw_avframe_from_device(kCUDA, width, height, NV12); + // auto RGB24 = PixelInfo(hmp::PF_BGR24, hmp::CS_BT709); + AVFrame *avfrm = + hmp::ffmpeg::hw_avframe_from_device(kCUDA, width, height, NV12); VideoFrame vf = ffmpeg::to_video_frame(avfrm); EXPECT_TRUE(vf.device() == kCUDA); @@ -214,30 +206,26 @@ TEST(video_frame, hardware_avframe_csc_resize) hmp::img::rgb_to_yuv(tl, vf_rgb.frame().data()[0], H420, kNHWC); auto vf_resize = VideoFrame::make(width / 2, height / 2, H420, kCUDA); - //TensorList &yuv_resize(TensorList &dst, const TensorList &src, + // TensorList &yuv_resize(TensorList &dst, const TensorList &src, // PPixelFormat format, ImageFilterMode mode) - //HMP_API TensorList &yuv_resize(TensorList &dst, const TensorList &src, const PixelInfo &pix_info, ImageFilterMode mode = ImageFilterMode::Bilinear); + // HMP_API TensorList &yuv_resize(TensorList &dst, const TensorList &src, + // const PixelInfo &pix_info, ImageFilterMode mode = + // ImageFilterMode::Bilinear); TensorList tl_resize = vf_resize.frame().data(); hmp::img::yuv_resize(tl_resize, vf_yuv_from_rgb.frame().data(), H420); - EXPECT_EQ(tl_resize.data()[0].size(0), height/2); - EXPECT_EQ(tl_resize.data()[0].size(1), width/2); + EXPECT_EQ(tl_resize.data()[0].size(0), height / 2); + EXPECT_EQ(tl_resize.data()[0].size(1), width / 2); } #endif +namespace bmf_sdk { -namespace bmf_sdk{ +struct MockAVFrame { + MockAVFrame(bool *valid_p) : valid(valid_p) { *valid = true; } -struct MockAVFrame -{ - MockAVFrame(bool *valid_p) : valid(valid_p) - { - *valid = true; - } - - ~MockAVFrame() - { - if(valid){ + ~MockAVFrame() { + if (valid) { *valid = false; } } @@ -247,23 +235,18 @@ struct MockAVFrame bool *valid = nullptr; }; -template<> -struct OpaqueDataInfo -{ +template <> struct OpaqueDataInfo { const static int key = OpaqueDataKey::kAVFrame; - static OpaqueData construct(const MockAVFrame *avf) - { - return OpaqueData(const_cast(avf), [](void *p){ - delete (MockAVFrame*)p; - }); + static OpaqueData construct(const MockAVFrame *avf) { + return OpaqueData(const_cast(avf), + [](void *p) { delete (MockAVFrame *)p; }); } }; -} //namespace bmf_sdk +} // namespace bmf_sdk -TEST(video_frame, private_data) -{ +TEST(video_frame, private_data) { int width = 1920, height = 1080; bool valid = false; @@ -279,13 +262,16 @@ TEST(video_frame, private_data) // auto vf1 = VideoFrame::make(width, height, RGB); // vf1.copy_(vf0); - vf1.private_merge(vf0); // now, vf0 and vf1 will share the same private data + vf1.private_merge( + vf0); // now, vf0 and vf1 will share the same private data EXPECT_EQ(vf1.private_get()->value, 42); - //vf1.private_get()->value = 100; //modify already set private data is not allowed - //as it may cause unpredictable error(it may used in other modules) - //solution to modify private data is to copy it - auto pri_data_copy = new MockAVFrame(*vf0.private_get()); //copy + // vf1.private_get()->value = 100; //modify already set + // private data is not allowed + // as it may cause unpredictable error(it may used in other modules) + // solution to modify private data is to copy it + auto pri_data_copy = + new MockAVFrame(*vf0.private_get()); // copy EXPECT_EQ(pri_data_copy->value, 42); pri_data_copy->valid = nullptr; pri_data_copy->value = 100; @@ -294,23 +280,21 @@ TEST(video_frame, private_data) EXPECT_EQ(vf0.private_get()->value, 42); // - EXPECT_TRUE(valid); //ensure pri_data is alive + EXPECT_TRUE(valid); // ensure pri_data is alive } - EXPECT_FALSE(valid); //pri_data is destructed + EXPECT_FALSE(valid); // pri_data is destructed } - -TEST(video_frame, private_data_json_param) -{ +TEST(video_frame, private_data_json_param) { auto RGB = PixelInfo(hmp::PF_RGB24, hmp::CS_BT709); auto vf = VideoFrame::make(1920, 1080, RGB); // auto json_sptr = vf.private_get(); EXPECT_FALSE(json_sptr); - JsonParam ref; + JsonParam ref; ref.parse("{\"v\": 42}"); - vf.private_attach(&ref); //copy it internally + vf.private_attach(&ref); // copy it internally auto data_sptr = vf.private_get(); ASSERT_TRUE(data_sptr); @@ -318,14 +302,12 @@ TEST(video_frame, private_data_json_param) EXPECT_EQ(data_sptr->get("v"), 42); } - -TEST(video_frame, copy_props) -{ +TEST(video_frame, copy_props) { auto H420 = PixelInfo(hmp::PF_YUV420P, hmp::CS_BT709); int width = 1920, height = 1080; auto RGB = PixelInfo(hmp::PF_RGB24, hmp::CS_BT709); - auto vf0 = VideoFrame::make(width, height, RGB); //Image type - auto vf1 = VideoFrame::make(width, height, H420); //Frame type + auto vf0 = VideoFrame::make(width, height, RGB); // Image type + auto vf1 = VideoFrame::make(width, height, H420); // Frame type vf0.set_stream(42); vf0.set_time_base(Rational(1, 2)); @@ -338,8 +320,7 @@ TEST(video_frame, copy_props) EXPECT_EQ(vf1.time_base().num, 1); } -TEST(video_frame, reformat) -{ +TEST(video_frame, reformat) { auto ori_vf = decode_one_frame("../../files/big_bunny_10s_30fps.mp4"); ASSERT_EQ(ori_vf.frame().format(), hmp::PF_YUV420P); EXPECT_EQ(ori_vf.height(), 1080); @@ -350,7 +331,7 @@ TEST(video_frame, reformat) EXPECT_EQ(ori_vf.frame().plane(1).stride(0), 1920 / 2); EXPECT_EQ(ori_vf.frame().plane(2).stride(0), 1920 / 2); - //reformat yuv420p -> rgb + // reformat yuv420p -> rgb { auto RGB = PixelInfo(hmp::PF_RGB24, hmp::CS_BT709); auto rgb_vf = ori_vf.reformat(RGB); @@ -408,13 +389,11 @@ TEST(video_frame, reformat) ASSERT_EQ(new_img.frame().format(), hmp::PF_RGB24); ASSERT_TRUE(new_img.frame().pix_info().is_rgbx()); EXPECT_EQ(new_img.frame().plane(0).stride(0), 3 * 1920); - } } #ifdef BMF_ENABLE_FFMPEG -TEST(video_frame, reformat_by_ffmpeg) -{ +TEST(video_frame, reformat_by_ffmpeg) { auto ori_vf = decode_one_frame("../../files/big_bunny_10s_30fps.mp4"); ASSERT_EQ(ori_vf.frame().format(), hmp::PF_YUV420P); EXPECT_EQ(ori_vf.height(), 1080); @@ -425,7 +404,7 @@ TEST(video_frame, reformat_by_ffmpeg) EXPECT_EQ(ori_vf.frame().plane(1).stride(0), 1920 / 2); EXPECT_EQ(ori_vf.frame().plane(2).stride(0), 1920 / 2); - //reformat yuv420p -> rgb + // reformat yuv420p -> rgb { auto rgb_vf = ffmpeg::reformat(ori_vf, "rgb24"); EXPECT_EQ(rgb_vf.height(), 1080); @@ -505,6 +484,5 @@ TEST(video_frame, reformat_by_ffmpeg) EXPECT_EQ(yuv_vf.frame().plane(1).stride(0), 1920 / 2); EXPECT_EQ(yuv_vf.frame().plane(2).stride(0), 1920 / 2); } - } #endif diff --git a/bmf/test/cpp_builder/cpp_demo.cpp b/bmf/test/cpp_builder/cpp_demo.cpp index e852d7aa..12ace546 100644 --- a/bmf/test/cpp_builder/cpp_demo.cpp +++ b/bmf/test/cpp_builder/cpp_demo.cpp @@ -2,19 +2,18 @@ #include "nlohmann/json.hpp" void rgb2video() { - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { {"input_path", "/opt/tiger/bmf/test/files/test_rgba_806x654.rgb"}, {"s", "806:654"}, - {"pix_fmt", "rgba"} - }; + {"pix_fmt", "rgba"}}; auto stream = graph.Decode(bmf_sdk::JsonParam(decode_para)); - auto video_stream = stream["video"].FFMpegFilter({}, "loop", "loop=50:size=1"); + auto video_stream = + stream["video"].FFMpegFilter({}, "loop", "loop=50:size=1"); nlohmann::json encode_para = { {"output_path", "./rgb2video.mp4"}, @@ -22,7 +21,8 @@ void rgb2video() { // graph.Encode(video_stream, bmf_sdk::JsonParam(encode_para)); - graph.Encode(video_stream, stream["audio"], bmf_sdk::JsonParam(encode_para)); + graph.Encode(video_stream, stream["audio"], + bmf_sdk::JsonParam(encode_para)); graph.Run(); } diff --git a/bmf/test/cpp_builder/cpp_edit.cpp b/bmf/test/cpp_builder/cpp_edit.cpp index 42c320d7..7035b4fe 100644 --- a/bmf/test/cpp_builder/cpp_edit.cpp +++ b/bmf/test/cpp_builder/cpp_edit.cpp @@ -7,14 +7,12 @@ TEST(cpp_edit, edit_concat) { std::string output_file = "./video_concat.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 0} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 0}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; std::vector video_concat_streams; std::vector video_transit_streams; @@ -29,37 +27,36 @@ TEST(cpp_edit, edit_concat) { if (i < 2) { auto split_stream = video_stream.Split(""); auto concat_stream = split_stream[0] - .Trim("start=0:duration=5") - .Setpts("PTS-STARTPTS"); + .Trim("start=0:duration=5") + .Setpts("PTS-STARTPTS"); auto transition_stream = split_stream[1] - .Trim("start=5:duration=2") - .Setpts("PTS-STARTPTS") - .Scale("200:200"); + .Trim("start=5:duration=2") + .Setpts("PTS-STARTPTS") + .Scale("200:200"); video_transit_streams.push_back(transition_stream); video_concat_streams.push_back(concat_stream); } else { - auto concat_stream = video_stream - .Trim("start=0:duration=5") - .Setpts("PTS-STARTPTS"); - + auto concat_stream = + video_stream.Trim("start=0:duration=5").Setpts("PTS-STARTPTS"); + video_concat_streams.push_back(concat_stream); } if (i > 0) { - auto concat_stream = video_concat_streams[i] - .Overlay({video_transit_streams[i-1]}, "repeatlast=0"); + auto concat_stream = video_concat_streams[i].Overlay( + {video_transit_streams[i - 1]}, "repeatlast=0"); video_concat_streams.pop_back(); video_concat_streams.push_back(concat_stream); } - + // Process audio streams auto audio_stream = video["audio"] - .Atrim("start=0:duration=5") - .Asetpts("PTS-STARTPTS") - .Afade("t=in:st=0:d=2") - .Afade("t=out:st=5:d=2"); + .Atrim("start=0:duration=5") + .Asetpts("PTS-STARTPTS") + .Afade("t=in:st=0:d=2") + .Afade("t=out:st=5:d=2"); audio_concat_streams.push_back(audio_stream); } @@ -69,70 +66,58 @@ TEST(cpp_edit, edit_concat) { nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"width", 1280}, - {"height", 720} - }} - }; + {"video_params", {{"width", 1280}, {"height", 720}}}}; graph.Encode(concat_video, concat_audio, bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../edit/video_concat.mp4|720|1280|15.022000|MOV,MP4,M4A,3GP,3G2,MJ2|385322|722480|h264|{\"fps\": \"30.0166759311\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../edit/" + "video_concat.mp4|720|1280|15.022000|MOV," + "MP4,M4A,3GP,3G2,MJ2|385322|722480|h264|{" + "\"fps\": \"30.0166759311\"}"); } TEST(cpp_edit, edit_overlay) { std::string output_file = "./overlays.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 0} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 0}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); nlohmann::json logoPara = { - {"input_path", "../../files/xigua_prefix_logo_x.mov"} - }; + {"input_path", "../../files/xigua_prefix_logo_x.mov"}}; auto logo = graph.Decode(bmf_sdk::JsonParam(logoPara)); - auto output_stream = video["video"].Scale("1280:720") - .Trim("start=0:duration=7") - .Setpts("PTS-STARTPTS"); + auto output_stream = video["video"] + .Scale("1280:720") + .Trim("start=0:duration=7") + .Setpts("PTS-STARTPTS"); - auto overlay = logo["video"].Scale("300:200") - .Loop("loop=0:size=10000") - .Setpts("PTS+0/TB"); + auto overlay = logo["video"] + .Scale("300:200") + .Loop("loop=0:size=10000") + .Setpts("PTS+0/TB"); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"width", 640}, - {"height", 480}, - {"codec", "h264"} - }} - }; + {"video_params", {{"width", 640}, {"height", 480}, {"codec", "h264"}}}}; output_stream[0] - .Overlay( - {overlay}, - "x=if(between(t,0,7),0,NAN):y=if(between(t,0,7),0,NAN):repeatlast=1" - ) + .Overlay({overlay}, "x=if(between(t,0,7),0,NAN):y=if(between(t,0,7),0," + "NAN):repeatlast=1") .EncodeAsVideo(bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../edit/overlays.mp4|480|640|6.984000|MOV,MP4,M4A,3GP,3G2,MJ2|132817|116215|h264|{\"fps\": \"30.0715990453\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../edit/" + "overlays.mp4|480|640|6.984000|MOV,MP4,M4A," + "3GP,3G2,MJ2|132817|116215|h264|{\"fps\": " + "\"30.0715990453\"}"); } /* TEST(cpp_edit, edit_audio_mix) { */ @@ -142,7 +127,8 @@ TEST(cpp_edit, edit_overlay) { /* nlohmann::json graph_para = { */ /* {"dump_graph", 0} */ /* }; */ -/* auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); */ +/* auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + * bmf_sdk::JsonParam(graph_para)); */ /* nlohmann::json decode_para = { */ /* {"input_path", "../../files/big_bunny_10s_30fps.mp4"} */ @@ -162,8 +148,9 @@ TEST(cpp_edit, edit_overlay) { /* } */ /* } */ /* }; */ - -/* auto audio_stream = graph.Module({video["audio"], video2["audio"]}, "audio_mix", bmf::builder::Python, bmf_sdk::JsonParam(module_para), */ + +/* auto audio_stream = graph.Module({video["audio"], video2["audio"]}, + * "audio_mix", bmf::builder::Python, bmf_sdk::JsonParam(module_para), */ /* "MyModule", "../../example/edit", "audio_mix:audio_mix" */ /* ); */ @@ -174,12 +161,14 @@ TEST(cpp_edit, edit_overlay) { /* {"height", 480} */ /* }} */ /* }; */ -/* video["video"].EncodeAsVideo(audio_stream, bmf_sdk::JsonParam(encode_para)); */ +/* video["video"].EncodeAsVideo(audio_stream, + * bmf_sdk::JsonParam(encode_para)); */ /* std::cout << graph.Dump() << std::endl; */ /* graph.Run(); */ /* BMF_CPP_FILE_CHECK( */ -/* output_file, */ -/* "../edit/audio_mix.mp4|480|640|7.550000|MOV,MP4,M4A,3GP,3G2,MJ2|1143753|1079417|h264|{\"fps\": \"30.0662251656\"}" */ +/* output_file, */ +/* "../edit/audio_mix.mp4|480|640|7.550000|MOV,MP4,M4A,3GP,3G2,MJ2|1143753|1079417|h264|{\"fps\": + * \"30.0662251656\"}" */ /* ); */ /* } */ diff --git a/bmf/test/cpp_builder/cpp_fileconfig.cpp b/bmf/test/cpp_builder/cpp_fileconfig.cpp index 8ebe28cd..7f260eaa 100644 --- a/bmf/test/cpp_builder/cpp_fileconfig.cpp +++ b/bmf/test/cpp_builder/cpp_fileconfig.cpp @@ -11,9 +11,7 @@ TEST(cpp_fileconfig, run_by_config) { std::string output_file = "../../files/out.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; // auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); std::string filepath = "../../test/run_by_config/config.json"; // nlohmann::json graph_json; @@ -22,8 +20,8 @@ TEST(cpp_fileconfig, run_by_config) { auto graph = bmf::BMFGraph(filepath, true, true); graph.start(); graph.close(); - BMF_CPP_FILE_CHECK( - output_file, - "../../files/out.mp4|240|320|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|175470|219513|h264|{\"fps\": \"30.0662251656\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../../files/" + "out.mp4|240|320|10.008|MOV,MP4,M4A,3GP," + "3G2,MJ2|175470|219513|h264|{\"fps\": " + "\"30.0662251656\"}"); } diff --git a/bmf/test/cpp_builder/cpp_module.cpp b/bmf/test/cpp_builder/cpp_module.cpp index f666c6ad..d4db67e4 100644 --- a/bmf/test/cpp_builder/cpp_module.cpp +++ b/bmf/test/cpp_builder/cpp_module.cpp @@ -7,132 +7,108 @@ TEST(cpp_modules, module_python) { std::string output_file = "./output.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - nlohmann::json encode_para = { - {"output_path", output_file} - }; + nlohmann::json encode_para = {{"output_path", output_file}}; - graph.Module({video["video"]}, "test_python_module", bmf::builder::Python, bmf_sdk::JsonParam()).EncodeAsVideo(video["audio"], bmf_sdk::JsonParam(encode_para)); + graph + .Module({video["video"]}, "test_python_module", bmf::builder::Python, + bmf_sdk::JsonParam()) + .EncodeAsVideo(video["audio"], bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "|1080|1920|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|1918874|2400512|h264|{\"fps\": \"30.0662251656\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "|1080|1920|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|" + "1918874|2400512|h264|{\"fps\": " + "\"30.0662251656\"}"); } TEST(cpp_modules, module_cpp) { std::string output_file = "./output.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - auto video_2 = graph.Module( - {video["video"]}, - "copy_module", - bmf::builder::CPP, - bmf_sdk::JsonParam(), - "CopyModule", - "../lib/libcopy_module.so", - "copy_module:CopyModule" - ); + auto video_2 = + graph.Module({video["video"]}, "copy_module", bmf::builder::CPP, + bmf_sdk::JsonParam(), "CopyModule", + "../lib/libcopy_module.so", "copy_module:CopyModule"); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"vsync", "vfr"}, - {"max_fr", 60} - }}, - {"audio_params", { - {"codec", "aac"} - }} - }; + {"video_params", {{"vsync", "vfr"}, {"max_fr", 60}}}, + {"audio_params", {{"codec", "aac"}}}}; graph.Encode(video_2, video["audio"], bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../c_module/output.mp4|1080|1920|10.008000|MOV,MP4,M4A,3GP,3G2,MJ2|1918880|2400520|h264|{\"fps\": \"30.0662251656\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../c_module/" + "output.mp4|1080|1920|10.008000|MOV,MP4," + "M4A,3GP,3G2,MJ2|1918880|2400520|h264|{" + "\"fps\": \"30.0662251656\"}"); } TEST(cpp_modules, audio_python_module) { std::string output_file = "./audio_python_module"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto audio = graph.Decode(bmf_sdk::JsonParam(decode_para))["audio"]; - nlohmann::json encode_para = { - {"output_path", output_file} - }; + nlohmann::json encode_para = {{"output_path", output_file}}; - auto audio_output = graph.Module({audio}, "test_python_module", bmf::builder::Python, bmf_sdk::JsonParam()); - graph.Encode(graph.NewPlaceholderStream(), audio_output, bmf_sdk::JsonParam(encode_para)); + auto audio_output = graph.Module( + {audio}, "test_python_module", bmf::builder::Python, + bmf_sdk::JsonParam()); + graph.Encode(graph.NewPlaceholderStream(), audio_output, + bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../audio_copy/audio_c_module.mp4|0|0|10.008000|MOV,MP4,M4A,3GP,3G2,MJ2|136031|166183||{}" - ); + BMF_CPP_FILE_CHECK(output_file, "../audio_copy/" + "audio_c_module.mp4|0|0|10.008000|MOV,MP4," + "M4A,3GP,3G2,MJ2|136031|166183||{}"); } TEST(cpp_modules, test_exception_in_python_module) { std::string output_file = "./test_exception_in_python_module.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto audio = graph.Decode(bmf_sdk::JsonParam(decode_para))["audio"]; - nlohmann::json encode_para = { - {"output_path", output_file} - }; - nlohmann::json module_para = { - {"exception", 1} - }; - - auto audio_output = graph.Module({audio}, "my_module", bmf::builder::Python, bmf_sdk::JsonParam(module_para), - "MyModule", "../../example/customize_module", "my_module:my_module" - ); - try - { - graph.Encode(graph.NewPlaceholderStream(), audio_output, bmf_sdk::JsonParam(encode_para)); + nlohmann::json encode_para = {{"output_path", output_file}}; + nlohmann::json module_para = {{"exception", 1}}; + + auto audio_output = + graph.Module({audio}, "my_module", bmf::builder::Python, + bmf_sdk::JsonParam(module_para), "MyModule", + "../../example/customize_module", "my_module:my_module"); + try { + graph.Encode(graph.NewPlaceholderStream(), audio_output, + bmf_sdk::JsonParam(encode_para)); graph.Run(); - } - catch(const std::exception& e) - { + } catch (const std::exception &e) { std::cerr << e.what() << '\n'; } } diff --git a/bmf/test/cpp_builder/cpp_premodule.cpp b/bmf/test/cpp_builder/cpp_premodule.cpp index 5680abfa..a6b15859 100644 --- a/bmf/test/cpp_builder/cpp_premodule.cpp +++ b/bmf/test/cpp_builder/cpp_premodule.cpp @@ -7,42 +7,34 @@ TEST(cpp_premodule, premodule) { std::string output_file = "./output.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json pre_module_option = { - {"name", "analysis_SR"}, - {"para", "analysis_SR"} - }; + nlohmann::json pre_module_option = {{"name", "analysis_SR"}, + {"para", "analysis_SR"}}; auto pre_module = bmf::builder::GetModuleInstance( - "analysis", - pre_module_option.dump(), - bmf::builder::Python, - "../../test/pre_module", - "analysis:analysis" - ); + "analysis", pre_module_option.dump(), bmf::builder::Python, + "../../test/pre_module", "analysis:analysis"); for (int i = 0; i < 3; i++) { - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - + auto output = video["video"].Scale("320:240"); - auto analyzed = output.PythonModule({}, "analysis", bmf_sdk::JsonParam()); + auto analyzed = + output.PythonModule({}, "analysis", bmf_sdk::JsonParam()); analyzed.SetPreModule(pre_module); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"width", 300}, - {"height", 200} - }} - }; + {"video_params", {{"width", 300}, {"height", 200}}}}; analyzed.EncodeAsVideo(bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK(output_file, "../pre_module/output.mp4|200|300|10.0|MOV,MP4,M4A,3GP,3G2,MJ2|62956|78695|h264|{\"fps\": \"30.0662251656\"}"); + BMF_CPP_FILE_CHECK(output_file, "../pre_module/" + "output.mp4|200|300|10.0|MOV,MP4,M4A," + "3GP,3G2,MJ2|62956|78695|h264|{\"fps\":" + " \"30.0662251656\"}"); } } diff --git a/bmf/test/cpp_builder/cpp_set_option.cpp b/bmf/test/cpp_builder/cpp_set_option.cpp index 1ae00bab..5dc44447 100644 --- a/bmf/test/cpp_builder/cpp_set_option.cpp +++ b/bmf/test/cpp_builder/cpp_set_option.cpp @@ -11,41 +11,26 @@ TEST(cpp_set_option, set_option) { std::string output_file = "./output.mp4"; BMF_CPP_FILE_REMOVE(output_file); - nlohmann::json graph_para = { - {"dump_graph", 0} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 0}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - auto video_2 = graph.Module( - {video["video"]}, - "copy_module", - bmf::builder::CPP, - bmf_sdk::JsonParam(), - "CopyModule", - "../lib/libcopy_module.so", - "copy_module:CopyModule" - ); + auto video_2 = + graph.Module({video["video"]}, "copy_module", bmf::builder::CPP, + bmf_sdk::JsonParam(), "CopyModule", + "../lib/libcopy_module.so", "copy_module:CopyModule"); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"vsync", "vfr"}, - {"max_fr", 60} - }}, - {"audio_params", { - {"codec", "aac"} - }} - }; + {"video_params", {{"vsync", "vfr"}, {"max_fr", 60}}}, + {"audio_params", {{"codec", "aac"}}}}; graph.Encode(video_2, video["audio"], bmf_sdk::JsonParam(encode_para)); - nlohmann::json option_patch = { - {"dump_graph", 1} - }; + nlohmann::json option_patch = {{"dump_graph", 1}}; graph.SetOption(bmf_sdk::JsonParam(option_patch)); graph.Run(false); diff --git a/bmf/test/cpp_builder/cpp_sync_mode.cpp b/bmf/test/cpp_builder/cpp_sync_mode.cpp index 53fd8604..965ded68 100644 --- a/bmf/test/cpp_builder/cpp_sync_mode.cpp +++ b/bmf/test/cpp_builder/cpp_sync_mode.cpp @@ -10,30 +10,24 @@ TEST(cpp_sync_mode, sync_videoframe) { bmf::builder::Graph graph = bmf::builder::Graph(bmf::builder::NormalMode); // create decoder - nlohmann::json decoder_option = { - {"input_path", "../../files/overlay.png"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {0}, - bmf_sdk::JsonParam(decoder_option), "c_ffmpeg_decoder"); + nlohmann::json decoder_option = {{"input_path", "../../files/overlay.png"}}; + auto decoder = + graph.Sync(std::vector {}, std::vector {0}, + bmf_sdk::JsonParam(decoder_option), "c_ffmpeg_decoder"); // create scale - nlohmann::json scale_option = { - {"name", "scale"}, - {"para", "320:240"} - }; - auto scale = graph.Sync(std::vector {0}, std::vector {0}, - bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); + nlohmann::json scale_option = {{"name", "scale"}, {"para", "320:240"}}; + auto scale = + graph.Sync(std::vector{0}, std::vector{0}, + bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); // create encoder - nlohmann::json encoder_option = { - {"output_path", output_file}, - {"format", "mjpeg"}, - {"video_params", { - {"codec", "jpg"} - }} - }; - auto encoder = graph.Sync(std::vector {0}, std::vector {}, - bmf_sdk::JsonParam(encoder_option), "c_ffmpeg_encoder"); + nlohmann::json encoder_option = {{"output_path", output_file}, + {"format", "mjpeg"}, + {"video_params", {{"codec", "jpg"}}}}; + auto encoder = + graph.Sync(std::vector{0}, std::vector{}, + bmf_sdk::JsonParam(encoder_option), "c_ffmpeg_encoder"); // call init if necessary, otherwise we skip this step graph.Init(decoder); @@ -60,7 +54,9 @@ TEST(cpp_sync_mode, sync_videoframe) { graph.Close(scale); graph.Close(encoder); - BMF_CPP_FILE_CHECK(output_file, "./videoframe.jpg|240|320|0.04|IMAGE2|950000|4750|mjpeg|{\"fps\": \"25.0\"}"); + BMF_CPP_FILE_CHECK(output_file, "./" + "videoframe.jpg|240|320|0.04|IMAGE2|950000|" + "4750|mjpeg|{\"fps\": \"25.0\"}"); } TEST(cpp_sync_mode, sync_audioframe) { @@ -71,40 +67,40 @@ TEST(cpp_sync_mode, sync_audioframe) { // create decoder nlohmann::json decoder_option = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {1}, decoder_option, "c_ffmpeg_decoder"); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto decoder = graph.Sync(std::vector{}, std::vector{1}, + decoder_option, "c_ffmpeg_decoder"); // create volume - nlohmann::json volume_option = { - {"name", "volume"}, - {"para", "volume=3"} - }; - auto volume = graph.Sync(std::vector {0}, std::vector {0}, volume_option, "c_ffmpeg_filter"); + nlohmann::json volume_option = {{"name", "volume"}, {"para", "volume=3"}}; + auto volume = graph.Sync(std::vector{0}, std::vector{0}, + volume_option, "c_ffmpeg_filter"); // create encoder - nlohmann::json encoder_option = { - {"output_path", output_file} - }; - auto encoder = graph.Sync(std::vector {0,1}, std::vector {}, encoder_option, "c_ffmpeg_encoder"); + nlohmann::json encoder_option = {{"output_path", output_file}}; + auto encoder = graph.Sync(std::vector{0, 1}, std::vector{}, + encoder_option, "c_ffmpeg_encoder"); // decode and get audio frame - auto decoded_frames = decoder.ProcessPkts(std::map > {}); + auto decoded_frames = + decoder.ProcessPkts(std::map>{}); // volume - std::map > input_volume; + std::map> input_volume; input_volume.insert(std::make_pair(0, decoded_frames[1])); auto volume_frames = volume.ProcessPkts(input_volume); // encode - std::map > input_encode; + std::map> input_encode; input_encode.insert(std::make_pair(1, input_volume[0])); encoder.ProcessPkts(input_encode); // send eof to encoder encoder.SendEOF(); - BMF_CPP_FILE_CHECK(output_file, "./audioframe.mp4|0|0|0.024|MOV,MP4,M4A,3GP,3G2,MJ2|271000|795||{}"); + BMF_CPP_FILE_CHECK( + output_file, + "./audioframe.mp4|0|0|0.024|MOV,MP4,M4A,3GP,3G2,MJ2|271000|795||{}"); } TEST(cpp_sync_mode, sync_video_by_pkts) { @@ -115,27 +111,22 @@ TEST(cpp_sync_mode, sync_video_by_pkts) { // create sync modules nlohmann::json decoder_option = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {0,1}, decoder_option, "c_ffmpeg_decoder"); - - nlohmann::json scale_option = { - {"name", "scale"}, - {"para", "320:250"} - }; - auto scale = graph.Sync(std::vector {0}, std::vector {0}, - bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); - - nlohmann::json volume_option = { - {"name", "volume"}, - {"para", "volume=3"} - }; - auto volume = graph.Sync(std::vector {0}, std::vector {0}, volume_option, "c_ffmpeg_filter"); - - nlohmann::json encoder_option = { - {"output_path", output_file} - }; - auto encoder = graph.Sync(std::vector {0,1}, std::vector {}, encoder_option, "c_ffmpeg_encoder"); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto decoder = graph.Sync(std::vector{}, std::vector {0,1}, + decoder_option, "c_ffmpeg_decoder"); + + nlohmann::json scale_option = {{"name", "scale"}, {"para", "320:250"}}; + auto scale = + graph.Sync(std::vector{0}, std::vector{0}, + bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); + + nlohmann::json volume_option = {{"name", "volume"}, {"para", "volume=3"}}; + auto volume = graph.Sync(std::vector{0}, std::vector{0}, + volume_option, "c_ffmpeg_filter"); + + nlohmann::json encoder_option = {{"output_path", output_file}}; + auto encoder = graph.Sync(std::vector{0,1}, std::vector{}, + encoder_option, "c_ffmpeg_encoder"); // call init if necessary, otherwise we skip this step graph.Init(decoder); @@ -180,7 +171,10 @@ TEST(cpp_sync_mode, sync_video_by_pkts) { graph.Close(volume); graph.Close(encoder); - BMF_CPP_FILE_CHECK(output_file, "./video_simple_interface.mp4|250|320|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|224724|281130|h264|{\"fps\": \"30\"}"); + BMF_CPP_FILE_CHECK(output_file, "./" + "video_simple_interface.mp4|250|320|10.008|" + "MOV,MP4,M4A,3GP,3G2,MJ2|224724|281130|" + "h264|{\"fps\": \"30\"}"); } TEST(cpp_sync_mode, sync_audio) { @@ -191,20 +185,17 @@ TEST(cpp_sync_mode, sync_audio) { // create sync modules nlohmann::json decoder_option = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {1}, decoder_option, "c_ffmpeg_decoder"); - - nlohmann::json volume_option = { - {"name", "volume"}, - {"para", "volume=3"} - }; - auto volume = graph.Sync(std::vector {0}, std::vector {0}, volume_option, "c_ffmpeg_filter"); - - nlohmann::json encoder_option = { - {"output_path", output_file} - }; - auto encoder = graph.Sync(std::vector {0,1}, std::vector {}, encoder_option, "c_ffmpeg_encoder"); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto decoder = graph.Sync(std::vector{}, std::vector{1}, + decoder_option, "c_ffmpeg_decoder"); + + nlohmann::json volume_option = {{"name", "volume"}, {"para", "volume=3"}}; + auto volume = graph.Sync(std::vector{0}, std::vector{0}, + volume_option, "c_ffmpeg_filter"); + + nlohmann::json encoder_option = {{"output_path", output_file}}; + auto encoder = graph.Sync(std::vector{0,1}, std::vector{}, + encoder_option, "c_ffmpeg_encoder"); // process video/audio by sync mode while (1) { @@ -217,13 +208,15 @@ TEST(cpp_sync_mode, sync_audio) { bmf::builder::SyncPackets input_volume; input_volume.Insert(0, decoded_frames[1]); auto volume_frames = volume.ProcessPkts(input_volume); - + bmf::builder::SyncPackets input_encoder; input_encoder.Insert(1, volume_frames[0]); encoder.ProcessPkts(input_encoder); } - BMF_CPP_FILE_CHECK(output_file, "./audio.mp4|0|0|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|131882|166192||{}"); + BMF_CPP_FILE_CHECK( + output_file, + "./audio.mp4|0|0|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|131882|166192||{}"); } TEST(cpp_sync_mode, sync_video) { @@ -234,27 +227,22 @@ TEST(cpp_sync_mode, sync_video) { // create sync modules nlohmann::json decoder_option = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {0,1}, decoder_option, "c_ffmpeg_decoder"); - - nlohmann::json scale_option = { - {"name", "scale"}, - {"para", "320:250"} - }; - auto scale = graph.Sync(std::vector {0}, std::vector {0}, - bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); - - nlohmann::json volume_option = { - {"name", "volume"}, - {"para", "volume=3"} - }; - auto volume = graph.Sync(std::vector {0}, std::vector {0}, volume_option, "c_ffmpeg_filter"); - - nlohmann::json encoder_option = { - {"output_path", output_file} - }; - auto encoder = graph.Sync(std::vector {0,1}, std::vector {}, encoder_option, "c_ffmpeg_encoder"); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto decoder = graph.Sync(std::vector{}, std::vector{0,1}, + decoder_option, "c_ffmpeg_decoder"); + + nlohmann::json scale_option = {{"name", "scale"}, {"para", "320:250"}}; + auto scale = + graph.Sync(std::vector{0}, std::vector{0}, + bmf_sdk::JsonParam(scale_option), "c_ffmpeg_filter"); + + nlohmann::json volume_option = {{"name", "volume"}, {"para", "volume=3"}}; + auto volume = graph.Sync(std::vector{0}, std::vector{0}, + volume_option, "c_ffmpeg_filter"); + + nlohmann::json encoder_option = {{"output_path", output_file}}; + auto encoder = graph.Sync(std::vector{0,1}, std::vector{}, + encoder_option, "c_ffmpeg_encoder"); // call init if necessary, otherwise we skip this step graph.Init(decoder); @@ -264,7 +252,8 @@ TEST(cpp_sync_mode, sync_video) { // process video/audio by sync mode while (1) { - auto decoded_frames = graph.Process(decoder, bmf::builder::SyncPackets()); + auto decoded_frames = + graph.Process(decoder, bmf::builder::SyncPackets()); bool has_next = false; for (const auto &stream : decoded_frames.packets) { if (!stream.second.empty()) { @@ -277,17 +266,17 @@ TEST(cpp_sync_mode, sync_video) { bmf::builder::SyncPackets input_encoder; input_encoder.Insert(0, scaled_frames[0]); graph.Process(encoder, input_encoder); - //encoder.ProcessPkts(input_encoder); + // encoder.ProcessPkts(input_encoder); } else if (stream.first == 1) { bmf::builder::SyncPackets input_volume; input_volume.Insert(0, decoded_frames[1]); auto volume_frames = graph.Process(volume, input_volume); - //auto volume_frames = volume.ProcessPkts(input_volume); + // auto volume_frames = volume.ProcessPkts(input_volume); bmf::builder::SyncPackets input_encoder; input_encoder.Insert(1, volume_frames[0]); graph.Process(encoder, input_encoder); - //encoder.ProcessPkts(input_encoder); + // encoder.ProcessPkts(input_encoder); } } } @@ -302,7 +291,10 @@ TEST(cpp_sync_mode, sync_video) { graph.Close(volume); graph.Close(encoder); - BMF_CPP_FILE_CHECK(output_file, "./video_simple_interface.mp4|250|320|10.008|MOV,MP4,M4A,3GP,3G2,MJ2|224724|281130|h264|{\"fps\": \"30\"}"); + BMF_CPP_FILE_CHECK(output_file, "./" + "video_simple_interface.mp4|250|320|10.008|" + "MOV,MP4,M4A,3GP,3G2,MJ2|224724|281130|" + "h264|{\"fps\": \"30\"}"); } TEST(cpp_sync_mode, sync_eof_flush_data) { @@ -310,14 +302,16 @@ TEST(cpp_sync_mode, sync_eof_flush_data) { // create decoder nlohmann::json decoder_option = { - {"input_path", "../../files/big_bunny_10s_30fps.mp4"} - }; - auto decoder = graph.Sync(std::vector {}, std::vector {0}, - bmf_sdk::JsonParam(decoder_option), "c_ffmpeg_decoder"); + {"input_path", "../../files/big_bunny_10s_30fps.mp4"}}; + auto decoder = + graph.Sync(std::vector{}, std::vector{0}, + bmf_sdk::JsonParam(decoder_option), "c_ffmpeg_decoder"); auto decoded_frames = graph.Process(decoder, bmf::builder::SyncPackets()); - std::cout<< "get vframe number:" << decoded_frames.packets.size() << std::endl; + std::cout << "get vframe number:" << decoded_frames.packets.size() + << std::endl; decoder.SendEOF(); - std::cout<< "get vframe number after send eof:" << decoded_frames.packets.size() << std::endl; + std::cout << "get vframe number after send eof:" + << decoded_frames.packets.size() << std::endl; graph.Close(decoder); } diff --git a/bmf/test/cpp_builder/cpp_test_helper.cpp b/bmf/test/cpp_builder/cpp_test_helper.cpp index 13a300b1..7b8ab5ea 100644 --- a/bmf/test/cpp_builder/cpp_test_helper.cpp +++ b/bmf/test/cpp_builder/cpp_test_helper.cpp @@ -4,9 +4,11 @@ MediaInfo::MediaInfo(std::string filepath) { // Execute ffprobe char buffer[128]; std::string result = ""; - std::string cmd = "ffprobe -hide_banner -loglevel quiet -print_format json -show_format -show_streams "; - FILE* pipe = popen((cmd + filepath).c_str(), "r"); - if (!pipe) throw std::runtime_error("popen() failed!"); + std::string cmd = "ffprobe -hide_banner -loglevel quiet -print_format json " + "-show_format -show_streams "; + FILE *pipe = popen((cmd + filepath).c_str(), "r"); + if (!pipe) + throw std::runtime_error("popen() failed!"); filePath = filepath; try { while (fgets(buffer, sizeof buffer, pipe) != NULL) { @@ -28,7 +30,7 @@ bool MediaInfo::MediaCompareEquals(std::string expected) { std::vector expected_comps; std::stringstream mcps(expected); std::string token; - while(std::getline(mcps, token, '|')) { + while (std::getline(mcps, token, '|')) { expected_comps.push_back(token); } @@ -39,18 +41,27 @@ bool MediaInfo::MediaCompareEquals(std::string expected) { for (int i = 0; i < mediaJson["streams"].size(); i++) { if (mediaJson["streams"][i]["codec_type"] == "video") { // Check video stream - if (mediaJson["streams"][i]["height"].get() != std::stof(expected_comps[1])) { - std::cout << "Invalid height: " << mediaJson["streams"][i]["height"] << " != " << expected_comps[1] <() != + std::stof(expected_comps[1])) { + std::cout << "Invalid height: " << mediaJson["streams"][i] + ["height"] + << " != " << expected_comps[1] << std::endl; return false; } - if (mediaJson["streams"][i]["width"].get() != std::stof(expected_comps[2])) { - std::cout << "Invalid width: " << mediaJson["streams"][i]["width"] << " != " << expected_comps[2] <() != + std::stof(expected_comps[2])) { + std::cout << "Invalid width: " << mediaJson["streams"][i] + ["width"] + << " != " << expected_comps[2] << std::endl; return false; } - if (mediaJson["streams"][i]["codec_name"].get() != expected_comps[7]) { - std::cout << "Invalid encoding: " << mediaJson["streams"][i]["codec_name"] << " != " << expected_comps[7] <() != + expected_comps[7]) { + std::cout << "Invalid encoding: " << mediaJson["streams"][i] + ["codec_name"] + << " != " << expected_comps[7] << std::endl; return false; } @@ -73,17 +84,21 @@ bool MediaInfo::MediaCompareEquals(std::string expected) { if (fps_comps.size() == 1) fps_f = float(fps_comps[0]); else if (fps_comps.size() > 2) - throw std::runtime_error("Invalid fraction in expected media output"); + throw std::runtime_error( + "Invalid fraction in expected media output"); else if (fps_comps.size() != 0) { if (fps_comps[1] != 0) fps_f = float(fps_comps[0]) / float(fps_comps[1]); } - - float expected_fps = std::stof(extraInfo["fps"].get()); + + float expected_fps = + std::stof(extraInfo["fps"].get()); float expected_diff_fps = expected_fps * 0.1; float actual_diff_fps = std::abs(fps_f - expected_fps); if (actual_diff_fps > expected_diff_fps) { - std::cout << "Invalid FPS: " << mediaJson["streams"][i]["avg_frame_rate"] << " != " << expected_comps[8] <()) - expected_duration); + float actual_diff_duration = + std::abs(std::stof(mediaJson["format"]["duration"].get()) - + expected_duration); if (actual_diff_duration > expected_diff_duration) { - std::cout << "Invalid duration: " << mediaJson["format"]["duration"] << " != " << expected_comps[3] <(); + + std::string format_name = + mediaJson["format"]["format_name"].get(); std::string expected_format_name = expected_comps[4]; - std::transform(format_name.begin(), format_name.end(), format_name.begin(), ::toupper); - std::transform(expected_format_name.begin(), expected_format_name.end(), expected_format_name.begin(), ::toupper); + std::transform(format_name.begin(), format_name.end(), format_name.begin(), + ::toupper); + std::transform(expected_format_name.begin(), expected_format_name.end(), + expected_format_name.begin(), ::toupper); if (format_name != expected_format_name) { - std::cout << "Invalid format: " << mediaJson["format"]["format_name"] << " != " << expected_comps[4] <()) - expected_bitrate); + float actual_diff_bitrate = + std::abs(std::stof(mediaJson["format"]["bit_rate"].get()) - + expected_bitrate); if (actual_diff_bitrate > expected_diff_bitrate) { - std::cout << "Invalid bitrate: " << mediaJson["format"]["bit_rate"] << " != " << expected_comps[5] <()) - expected_size); + float actual_diff_size = + std::abs(std::stof(mediaJson["format"]["size"].get()) - + expected_size); if (actual_diff_size > expected_diff_size) { - std::cout << "Invalid size: " << mediaJson["format"]["size"] << " != " << expected_comps[6] <(); num++; } - } EXPECT_EQ(num, 6); } @@ -651,27 +582,21 @@ TEST(cpp_transcode, transcode_extract_frames) { TEST(cpp_transcode, transcode_incorrect_stream_notify) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./incorrect_stream_notify.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; nlohmann::json encode_para = { {"output_path", output_file}, }; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - try - { + try { auto v = video["wrong_name"]; graph.Encode(v, bmf_sdk::JsonParam(encode_para)); graph.Run(); - } - catch(const std::exception& e) - { + } catch (const std::exception &e) { std::cerr << e.what() << '\n'; } } @@ -679,15 +604,12 @@ TEST(cpp_transcode, transcode_incorrect_stream_notify) { TEST(cpp_transcode, transcode_incorrect_encoder_param) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./incorrect_encoder_param.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); auto v = video["video"]; auto a = video["audio"]; @@ -697,29 +619,20 @@ TEST(cpp_transcode, transcode_incorrect_encoder_param) { std::string wrong_v_2 = "wrong_value_2"; nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"codec", "h264"}, - {"preset", "fast"}, - {"crf", "23"}, - {wrong_k_1, wrong_v_1}, - {wrong_k_2, wrong_v_2}, - }}, - {"audio_params", { - {wrong_k_1, wrong_v_1}, - {wrong_k_2, wrong_v_2} - }}, - {"mux_params", { - {wrong_k_1: wrong_v_1}, - {wrong_k_2: wrong_v_2} - }} - }; - try - { + {"video_params", + { + {"codec", "h264"}, + {"preset", "fast"}, + {"crf", "23"}, + {wrong_k_1, wrong_v_1}, + {wrong_k_2, wrong_v_2}, + }}, + {"audio_params", {{wrong_k_1, wrong_v_1}, {wrong_k_2, wrong_v_2}}}, + {"mux_params", {{wrong_k_1 : wrong_v_1}, {wrong_k_2 : wrong_v_2}}}}; + try { graph.Encode(v, a, bmf_sdk::JsonParam(encode_para)); graph.Run(); - } - catch(const std::exception& e) - { + } catch (const std::exception &e) { std::cerr << e.what() << '\n'; } } @@ -727,91 +640,78 @@ TEST(cpp_transcode, transcode_incorrect_encoder_param) { TEST(cpp_transcode, transcode_duration) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./durations.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file}, - {"durations", {1.5, 3, 5, 6}} - }; + nlohmann::json decode_para = {{"input_path", input_file}, + {"durations", {1.5, 3, 5, 6}}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"codec", "h264"}, - {"width", 320}, - {"height", 240}, - {"crf", 23}, - {"preset", "veryfast"}, - {"vsync", "vfr"}, - {"r", 30} - }}, - }; - graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encode_para)); + {"video_params", + {{"codec", "h264"}, + {"width", 320}, + {"height", 240}, + {"crf", 23}, + {"preset", "veryfast"}, + {"vsync", "vfr"}, + {"r", 30}}}, + }; + graph.Encode(video["video"], video["audio"], + bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../transcode/durations.mp4|240|320|4.54|MOV,MP4,M4A,3GP,3G2,MJ2|105089|59113|h264|{\"fps\": \"16.67\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../transcode/" + "durations.mp4|240|320|4.54|MOV,MP4,M4A," + "3GP,3G2,MJ2|105089|59113|h264|{\"fps\": " + "\"16.67\"}"); } TEST(cpp_transcode, transcode_output_raw_video) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./out.yuv"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); nlohmann::json encode_para = { {"output_path", output_file}, - {"video_params", { - {"codec", "rawvideo"}, - }}, + {"video_params", + { + {"codec", "rawvideo"}, + }}, {"format", "rawvideo"}, }; graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK_MD5( - output_file, - "992f929388f18c43c06c767d63eea15d" - ); + BMF_CPP_FILE_CHECK_MD5(output_file, "992f929388f18c43c06c767d63eea15d"); } TEST(cpp_transcode, transcode_output_null) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - nlohmann::json encode_para = { - {"null_output", 1} - }; - graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encode_para)); + nlohmann::json encode_para = {{"null_output", 1}}; + graph.Encode(video["video"], video["audio"], + bmf_sdk::JsonParam(encode_para)); graph.Run(); } TEST(cpp_transcode, transcode_vframes) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./simple.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); nlohmann::json decode_para = { {"input_path", input_file}, @@ -820,244 +720,226 @@ TEST(cpp_transcode, transcode_vframes) { nlohmann::json encode_para = { {"output_path", output_file}, {"vframes", 30}, - {"video_params", { - {"codec", "h264"}, - {"width", 640}, - {"height", 480}, - {"crf", 23}, - {"preset", "veryfast"} - }}, + {"video_params", + {{"codec", "h264"}, + {"width", 640}, + {"height", 480}, + {"crf", 23}, + {"preset", "veryfast"}}}, }; graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - output_file, - "../transcode/simple.mp4|480|640|1.001000|MOV,MP4,M4A,3GP,3G2,MJ2|110976|13872|h264|{\"fps\": \"29.97\"}" - ); + BMF_CPP_FILE_CHECK(output_file, "../transcode/" + "simple.mp4|480|640|1.001000|MOV,MP4,M4A," + "3GP,3G2,MJ2|110976|13872|h264|{\"fps\": " + "\"29.97\"}"); } TEST(cpp_transcode, transcode_segment_trans) { std::string input_file = "../../files/big_bunny_10s_30fps_mpeg.mp4"; std::string output_file = "./simple_%05d.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file}, - {"video_codec", "copy"} - }; + nlohmann::json decode_para = {{"input_path", input_file}, + {"video_codec", "copy"}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); nlohmann::json encode_para = { {"output_path", output_file}, {"format", "segment"}, - {"mux_params", { - {"segment_time", 4} - }}, + {"mux_params", {{"segment_time", 4}}}, }; - graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encode_para)); + graph.Encode(video["video"], video["audio"], + bmf_sdk::JsonParam(encode_para)); graph.Run(); - BMF_CPP_FILE_CHECK( - "./simple_00000.mp4", - "../simple_00000.mp4|1080|1920|4.296|MOV,MP4,M4A,3GP,3G2,MJ2|1988878|1068028|mpeg4|{\"fps\": \"29.97\", \"accurate\": \"d\"}" - ); - BMF_CPP_FILE_CHECK( - "./simple_00001.mp4", - "../transcode/simple_00001.mp4|1080|1920|8.313|MOV,MP4,M4A,3GP,3G2,MJ2|1102862|1146012|mpeg4|{\"fps\": \"29.97\", \"accurate\": \"d\"}" - ); + BMF_CPP_FILE_CHECK("./simple_00000.mp4", "../" + "simple_00000.mp4|1080|1920|4.296|" + "MOV,MP4,M4A,3GP,3G2,MJ2|1988878|" + "1068028|mpeg4|{\"fps\": " + "\"29.97\", \"accurate\": \"d\"}"); + BMF_CPP_FILE_CHECK("./simple_00001.mp4", "../transcode/" + "simple_00001.mp4|1080|1920|8.313|" + "MOV,MP4,M4A,3GP,3G2,MJ2|1102862|" + "1146012|mpeg4|{\"fps\": " + "\"29.97\", \"accurate\": \"d\"}"); } TEST(cpp_transcode, test_encoder_push_output_mp4) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./simple_vframe_python.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - nlohmann::json encode_para = { - {"output_path", output_file}, - {"push_output", 1}, - {"vframes", 60}, - {"video_params", { - {"codec", "jpg"}, - {"width", 640}, - {"height", 480}, - {"crf", 23}, - {"preset", "veryfast"} - }} - }; - nlohmann::json encode_para_2 = { - {"output_path", output_file} - }; - bmf::builder::Stream stream = graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); - stream.Start(); - std::ofstream outFile(output_file, std::ios::out | std::ios::binary); - while (true) { - Packet pkt = graph.Generate(); + nlohmann::json encode_para = {{"output_path", output_file}, + {"push_output", 1}, + {"vframes", 60}, + {"video_params", + {{"codec", "jpg"}, + {"width", 640}, + {"height", 480}, + {"crf", 23}, + {"preset", "veryfast"}}}}; + nlohmann::json encode_para_2 = {{"output_path", output_file}}; + bmf::builder::Stream stream = + graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); + stream.Start(); + std::ofstream outFile(output_file, std::ios::out | std::ios::binary); + while (true) { + Packet pkt = graph.Generate(); if (pkt.timestamp() == BMF_EOF) { break; } - if (pkt.is() == true) { + if (pkt.is() == true) { BMFAVPacket ppkt = pkt.get(); int offset = ppkt.get_offset(); - int whence = ppkt.get_whence(); - void *data = ppkt.data_ptr(); - if (offset > 0) { - if (whence == 0){ - outFile.seekp(offset, std::ios_base::beg); - } else if (whence == 1) { - outFile.seekp(offset, std::ios_base::cur); - } else if (whence == 2) { - outFile.seekp(offset, std::ios_base::end); - } - } - std::cout << "tby : " << offset << " " << " " << whence << " " << ppkt.nbytes() << std::endl; - outFile.write((char *)data, ppkt.nbytes()); + int whence = ppkt.get_whence(); + void *data = ppkt.data_ptr(); + if (offset > 0) { + if (whence == 0) { + outFile.seekp(offset, std::ios_base::beg); + } else if (whence == 1) { + outFile.seekp(offset, std::ios_base::cur); + } else if (whence == 2) { + outFile.seekp(offset, std::ios_base::end); + } + } + std::cout << "tby : " << offset << " " + << " " << whence << " " << ppkt.nbytes() << std::endl; + outFile.write((char *)data, ppkt.nbytes()); } - } - outFile.close(); + outFile.close(); } TEST(cpp_transcode, test_encoder_push_output_image2pipe) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - nlohmann::json encode_para = { - {"push_output", 1}, - {"vframes", 2}, - {"format", "image2pipe"}, - {"avio_buffer_size", 65536}, - {"video_params", { - {"codec", "jpg"}, - {"width", 640}, - {"height", 480}, - {"crf", 23}, - {"preset", "veryfast"} - }} - }; - - bmf::builder::Stream stream = graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); - stream.Start(); - int write_num = 0; - while (true) { - Packet pkt = graph.Generate(); + nlohmann::json encode_para = {{"push_output", 1}, + {"vframes", 2}, + {"format", "image2pipe"}, + {"avio_buffer_size", 65536}, + {"video_params", + {{"codec", "jpg"}, + {"width", 640}, + {"height", 480}, + {"crf", 23}, + {"preset", "veryfast"}}}}; + + bmf::builder::Stream stream = + graph.Encode(video["video"], bmf_sdk::JsonParam(encode_para)); + stream.Start(); + int write_num = 0; + while (true) { + Packet pkt = graph.Generate(); if (pkt.timestamp() == BMF_EOF) { break; } - if (pkt.is() == true) { + if (pkt.is() == true) { BMFAVPacket ppkt = pkt.get(); int offset = ppkt.get_offset(); - int whence = ppkt.get_whence(); - void *data = ppkt.data_ptr(); - std::string output_file = "./simple_image" + std::to_string(write_num) + ".jpg"; - std::ofstream outFile(output_file, std::ios::out | std::ios::binary); - if (offset > 0) { - if (whence == 0){ - outFile.seekp(offset, std::ios_base::beg); - } else if (whence == 1) { - outFile.seekp(offset, std::ios_base::cur); - } else if (whence == 2) { - outFile.seekp(offset, std::ios_base::end); - } - } - outFile.write((char *)data, ppkt.nbytes()); - write_num++; - outFile.close(); + int whence = ppkt.get_whence(); + void *data = ppkt.data_ptr(); + std::string output_file = + "./simple_image" + std::to_string(write_num) + ".jpg"; + std::ofstream outFile(output_file, + std::ios::out | std::ios::binary); + if (offset > 0) { + if (whence == 0) { + outFile.seekp(offset, std::ios_base::beg); + } else if (whence == 1) { + outFile.seekp(offset, std::ios_base::cur); + } else if (whence == 2) { + outFile.seekp(offset, std::ios_base::end); + } + } + outFile.write((char *)data, ppkt.nbytes()); + write_num++; + outFile.close(); } - } } TEST(cpp_transcode, test_encoder_push_output_audio_pcm_s16le) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; std::string output_file = "./test_audio_simple_pcm_s16le.wav"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; + nlohmann::json graph_para = {{"dump_graph", 1}}; BMF_CPP_FILE_REMOVE(output_file); - auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, bmf_sdk::JsonParam(graph_para)); + auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; + nlohmann::json decode_para = {{"input_path", input_file}}; auto video = graph.Decode(bmf_sdk::JsonParam(decode_para)); - nlohmann::json encode_para = { - {"output_path", output_file}, - {"push_output", 1}, - {"format", "wav"}, - {"audio_params", { - {"codec", "pcm_s16le"}, - }} - }; - nlohmann::json encode_para_2 = { - {"output_path", output_file} - }; - bmf::builder::Stream stream = graph.Encode(graph.NewPlaceholderStream(), video["audio"], bmf_sdk::JsonParam(encode_para)); - stream.Start(); - std::ofstream outFile(output_file, std::ios::out | std::ios::binary); - while (true) { - Packet pkt = graph.Generate(); + nlohmann::json encode_para = {{"output_path", output_file}, + {"push_output", 1}, + {"format", "wav"}, + {"audio_params", + { + {"codec", "pcm_s16le"}, + }}}; + nlohmann::json encode_para_2 = {{"output_path", output_file}}; + bmf::builder::Stream stream = + graph.Encode(graph.NewPlaceholderStream(), video["audio"], + bmf_sdk::JsonParam(encode_para)); + stream.Start(); + std::ofstream outFile(output_file, std::ios::out | std::ios::binary); + while (true) { + Packet pkt = graph.Generate(); if (pkt.timestamp() == BMF_EOF) { break; } - if (pkt.is() == true) { + if (pkt.is() == true) { auto ppkt = pkt.get(); - int offset = ppkt.get_offset(); - int whence = ppkt.get_whence(); - void *data = ppkt.data_ptr(); - if (offset > 0) { - if (whence == 0){ - outFile.seekp(offset, std::ios_base::beg); - } else if (whence == 1) { - outFile.seekp(offset, std::ios_base::cur); - } else if (whence == 2) { - outFile.seekp(offset, std::ios_base::end); - } - } - outFile.write((char *)data, ppkt.nbytes()); + int offset = ppkt.get_offset(); + int whence = ppkt.get_whence(); + void *data = ppkt.data_ptr(); + if (offset > 0) { + if (whence == 0) { + outFile.seekp(offset, std::ios_base::beg); + } else if (whence == 1) { + outFile.seekp(offset, std::ios_base::cur); + } else if (whence == 2) { + outFile.seekp(offset, std::ios_base::end); + } + } + outFile.write((char *)data, ppkt.nbytes()); } - } - outFile.close(); + outFile.close(); } TEST(cpp_transcode, test_generator) { std::string input_file = "../../files/big_bunny_10s_30fps.mp4"; - nlohmann::json graph_para = { - {"dump_graph", 1} - }; - auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, bmf_sdk::JsonParam(graph_para)); + nlohmann::json graph_para = {{"dump_graph", 1}}; + auto graph = bmf::builder::Graph(bmf::builder::GeneratorMode, + bmf_sdk::JsonParam(graph_para)); - nlohmann::json decode_para = { - {"input_path", input_file} - }; - - graph.Decode(bmf_sdk::JsonParam(decode_para))["video"].Scale("299:299").Start(); - int frame_num = 0; + nlohmann::json decode_para = {{"input_path", input_file}}; + + graph.Decode(bmf_sdk::JsonParam(decode_para))["video"] + .Scale("299:299") + .Start(); + int frame_num = 0; while (true) { - Packet pkt = graph.Generate(); + Packet pkt = graph.Generate(); if (pkt.timestamp() == BMF_EOF) { break; } if (pkt.is() == true) { VideoFrame video_frame = pkt.get(); - std::cout << "frame :" << frame_num << " " << "format: " << video_frame.frame().format() << std::endl; + std::cout << "frame :" << frame_num << " " + << "format: " << video_frame.frame().format() + << std::endl; } } } @@ -1069,7 +951,8 @@ TEST(cpp_transcode, test_generator) { /* {"dump_graph", 1} */ /* }; */ /* BMF_CPP_FILE_REMOVE(output_file); */ -/* auto graph = bmf::builder::Graph(bmf::builder::NormalMode, bmf_sdk::JsonParam(graph_para)); */ +/* auto graph = bmf::builder::Graph(bmf::builder::NormalMode, + * bmf_sdk::JsonParam(graph_para)); */ /* nlohmann::json decode_para = { */ /* {"input_path", input_file} */ @@ -1095,12 +978,15 @@ TEST(cpp_transcode, test_generator) { /* nlohmann::json encode_para_2 = { */ /* {"output_path", output_file} */ /* }; */ -/* auto encoded_video = graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encode_para)); */ -/* graph.Encode(encoded_video["video"], encoded_video["audio"], bmf_sdk::JsonParam(encode_para_2)); */ +/* auto encoded_video = graph.Encode(video["video"], video["audio"], + * bmf_sdk::JsonParam(encode_para)); */ +/* graph.Encode(encoded_video["video"], encoded_video["audio"], + * bmf_sdk::JsonParam(encode_para_2)); */ /* graph.Run(); */ /* BMF_CPP_FILE_CHECK( */ -/* output_file, */ -/* "../transcode/unmuxed_output.mp4|240|320|7.574233|MOV,MP4,M4A,3GP,3G2,MJ2|404941|384340|h264|{\"fps\": \"29.97002997\"}" */ +/* output_file, */ +/* "../transcode/unmuxed_output.mp4|240|320|7.574233|MOV,MP4,M4A,3GP,3G2,MJ2|404941|384340|h264|{\"fps\": + * \"29.97002997\"}" */ /* ); */ /* } */ @@ -1111,7 +997,8 @@ TEST(cpp_transcode, test_generator) { /* {"dump_graph", 1} */ /* }; */ /* BMF_CPP_FILE_REMOVE(output_file); */ -/* auto graph = bmf::builder::Graph(bmf::builder::UpdateMode, bmf_sdk::JsonParam(graph_para)); */ +/* auto graph = bmf::builder::Graph(bmf::builder::UpdateMode, + * bmf_sdk::JsonParam(graph_para)); */ /* nlohmann::json decode_para = { */ /* {"input_path", input_file} */ @@ -1137,12 +1024,14 @@ TEST(cpp_transcode, test_generator) { /* nlohmann::json encode_para_2 = { */ /* {"output_path", output_file} */ /* }; */ -/* auto encoded_video = graph.Encode(video["video"], video["audio"], bmf_sdk::JsonParam(encode_para)); */ -/* graph.Encode(encoded_video["video"], encoded_video["audio"], bmf_sdk::JsonParam(encode_para_2)); */ +/* auto encoded_video = graph.Encode(video["video"], video["audio"], + * bmf_sdk::JsonParam(encode_para)); */ +/* graph.Encode(encoded_video["video"], encoded_video["audio"], + * bmf_sdk::JsonParam(encode_para_2)); */ /* graph.Run(); */ /* BMF_CPP_FILE_CHECK( */ -/* output_file, */ -/* "../transcode/unmuxed_output.mp4|240|320|7.574233|MOV,MP4,M4A,3GP,3G2,MJ2|404941|384340|h264|{\"fps\": \"29.97002997\"}" */ +/* output_file, */ +/* "../transcode/unmuxed_output.mp4|240|320|7.574233|MOV,MP4,M4A,3GP,3G2,MJ2|404941|384340|h264|{\"fps\": + * \"29.97002997\"}" */ /* ); */ /* } */ - diff --git a/bmf/test/demux/pull_stream.cpp b/bmf/test/demux/pull_stream.cpp index b2427a9f..f91f1b92 100644 --- a/bmf/test/demux/pull_stream.cpp +++ b/bmf/test/demux/pull_stream.cpp @@ -4,24 +4,23 @@ using namespace boost::python; -PullStreamModule::PullStreamModule(int node_id, JsonParam option) : Module(node_id, option) { +PullStreamModule::PullStreamModule(int node_id, JsonParam option) + : Module(node_id, option) { std::string data_file_path; - option.get_string("data_path",data_file_path); + option.get_string("data_path", data_file_path); std::string size_file_path; - option.get_string("size_path",size_file_path); - if (option.has_key("pts_path")) - { - option.get_string("pts_path",pts_file_path_); + option.get_string("size_path", size_file_path); + if (option.has_key("pts_path")) { + option.get_string("pts_path", pts_file_path_); f_pts.open(pts_file_path_); } - f_data.open(data_file_path, - std::ios::in | std::ios::binary); + f_data.open(data_file_path, std::ios::in | std::ios::binary); f_size.open(size_file_path); return; } int PullStreamModule::process(Task &task) { - if (f_size.eof()){ + if (f_size.eof()) { task.fill_output_packet(0, Packet::generate_eof_packet()); task.set_timestamp(DONE); return 0; @@ -29,30 +28,29 @@ int PullStreamModule::process(Task &task) { char buffer[50]; Packet packet; f_size.getline(buffer, 20); -// static int start_code = 0; - if (pts_file_path_.empty()){ - pts_=pts_+66; - } - else{ - f_pts>>pts_; + // static int start_code = 0; + if (pts_file_path_.empty()) { + pts_ = pts_ + 66; + } else { + f_pts >> pts_; } -// if (start_code==0) -// { -// start_code = pts_; -// } -// pts_=pts_-start_code; - std::cout<<"pts:"<0) { - f_data.read((char *) (pkt.get_data()), packet_size); + if (packet_size > 0) { + f_data.read((char *)(pkt.get_data()), packet_size); } -// pts_+=20; + // pts_+=20; packet.set_data(pkt); packet.set_data_class_type(PACKET_TYPE); packet.set_class_name("libbmf_module_sdk.BMFAVPacket"); diff --git a/bmf/test/numpy_c_module/copy_module.cc b/bmf/test/numpy_c_module/copy_module.cc index 6436b6e6..ebbd206a 100644 --- a/bmf/test/numpy_c_module/copy_module.cc +++ b/bmf/test/numpy_c_module/copy_module.cc @@ -30,8 +30,8 @@ void CopyModule::process(Task &task) { // Get packet data // Here we should know the data type in packet -// const VideoFrame &frame = pkt.get_data(); -// const ndarray &frame = extract(pkt.data_); + // const VideoFrame &frame = pkt.get_data(); + // const ndarray &frame = extract(pkt.data_); const ndarray &frame = pkt.get_data(); // Create output frame ndarray new_frame = frame.copy(); diff --git a/bmf/test/predict/trt_sr.py b/bmf/test/predict/trt_sr.py index 9e079b34..ac0a494f 100644 --- a/bmf/test/predict/trt_sr.py +++ b/bmf/test/predict/trt_sr.py @@ -140,7 +140,7 @@ def inference(self): mp.ColorRange.kCR_MPEG) RGB = mp.PixelInfo(mp.PixelFormat.kPF_RGB24, mp.ColorSpace.kCS_BT709, mp.ColorRange.kCR_MPEG) - frame = mp.Frame(mp.from_torch(output_tensor[i].contiguous()), RGB) + frame = mp.Frame(mp.from_dlpack(output_tensor[i].contiguous()), RGB) out_frame = mp.Frame(frame.width(), frame.height(), NV12,