新的RDP录像播放工具可以播放录像了,下一步继续完善,包括播放器的控制部分。
parent
cc9552c743
commit
51932cb092
|
@ -32,36 +32,24 @@ bool rdpimg2QImage(QImage& out, int w, int h, int bitsPerPixel, bool isCompresse
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static bool first = true;
|
// TODO: 这里需要进一步优化,直接操作QImage的buffer。
|
||||||
// if(first) {
|
|
||||||
// first = false;
|
|
||||||
// int total_bytes = w*h*2;
|
|
||||||
// for(int i = 0; i < total_bytes; i++) {
|
|
||||||
// printf("%02x ", _dat[i]);
|
|
||||||
// if(i != 0 && i % 16 == 0)
|
|
||||||
// printf("\n");
|
|
||||||
// }
|
|
||||||
// fflush(stdout);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//out = QImage(_dat, w, h, QImage::Format_RGB16);
|
out = QImage(w, h, QImage::Format_RGB16);
|
||||||
|
for(int y = 0; y < h; y++) {
|
||||||
|
for(int x = 0; x < w; x++) {
|
||||||
|
uint16 a = ((uint16*)_dat)[y * w + x];
|
||||||
|
uint8 r = ((a & 0xf800) >> 11) * 255 / 31;
|
||||||
|
uint8 g = ((a & 0x07e0) >> 5) * 255 / 63;
|
||||||
|
uint8 b = (a & 0x001f) * 255 / 31;
|
||||||
|
// r = r * 255 / 31;
|
||||||
|
// g = g * 255 / 63;
|
||||||
|
// b = b * 255 / 31;
|
||||||
|
|
||||||
static bool bf = true;
|
out.setPixelColor(x, y, QColor(r,g,b));
|
||||||
if(bf) {
|
|
||||||
bf = false;
|
|
||||||
int total_bytes = w*h*2;
|
|
||||||
if(total_bytes == 32) {
|
|
||||||
uchar aaa[32] = {0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff};
|
|
||||||
memcpy(_dat, aaa, 32);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out = QImage(_dat, w, h, QImage::Format_RGB16);
|
|
||||||
free(_dat);
|
free(_dat);
|
||||||
|
|
||||||
// QPixmap x(w, h);
|
|
||||||
// x.fill(QColor(0,0,0));
|
|
||||||
// out = x.toImage();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out = QImage(dat, w, h, QImage::Format_RGB16).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)) ;
|
out = QImage(dat, w, h, QImage::Format_RGB16).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)) ;
|
||||||
|
@ -87,7 +75,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
m_show_bg = true;
|
m_show_bg = true;
|
||||||
m_bg = QImage(":/tp-player/res/bg");
|
m_bg = QImage(":/tp-player/res/bg");
|
||||||
m_pt_normal = QImage(":/tp-player/res/cursor.png");
|
m_pt_normal = QImage(":/tp-player/res/cursor.png");
|
||||||
m_update_img = false;
|
|
||||||
memset(&m_pt, 0, sizeof(TS_RECORD_RDP_POINTER));
|
memset(&m_pt, 0, sizeof(TS_RECORD_RDP_POINTER));
|
||||||
|
|
||||||
qDebug() << m_pt_normal.width() << "x" << m_pt_normal.height();
|
qDebug() << m_pt_normal.width() << "x" << m_pt_normal.height();
|
||||||
|
@ -126,33 +113,23 @@ void MainWindow::paintEvent(QPaintEvent *pe)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
if(m_show_bg) {
|
painter.drawPixmap(pe->rect(), m_canvas, pe->rect());
|
||||||
//qDebug() << "draw bg.";
|
|
||||||
// painter.setBrush(Qt::black);
|
|
||||||
// painter.drawRect(this->rect());
|
|
||||||
|
|
||||||
// int x = (rect().width() - m_bg.width()) / 2;
|
if(!m_pt_history.empty()) {
|
||||||
// int y = (rect().height() - m_bg.height()) / 2;
|
for(int i = 0; i < m_pt_history.count(); i++) {
|
||||||
// painter.drawImage(x, y, m_bg);
|
qDebug("pt clean %d,%d", m_pt_history[i].x, m_pt_history[i].y);
|
||||||
|
QRect rcpt(m_pt_normal.rect());
|
||||||
painter.drawPixmap(rect(), m_canvas);
|
rcpt.moveTo(m_pt_history[i].x - m_pt_normal.width()/2, m_pt_history[i].y-m_pt_normal.height()/2);
|
||||||
|
painter.drawPixmap(rcpt, m_canvas, rcpt);
|
||||||
|
}
|
||||||
|
m_pt_history.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
painter.drawPixmap(rect(), m_canvas);
|
|
||||||
|
|
||||||
// if(m_update_img)
|
|
||||||
// painter.drawImage(m_img_update_x, m_img_update_y, m_img_update, 0, 0, m_img_update_w, m_img_update_h, Qt::AutoColor);
|
|
||||||
// else
|
|
||||||
//qDebug() << "draw pt (" << m_pt.x << "," << m_pt.y << ")";
|
|
||||||
// painter.drawImage(m_pt.x, m_pt.y, m_pt_normal);
|
|
||||||
|
|
||||||
QRect rcpt(m_pt_normal.rect());
|
QRect rcpt(m_pt_normal.rect());
|
||||||
rcpt.moveTo(m_pt.x - m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2);
|
rcpt.moveTo(m_pt.x - m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2);
|
||||||
QRect rcpe(pe->rect());
|
|
||||||
|
|
||||||
if(pe->rect().intersects(rcpt))
|
if(pe->rect().intersects(rcpt)) {
|
||||||
painter.drawImage(m_pt.x, m_pt.y, m_pt_normal);
|
painter.drawImage(m_pt.x-m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2, m_pt_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +142,6 @@ void MainWindow::paintEvent(QPaintEvent *pe)
|
||||||
void MainWindow::on_update_data(update_data* dat) {
|
void MainWindow::on_update_data(update_data* dat) {
|
||||||
if(!dat)
|
if(!dat)
|
||||||
return;
|
return;
|
||||||
// qDebug() << "slot-event: " << dat->data_type();
|
|
||||||
|
|
||||||
if(dat->data_type() == TYPE_DATA) {
|
if(dat->data_type() == TYPE_DATA) {
|
||||||
m_show_bg = false;
|
m_show_bg = false;
|
||||||
|
@ -185,10 +161,16 @@ void MainWindow::on_update_data(update_data* dat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将现有虚拟鼠标信息放入历史队列,这样下一次绘制界面时就会将其清除掉
|
||||||
|
m_pt_history.push_back(m_pt);
|
||||||
|
|
||||||
|
// 更新虚拟鼠标信息,这样下一次绘制界面时就会在新的位置绘制出虚拟鼠标
|
||||||
memcpy(&m_pt, dat->data_buf() + sizeof(TS_RECORD_PKG), sizeof(TS_RECORD_RDP_POINTER));
|
memcpy(&m_pt, dat->data_buf() + sizeof(TS_RECORD_PKG), sizeof(TS_RECORD_RDP_POINTER));
|
||||||
m_update_img = false;
|
qDebug("pt new position %d,%d", m_pt.x, m_pt.y);
|
||||||
update();
|
|
||||||
//update(m_pt.x - 8, m_pt.y - 8, 32, 32);
|
//setUpdatesEnabled(false);
|
||||||
|
update(m_pt.x - m_pt_normal.width()/2, m_pt.y - m_pt_normal.width()/2, m_pt_normal.width(), m_pt_normal.height());
|
||||||
|
//setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
else if(pkg->type == TS_RECORD_TYPE_RDP_IMAGE) {
|
else if(pkg->type == TS_RECORD_TYPE_RDP_IMAGE) {
|
||||||
if(dat->data_len() <= sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO)) {
|
if(dat->data_len() <= sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO)) {
|
||||||
|
@ -203,40 +185,17 @@ void MainWindow::on_update_data(update_data* dat) {
|
||||||
|
|
||||||
rdpimg2QImage(m_img_update, info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len);
|
rdpimg2QImage(m_img_update, info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len);
|
||||||
|
|
||||||
static bool need_save = true;
|
|
||||||
if(need_save) {
|
|
||||||
need_save = false;
|
|
||||||
m_img_update.save("E:\\work\\tp4a\\teleport\\server\\share\\replay\\rdp\\000000197\\test.bmp", "BMP");
|
|
||||||
|
|
||||||
uchar* xx = m_img_update.bits();
|
|
||||||
int total_bytes = m_img_update.width()*m_img_update.height()*2;
|
|
||||||
for(int i = 0; i < total_bytes; i++) {
|
|
||||||
printf("%02x ", xx[i]);
|
|
||||||
if(i != 0 && i % 16 == 0)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QPainter pp(&m_canvas);
|
|
||||||
pp.drawImage(m_img_update_x, m_img_update_y, m_img_update, 0, 0, m_img_update_w, m_img_update_h, Qt::AutoColor);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_img_update_x = info->destLeft;
|
m_img_update_x = info->destLeft;
|
||||||
m_img_update_y = info->destTop;
|
m_img_update_y = info->destTop;
|
||||||
m_img_update_w = info->destRight - info->destLeft + 1;
|
m_img_update_w = info->destRight - info->destLeft + 1;
|
||||||
m_img_update_h = info->destBottom - info->destTop + 1;
|
m_img_update_h = info->destBottom - info->destTop + 1;
|
||||||
|
|
||||||
static int count = 0;
|
setUpdatesEnabled(false);
|
||||||
qDebug() << count << "img " << ((info->format == TS_RDP_IMG_BMP) ? "+" : " ") << " (" << m_img_update_x << "," << m_img_update_y << "), [" << m_img_update.width() << "x" << m_img_update.height() << "]";
|
QPainter pp(&m_canvas);
|
||||||
count++;
|
pp.drawImage(m_img_update_x, m_img_update_y, m_img_update, 0, 0, m_img_update_w, m_img_update_h, Qt::AutoColor);
|
||||||
|
|
||||||
m_update_img = true;
|
|
||||||
update(m_img_update_x, m_img_update_y, m_img_update_w, m_img_update_h);
|
update(m_img_update_x, m_img_update_y, m_img_update_w, m_img_update_h);
|
||||||
|
setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete dat;
|
delete dat;
|
||||||
|
@ -262,8 +221,10 @@ void MainWindow::on_update_data(update_data* dat) {
|
||||||
m_win_board_w = frameGeometry().width() - geometry().width();
|
m_win_board_w = frameGeometry().width() - geometry().width();
|
||||||
m_win_board_h = frameGeometry().height() - geometry().height();
|
m_win_board_h = frameGeometry().height() - geometry().height();
|
||||||
|
|
||||||
setFixedSize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
|
//setFixedSize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
|
||||||
resize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
|
//resize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
|
||||||
|
setFixedSize(m_rec_hdr.basic.width, m_rec_hdr.basic.height);
|
||||||
|
resize(m_rec_hdr.basic.width, m_rec_hdr.basic.height);
|
||||||
|
|
||||||
// QDesktopWidget *desktop = QApplication::desktop(); // =qApp->desktop();也可以
|
// QDesktopWidget *desktop = QApplication::desktop(); // =qApp->desktop();也可以
|
||||||
// //move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
|
// //move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QVector>
|
||||||
#include "thr_play.h"
|
#include "thr_play.h"
|
||||||
#include "update_data.h"
|
#include "update_data.h"
|
||||||
#include "record_format.h"
|
#include "record_format.h"
|
||||||
|
@ -37,10 +38,10 @@ private:
|
||||||
bool m_show_bg;
|
bool m_show_bg;
|
||||||
TS_RECORD_HEADER m_rec_hdr;
|
TS_RECORD_HEADER m_rec_hdr;
|
||||||
|
|
||||||
bool m_update_img;
|
|
||||||
|
|
||||||
QImage m_pt_normal;
|
QImage m_pt_normal;
|
||||||
TS_RECORD_RDP_POINTER m_pt;
|
TS_RECORD_RDP_POINTER m_pt;
|
||||||
|
QVector<TS_RECORD_RDP_POINTER> m_pt_history;
|
||||||
|
|
||||||
|
|
||||||
QImage m_img_update;
|
QImage m_img_update;
|
||||||
int m_win_board_w;
|
int m_win_board_w;
|
||||||
|
|
|
@ -18,10 +18,10 @@ RD_BOOL bitmap_decompress2(uint8 * output, int width, int height, uint8 * input,
|
||||||
RD_BOOL bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size);
|
RD_BOOL bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size);
|
||||||
RD_BOOL bitmap_decompress4(uint8 * output, int width, int height, uint8 * input, int size);
|
RD_BOOL bitmap_decompress4(uint8 * output, int width, int height, uint8 * input, int size);
|
||||||
|
|
||||||
//int bitmap_decompress_15(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
int bitmap_decompress_15(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
||||||
//int bitmap_decompress_16(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
int bitmap_decompress_16(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
||||||
//int bitmap_decompress_24(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
int bitmap_decompress_24(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
||||||
//int bitmap_decompress_32(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
int bitmap_decompress_32(uint8 * output, int output_width, int output_height, int input_width, int input_height, uint8* input, int size);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <QDebug>
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include "thr_play.h"
|
#include "thr_play.h"
|
||||||
|
@ -57,6 +58,10 @@ void ThreadPlay::run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t time_pass = 0;
|
||||||
|
|
||||||
|
qint64 time_begin = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|
||||||
for(uint32_t i = 0; i < total_pkg; ++i) {
|
for(uint32_t i = 0; i < total_pkg; ++i) {
|
||||||
if(m_need_stop) {
|
if(m_need_stop) {
|
||||||
qDebug() << "stop, user cancel.";
|
qDebug() << "stop, user cancel.";
|
||||||
|
@ -66,7 +71,7 @@ void ThreadPlay::run() {
|
||||||
TS_RECORD_PKG pkg;
|
TS_RECORD_PKG pkg;
|
||||||
read_len = f_dat.read((char*)(&pkg), sizeof(pkg));
|
read_len = f_dat.read((char*)(&pkg), sizeof(pkg));
|
||||||
if(read_len != sizeof(TS_RECORD_PKG)) {
|
if(read_len != sizeof(TS_RECORD_PKG)) {
|
||||||
qDebug() << "invaid .dat file.";
|
qDebug() << "invaid .dat file (1).";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +86,40 @@ void ThreadPlay::run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_pass = (uint32_t)(QDateTime::currentMSecsSinceEpoch() - time_begin);
|
||||||
|
|
||||||
|
if(time_pass >= pkg.time_ms) {
|
||||||
|
//time_pass = pkg.time_ms;
|
||||||
emit signal_update_data(dat);
|
emit signal_update_data(dat);
|
||||||
msleep(10);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 需要等待
|
||||||
|
uint32_t time_wait = pkg.time_ms - time_pass;
|
||||||
|
uint32_t wait_this_time = 0;
|
||||||
|
for(;;) {
|
||||||
|
wait_this_time = time_wait;
|
||||||
|
if(wait_this_time > 5)
|
||||||
|
wait_this_time = 5;
|
||||||
|
|
||||||
|
if(m_need_stop) {
|
||||||
|
qDebug() << "stop, user cancel (2).";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
msleep(wait_this_time);
|
||||||
|
|
||||||
|
//time_pass += wait_this_time;
|
||||||
|
//time_pass = pkg.time_ms;
|
||||||
|
|
||||||
|
time_wait -= wait_this_time;
|
||||||
|
if(time_wait == 0) {
|
||||||
|
emit signal_update_data(dat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit signal_update_data(dat);
|
||||||
|
// msleep(15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue