-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
457 additions
and
323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include "calcmask.h" | ||
|
||
#include <mutex> | ||
#include <string> | ||
|
||
#include "lib/libbackscrub.h" | ||
|
||
CalcMask::CalcMask( | ||
const std::string& modelname, | ||
size_t threads, | ||
size_t width, | ||
size_t height | ||
) { | ||
maskctx = bs_maskgen_new(modelname.c_str(), threads, width, height, nullptr, onprep, oninfer, onmask, this); | ||
if (!maskctx) | ||
throw "Could not create mask context"; | ||
|
||
// Do all other initialization … | ||
frame_next = &frame1; | ||
frame_current = &frame2; | ||
mask_current = &mask1; | ||
mask_out = &mask2; | ||
new_frame = false; | ||
new_mask = false; | ||
|
||
// Start the actual processing | ||
state = thread_state_t::RUNNING; | ||
thread = std::thread(&CalcMask::run, this); | ||
} | ||
|
||
CalcMask::~CalcMask() { | ||
// mark as done | ||
state = thread_state_t::DONE; | ||
|
||
// wake up processing thread | ||
new_frame = true; | ||
condition_new_frame.notify_all(); | ||
|
||
// collect termination | ||
thread.join(); | ||
|
||
// free resources | ||
bs_maskgen_delete(maskctx); | ||
} | ||
|
||
void CalcMask::set_input_frame(cv::Mat &frame) { | ||
std::lock_guard<std::mutex> hold(lock_frame); | ||
|
||
*frame_next = frame.clone(); | ||
new_frame = true; | ||
condition_new_frame.notify_all(); | ||
} | ||
|
||
void CalcMask::get_output_mask(cv::Mat &out) { | ||
if (new_mask) { | ||
std::lock_guard<std::mutex> hold(lock_mask); | ||
|
||
out = mask_out->clone(); | ||
new_mask = false; | ||
} | ||
} | ||
|
||
void CalcMask::run() { | ||
cv::Mat *raw_tmp; | ||
timestamp_t tloop; | ||
|
||
while(thread_state_t::RUNNING == this->state) { | ||
tloop = t0 = timestamp(); | ||
|
||
/* actual handling */ | ||
{ | ||
std::unique_lock<std::mutex> hold(lock_frame); | ||
while (!new_frame) { | ||
condition_new_frame.wait(hold); | ||
} | ||
|
||
// change frame buffer pointer | ||
new_frame = false; | ||
raw_tmp = frame_next; | ||
frame_next = frame_current; | ||
frame_current = raw_tmp; | ||
} | ||
|
||
waitns = diffnanosecs(timestamp(), t0); | ||
t0 = timestamp(); | ||
|
||
if(!bs_maskgen_process(maskctx, *frame_current, *mask_current)) { | ||
fprintf(stderr, "failed to process video frame\n"); | ||
exit(1); | ||
} | ||
|
||
{ | ||
std::unique_lock<std::mutex> hold(lock_mask); | ||
|
||
raw_tmp = mask_out; | ||
mask_out = mask_current; | ||
mask_current = raw_tmp; | ||
new_mask = true; | ||
} | ||
|
||
loopns = diffnanosecs(timestamp(), tloop); | ||
} | ||
} | ||
|
||
// timing callbacks | ||
void CalcMask::onprep(void *ctx) { | ||
CalcMask *cls = (CalcMask *)ctx; | ||
cls->prepns = diffnanosecs(timestamp(), cls->t0); | ||
cls->t0 = timestamp(); | ||
} | ||
|
||
void CalcMask::oninfer(void *ctx) { | ||
CalcMask *cls = (CalcMask *)ctx; | ||
cls->tfltns = diffnanosecs(timestamp(), cls->t0); | ||
cls->t0 = timestamp(); | ||
} | ||
|
||
void CalcMask::onmask(void *ctx) { | ||
CalcMask *cls = (CalcMask *)ctx; | ||
cls->maskns = diffnanosecs(timestamp(), cls->t0); | ||
cls->t0 = timestamp(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#pragma once | ||
|
||
#include <unistd.h> | ||
|
||
#include <chrono> | ||
#include <condition_variable> | ||
#include <cstdint> | ||
#include <mutex> | ||
#include <string> | ||
#include <thread> | ||
|
||
#include <opencv2/core/mat.hpp> | ||
|
||
#include "utils.h" | ||
|
||
enum class thread_state_t { RUNNING, DONE }; | ||
|
||
class CalcMask final { | ||
protected: | ||
volatile thread_state_t state; | ||
|
||
void *maskctx; | ||
timestamp_t t0; | ||
|
||
// buffers | ||
cv::Mat mask1; | ||
cv::Mat mask2; | ||
cv::Mat *mask_current; | ||
cv::Mat *mask_out; | ||
cv::Mat frame1; | ||
cv::Mat frame2; | ||
cv::Mat *frame_current; | ||
cv::Mat *frame_next; | ||
|
||
// thread synchronisation | ||
std::mutex lock_frame; | ||
std::mutex lock_mask; | ||
std::condition_variable condition_new_frame; | ||
bool new_frame; | ||
bool new_mask; | ||
std::thread thread; | ||
|
||
// thread execution | ||
void run(); | ||
|
||
// timing callbacks | ||
static void onprep(void *ctx); | ||
static void oninfer(void *ctx); | ||
static void onmask(void *ctx); | ||
|
||
public: | ||
long waitns; | ||
long prepns; | ||
long tfltns; | ||
long maskns; | ||
long loopns; | ||
|
||
CalcMask() = delete; | ||
CalcMask(const CalcMask&) = delete; | ||
CalcMask(const std::string& modelname, size_t threads, size_t width, size_t height); | ||
~CalcMask(); | ||
|
||
void set_input_frame(cv::Mat &frame); | ||
void get_output_mask(cv::Mat &out); | ||
}; |
Oops, something went wrong.