调整图像包头信息;启动扫描成功返回硬件配置参数JSON
This commit is contained in:
parent
d98f5039a5
commit
4291bca09c
|
@ -355,11 +355,15 @@ void FpgaComm::setDelayTime(int value) {
|
|||
WR_Reg(DelayTime);
|
||||
}
|
||||
|
||||
bool FpgaComm::update()
|
||||
bool FpgaComm::update(std::vector<int>* data)
|
||||
{
|
||||
bool good = true;
|
||||
std::vector<int> d;
|
||||
chronograph watch;
|
||||
|
||||
if(!data)
|
||||
data = &d;
|
||||
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "Read %u FpgaComm registers ...\n", MAX_REGS);
|
||||
for(int i = 0; i < MAX_REGS; i++)
|
||||
{
|
||||
|
@ -369,6 +373,7 @@ bool FpgaComm::update()
|
|||
utils::to_log(LOG_LEVEL_FATAL, " FATAL: Register %d(0x%08x) timeout.\n", i, fpgaParams.regs[i]);
|
||||
break;
|
||||
}
|
||||
data->push_back(fpgaParams.regs[i]);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, " reg(%02d) = 0x%08x\n", i, fpgaParams.regs[i]);
|
||||
}
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "Read FpgaComm registers over.\n");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "../uart/regsaccess.h"
|
||||
|
||||
#ifdef HAS_UV
|
||||
|
@ -234,7 +235,7 @@ public:
|
|||
void setDelayTime(int value);
|
||||
void setTrigMode(bool isArmMode);
|
||||
|
||||
bool update();
|
||||
bool update(std::vector<int>* data = nullptr);
|
||||
void enableJamCheck(bool b);
|
||||
void resetADC();
|
||||
virtual bool write(unsigned int addr, unsigned int val);
|
||||
|
|
|
@ -240,7 +240,7 @@ void scanner_hw::init(void)
|
|||
};
|
||||
OPT_HANDLER(cntm)
|
||||
{
|
||||
|
||||
scan_cntless_ = strcmp((char*)value, "\350\277\236\347\273\255\346\211\253\346\217\217") == 0;
|
||||
};
|
||||
OPT_HANDLER(cnt)
|
||||
{
|
||||
|
@ -331,7 +331,9 @@ void scanner_hw::thread_image_capture(void)
|
|||
{
|
||||
PACKIMAGE img(img_base_);
|
||||
safe_fifo<int> avail_mem("v4l2-mem");
|
||||
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4;
|
||||
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4,
|
||||
err = SCANNER_ERR_OK;
|
||||
chronograph watch;
|
||||
std::pair<int, int> mbev;
|
||||
|
||||
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
|
||||
|
@ -347,7 +349,7 @@ void scanner_hw::thread_image_capture(void)
|
|||
motor_->start();
|
||||
while(scanning_ && times++ < 5)
|
||||
{
|
||||
if(mb_events_.take(mbev, true, 5000))
|
||||
if(mb_events_.take(mbev, true, to_lifter_))
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "take first motorboard event: %d - 0x%08x\n", mbev.first, mbev.second);
|
||||
break;
|
||||
|
@ -359,22 +361,27 @@ void scanner_hw::thread_image_capture(void)
|
|||
times = 0;
|
||||
while(scanning_ && mbev.first == MOTOR_BORD_EVENT_LIFTER_READY) // auto scan cycle ...
|
||||
{
|
||||
times++;
|
||||
watch.reset();
|
||||
motor_->pick_paper();
|
||||
|
||||
// scanning ONE turn ...
|
||||
while(scanning_ && motor_->wait_paper_out(3000))
|
||||
while(scanning_ && motor_->wait_paper_out(to_paper_out_))
|
||||
{
|
||||
img.height = get_image_real_height(minh);
|
||||
|
||||
size_t size = 0;
|
||||
int ind = -1;
|
||||
void* frame = camera_->read_frame(5 * 1000, size, ind);
|
||||
void* frame = camera_->read_frame(to_stream_, size, ind);
|
||||
dyn_mem_shared_ptr mem = nullptr;
|
||||
|
||||
if(!frame)
|
||||
{
|
||||
err = SCANNER_ERR_DEVICE_CIS_STREAM;
|
||||
break;
|
||||
}
|
||||
img.prc_time = watch.elapse_ms();
|
||||
printf("Fetch paper %d: %ums\n", img.pos.paper_ind + 1, img.prc_time);
|
||||
mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
|
||||
used_v4l2_mem++;
|
||||
img.pos.paper_ind++;
|
||||
|
@ -383,18 +390,20 @@ void scanner_hw::thread_image_capture(void)
|
|||
img_handler_(mem, true, &img);
|
||||
mem->release();
|
||||
|
||||
if(img.pos.paper_ind == scan_count_ || is_scan_fatal())
|
||||
if((!scan_cntless_ && img.pos.paper_ind == scan_count_) || is_scan_fatal())
|
||||
break;
|
||||
|
||||
// retrieve V4L2 memory ...
|
||||
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
|
||||
if(used_v4l2_mem >= camera_->get_mem_count())
|
||||
{
|
||||
err = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
|
||||
stop_scan();
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
watch.reset();
|
||||
motor_->pick_paper();
|
||||
}
|
||||
|
||||
|
@ -412,6 +421,9 @@ void scanner_hw::thread_image_capture(void)
|
|||
// wait paper ...
|
||||
}
|
||||
|
||||
if(scanning_ && mbev.first != MOTOR_BORD_EVENT_LIFTER_READY && times == 0)
|
||||
err = SCANNER_ERR_DEVICE_FEEDER_POS;
|
||||
|
||||
stop_scan();
|
||||
while(used_v4l2_mem)
|
||||
{
|
||||
|
@ -428,7 +440,7 @@ void scanner_hw::thread_image_capture(void)
|
|||
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited.\n");
|
||||
|
||||
scanning_ = false;
|
||||
img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, 0);
|
||||
img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, (LPPACKIMAGE)err);
|
||||
}
|
||||
int scanner_hw::get_image_real_height(int minh)
|
||||
{
|
||||
|
@ -594,9 +606,10 @@ void scanner_hw::enable(const char* name, bool able)
|
|||
}
|
||||
|
||||
// operation ...
|
||||
int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
||||
int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler, std::string* cfgjson)
|
||||
{
|
||||
std::string tips("");
|
||||
refer_guard<gb_json> cfg(new gb_json());
|
||||
|
||||
this->close();
|
||||
int fh = 16380;
|
||||
|
@ -630,6 +643,16 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
|||
img_controller_->enableLed(cis_led_);
|
||||
img_controller_->setVsp(66, 67);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "FPGA Sp = %d, Sample = %d\n", sp_, sample_);
|
||||
if(cfgjson)
|
||||
{
|
||||
cfg->set_value("color", mode_.c_str());
|
||||
cfg->set_value("dpi", (std::to_string(dpi_) + " * " + std::to_string(dpi_y_)).c_str());
|
||||
cfg->set_value("sample", sample_);
|
||||
cfg->set_value("Sp", sp_);
|
||||
cfg->set_value("Vsp-A", 66);
|
||||
cfg->set_value("Vsp-B", 67);
|
||||
cfg->set_value("Led-On", cis_led_);
|
||||
}
|
||||
|
||||
void(FpgaComm::* exposure[])(int) = {&FpgaComm::setAExposureB, &FpgaComm::setAExposureG
|
||||
, &FpgaComm::setAExposureR, &FpgaComm::setBExposureB, &FpgaComm::setBExposureG, &FpgaComm::setBExposureR};
|
||||
|
@ -646,6 +669,16 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
|||
tips += "];";
|
||||
}
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str());
|
||||
if(cfgjson)
|
||||
{
|
||||
char val[128] = {0};
|
||||
|
||||
sprintf(val, "(%u, %u, %u)", exposure_[SIDE_FRONT][COLOR_IND_RED], exposure_[SIDE_FRONT][COLOR_IND_GREEN], exposure_[SIDE_FRONT][COLOR_IND_BLUE]);
|
||||
cfg->set_value("exposure-A(RGB)", val);
|
||||
|
||||
sprintf(val, "(%u, %u, %u)", exposure_[SIDE_BACK][COLOR_IND_RED], exposure_[SIDE_BACK][COLOR_IND_GREEN], exposure_[SIDE_BACK][COLOR_IND_BLUE]);
|
||||
cfg->set_value("exposure-B(RGB)", val);
|
||||
}
|
||||
|
||||
for(int i = 0; i < CIS_SECTOR_COUNT; ++i)
|
||||
{
|
||||
|
@ -658,6 +691,19 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
|||
img_controller_->setBOffset(i, off_[SIDE_BACK][i]);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str());
|
||||
}
|
||||
if(cfgjson)
|
||||
{
|
||||
for(int i = 0; i < CIS_SECTOR_COUNT; ++i)
|
||||
{
|
||||
char key[40] = {0}, val[128] = {0};
|
||||
|
||||
sprintf(key, "gain-sec-%d", i + 1);
|
||||
sprintf(val, "A = %ux + %u, B = %ux + %u"
|
||||
, gain_[SIDE_FRONT][i], off_[SIDE_FRONT][i]
|
||||
, gain_[SIDE_BACK][i], off_[SIDE_BACK][i]);
|
||||
cfg->set_value(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
auto cb = [this](int ev, unsigned int data) -> void
|
||||
{
|
||||
|
@ -717,7 +763,19 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
|||
// for(int i = 0; i < _countof(vals); ++i)
|
||||
// img_controller_->write(i, vals[i]);
|
||||
// }
|
||||
img_controller_->update();
|
||||
|
||||
std::vector<int> regs;
|
||||
img_controller_->update(®s);
|
||||
if(cfgjson)
|
||||
{
|
||||
gb_json *c = new gb_json();
|
||||
c->clear(true);
|
||||
for(auto& v: regs)
|
||||
*c += v;
|
||||
cfg->set_value("controller", c);
|
||||
c->release();
|
||||
*cfgjson = std::move(cfg->to_string());
|
||||
}
|
||||
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ class scanner_hw : public sane_opt_provider
|
|||
std::string family_ = "G200";
|
||||
PACKIMAGE img_base_;
|
||||
volatile bool auto_scan_ = false;
|
||||
int scan_count_ = -1;
|
||||
bool scan_cntless_ = true;
|
||||
int scan_count_ = 1;
|
||||
int cis_length_ = 3888;
|
||||
bool cis_led_ = true;
|
||||
int dpi_ = 300;
|
||||
|
@ -89,6 +90,10 @@ class scanner_hw : public sane_opt_provider
|
|||
std::map<std::string, std::function<void(void*)>> opt_handler_;
|
||||
|
||||
|
||||
int to_lifter_ = 5000; // timeout in ms of lifter arrived
|
||||
int to_paper_out_ = 3000; // timeout in ms of paper passed
|
||||
int to_stream_ = 5000; // timeout in ms of frame data can be read
|
||||
|
||||
void init(void);
|
||||
void init_version(std::string& text);
|
||||
void thread_image_capture(void);
|
||||
|
@ -111,7 +116,7 @@ public:
|
|||
|
||||
// operation ...
|
||||
public:
|
||||
int open(std::function<IMAGE_HANDLER_PROTO> image_handler);
|
||||
int open(std::function<IMAGE_HANDLER_PROTO> image_handler, std::string* cfgjson = nullptr);
|
||||
int start_scan(void);
|
||||
int stop_scan(void);
|
||||
int close(bool from_worker = false);
|
||||
|
|
|
@ -57,7 +57,7 @@ typedef struct SMB_CONFIG
|
|||
unsigned int v_setting : 2;//10
|
||||
unsigned int speed_set_enable : 1;
|
||||
unsigned int double_out_en : 1;
|
||||
|
||||
|
||||
unsigned int dpi_mode : 2;
|
||||
// unsigned int sleep_parameter : 2;//6
|
||||
// unsigned int dpi600:1;
|
||||
|
@ -183,6 +183,9 @@ enum motor_board_port
|
|||
MB_PORT_TIME, // ???
|
||||
MB_PORT_FUNCTION,
|
||||
MB_PORT_ULTROSONIC,
|
||||
|
||||
// I am the last
|
||||
MB_PORT_COUNT
|
||||
};
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -22,68 +22,6 @@ rebuild::rebuild() : image_processor("rebuild")
|
|||
rebuild::~rebuild()
|
||||
{}
|
||||
|
||||
int rebuild::do_rebuild(PROCIMGINFO& in, std::vector<PROCIMGINFO>& out)
|
||||
{
|
||||
int ret = SCANNER_ERR_OK,
|
||||
secl = cis::get_sector_pixels(0, in.info.resolution_x, true),
|
||||
linel = cis::get_line_stream_length(in.info.resolution_x, false),
|
||||
size = in.info.height * in.info.width / 2;
|
||||
PROCIMGINFO o;
|
||||
|
||||
o.info = in.info;
|
||||
if(in.info.pos.paper_side != PAPER_SIDE_BACK &&
|
||||
in.info.pos.paper_side != PAPER_SIDE_FRONT)
|
||||
linel *= 2;
|
||||
|
||||
if(in.info.width == linel) // gray
|
||||
{
|
||||
|
||||
}
|
||||
else // color
|
||||
{
|
||||
|
||||
uint8_t *srcd = in.img.data + in.info.width * (in.info.height - 1), // line reverse
|
||||
*dstf = (uint8_t*)malloc(size),
|
||||
*dstb = (uint8_t*)malloc(size),
|
||||
*df = dstf, *db = dstb,
|
||||
soff[] = {11, 10, 9, 2, 1, 0};
|
||||
|
||||
o.info.channels = 3;
|
||||
o.info.width /= 3 * 2;
|
||||
o.info.prc_stage = get_position();
|
||||
|
||||
printf("rebuild (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", in.info.width, in.info.height
|
||||
, o.info.width, o.info.height, dstf, dstb, size);
|
||||
for(int h = 0; h < in.info.height; ++h)
|
||||
{
|
||||
for(int w = 0; w < o.info.width; ++w)
|
||||
{
|
||||
int s = w / secl;
|
||||
*df++ = srcd[(soff[s] + 0) * secl + (w % secl)];
|
||||
*df++ = srcd[(soff[s] + 6) * secl + (w % secl)];
|
||||
*df++ = srcd[(soff[s] + 3) * secl + (w % secl)];
|
||||
|
||||
*db++ = srcd[in.info.width / 2 + (soff[s] + 6) * secl + (w % secl)];
|
||||
*db++ = srcd[in.info.width / 2 + (soff[s] + 0) * secl + (w % secl)];
|
||||
*db++ = srcd[in.info.width / 2 + (soff[s] + 3) * secl + (w % secl)];
|
||||
}
|
||||
srcd -= in.info.width;
|
||||
}
|
||||
printf(" bits data ready, construct cv::Mat(front = %u, back = %u) ...\n", df - dstf, db - dstb);
|
||||
o.info.pos.paper_side = PAPER_SIDE_FRONT;
|
||||
o.img = cv::Mat(o.info.height, o.info.width, CV_8UC3, (void*)dstf, size);
|
||||
out.push_back(o);
|
||||
// free(dstf);
|
||||
|
||||
o.info.pos.paper_side = PAPER_SIDE_BACK;
|
||||
o.img = (cv::Mat(o.info.height, o.info.width, CV_8UC3, (void*)dstb, size));
|
||||
out.push_back(o);
|
||||
// free(dstb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rebuild::set_value(const char* name/*nullptr for all options*/, void* val/*nullptr for restore*/)
|
||||
{
|
||||
int ret = SCANNER_ERR_OK;
|
||||
|
@ -108,7 +46,7 @@ int rebuild::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out
|
|||
{
|
||||
for(auto& v: in)
|
||||
{
|
||||
ret = do_rebuild(v, out);
|
||||
do_rebuild(&v.info, v.img.ptr(), out);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -121,3 +59,69 @@ int rebuild::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out
|
|||
return ret;
|
||||
}
|
||||
|
||||
void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGINFO>& out)
|
||||
{
|
||||
int secl = cis::get_sector_pixels(0, info->resolution_x, true),
|
||||
linel = cis::get_line_stream_length(info->resolution_x, false),
|
||||
size = info->height * info->width / 2;
|
||||
PROCIMGINFO o;
|
||||
chronograph watch;
|
||||
|
||||
o.info = *info;
|
||||
if(info->pos.paper_side != PAPER_SIDE_BACK &&
|
||||
info->pos.paper_side != PAPER_SIDE_FRONT)
|
||||
linel *= 2;
|
||||
|
||||
o.info.prc_stage = get_position();
|
||||
o.info.pos.paper_side = PAPER_SIDE_FRONT;
|
||||
out.push_back(o);
|
||||
o.info.pos.paper_side = PAPER_SIDE_BACK;
|
||||
out.push_back(o);
|
||||
|
||||
if(info->width == linel) // gray
|
||||
{
|
||||
|
||||
}
|
||||
else // color
|
||||
{
|
||||
uint8_t *srcd = stream + info->width * (info->height - 1), // line reverse
|
||||
*dstf = nullptr, // (uint8_t*)malloc(size),
|
||||
*dstb = nullptr, // (uint8_t*)malloc(size),
|
||||
*df = dstf, *db = dstb,
|
||||
soff[] = {11, 10, 9, 2, 1, 0};
|
||||
|
||||
out[1].info.channels = out[0].info.channels = 3;
|
||||
out[0].info.width /= out[0].info.channels * 2;
|
||||
out[1].info.width /= out[1].info.channels * 2;
|
||||
|
||||
out[0].img.create(out[0].info.height, out[0].info.width, CV_8UC3);
|
||||
out[1].img.create(out[1].info.height, out[1].info.width, CV_8UC3);
|
||||
|
||||
df = dstf = out[0].img.ptr();
|
||||
db = dstb = out[1].img.ptr();
|
||||
|
||||
o.info.width = out[0].info.width;
|
||||
o.info.channels = out[0].info.channels;
|
||||
printf("rebuild (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", info->width, info->height
|
||||
, o.info.width, o.info.height, dstf, dstb, size);
|
||||
for(int h = 0; h < info->height; ++h)
|
||||
{
|
||||
for(int w = 0; w < o.info.width; ++w)
|
||||
{
|
||||
int s = w / secl;
|
||||
*df++ = srcd[(soff[s] + 0) * secl + (w % secl)];
|
||||
*df++ = srcd[(soff[s] + 6) * secl + (w % secl)];
|
||||
*df++ = srcd[(soff[s] + 3) * secl + (w % secl)];
|
||||
|
||||
*db++ = srcd[info->width / 2 + (soff[s] + 6) * secl + (w % secl)];
|
||||
*db++ = srcd[info->width / 2 + (soff[s] + 0) * secl + (w % secl)];
|
||||
*db++ = srcd[info->width / 2 + (soff[s] + 3) * secl + (w % secl)];
|
||||
}
|
||||
srcd -= info->width;
|
||||
}
|
||||
}
|
||||
|
||||
size = watch.elapse_ms();
|
||||
out[0].info.prc_time = size;
|
||||
out[1].info.prc_time = size;
|
||||
}
|
|
@ -9,8 +9,6 @@ class rebuild : public image_processor
|
|||
{
|
||||
bool rebuild_ = true;
|
||||
|
||||
int do_rebuild(PROCIMGINFO& in, std::vector<PROCIMGINFO>& out);
|
||||
|
||||
public:
|
||||
rebuild();
|
||||
|
||||
|
@ -23,4 +21,7 @@ public:
|
|||
|
||||
public:
|
||||
virtual int process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out) override;
|
||||
|
||||
public:
|
||||
void do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGINFO>& out);
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ imgproc_mgr::imgproc_mgr(std::function<void(data_source_ptr)> sender
|
|||
else
|
||||
opts_ = new device_option(true);
|
||||
load_processor(nullptr);
|
||||
rebuild_.reset(new rebuild());
|
||||
|
||||
auto thrd = [&](void) -> void
|
||||
{
|
||||
|
@ -108,63 +109,77 @@ void imgproc_mgr::process(RAWIMG* img)
|
|||
if(img->img)
|
||||
{
|
||||
std::vector<PROCIMGINFO> in, out;
|
||||
PROCIMGINFO ele;
|
||||
chronograph watch;
|
||||
|
||||
ele.ext_info = "";
|
||||
ele.info = img->info;
|
||||
ele.img = cv::Mat(ele.info.height, ele.info.width, CV_8UC1, (void*)img->data->ptr(), img->data->get_rest());
|
||||
// ele.img.create(img->info.height, img->info.width, CV_8UC1);
|
||||
// memcpy(ele.img.ptr(), img->data->ptr(), img->data->get_rest());
|
||||
img->data->release();
|
||||
in.push_back(ele);
|
||||
rebuild_->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());
|
||||
|
||||
if(dump_img_)
|
||||
{
|
||||
send_image(&img->info, img->data->ptr(), img->info.width * img->info.height);
|
||||
img->data->release();
|
||||
for(auto& v: processors_)
|
||||
{
|
||||
send_image(in, false);
|
||||
v->process(in, out);
|
||||
in = std::move(out);
|
||||
if(v->is_enable())
|
||||
{
|
||||
v->process(in, out);
|
||||
in = std::move(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
img->data->release();
|
||||
for(auto& v: processors_)
|
||||
{
|
||||
v->process(in, out);
|
||||
in = std::move(out);
|
||||
if(v->is_enable())
|
||||
{
|
||||
v->process(in, out);
|
||||
in = std::move(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
send_image(in, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.reserve);
|
||||
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.data_size);
|
||||
uint32_t wait = 0, que = 0;
|
||||
|
||||
ptr->set_session_id(session_id_);
|
||||
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);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
img_sender_(ptr);
|
||||
ptr->release();
|
||||
}
|
||||
}
|
||||
void imgproc_mgr::send_image(LPPACKIMAGE head, uint8_t* data, size_t size, void* info, size_t info_l)
|
||||
{
|
||||
dyn_mem_ptr mem(dyn_mem::memory(size));
|
||||
image_packet_ptr ptr = nullptr;
|
||||
|
||||
printf("send image %d(%d-0x%04x) with size %u:\n", head->pos.paper_ind, head->pos.paper_side, head->prc_stage, size);
|
||||
mem->put(data, size);
|
||||
ptr = imgproc_mgr::image_sent_packet(head, mem, scan_id_, info, info_l);
|
||||
mem->release();
|
||||
ptr->set_session_id(session_id_);
|
||||
img_sender_(ptr);
|
||||
ptr->release();
|
||||
}
|
||||
void imgproc_mgr::send_image(std::vector<PROCIMGINFO>& imgs, bool clear_after_send)
|
||||
{
|
||||
printf("send image %d - %d:\n", imgs[0].info.pos.paper_ind, imgs[0].info.prc_stage);
|
||||
for(auto& v: imgs)
|
||||
{
|
||||
uint32_t size = v.img.total() * v.img.channels();
|
||||
dyn_mem_ptr mem(dyn_mem::memory(size));
|
||||
// printf(" %d - image bits: %p + %u, src = %p([0] = %02x)\n", v.info.pos.paper_side, mem->ptr(), size, v.img.data, v.img.data[0]);
|
||||
mem->put(v.img.data, size);
|
||||
// if(clear_after_send)
|
||||
// v.img.deallocate();
|
||||
// printf(" consturct image packet ...\n");
|
||||
image_packet_ptr ptr = imgproc_mgr::image_sent_packet(&v.info, mem, scan_id_, &v.ext_info[0], v.ext_info.length());
|
||||
|
||||
ptr->set_session_id(session_id_);
|
||||
// printf(" sending image packet: %p + %u\n", ptr->ptr(), ptr->get_rest());
|
||||
img_sender_(ptr);
|
||||
ptr->release();
|
||||
mem->release();
|
||||
send_image(&v.info, v.img.ptr(), v.img.total() * v.img.channels()
|
||||
, v.ext_info.empty() ? nullptr : &v.ext_info[0], v.ext_info.length());
|
||||
if(clear_after_send)
|
||||
v.img.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +206,7 @@ int imgproc_mgr::load_processor(const char* path)
|
|||
processors_.push_back(obj); \
|
||||
}
|
||||
|
||||
ADD_IMG_PROCESSOR(rebuild);
|
||||
// ADD_IMG_PROCESSOR(rebuild);
|
||||
|
||||
std::sort(processors_.begin(), processors_.end(), &imgproc_mgr::sort_processor_by_pos);
|
||||
|
||||
|
@ -217,7 +232,7 @@ int imgproc_mgr::process(LPPACKIMAGE info, dyn_mem_ptr data, bool img)
|
|||
if(img)
|
||||
ri.info = *info;
|
||||
else
|
||||
ri.info.reserve = (uint32_t)(long)info;
|
||||
ri.info.data_size = (uint32_t)(long)info;
|
||||
ri.img = img;
|
||||
prc_que_.save(ri, true);
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
typedef std::shared_ptr<std::vector<char>> dcptr;
|
||||
|
||||
class device_option;
|
||||
class rebuild;
|
||||
|
||||
class imgproc_mgr : public sane_opt_provider
|
||||
{
|
||||
typedef struct _raw_img
|
||||
|
@ -25,6 +27,7 @@ class imgproc_mgr : public sane_opt_provider
|
|||
bool img;
|
||||
}RAWIMG;
|
||||
|
||||
refer_guard<rebuild> rebuild_;
|
||||
volatile bool run_ = true;
|
||||
bool dump_img_ = false;
|
||||
uint32_t scan_id_ = 0;
|
||||
|
@ -46,6 +49,7 @@ class imgproc_mgr : public sane_opt_provider
|
|||
uint32_t add_busy_worker(int inc = 1);
|
||||
void thread_worker(void);
|
||||
void process(RAWIMG* img);
|
||||
void send_image(LPPACKIMAGE head, uint8_t* data, size_t size, void* info = nullptr, size_t info_l = 0);
|
||||
void send_image(std::vector<PROCIMGINFO>& imgs, bool clear_after_send);
|
||||
|
||||
public:
|
||||
|
|
|
@ -64,6 +64,12 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0)
|
|||
|
||||
auto sender = [this](data_source_ptr img) -> void
|
||||
{
|
||||
if(img->ptr() && ((LPPACK_BASE)img->ptr())->cmd == PACK_CMD_SCAN_FINISHED_ROGER)
|
||||
{
|
||||
cis_->close();
|
||||
utils::print_memory_usage("Memory usage when finished scanning", false);
|
||||
}
|
||||
|
||||
usb_->write_bulk(img);
|
||||
};
|
||||
|
||||
|
@ -456,8 +462,9 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t base_head_size = sizeof(PACK_BASE);
|
||||
dyn_mem_ptr reply = dyn_mem::memory(base_head_size);
|
||||
uint32_t base_head_size = sizeof(PACK_BASE);
|
||||
dyn_mem_ptr reply = nullptr;
|
||||
std::string config("");
|
||||
|
||||
img_cnt_ = 0;
|
||||
scan_id_ = pack->pack_id;
|
||||
|
@ -467,26 +474,14 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
|
|||
auto receiver = [this](dyn_mem_ptr data, bool img, LPPACKIMAGE lpinfo) -> void
|
||||
{
|
||||
img_prcr_->process(lpinfo, data, img);
|
||||
// if(img)
|
||||
// {
|
||||
// FILE* dst = fopen(("/tmp/scan_" + std::to_string(lpinfo->pos.paper_ind) + ".bmp").c_str(), "wb");
|
||||
// if(dst)
|
||||
// {
|
||||
// std::string bih(utils::bitmap_info_header(lpinfo->width, lpinfo->height, lpinfo->bpp, lpinfo->resolution_x, lpinfo->resolution_y)),
|
||||
// bfh(utils::bitmap_file_header((BITMAPINFOHEADER*)&bih[0]));
|
||||
// fwrite(bfh.c_str(), 1, bfh.length(), dst);
|
||||
// fwrite(bih.c_str(), 1, bih.length(), dst);
|
||||
// fwrite(data->ptr(), 1, ((BITMAPINFOHEADER*)&bih[0])->biSizeImage, dst);
|
||||
// fclose(dst);
|
||||
// }
|
||||
// data->release();
|
||||
// }
|
||||
};
|
||||
|
||||
utils::print_memory_usage("Memory usage before scanning", false);
|
||||
*used = base_head_size;
|
||||
reply->set_len(base_head_size);
|
||||
img_prcr_->start_new_turn(scan_id_, session);
|
||||
scan_err_ = cis_->open(receiver);
|
||||
scan_err_ = cis_->open(receiver, &config);
|
||||
reply = dyn_mem::memory(base_head_size + config.length() + 2);
|
||||
reply->set_len(base_head_size + config.length() + 2);
|
||||
if(scan_err_ == 0)
|
||||
scan_err_ = cis_->start_scan();
|
||||
if(scan_err_)
|
||||
|
@ -494,6 +489,8 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
|
|||
cis_->stop_scan();
|
||||
}
|
||||
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, scan_err_);
|
||||
((LPPACK_BASE)reply->ptr())->payload_len = config.length() + 2;
|
||||
strcpy(((LPPACK_BASE)reply->ptr())->payload, config.c_str());
|
||||
*used |= INT32_MAX + 1;
|
||||
|
||||
return reply;
|
||||
|
|
|
@ -30,7 +30,16 @@ static void sigHandler(int sig)
|
|||
|
||||
_exit(0);
|
||||
}
|
||||
static std::string get_command(void)
|
||||
{
|
||||
std::string cmd("");
|
||||
char in[2] = {0};
|
||||
|
||||
while((in[0] = getchar()) != 0x0a)
|
||||
cmd += in;
|
||||
|
||||
return std::move(cmd);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -45,25 +54,20 @@ int main()
|
|||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* kill pid / killall name */
|
||||
signal(SIGKILL, sigHandler);
|
||||
|
||||
scanner = new async_scanner();
|
||||
int err = scanner->last_error();
|
||||
|
||||
if(err == 0)
|
||||
while(err == 0)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(getchar() == 'e')
|
||||
{
|
||||
if(getchar() == 'x')
|
||||
{
|
||||
if(getchar() == 'i')
|
||||
{
|
||||
if(getchar() == 't')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string cmd(get_command());
|
||||
if(cmd == "exit")
|
||||
break;
|
||||
if(cmd == "mem")
|
||||
utils::print_memory_usage(" Memory usage", false);
|
||||
}
|
||||
|
||||
async_scanner* tmp = scanner;
|
||||
|
|
|
@ -384,6 +384,7 @@ dyn_mem::dyn_mem(void* buf, size_t size)
|
|||
|
||||
dyn_mem::~dyn_mem()
|
||||
{
|
||||
notify_progress(space_, len_, 0);
|
||||
if (buf_)
|
||||
{
|
||||
free(buf_);
|
||||
|
|
|
@ -301,10 +301,11 @@ typedef struct _pack_img
|
|||
uint32_t bpp : 6; // bits per pixel. (image-collector set)
|
||||
uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f. (image-collector set)
|
||||
uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set)
|
||||
uint32_t reserve : 2; // unused now
|
||||
uint32_t reserved : 2; //
|
||||
uint32_t prc_stage : 14; // position of image processor, 0 is raw from CIS directly
|
||||
uint32_t prc_time : 18; // spent time in milliseconds of image-process prc_stage
|
||||
uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set)
|
||||
uint64_t prc_stage : 16; // position of image processor, 0 is raw from CIS directly
|
||||
uint64_t data_size : 48; // image data size in 'data' with bytes. (image-collector set)
|
||||
uint32_t data_size; // image data size in 'data' with bytes. (image-collector set)
|
||||
// char data[0]; // two parts: image info (info_size) + image data (data_size)
|
||||
|
||||
STRUCT_CONSTRUCTOR(_pack_img)
|
||||
|
|
|
@ -1087,6 +1087,67 @@ namespace utils
|
|||
return err;
|
||||
}
|
||||
|
||||
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid)
|
||||
{
|
||||
if(pid == -1)
|
||||
pid = GetCurrentProcessId();
|
||||
|
||||
#if OW_WIN
|
||||
#else
|
||||
char cmd[40] = {0};
|
||||
std::string result(""), tag("");
|
||||
size_t pos = 0;
|
||||
|
||||
sprintf(cmd, "cat /proc/%u/status | grep Vm", pid);
|
||||
result = get_command_result(cmd);
|
||||
if(result.empty())
|
||||
return -1;
|
||||
|
||||
if(peak)
|
||||
{
|
||||
tag = "VmPeak";
|
||||
pos = result.find(tag);
|
||||
if(pos != std::string::npos)
|
||||
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), peak);
|
||||
else
|
||||
*peak = 0;
|
||||
*peak *= 1024;
|
||||
}
|
||||
|
||||
if(now)
|
||||
{
|
||||
tag = "VmSize";
|
||||
pos = result.find(tag);
|
||||
if(pos != std::string::npos)
|
||||
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), now);
|
||||
else
|
||||
*now = 0;
|
||||
*now *= 1024;
|
||||
}
|
||||
|
||||
if(phymem)
|
||||
{
|
||||
tag = "VmRSS";
|
||||
pos = result.find(tag);
|
||||
if(pos != std::string::npos)
|
||||
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), phymem);
|
||||
else
|
||||
*phymem = 0;
|
||||
*phymem *= 1024;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
void print_memory_usage(const char* tips, bool to_log_file)
|
||||
{
|
||||
uint64_t peak = 0, now = 0, phy = 0;
|
||||
|
||||
get_memory_usage(&peak, &now, &phy);
|
||||
if(to_log_file)
|
||||
to_log(LOG_LEVEL_DEBUG, "%s: Peak = %llu, Now = %llu, Phy = %llu\n", tips, peak, now, phy);
|
||||
else
|
||||
printf("%s: Peak = %llu, Now = %llu, Phy = %llu\n", tips, peak, now, phy);
|
||||
}
|
||||
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
@ -64,6 +64,8 @@ namespace utils
|
|||
int move_file(const char* from, const char* to);
|
||||
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
|
||||
|
||||
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid = -1);
|
||||
void print_memory_usage(const char* tips, bool to_log_file);
|
||||
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
|
||||
unsigned int get_page_size(unsigned int* map_unit = nullptr);
|
||||
|
||||
|
@ -220,6 +222,40 @@ public:
|
|||
virtual int32_t release(void);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class refer_guard
|
||||
{
|
||||
T *obj_ = nullptr;
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
if(obj_)
|
||||
obj_->release();
|
||||
obj_ = nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
refer_guard()
|
||||
{}
|
||||
refer_guard(T* obj) : obj_(obj)
|
||||
{}
|
||||
~refer_guard()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
public:
|
||||
void reset(T* obj)
|
||||
{
|
||||
clear();
|
||||
obj_ = obj;
|
||||
}
|
||||
T* operator->(void)
|
||||
{
|
||||
return obj_;
|
||||
}
|
||||
};
|
||||
|
||||
// time utility
|
||||
class chronograph
|
||||
{
|
||||
|
|
|
@ -82,6 +82,9 @@ enum scanner_err
|
|||
|
||||
SCANNER_ERR_DEVICE_NOT_READY, // 设备未准备好(执行某操作的前置条件未准备好)
|
||||
SCANNER_ERR_DEVICE_GET_STATUS_FAILED, // 获取电机板状态失败
|
||||
SCANNER_ERR_DEVICE_FEEDER_POS, // 送纸器到位信号未触发
|
||||
SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM, // CIS缓冲区被耗尽
|
||||
SCANNER_ERR_DEVICE_CIS_STREAM, // 获取CIS图像数据失败
|
||||
SCANNER_ERR_DEVICE_HD_001, // 设备硬件访问错误
|
||||
SCANNER_ERR_DEVICE_HD_002, // 设备硬件访问错误
|
||||
SCANNER_ERR_DEVICE_HD_003, // 设备硬件访问错误
|
||||
|
|
|
@ -60,8 +60,8 @@ add_packagedirs("sdk")
|
|||
add_defines("BUILD_AS_DEVICE")
|
||||
add_defines("VER_MAIN=2")
|
||||
add_defines("VER_FAMILY=200")
|
||||
add_defines("VER_DATE=20240119")
|
||||
add_defines("VER_BUILD=41")
|
||||
add_defines("VER_DATE=20240123")
|
||||
add_defines("VER_BUILD=21")
|
||||
|
||||
target("conf")
|
||||
set_kind("phony")
|
||||
|
|
Loading…
Reference in New Issue