电机板事件改在扫描线程中监控;CIS原图重构移到扫描线程处理(一张纸重构平均大约150ms,在等待出图的过程中处理)

This commit is contained in:
gb 2024-03-07 16:00:48 +08:00
parent fe90a83e5c
commit e264cd6556
11 changed files with 329 additions and 82 deletions

View File

@ -374,7 +374,7 @@ void scanner_hw::thread_image_capture(bool paper_ready)
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n");
utils::to_log(LOG_LEVEL_DEBUG, "set capture thread to CPU %d = %d\n", CPU_MAJOR_0, utils::set_cpu_affinity(CPU_MAJOR_0));
avail_mem.enable_wait_log(false);
motor_->clear_error();
if(paper_ready)
@ -410,20 +410,16 @@ void scanner_hw::thread_image_capture(bool paper_ready)
}
// wait paper ...
while(auto_scan_)
while(auto_scan_ && scanning_)
{
mbev.first = -1;
mbev.second = 0;
if(mb_events_.take(mbev, true))
int err = 0,
fatal = 0;
if(motor_->wait_event(MOTOR_BORD_EVENT_PAPER_READY, &err, SEC_2_MS(10), &fatal, nullptr))
{
if(mbev.first == MOTOR_BORD_EVENT_PAPER_READY)
{
printf("paper ready: %d-%x\n", mbev.first, mbev.second);
paper_ready = true;
paper_ready = true;
if(scanning_)
motor_->start();
break;
}
printf("\tmotor-board event is %d\n", mbev.first);
break;
}
}
if(!scanning_)
@ -441,12 +437,15 @@ void scanner_hw::thread_image_capture(bool paper_ready)
{
if(times++ == 0)
utils::to_log(LOG_LEVEL_DEBUG, "Wait to retrieve %d V4L2 memory(s) ...\n", used_v4l2_mem);
else if(times >= 1000)
else if(times >= 2000)
{
utils::to_log(LOG_LEVEL_FATAL, "Wait %d times, but %d V4L2 memory(s) has not returned yet!\n", times, used_v4l2_mem);
break;
}
int old = used_v4l2_mem;
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
if(used_v4l2_mem < old)
times = 1;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited with error: %d.\n", err);
@ -463,30 +462,12 @@ void scanner_hw::thread_image_capture(bool paper_ready)
int scanner_hw::start_and_wait_lifter(int to_ms, int* ui_words_id)
{
int ret = SCANNER_ERR_DEVICE_FEEDER_POS,
words = ID_WORDS_STATUS_DEVICE_HD_001;
chronograph watch;
words = ID_WORDS_STATUS_DEVICE_HD_001,
err = 0;
while(scanning_ && watch.elapse_ms() < to_ms)
{
std::pair<int, int> mbev;
if(mb_events_.take(mbev, true, 3))
{
if(mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
{
ret = words = 0;
break;
}
else
{
int err = trans_motorboard_err_2_hg_error(mbev.first, &words);
if(err)
{
ret = err;
break;
}
}
}
}
if(motor_->wait_event(MOTOR_BORD_EVENT_LIFTER_READY, &ret, to_ms, &err, &words))
ret = words = 0;
if(!scanning_) // user cancelled
{
ret = SCANNER_ERR_USER_CANCELED;
@ -505,6 +486,7 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
uint32_t pass = 0;
chronograph watch;
std::pair<int, int> mbev;
dyn_mem_shared_ptr mem = nullptr;
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
{
@ -520,37 +502,39 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
img->life = chronograph::from_process_born();
while(scanning_)
{
if(!motor_->wait_paper_out(to_paper_out_))
#ifdef REBUILD_IN_CIS_THREAD
if(mem)
{
ret = SCANNER_ERR_DEVICE_HD_002;
words = ID_WORDS_STATUS_DEVICE_HD_002;
break;
img_handler_(mem, true, img);
mem->release();
mem = nullptr;
}
pass = watch.elapse_ms();
mbev.first = -1;
mbev.second = 0;
if(mb_events_.take(mbev, true, 10) && mbev.first == MOTOR_BORD_EVENT_ERROR)
#endif
int fatal = 0;
ret = SCANNER_ERR_DEVICE_HD_002;
words = ID_WORDS_STATUS_DEVICE_HD_002;
if(!motor_->wait_event(MOTOR_BORD_EVENT_PAPER_PASSING, &ret, to_paper_out_, &fatal, &words))
{
ret = trans_motorboard_err_2_hg_error(mbev.second, &words);
if(ret != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
{
break;
if(fatal == MOTOR_BORD_EVENT_SCAN_DONE)
{
ret = words = 0;
if(mbstopped)
*mbstopped = true;
printf("-->scan done event received from motorboard.\n");
}
// else
break;
}
}
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE)
{
if(mbstopped)
*mbstopped = true;
printf("-->scan done event received from motorboard.\n");
break;
}
else
{
ret = SCANNER_ERR_OK;
words = 0;
}
pass = watch.elapse_ms();
img->pos.paper_ind++;
if(count_mode_)
@ -564,12 +548,14 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
ret = SCANNER_ERR_DEVICE_CIS_STREAM;
words = ID_WORDS_STATUS_CAPTURE_FAILED;
if(fatal != MOTOR_BORD_EVENT_SCAN_DONE)
{
ret = SCANNER_ERR_DEVICE_CIS_STREAM;
words = ID_WORDS_STATUS_CAPTURE_FAILED;
}
break;
}
cism_cnt[0]++;
@ -580,8 +566,10 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
mem->set_param(cism, 0);
mem->set_param((void*)(long)ind, 1);
img->pos.status = hg_err_2_image_status(ret);
#ifndef REBUILD_IN_CIS_THREAD
img_handler_(mem, true, img); // (frame, ind, LPPACKIMAGE, cism, ret, pass, bool)
mem->release();
#endif
if(!scan_cntless_ && img->pos.paper_ind == scan_count_)
{
@ -600,6 +588,9 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
}
}
if(ret || fatal == MOTOR_BORD_EVENT_SCAN_DONE)
break;
// resource checking ...
if(res_(TASK_CAPTURER, true, 3000) && scanning_)
{
@ -616,6 +607,15 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
}
}
#ifdef REBUILD_IN_CIS_THREAD
if(mem)
{
img_handler_(mem, true, img);
mem->release();
mem = nullptr;
}
#endif
if(ui_words)
*ui_words = words;
@ -900,7 +900,7 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler, CHK_RES_F
mb_events_.save(std::make_pair(ev, data), true);
};
mb_events_.clear();
motor_.reset(new MotorBoard(cb));
motor_.reset(new MotorBoard(/*cb*/));
motor_->set_double_inpect(double_chk_);
motor_->set_staple_inpect(staple_chk_);
motor_->set_screw_inpect(screw_chk_);

View File

@ -8,6 +8,8 @@
#include <base/utils.h>
#include <base/ui.h>
#include <huagao/hgscanner_error.h>
#include <base/words.h>
#define MOTOR_UART "/dev/ttyS4"
@ -18,19 +20,13 @@ MotorBoard::MotorBoard(std::function<void(int, unsigned int)> evcb)
: devPort(MOTOR_UART), event_cb_(evcb)
, autopaperkeystop(nullptr)
{
auto empty_cb = [&](int t, unsigned int v) -> void
{
utils::to_log(LOG_LEVEL_DEBUG, "motorboard event(%d, 0x%08x)\n", t, v);
};
if(!event_cb_)
event_cb_ = empty_cb;
// LOG_INIT();
//m_uartEnable.reset(new GpioOut(149));
//m_uartEnable->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
m_regsAccess.reset(new UartRegsAccess(devPort, bauds, 0x07, 0x87));
m_intPinMonitor.reset(new PinMonitor(intport, std::bind(&MotorBoard::pin_call, this, std::placeholders::_1)));
if(event_cb_)
m_intPinMonitor.reset(new PinMonitor(intport, std::bind(&MotorBoard::pin_call, this, std::placeholders::_1)));
//m_uartEnable->setValue(Gpio::High);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
m_os_mode = os_mode();
@ -400,7 +396,7 @@ static int countindex =0;
void MotorBoard::pin_call(unsigned int pinNum)
{
static int index = 0;
// int os_m = os_mode(); //安路å±<EFBFBD>蔽计数 扫æ<C2AB><C3A6>过ç¨ä¸­æ— æ³•æ“<C3A6>作按é”?
// int os_m = os_mode(); //安路屏蔽计数 扫描过程中无法操作按键
// if (m_os_mode != os_m)
// {
// m_os_mode = os_m;
@ -409,7 +405,7 @@ void MotorBoard::pin_call(unsigned int pinNum)
// m_glue.m_os_mode_call(m_os_mode);
// }
// if (m_os_mode) //安路å±<EFBFBD>è”½è®¡æ•°è¿”åž ä»¥åˆ·æ–°è®¡æ•°çŠ¶æ€?
// if (m_os_mode) //安路屏蔽计数返回 以刷新计数状态
// {
// LOG_TRACE("not scan mode");
// return;
@ -419,6 +415,9 @@ void MotorBoard::pin_call(unsigned int pinNum)
SMBSTATUS *s = (SMBSTATUS *)&val;
if (!read(MB_PORT_STATUS, val))
utils::to_log(LOG_LEVEL_FATAL, "read motorboard status failed.\n");
else
printf("\tmotorboard status = 0x%08X\n", val);
if(s->keep_last_paper) // (val & 0x800)
{
//printf("\n keep_last_paper ");
@ -477,7 +476,7 @@ void MotorBoard::pin_call(unsigned int pinNum)
unsigned int papercount = 0;
read(MB_PORT_MODE,papercount);
SMBMODE smbmode = *(SMBMODE*)&papercount;
printf("paper in arm count = %d ,motorcount = %d\n",++countindex,smbmode.scan_num);
printf("paper in arm count = %d, motorcount = %d\n",++countindex,smbmode.scan_num);
startcapimage(true);
}
if(s->paper_left)
@ -760,7 +759,7 @@ void MotorBoard::startcapimage(bool value)
bool MotorBoard::set_sensor_pwm_duty(int sensorid,int duty)
{
//1:扫æ<EFBFBD><EFBFBD>ï¼2:开çï¼3:歪æœâ€?ï¼?:歪æ–?2ï¼?:出纸å<C2B8>£ï¼?:有无纸
//1扫描2开盖3歪斜—14歪斜-25出纸口6有无纸
printf("set_sensor_pwm_duty type = %d duty = %d \n",sensorid,duty);
unsigned int val;
if (!read(MB_PORT_TIME, val))
@ -861,4 +860,126 @@ std::string MotorBoard::getmbversion(){
m_version = value;
printf("mb version: = %s \n", std::to_string(value).c_str());
return std::to_string(value);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
bool MotorBoard::wait_event(int event, int *evdata, int to_ms, int* fatal_ev, int* fatal_msg)
{
bool waited = false;
int evd = 0, fe = 0, msg = 0;
chronograph watch;
if(!evdata)
evdata = &evd;
if(!fatal_ev)
fatal_ev = &fe;
if(!fatal_msg)
fatal_msg = &msg;
*fatal_ev = 0;
while(watch.elapse_ms() < to_ms)
{
unsigned int val = 0;
SMBSTATUS *s = (SMBSTATUS *)&val;
if (!read(MB_PORT_STATUS, val))
{
utils::to_log(LOG_LEVEL_FATAL, "read motorboard status failed.\n");
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
else if(val <= 1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
if(s->arrival_top_int) // (val & 0x80000)
{
if(event == MOTOR_BORD_EVENT_LIFTER_READY)
{
*evdata = 1;
waited = true;
break;
}
}
if(s->auto_feed)
{
if(event == MOTOR_BORD_EVENT_PAPER_READY)
{
*evdata = 1;
waited = true;
break;
}
}
if(s->paper_left)
{
startcapimage(true);
if(event == MOTOR_BORD_EVENT_PAPER_PASSING)
{
*evdata = 0;
waited = true;
break;
}
}
if(s->motor_status)
{
*evdata = 0;
if(event == MOTOR_BORD_EVENT_SCAN_DONE)
{
waited = true;
}
else
{
*fatal_ev = MOTOR_BORD_EVENT_SCAN_DONE;
}
break;
}
if(!s->scan_pulse)
startcapimage(true);
if (val & 0x7c003FE)
{
*fatal_ev = MOTOR_BORD_EVENT_ERROR;
if(s->m1_paper_sin)
{
*evdata = SCANNER_ERR_DEVICE_NO_PAPER;
*fatal_msg = ID_WORDS_STATUS_NO_PAPER;
}
else if(s->open_machine)
{
*evdata = SCANNER_ERR_DEVICE_COVER_OPENNED;
*fatal_msg = ID_WORDS_STATUS_COVER_OPEN;
}
else if(s->pick_failed)
{
*evdata = SCANNER_ERR_DEVICE_FEEDING_PAPER;
*fatal_msg = ID_WORDS_STATUS_FEED_ERR;
}
else if(s->stop_jam && (s->jam_1 || s->jam_2 || s->jam_3))
{
*evdata = SCANNER_ERR_DEVICE_PAPER_JAMMED;
*fatal_msg = ID_WORDS_STATUS_JAMMED;
}
else if(s->double_paper)
{
*evdata = SCANNER_ERR_DEVICE_DOUBLE_FEEDING;
*fatal_msg = ID_WORDS_STATUS_DOUBLE_FEED;
}
else if(s->staple)
{
*evdata = SCANNER_ERR_DEVICE_STAPLE_ON;
*fatal_msg = ID_WORDS_STATUS_STAPLE;
}
else if(s->papertilted)
{
*evdata = SCANNER_ERR_DEVICE_PAPER_SKEW;
*fatal_msg = ID_WORDS_STATUS_ASKEW;
}
break;
}
}
return waited;
}

View File

@ -70,8 +70,8 @@ typedef struct SMB_CONFIG
typedef struct SMB_STATUS
{
unsigned int scan_pulse : 1;
unsigned int m1_paper_sin : 1;
unsigned int open_machine : 1;
unsigned int m1_paper_sin : 1; // no paper
unsigned int open_machine : 1; // cover openned
unsigned int pick_failed : 1;
unsigned int stop_jam : 1;//5
@ -100,6 +100,8 @@ typedef struct SMB_STATUS
unsigned int jam_3 : 1; //出纸口
unsigned int cover_closed : 1; //已关盖
unsigned int double_clean_f : 1; //液晶双张错误清除
unsigned int reserved : 5;
} SMBSTATUS;
typedef struct SMB_MODE
@ -295,4 +297,20 @@ private:
unsigned int m_os_mode;
volatile bool keep_last_paper;
std::function<void()> autopaperkeystop;
public:
// Function: wait given event in specified milliseconds
//
// Parameters: event - target event
//
// evdata - to receive the data of the event data or of fatal_ev
//
// to_ms - the max time in milliseconds to wait
//
// fatal_ev - to receive the fatal event if arrived before event
//
// fatal_msg - to receive the error message declared in words.h
//
// Return: wait event in to_ms return true, otherwise return false
bool wait_event(int event, int *evdata, int to_ms, int* fatal_ev, int* fatal_msg);
};

View File

@ -433,6 +433,7 @@ namespace hg
cv::Mat loadLUT(const std::string& file)
{
printf("loadLUT(%s) ...\n", file.c_str());
cv::Mat dataFile = cv::imread(file, cv::IMREAD_ANYCOLOR);
long total = dataFile.total();

View File

@ -141,6 +141,7 @@ namespace hg
float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2);
void initLut(const std::string lutpath, bool iscolor);
cv::Mat loadLUT(const std::string& file);
void correctColor(cv::Mat& src, int dpi, int mode,bool isText);
}

View File

@ -27,7 +27,7 @@ color_correct::color_correct(bool weaker) : image_processor("color_correct")
return;
ADD_THIS_JSON();
hg::initLut(lut_path_.c_str(), clr_);
lut_ = hg::loadLUT(lut_path_);
}
color_correct::~color_correct()
{}
@ -44,7 +44,7 @@ int color_correct::set_value(const char* name/*nullptr for all options*/, void*
if(lut_path_ != (char*)val)
{
lut_path_ = (char*)val;
hg::initLut(lut_path_.c_str(), clr_);
lut_ = hg::loadLUT(lut_path_);
}
}
else if(strcmp(name, SANE_OPT_NAME(CIS_MODE)) == 0)
@ -52,8 +52,6 @@ int color_correct::set_value(const char* name/*nullptr for all options*/, void*
bool pre = clr_;
clr_ = strcmp((char*)val, WORDS_COLOR_COLOR) == 0;
if(pre != clr_)
hg::initLut(lut_path_.c_str(), clr_);
}
else
ret = SCANNER_ERR_DEVICE_NOT_SUPPORT;
@ -68,6 +66,7 @@ image_processor* color_correct::copy_weaker(void)
weaker->enabled_ = enabled_;
weaker->correct_ = correct_;
weaker->clr_ = clr_;
weaker->lut_ = lut_.clone();
return weaker;
}
@ -82,7 +81,11 @@ int color_correct::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO
PROCIMGINFO o = v;
chronograph watch;
hg::correctColor(o.img, o.info.resolution_x, 1, true);
// hg::correctColor(o.img, o.info.resolution_x, 1, true);
cv::Mat image_temp(o.img.rows, o.img.cols * o.img.channels() / lut_.channels(), CV_8UC(lut_.channels()), o.img.data);
for (size_t i = 0; i < image_temp.cols; i++)
cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lut_(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows)));
o.info.prc_time = watch.elapse_ms();
o.info.prc_stage = get_position();

View File

@ -9,6 +9,7 @@ class color_correct : public image_processor
{
bool correct_ = true;
bool clr_ = true;
cv::Mat lut_;
std::string lut_path_ = "/usr/local/huago/Textlut200clr.bmp";
public:

View File

@ -112,6 +112,7 @@ void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGI
o.info.width = out[0].info.width;
o.info.channels = out[0].info.channels;
//*/
for(int h = 0; h < info->height; ++h)
{
for(int w = 0; w < o.info.width; ++w)
@ -127,6 +128,45 @@ void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGI
}
srcd -= info->width;
}
/*/
uint64_t *srcl = (uint64_t*)srcd;
int width = info->width / sizeof(*srcl),
count = width * info->height,
secll = secl / sizeof(*srcl),
secpos[] = {5, 4, 3, 5, 4, 3, 5, 4, 3, 2, 1, 0, 2, 1, 0, 2, 1, 0},
rgbsf[] = {0, 2, 1},
rgbsb[] = {1, 2, 0},
*rgbx[] = {rgbsf, rgbsb};
uint8_t *dstbuf[] = {df, db};
for(int off = 0; off < count; ++off)
{
int pixel = off / (secll * CIS_SECTOR_COUNT * 6) * o.info.width,
sector = (off / secll) % (CIS_SECTOR_COUNT * 3),
lm = off % width,
ind = lm / (width / 2);
uint64_t val = *srcl++;
uint8_t *dst = dstbuf[ind], rgb = rgbx[ind][(sector / 3) % 3];
pixel += secpos[sector] * secl;
pixel += (off % secll) * 8;
if(ind && lm + 1 == width)
{
srcd -= info->width;
srcl = (uint64_t*)srcd;
}
dst += pixel * 3 + rgb;
dst[0 * 3] = val >> (0 * 8);
dst[1 * 3] = val >> (1 * 8);
dst[2 * 3] = val >> (2 * 8);
dst[3 * 3] = val >> (3 * 8);
dst[4 * 3] = val >> (4 * 8);
dst[5 * 3] = val >> (5 * 8);
dst[6 * 3] = val >> (6 * 8);
dst[7 * 3] = val >> (7 * 8);
}
/////*///////////////////////////
}
size = watch.elapse_ms();

View File

@ -239,7 +239,7 @@ void imgproc_mgr::thread_worker(void* param)
int cpu = (para->mean.ind % (CPU_CORES - CPU_MAJOR_CNT)) + CPU_MINOR_0;
utils::to_log(LOG_LEVEL_DEBUG, "set image process thread %d to CPU %d = %d\n"
, para->mean.ind, cpu, utils::set_cpu_affinity(cpu));
, para->mean.ind + 1, cpu, utils::set_cpu_affinity(cpu));
add_busy_worker();
while(para->mean.run)
@ -256,7 +256,11 @@ void imgproc_mgr::thread_worker(void* param)
}
if(para->mean.que->take(img, true))
{
#ifdef REBUILD_IN_CIS_THREAD
if(img.img && img.imgs.size() == 0)
#else
if(img.img && !img.data)
#endif
break;
process(&img, para);
}
@ -270,6 +274,9 @@ void imgproc_mgr::process(RAWIMG* img, LPPAGEDPARAM param)
std::vector<PROCIMGINFO> in, out, *src = &in, *dst = &out, *swp = nullptr;
chronograph watch;
#ifdef REBUILD_IN_CIS_THREAD
src = &img->imgs;
#else
if(param->mean.dumpi)
{
cv::Mat mat(img->info.width, img->info.height, CV_8UC1, img->data->ptr());
@ -279,7 +286,7 @@ void imgproc_mgr::process(RAWIMG* img, LPPAGEDPARAM param)
if(param->mean.rebld)
{
param->mean.rebld->do_rebuild(&img->info, img->data->ptr(), in);
utils::to_log(LOG_LEVEL_ALL, "Rebuild paper %d spend %llu milliseconds.\n", img->info.pos.paper_ind, watch.elapse_ms());
utils::to_log(LOG_LEVEL_ALL, "Thread %d Rebuild paper %d spend %llu milliseconds.\n", param->mean.ind + 1, img->info.pos.paper_ind, watch.elapse_ms());
param->mean.dump(param, &in, nullptr, nullptr, nullptr, 0, false, param->mean.dump_param);
}
else
@ -289,7 +296,8 @@ void imgproc_mgr::process(RAWIMG* img, LPPAGEDPARAM param)
i.img = cv::Mat(img->info.width, img->info.height, CV_8UC1, img->data->ptr());
in.push_back(i);
}
img->data->release();
img->data->release(); // page fault
#endif
for(auto& v: param->mean.processors)
{
@ -312,11 +320,16 @@ void imgproc_mgr::process(RAWIMG* img, LPPAGEDPARAM param)
}
else
{
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.data_size);
uint32_t wait = 0, que = 0;
RAWIMG over;
#ifdef REBUILD_IN_CIS_THREAD
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->imgs[0].info.data_size);
#else
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.data_size);
over.data = nullptr;
#endif
over.img = true;
for(auto& v: params_)
v->mean.que->save(over, true);
@ -325,7 +338,7 @@ void imgproc_mgr::process(RAWIMG* img, LPPAGEDPARAM param)
while((que = add_busy_worker(0)) > 1)
{
if(wait++ == 0)
utils::to_log(LOG_LEVEL_DEBUG, "Received scan completed event while processing %u paper(s), wait ...\n", que - 1);
utils::to_log(LOG_LEVEL_DEBUG, "Received scan completed (in thread %d) event while processing %u paper(s), wait ...\n", param->mean.ind + 1, que - 1);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
@ -409,12 +422,50 @@ int imgproc_mgr::clear(void)
return 0;
}
static uint64_t rebuild_cis = 0;
static uint32_t scan_count = 0;
int imgproc_mgr::process(LPPACKIMAGE info, dyn_mem_ptr data, bool img)
{
RAWIMG ri;
int ret = SCANNER_ERR_OK;
int ind = put_ind_ % working_cnt_;
#ifdef REBUILD_IN_CIS_THREAD
if(img)
{
if(dump_img_)
{
cv::Mat mat(info->width, info->height, CV_8UC1, data->ptr());
send_image(params_[0], info, mat, nullptr, 0, false);
}
if(do_rebuild_)
{
chronograph watch;
first_->do_rebuild(info, data->ptr(), ri.imgs);
rebuild_cis += watch.elapse_ms();
scan_count++;
utils::to_log(LOG_LEVEL_ALL, "Rebuild paper %d spend %llu milliseconds.\n", info->pos.paper_ind, watch.elapse_ms());
if(dump_img_)
send_image(params_[0], ri.imgs, false);
}
else
{
PROCIMGINFO i;
i.info = *info;
i.img = cv::Mat(info->width, info->height, CV_8UC1, data->ptr());
ri.imgs.push_back(i);
}
}
else
{
PROCIMGINFO i;
i.info.data_size = (uint32_t)(long)info;
ri.imgs.push_back(i);
printf("--> Rebuild %d papers in %llums, average is %.2fms\n", scan_count
, rebuild_cis, rebuild_cis * 1.0f / scan_count);
}
#else
ri.data = data;
if(img)
data->add_ref();
@ -422,7 +473,10 @@ int imgproc_mgr::process(LPPACKIMAGE info, dyn_mem_ptr data, bool img)
ri.info = *info;
else
ri.info.data_size = (uint32_t)(long)info;
#endif
ri.img = img;
// if(!img)
params_[ind]->mean.que->save(ri, true);
++put_ind_;
@ -454,4 +508,6 @@ void imgproc_mgr::start_new_turn(uint32_t scanid, uint32_t sessionid)
session_id_ = sessionid;
put_ind_ = 0;
start_workers(3);
rebuild_cis = 0;
scan_count = 0;
}

View File

@ -24,8 +24,12 @@ class imgproc_mgr : public sane_opt_provider
{
typedef struct _raw_img
{
#ifdef REBUILD_IN_CIS_THREAD
std::vector<PROCIMGINFO> imgs;
#else
PACKIMAGE info;
dyn_mem_ptr data; // nullptr and img is 'true' to exit worker
#endif
bool img;
}RAWIMG;

View File

@ -402,5 +402,7 @@ public:
#define FUNCTION_PROTO_PARAMETERS dyn_mem_ptr, uint32_t*, packet_data_base_ptr*
#define FUNCTION_PROTO_COMMAND_HANDLE dyn_mem_ptr(FUNCTION_PROTO_PARAMETERS)
#define REBUILD_IN_CIS_THREAD
#define SENDER_PROTO data_source_ptr ptr, void* param
#define RES_CHK_PROTO int type, bool wait, int to_ms, void* param