From dd115c8af61c2ff391c0e40ab8daaba5b75c6352 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Sun, 10 Nov 2019 20:37:09 +0800 Subject: [PATCH] =?UTF-8?q?RDP=E6=92=AD=E6=94=BE=E5=99=A8=E5=AE=8C?= =?UTF-8?q?=E5=B7=A5=EF=BC=8C=E5=85=81=E8=AE=B8=E6=8B=96=E5=8A=A8=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E6=9D=A1=E4=BA=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/tp-player/bar.cpp | 2 +- client/tp-player/main.cpp | 2 +- client/tp-player/mainwindow.cpp | 76 ++++++-------- client/tp-player/record_format.h | 7 +- client/tp-player/thr_data.cpp | 156 +--------------------------- client/tp-player/thr_data.h | 4 +- client/tp-player/thr_play.cpp | 27 ++--- client/tp-player/update_data.cpp | 75 +++++++++---- client/tp-player/update_data.h | 47 ++++++--- server/tp_core/common/base_record.h | 6 +- 10 files changed, 146 insertions(+), 256 deletions(-) diff --git a/client/tp-player/bar.cpp b/client/tp-player/bar.cpp index 61ebbcc..0c9bea5 100644 --- a/client/tp-player/bar.cpp +++ b/client/tp-player/bar.cpp @@ -372,7 +372,7 @@ void Bar::onMouseMove(int x, int y) { if(pt.x() < m_rc_progress.left()) { percent = 0; - m_resume_ms = 0; + m_resume_ms = 1; } else if(pt.x() > m_rc_progress.right()) { percent = 100; diff --git a/client/tp-player/main.cpp b/client/tp-player/main.cpp index 486d0c5..b4a133e 100644 --- a/client/tp-player/main.cpp +++ b/client/tp-player/main.cpp @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) // qDebug("data-path-base: %s", data_path_base.toStdString().c_str()); // return 0; - QGuiApplication::setApplicationDisplayName("TP-Player"); + QGuiApplication::setApplicationDisplayName(LOCAL8BIT("[Teleport播放器]")); QCommandLineParser parser; const QCommandLineOption opt_help = parser.addHelpOption(); diff --git a/client/tp-player/mainwindow.cpp b/client/tp-player/mainwindow.cpp index 28d93d5..c9d9adf 100644 --- a/client/tp-player/mainwindow.cpp +++ b/client/tp-player/mainwindow.cpp @@ -75,8 +75,6 @@ MainWindow::~MainWindow() { if(m_thr_play) { m_thr_play->stop(); - //m_thr_play->wait(); - //qDebug() << "play thread stoped."; disconnect(m_thr_play, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); @@ -87,16 +85,10 @@ MainWindow::~MainWindow() if(m_thr_data) { m_thr_data->stop(); disconnect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); -// disconnect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*))); delete m_thr_data; m_thr_data = nullptr; } -// if(m_dl) { -// delete m_dl; -// m_dl = nullptr; -// } - delete ui; } @@ -107,10 +99,8 @@ void MainWindow::set_resource(const QString &res) { void MainWindow::_do_first_run() { m_thr_data = new ThrData(this, m_res); connect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); -// connect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*))); m_thr_data->start(); - //_start_play_thread(); m_thr_play = new ThrPlay(this); connect(m_thr_play, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); @@ -118,24 +108,6 @@ void MainWindow::_do_first_run() { m_thr_play->start(); } -//void MainWindow::_start_play_thread() { -// if(m_thr_play) { -// m_thr_play->stop(); -// //m_thr_play->wait(); - -// disconnect(m_thr_play, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); - -// delete m_thr_play; -// m_thr_play = nullptr; -// } - -// m_thr_play = new ThrPlay(this); -// connect(m_thr_play, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); - -// m_thr_play->speed(m_bar.get_speed()); -// m_thr_play->start(); -//} - void MainWindow::set_speed(int s) { if(m_thr_play) m_thr_play->speed(s); @@ -242,20 +214,27 @@ void MainWindow::_do_update_data(UpdateData* dat) { return; } else if(dat->data_type() == TYPE_IMAGE) { - QImage* img_update = nullptr; - int x, y, w, h; - if(!dat->get_image(&img_update, x, y, w, h)) + UpdateImages uimgs; + if(!dat->get_images(uimgs)) return; - static int img_idx = 0; - img_idx++; - qDebug("draw img: %d (%d,%d)-(%d,%d)", img_idx, x, y, w, h); + if(uimgs.size() > 1) { + // 禁止界面更新 + setUpdatesEnabled(false); + } QPainter pp(&m_canvas); - pp.drawImage(x, y, *img_update, 0, 0, w, h, Qt::AutoColor); + for(int i = 0; i < uimgs.size(); ++i) { + pp.drawImage(uimgs[i].x, uimgs[i].y, *(uimgs[i].img), 0, 0, uimgs[i].w, uimgs[i].h, Qt::AutoColor); + update(uimgs[i].x, uimgs[i].y, uimgs[i].w, uimgs[i].h); + } - update(x, y, w, h); + + if(uimgs.size() > 1) { + // 允许界面更新 + setUpdatesEnabled(true); + } return; } @@ -265,6 +244,18 @@ void MainWindow::_do_update_data(UpdateData* dat) { return; } + else if(dat->data_type() == TYPE_DISABLE_DRAW) { + // 禁止界面更新 + setUpdatesEnabled(false); + return; + } + + else if(dat->data_type() == TYPE_ENABLE_DRAW) { + // 允许界面更新 + setUpdatesEnabled(true); + return; + } + else if(dat->data_type() == TYPE_MESSAGE) { if(dat->message().isEmpty()) { m_show_message = false; @@ -361,12 +352,14 @@ void MainWindow::_do_update_data(UpdateData* dat) { QString title; if (m_rec_hdr.basic.conn_port == 3389) { - title = QString(LOCAL8BIT("[%1] %2@%3 [Teleport-RDP录像回放]").arg(m_rec_hdr.basic.acc_username, m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip)); +// title = QString(LOCAL8BIT("[%1] %2@%3 [Teleport-RDP录像回放]").arg(m_rec_hdr.basic.acc_username, m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip)); + title = QString(LOCAL8BIT("用户 %1 访问 %2 的 %3 账号").arg(m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip, m_rec_hdr.basic.acc_username)); } else { QString _port; _port.sprintf("%d", m_rec_hdr.basic.conn_port); - title = QString(LOCAL8BIT("[%1] %2@%3:%4 [Teleport-RDP录像回放]").arg(m_rec_hdr.basic.acc_username, m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip, _port)); + //title = QString(LOCAL8BIT("[%1] %2@%3:%4 [Teleport-RDP录像回放]").arg(m_rec_hdr.basic.acc_username, m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip, _port)); + title = QString(LOCAL8BIT("用户 %1 访问 %2:%3 的 %4 账号").arg(m_rec_hdr.basic.user_username, m_rec_hdr.basic.conn_ip, _port, m_rec_hdr.basic.acc_username)); } setWindowTitle(title); @@ -457,13 +450,6 @@ void MainWindow::mousePressEvent(QMouseEvent *e) { } void MainWindow::mouseReleaseEvent(QMouseEvent *e) { - qDebug("mouse release."); -// if(!m_show_default) { -// QRect rc = m_bar.rc(); -// if(rc.contains(e->pos())) { -// m_bar.onMouseRelease(e->x(), e->y(), e->button()); -// } -// } m_bar.onMouseRelease(e->x(), e->y(), e->button()); } diff --git a/client/tp-player/record_format.h b/client/tp-player/record_format.h index 3fe863c..ebc6041 100644 --- a/client/tp-player/record_format.h +++ b/client/tp-player/record_format.h @@ -24,10 +24,10 @@ typedef struct TS_RECORD_HEADER_INFO { uint32_t magic; // "TPPR" 标志 TelePort Protocol Record uint16_t ver; // 录像文件版本,从3.5.0开始,为4 uint16_t type; // - uint32_t packages; // 总包数 + // uint32_t packages; // 总包数 uint32_t time_ms; // 总耗时(毫秒) uint32_t dat_file_count; // 数据文件数量 - uint8_t _reserve[64-4-2-2-4-4-4]; + uint8_t _reserve[64-4-2-2-4-4]; }TS_RECORD_HEADER_INFO; #define ts_record_header_info_size sizeof(TS_RECORD_HEADER_INFO) @@ -69,7 +69,7 @@ typedef struct TS_RECORD_PKG { uint8_t _reserve[3]; // 保留 uint32_t size; // 这个包的总大小(不含包头) uint32_t time_ms; // 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天) - uint32_t index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) + // uint32_t index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) }TS_RECORD_PKG; @@ -91,6 +91,7 @@ typedef struct TS_RECORD_RDP_IMAGE_INFO { uint16_t bitsPerPixel; uint8_t format; uint8_t _reserved; + uint32_t dat_len; }TS_RECORD_RDP_IMAGE_INFO; // 关键帧索引 diff --git a/client/tp-player/thr_data.cpp b/client/tp-player/thr_data.cpp index 6c56156..60502a3 100644 --- a/client/tp-player/thr_data.cpp +++ b/client/tp-player/thr_data.cpp @@ -15,77 +15,6 @@ #include "rle.h" -// for test only -int g_kf_idx = 0; -QByteArray g_kfdata[10]; -QByteArray* g_kf = nullptr; - -int g_img_idx = 0; - -void _update_key_frame(QByteArray* kf, uint16_t screen_w, uint16_t screen_h, uint16_t destLeft, uint16_t destTop, uint16_t w, uint16_t h, uint16_t wr, uint16_t hr, uint16_t bitsPerPixel, bool isCompressed, const uint8_t* dat, size_t len) { - switch(bitsPerPixel) { -// case 15: -// if(isCompressed) { -// uint8_t* _dat = reinterpret_cast(calloc(1, w*h*2)); -// if(!bitmap_decompress1(_dat, w, h, dat, len)) { -// free(_dat); -// qDebug("bitmap_decompress1() failed."); -// return; -// } -// out = new QImage(_dat, w, h, QImage::Format_RGB555); -// free(_dat); -// } -// else { -// out = new QImage(QImage(dat, w, h, QImage::Format_RGB555).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))); -// } -// return out; - - case 16: - { - g_img_idx++; - uint8_t* kfd = reinterpret_cast(kf->data()); - if(isCompressed) { - uint8_t* _dat = reinterpret_cast(calloc(1, w*h*2)); - if(!bitmap_decompress2(_dat, w, h, dat, static_cast(len))) { - free(_dat); - qDebug() << "------------------DECOMPRESS2 failed."; - return; - } - -// out = new QImage(w, h, QImage::Format_RGB16); - - qDebug("c: %ld, img: %d (%d,%d)-(%d,%d) (%d,%d)", ((destTop+hr-1)*screen_w)+destLeft+wr-1, g_img_idx, destLeft, destTop, w, h, wr, hr); - for(int y = 0; y < hr; y++) { -// if((destTop+y)*screen_w+destLeft > 6) -// memcpy(kfd+((destTop+y)*screen_w+destLeft - 6)*2, _dat+((y*w)*2), wr*2); -// else - memcpy(kfd+((destTop+y)*screen_w+destLeft)*2, _dat+((y*w)*2), wr*2); - } - - free(_dat); - return; - } - else { -// out = new QImage(QImage(dat, w, h, QImage::Format_RGB16).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))); - - qDebug("nc: %ld, img: %d (%d,%d)-(%d,%d) (%d,%d)", ((destTop+hr-1)*screen_w)+destLeft+wr-1, g_img_idx, destLeft, destTop, w, h, wr, hr); - for(int y = 0; y < hr; y++) { - memcpy(kfd+((destTop+h-y)*screen_w+destLeft)*2, dat+(y*w*2), wr*2); - } - } - - return; - } - - case 24: - case 32: - default: - qDebug() << "------------------NOT support UNKNOWN bitsPerPix" << bitsPerPixel; - return; - } -} - - //================================================================= // ThrData //================================================================= @@ -102,8 +31,6 @@ ThrData::ThrData(MainWindow* mainwin, const QString& res) { m_file_idx = 0; m_offset = 0; - m_xxx = false; - #ifdef __APPLE__ m_data_path_base = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); m_data_path_base += "/tp-testdata/"; @@ -223,18 +150,11 @@ void ThrData::_run() { QFile* fdata = nullptr; - //uint32_t file_idx = 0; - //uint32_t start_offset = 0; qint64 file_size = 0; qint64 file_processed = 0; qint64 read_len = 0; QString str_fidx; - g_kf_idx = 0; - g_kf = &(g_kfdata[g_kf_idx]); - g_kf->resize(m_hdr.basic.width*m_hdr.basic.height*2); - memset(g_kf->data(), 0, m_hdr.basic.width*m_hdr.basic.height*2); - for(;;) { // 任何时候确保第一时间响应退出操作 if(m_need_stop) @@ -356,49 +276,13 @@ void ThrData::_run() { } QByteArray pkg_data = fdata->read(pkg.size); - if(pkg_data.size() != pkg.size) { + if(pkg_data.size() != static_cast(pkg.size)) { qDebug("invaid tp-rdp-%d.tpd file, read_len=%" PRId64 " (3).", m_file_idx+1, read_len); _notify_error(QString("%1\ntp-rdp-%2.tpd").arg(LOCAL8BIT("错误的录像数据文件!"), str_fidx)); return; } file_processed += pkg.size; - - - - - // for test only - if(!m_xxx && pkg.type == TS_RECORD_TYPE_RDP_IMAGE) { - const TS_RECORD_RDP_IMAGE_INFO* info = reinterpret_cast(pkg_data.data()); - uint8_t* img_dat = reinterpret_cast(pkg_data.data() + sizeof(TS_RECORD_RDP_IMAGE_INFO)); - size_t img_len = pkg_data.size() - sizeof(TS_RECORD_RDP_IMAGE_INFO); - - bool isCompress = (info->format == TS_RDP_IMG_BMP) ? true : false; -// _update_key_frame(&g_kf, m_hdr.basic.width, m_hdr.basic.height, info->destLeft, info->destTop, (info->destRight-info->destLeft+1), (info->destBottom-info->destTop+1), info->bitsPerPixel, isCompress, img_dat, img_len); - _update_key_frame(g_kf, m_hdr.basic.width, m_hdr.basic.height, - info->destLeft, info->destTop, - info->width, info->height, - info->destRight - info->destLeft + 1, info->destBottom - info->destTop + 1, - info->bitsPerPixel, isCompress, img_dat, img_len); - } - if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) { -// const TS_RECORD_RDP_KEYFRAME_INFO* info = reinterpret_cast(pkg_data.data()); - uint8_t* img_dat = reinterpret_cast(pkg_data.data() + sizeof(TS_RECORD_RDP_KEYFRAME_INFO)); - uint32_t img_len = pkg_data.size() - sizeof(TS_RECORD_RDP_KEYFRAME_INFO); - - if(m_xxx) { - qDebug("use kf: %d", m_restart_kf_idx); - memcpy(img_dat, g_kfdata[m_restart_kf_idx].data(), img_len); - } - else { - memcpy(img_dat, g_kf->data(), img_len); - } - } - - - - - UpdateData* dat = new UpdateData(m_hdr.basic.width, m_hdr.basic.height); if(!dat->parse(pkg, pkg_data)) { qDebug("invaid tp-rdp-%d.tpd file (4).", m_file_idx+1); @@ -406,47 +290,20 @@ void ThrData::_run() { return; } - - - - // 拖动滚动条后,需要显示一次关键帧数据,然后跳过后续关键帧。 if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) { - g_kf_idx++; - g_kf = &(g_kfdata[g_kf_idx]); - if(!m_xxx) { - g_kf->resize(m_hdr.basic.width*m_hdr.basic.height*2); - memcpy(g_kf->data(), g_kfdata[g_kf_idx-1].data(), m_hdr.basic.width*m_hdr.basic.height*2); - } - qDebug("----key frame: %ld, processed=%" PRId64 ", pkg.size=%d", pkg.time_ms, file_processed, pkg.size); if(m_need_show_kf) { m_need_show_kf = false; qDebug("++ show keyframe."); } else { - //m_restart_kf_idx - - - QString tmp; - tmp.sprintf("%d", g_kf_idx); - QString img_fname = QString("%1/img-%2.png").arg(m_data_path, tmp); - QImage* img = nullptr; - int x = 0, y = 0, w = 0, h = 0; - dat->get_image(&img, x, y, w, h); - if(img != nullptr) - img->save(img_fname, "png"); - qDebug("-- skip keyframe."); delete dat; dat = nullptr; } } - - - - // 数据放到待播放列表中 if(dat) { m_locker.lock(); @@ -497,10 +354,6 @@ void ThrData::restart(uint32_t start_ms) { m_offset = 0; m_file_idx = 0; m_need_show_kf = false; - - g_kf_idx = 0; - m_restart_kf_idx = 0; - m_xxx = true; } else { // 找到最接近 start_ms 但小于它的关键帧 @@ -512,15 +365,14 @@ void ThrData::restart(uint32_t start_ms) { } if(i > 0) i--; - g_kf_idx = i; - m_restart_kf_idx = i; - m_xxx = true; qDebug("restart acturelly at %ld ms, kf: %d", m_kf[i].time_ms, i); // 指定要播放的数据的开始位置 m_offset = m_kf[i].offset; m_file_idx = m_kf[i].file_index; + if(m_file_idx == (uint32_t)-1) + m_file_idx = 0; m_need_show_kf = true; } @@ -596,7 +448,7 @@ bool ThrData::_load_keyframe() { } qint64 read_len = 0; - int kf_count = fsize / sizeof(KEYFRAME_INFO); + int kf_count = static_cast(fsize / sizeof(KEYFRAME_INFO)); for(int i = 0; i < kf_count; ++i) { KEYFRAME_INFO kf; memset(&kf, 0, sizeof(KEYFRAME_INFO)); diff --git a/client/tp-player/thr_data.h b/client/tp-player/thr_data.h index 18c07c6..a00c5e0 100644 --- a/client/tp-player/thr_data.h +++ b/client/tp-player/thr_data.h @@ -102,8 +102,8 @@ private: uint32_t m_file_idx; uint32_t m_offset; - bool m_xxx; - int m_restart_kf_idx; +// bool m_xxx; +// int m_restart_kf_idx; }; #endif // THR_DATA_H diff --git a/client/tp-player/thr_play.cpp b/client/tp-player/thr_play.cpp index f1d4d22..b76d017 100644 --- a/client/tp-player/thr_play.cpp +++ b/client/tp-player/thr_play.cpp @@ -102,6 +102,8 @@ void ThrPlay::run() { } last_time_ms = m_start_ms; m_start_ms = 0; + UpdateData* _enable = new UpdateData(TYPE_ENABLE_DRAW); + emit signal_update_data(_enable); } // 2. 根据数据包的信息,等待到播放时间点 @@ -139,10 +141,10 @@ void ThrPlay::run() { break; if(m_start_ms > 0) { -// if(dat) { -// delete dat; -// dat = nullptr; -// } + delete dat; + dat = nullptr; + UpdateData* _disable = new UpdateData(TYPE_DISABLE_DRAW); + emit signal_update_data(_disable); break; } @@ -170,25 +172,18 @@ void ThrPlay::run() { if(m_need_stop) break; - -// if(m_start_ms > 0) { -// if(dat) { -// delete dat; -// dat = nullptr; -// } -// break; -// } } } last_time_ms = this_time_ms; // 3. 将数据包发送给主UI界面进行显示 - if(dat->data_type() == TYPE_END) { - _notify_message(LOCAL8BIT("播放结束")); + if(dat != nullptr) { + if(dat->data_type() == TYPE_END) { + _notify_message(LOCAL8BIT("播放结束")); + } + emit signal_update_data(dat); } - - emit signal_update_data(dat); } if(dat != nullptr) diff --git a/client/tp-player/update_data.cpp b/client/tp-player/update_data.cpp index ac25d01..15e8165 100644 --- a/client/tp-player/update_data.cpp +++ b/client/tp-player/update_data.cpp @@ -105,7 +105,7 @@ void UpdateData::_init() { m_data_type = TYPE_UNKNOWN; m_hdr = nullptr; m_pointer = nullptr; - m_img = nullptr; +// m_img = nullptr; // m_img_info = nullptr; m_data_buf = nullptr; @@ -121,10 +121,14 @@ UpdateData::~UpdateData() { delete m_hdr; if(m_pointer) delete m_pointer; - if(m_img) - delete m_img; +// if(m_img) +// delete m_img; // if(m_img_info) // delete m_img_info; + for(int i = 0; i < m_images.size(); ++i) { + delete m_images[i].img; + } + m_images.clear(); if(m_data_buf) delete m_data_buf; @@ -143,21 +147,41 @@ bool UpdateData::parse(const TS_RECORD_PKG& pkg, const QByteArray& data) { } else if(pkg.type == TS_RECORD_TYPE_RDP_IMAGE) { m_data_type = TYPE_IMAGE; - if(data.size() <= sizeof(TS_RECORD_RDP_IMAGE_INFO)) - return false; - const TS_RECORD_RDP_IMAGE_INFO* info = reinterpret_cast(data.data()); - const uint8_t* img_dat = reinterpret_cast(data.data() + sizeof(TS_RECORD_RDP_IMAGE_INFO)); - uint32_t img_len = data.size() - sizeof(TS_RECORD_RDP_IMAGE_INFO); - - QImage* img = _rdpimg2QImage(info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len); - if(img == nullptr) + if(data.size() <= static_cast(sizeof(uint16_t) + sizeof(TS_RECORD_RDP_IMAGE_INFO))) return false; - m_img = img; - m_img_x = info->destLeft; - m_img_y = info->destTop; - m_img_w = info->destRight - info->destLeft + 1; - m_img_h = info->destBottom - info->destTop + 1; + const uint8_t* dat_ptr = reinterpret_cast(data.data()); + + uint16_t count = (reinterpret_cast(dat_ptr))[0]; + uint32_t offset = sizeof(uint16_t); + + for(uint16_t i = 0; i < count; ++i) { + + const TS_RECORD_RDP_IMAGE_INFO* info = reinterpret_cast(dat_ptr+offset); + offset += sizeof(TS_RECORD_RDP_IMAGE_INFO); + //const uint8_t* img_dat = reinterpret_cast(data.data() + sizeof(TS_RECORD_RDP_IMAGE_INFO)); + //uint32_t img_len = data.size() - sizeof(TS_RECORD_RDP_IMAGE_INFO); + const uint8_t* img_dat = dat_ptr + offset; + offset += info->dat_len; + + + QImage* img = _rdpimg2QImage(info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, info->dat_len); + if(img == nullptr) + return false; + +// m_img = img; +// m_img_x = info->destLeft; +// m_img_y = info->destTop; +// m_img_w = info->destRight - info->destLeft + 1; +// m_img_h = info->destBottom - info->destTop + 1; + UPDATE_IMAGE uimg; + uimg.x = info->destLeft; + uimg.y = info->destTop; + uimg.w = info->destRight - info->destLeft + 1; + uimg.h = info->destBottom - info->destTop + 1; + uimg.img = img; + m_images.push_back(uimg); + } return true; } @@ -170,11 +194,20 @@ bool UpdateData::parse(const TS_RECORD_PKG& pkg, const QByteArray& data) { QImage* img = _raw2QImage((int)m_screen_w, (int)m_screen_h, img_dat, img_len); if(img == nullptr) return false; - m_img = img; - m_img_x = 0; - m_img_y = 0; - m_img_w = m_screen_w; - m_img_h = m_screen_h; + + UPDATE_IMAGE uimg; + uimg.x = 0; + uimg.y = 0; + uimg.w = m_screen_w; + uimg.h = m_screen_h; + uimg.img = img; + m_images.push_back(uimg); + +// m_img = img; +// m_img_x = 0; +// m_img_y = 0; +// m_img_w = m_screen_w; +// m_img_h = m_screen_h; return true; } diff --git a/client/tp-player/update_data.h b/client/tp-player/update_data.h index e037588..d6e1380 100644 --- a/client/tp-player/update_data.h +++ b/client/tp-player/update_data.h @@ -2,10 +2,15 @@ #define UPDATE_DATA_H #include +#include #include "record_format.h" #define TYPE_UNKNOWN 0 #define TYPE_HEADER_INFO 1 + +#define TYPE_DISABLE_DRAW 5 +#define TYPE_ENABLE_DRAW 6 + #define TYPE_POINTER 10 #define TYPE_IMAGE 11 #define TYPE_KEYFRAME 12 @@ -15,6 +20,17 @@ #define TYPE_MESSAGE 90 #define TYPE_ERROR 91 + +typedef struct UPDATE_IMAGE { + int x; + int y; + int w; + int h; + QImage* img; +}UPDATE_IMAGE; + +typedef QVector UpdateImages; + class UpdateData : public QObject { Q_OBJECT @@ -28,14 +44,20 @@ public: bool parse(const TS_RECORD_PKG& pkg, const QByteArray& data); TS_RECORD_HEADER* get_header() {return m_hdr;} TS_RECORD_RDP_POINTER* get_pointer() {return m_pointer;} - bool get_image(QImage** img, int& x, int& y, int& w, int& h) { - if(m_img == nullptr) +// bool get_image(QImage** img, int& x, int& y, int& w, int& h) { +// if(m_img == nullptr) +// return false; +// *img = m_img; +// x = m_img_x; +// y = m_img_y; +// w = m_img_w; +// h = m_img_h; +// return true; +// } + bool get_images(UpdateImages& uimgs) const { + if(m_images.size() == 0) return false; - *img = m_img; - x = m_img_x; - y = m_img_y; - w = m_img_w; - h = m_img_h; + uimgs = m_images; return true; } @@ -76,11 +98,12 @@ private: // for POINTER TS_RECORD_RDP_POINTER* m_pointer; // for IMAGE - QImage* m_img; - int m_img_x; - int m_img_y; - int m_img_w; - int m_img_h; +// QImage* m_img; +// int m_img_x; +// int m_img_y; +// int m_img_w; +// int m_img_h; + UpdateImages m_images; // TS_RECORD_RDP_IMAGE_INFO* m_img_info; diff --git a/server/tp_core/common/base_record.h b/server/tp_core/common/base_record.h index c3fb219..a7080f3 100644 --- a/server/tp_core/common/base_record.h +++ b/server/tp_core/common/base_record.h @@ -36,10 +36,10 @@ typedef struct TS_RECORD_HEADER_INFO { ex_u32 magic; // "TPPR" 标志 TelePort Protocol Record ex_u16 ver; // 录像文件版本,v3.5.0开始为4 ex_u16 type; // 录像内容,SSH or RDP - ex_u32 packages; // 总包数 + // ex_u32 packages; // 总包数 ex_u32 time_ms; // 总耗时(毫秒) ex_u32 dat_file_count; // 数据文件数量 - ex_u8 _reserve[64-4-2-2-4-4-4]; + ex_u8 _reserve[64-4-2-2-4-4]; }TS_RECORD_HEADER_INFO; #define ts_record_header_info_size sizeof(TS_RECORD_HEADER_INFO) @@ -80,7 +80,7 @@ typedef struct TS_RECORD_PKG { ex_u8 _reserve[3]; // 保留 ex_u32 size; // 这个包的总大小(不含包头) ex_u32 time_ms; // 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天) - ex_u32 index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) + //ex_u32 index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) }TS_RECORD_PKG; #pragma pack(pop)