播放器流畅工作,还缺重播和进度条拖动功能。
parent
3aa4755876
commit
1bbc109ae9
|
@ -423,7 +423,7 @@ void Bar::onMousePress(int x, int y) {
|
||||||
if(m_speed_selected != speed_sel && speed_sel != speed_count) {
|
if(m_speed_selected != speed_sel && speed_sel != speed_count) {
|
||||||
int old_sel = m_speed_selected;
|
int old_sel = m_speed_selected;
|
||||||
m_speed_selected = speed_sel;
|
m_speed_selected = speed_sel;
|
||||||
m_owner->speed(get_speed());
|
m_owner->set_speed(get_speed());
|
||||||
m_owner->update(m_rc.left()+m_rc_btn_speed[old_sel].left(), m_rc.top()+m_rc_btn_speed[old_sel].top(), m_rc_btn_speed[old_sel].width(), m_rc_btn_speed[old_sel].height());
|
m_owner->update(m_rc.left()+m_rc_btn_speed[old_sel].left(), m_rc.top()+m_rc_btn_speed[old_sel].top(), m_rc_btn_speed[old_sel].width(), m_rc_btn_speed[old_sel].height());
|
||||||
m_owner->update(m_rc.left()+m_rc_btn_speed[m_speed_hover].left(), m_rc.top()+m_rc_btn_speed[m_speed_hover].top(), m_rc_btn_speed[m_speed_hover].width(), m_rc_btn_speed[m_speed_hover].height());
|
m_owner->update(m_rc.left()+m_rc_btn_speed[m_speed_hover].left(), m_rc.top()+m_rc_btn_speed[m_speed_hover].top(), m_rc_btn_speed[m_speed_hover].width(), m_rc_btn_speed[m_speed_hover].height());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "rle.h"
|
|
||||||
|
|
||||||
#include <QMatrix>
|
#include <QMatrix>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -10,64 +9,6 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
|
||||||
bool rdpimg2QImage(QImage& out, int w, int h, int bitsPerPixel, bool isCompressed, uint8_t* dat, uint32_t len) {
|
|
||||||
switch(bitsPerPixel) {
|
|
||||||
case 15:
|
|
||||||
if(isCompressed) {
|
|
||||||
uint8_t* _dat = (uint8_t*)calloc(1, w*h*2);
|
|
||||||
if(!bitmap_decompress1(_dat, w, h, dat, len)) {
|
|
||||||
free(_dat);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out = QImage(_dat, w, h, QImage::Format_RGB555);
|
|
||||||
free(_dat);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out = QImage(dat, w, h, QImage::Format_RGB555).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)) ;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
if(isCompressed) {
|
|
||||||
|
|
||||||
uint8_t* _dat = (uint8_t*)calloc(1, w*h*2);
|
|
||||||
if(!bitmap_decompress2(_dat, w, h, dat, len)) {
|
|
||||||
free(_dat);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: 这里需要进一步优化,直接操作QImage的buffer。
|
|
||||||
// QTime t1;
|
|
||||||
// t1.start();
|
|
||||||
|
|
||||||
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;
|
|
||||||
out.setPixelColor(x, y, QColor(r,g,b));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// qDebug("parse: %dB, %dms", len, t1.elapsed());
|
|
||||||
|
|
||||||
free(_dat);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out = QImage(dat, w, h, QImage::Format_RGB16).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)) ;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
qDebug() << "--------NOT support 24";
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
qDebug() << "--------NOT support 32";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int min(int a, int b){
|
static inline int min(int a, int b){
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +21,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
//m_shown = false;
|
|
||||||
m_show_default = true;
|
m_show_default = true;
|
||||||
m_bar_shown = false;
|
m_bar_shown = false;
|
||||||
m_bar_fade_in = false;
|
m_bar_fade_in = false;
|
||||||
|
@ -93,8 +33,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
m_play_state = PLAY_STATE_UNKNOWN;
|
m_play_state = PLAY_STATE_UNKNOWN;
|
||||||
m_thr_data = nullptr;
|
m_thr_data = nullptr;
|
||||||
|
|
||||||
// m_dl = nullptr;
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->centralWidget->setMouseTracking(true);
|
ui->centralWidget->setMouseTracking(true);
|
||||||
|
@ -125,7 +63,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// connect(&m_thr_play, SIGNAL(signal_update_data(update_data*)), this, SLOT(_do_update_data(update_data*)));
|
|
||||||
connect(&m_timer_first_run, SIGNAL(timeout()), this, SLOT(_do_first_run()));
|
connect(&m_timer_first_run, SIGNAL(timeout()), this, SLOT(_do_first_run()));
|
||||||
connect(&m_timer_bar_fade, SIGNAL(timeout()), this, SLOT(_do_bar_fade()));
|
connect(&m_timer_bar_fade, SIGNAL(timeout()), this, SLOT(_do_bar_fade()));
|
||||||
connect(&m_timer_bar_delay_hide, SIGNAL(timeout()), this, SLOT(_do_bar_delay_hide()));
|
connect(&m_timer_bar_delay_hide, SIGNAL(timeout()), this, SLOT(_do_bar_delay_hide()));
|
||||||
|
@ -194,11 +131,16 @@ void MainWindow::_start_play_thread() {
|
||||||
m_thr_play->start();
|
m_thr_play->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::speed(int s) {
|
void MainWindow::set_speed(int s) {
|
||||||
if(m_thr_play)
|
if(m_thr_play)
|
||||||
m_thr_play->speed(s);
|
m_thr_play->speed(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::set_skip(bool s) {
|
||||||
|
if(m_thr_play)
|
||||||
|
m_thr_play->skip(s);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::paintEvent(QPaintEvent *e)
|
void MainWindow::paintEvent(QPaintEvent *e)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
@ -252,12 +194,6 @@ void MainWindow::paintEvent(QPaintEvent *e)
|
||||||
int to_y = rc.top() + from_y;
|
int to_y = rc.top() + from_y;
|
||||||
painter.drawPixmap(to_x, to_y, m_img_message, from_x, from_y, w, h);
|
painter.drawPixmap(to_x, to_y, m_img_message, from_x, from_y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(!m_shown) {
|
|
||||||
// m_shown = true;
|
|
||||||
// //m_thr_play.start();
|
|
||||||
// _start_play_thread();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::pause() {
|
void MainWindow::pause() {
|
||||||
|
@ -271,7 +207,6 @@ void MainWindow::resume() {
|
||||||
if(m_play_state == PLAY_STATE_PAUSE)
|
if(m_play_state == PLAY_STATE_PAUSE)
|
||||||
m_thr_play->resume();
|
m_thr_play->resume();
|
||||||
else if(m_play_state == PLAY_STATE_STOP)
|
else if(m_play_state == PLAY_STATE_STOP)
|
||||||
//m_thr_play->start();
|
|
||||||
_start_play_thread();
|
_start_play_thread();
|
||||||
|
|
||||||
m_play_state = PLAY_STATE_RUNNING;
|
m_play_state = PLAY_STATE_RUNNING;
|
||||||
|
@ -283,53 +218,28 @@ void MainWindow::_do_update_data(UpdateData* dat) {
|
||||||
|
|
||||||
UpdateDataHelper data_helper(dat);
|
UpdateDataHelper data_helper(dat);
|
||||||
|
|
||||||
if(dat->data_type() == TYPE_DATA) {
|
if(dat->data_type() == TYPE_POINTER) {
|
||||||
|
|
||||||
if(dat->data_len() <= sizeof(TS_RECORD_PKG)) {
|
|
||||||
qDebug() << "invalid record package(1).";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TS_RECORD_PKG* pkg = (TS_RECORD_PKG*)dat->data_buf();
|
|
||||||
|
|
||||||
if(pkg->type == TS_RECORD_TYPE_RDP_POINTER) {
|
|
||||||
if(dat->data_len() != sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_POINTER)) {
|
|
||||||
qDebug() << "invalid record package(2).";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TS_RECORD_RDP_POINTER pt;
|
TS_RECORD_RDP_POINTER pt;
|
||||||
memcpy(&pt, &m_pt, sizeof(TS_RECORD_RDP_POINTER));
|
memcpy(&pt, &m_pt, sizeof(TS_RECORD_RDP_POINTER));
|
||||||
|
|
||||||
// 更新虚拟鼠标信息,这样下一次绘制界面时就会在新的位置绘制出虚拟鼠标
|
// 更新虚拟鼠标信息,这样下一次绘制界面时就会在新的位置绘制出虚拟鼠标
|
||||||
memcpy(&m_pt, dat->data_buf() + sizeof(TS_RECORD_PKG), sizeof(TS_RECORD_RDP_POINTER));
|
memcpy(&m_pt, dat->get_pointer(), sizeof(TS_RECORD_RDP_POINTER));
|
||||||
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());
|
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());
|
||||||
|
|
||||||
update(pt.x - m_pt_normal.width()/2, pt.y - m_pt_normal.width()/2, m_pt_normal.width(), m_pt_normal.height());
|
update(pt.x - m_pt_normal.width()/2, pt.y - m_pt_normal.width()/2, m_pt_normal.width(), m_pt_normal.height());
|
||||||
}
|
|
||||||
else if(pkg->type == TS_RECORD_TYPE_RDP_IMAGE) {
|
|
||||||
if(dat->data_len() <= sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO)) {
|
|
||||||
qDebug() << "invalid record package(3).";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(dat->data_type() == TYPE_IMAGE) {
|
||||||
TS_RECORD_RDP_IMAGE_INFO* info = (TS_RECORD_RDP_IMAGE_INFO*)(dat->data_buf() + sizeof(TS_RECORD_PKG));
|
QImage* img_update = nullptr;
|
||||||
uint8_t* img_dat = dat->data_buf() + sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO);
|
int x, y, w, h;
|
||||||
uint32_t img_len = dat->data_len() - sizeof(TS_RECORD_PKG) - sizeof(TS_RECORD_RDP_IMAGE_INFO);
|
if(!dat->get_image(&img_update, x, y, w, h))
|
||||||
|
return;
|
||||||
QImage img_update;
|
|
||||||
rdpimg2QImage(img_update, info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len);
|
|
||||||
|
|
||||||
int x = info->destLeft;
|
|
||||||
int y = info->destTop;
|
|
||||||
int w = info->destRight - info->destLeft + 1;
|
|
||||||
int h = info->destBottom - info->destTop + 1;
|
|
||||||
|
|
||||||
QPainter pp(&m_canvas);
|
QPainter pp(&m_canvas);
|
||||||
pp.drawImage(x, y, img_update, 0, 0, w, h, Qt::AutoColor);
|
pp.drawImage(x, y, *img_update, 0, 0, w, h, Qt::AutoColor);
|
||||||
|
|
||||||
update(x, y, w, h);
|
update(x, y, w, h);
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -394,11 +304,10 @@ void MainWindow::_do_update_data(UpdateData* dat) {
|
||||||
|
|
||||||
// 这是播放开始时收到的第一个数据包
|
// 这是播放开始时收到的第一个数据包
|
||||||
else if(dat->data_type() == TYPE_HEADER_INFO) {
|
else if(dat->data_type() == TYPE_HEADER_INFO) {
|
||||||
if(dat->data_len() != sizeof(TS_RECORD_HEADER)) {
|
TS_RECORD_HEADER* hdr = dat->get_header();
|
||||||
qDebug() << "invalid record header.";
|
if(hdr == nullptr)
|
||||||
return;
|
return;
|
||||||
}
|
memcpy(&m_rec_hdr, hdr, sizeof(TS_RECORD_HEADER));
|
||||||
memcpy(&m_rec_hdr, dat->data_buf(), sizeof(TS_RECORD_HEADER));
|
|
||||||
|
|
||||||
qDebug() << "resize (" << m_rec_hdr.basic.width << "," << m_rec_hdr.basic.height << ")";
|
qDebug() << "resize (" << m_rec_hdr.basic.width << "," << m_rec_hdr.basic.height << ")";
|
||||||
|
|
||||||
|
@ -490,18 +399,6 @@ void MainWindow::_do_bar_fade() {
|
||||||
update(m_bar.rc());
|
update(m_bar.rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
//void MainWindow::_do_download(DownloadParam* param) {
|
|
||||||
// qDebug("MainWindow::_do_download(). %s %s %s", param->url.toStdString().c_str(), param->sid.toStdString().c_str(), param->fname.toStdString().c_str());
|
|
||||||
|
|
||||||
// if(m_dl) {
|
|
||||||
// delete m_dl;
|
|
||||||
// m_dl = nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// m_dl = new Downloader();
|
|
||||||
// m_dl->run(&m_nam, param->url, param->sid, param->fname);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void MainWindow::mouseMoveEvent(QMouseEvent *e) {
|
void MainWindow::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if(!m_show_default) {
|
if(!m_show_default) {
|
||||||
QRect rc = m_bar.rc();
|
QRect rc = m_bar.rc();
|
||||||
|
|
|
@ -34,10 +34,8 @@ public:
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
void restart();
|
void restart();
|
||||||
void speed(int s);
|
void set_speed(int s);
|
||||||
|
void set_skip(bool s);
|
||||||
// Downloader* downloader() {return m_dl;}
|
|
||||||
// void reset_downloader() {if(m_dl){delete m_dl;m_dl= nullptr;}}
|
|
||||||
|
|
||||||
// TODO: 将thr_data移动到thr_play线程,由play线程进行管理
|
// TODO: 将thr_data移动到thr_play线程,由play线程进行管理
|
||||||
ThrData* get_thr_data() {return m_thr_data;}
|
ThrData* get_thr_data() {return m_thr_data;}
|
||||||
|
@ -55,13 +53,9 @@ private slots:
|
||||||
void _do_bar_fade();
|
void _do_bar_fade();
|
||||||
void _do_bar_delay_hide();
|
void _do_bar_delay_hide();
|
||||||
|
|
||||||
// void _do_download(Downloader*);
|
|
||||||
// void _do_download(DownloadParam*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
//bool m_shown;
|
|
||||||
bool m_show_default;
|
bool m_show_default;
|
||||||
bool m_bar_shown;
|
bool m_bar_shown;
|
||||||
QPixmap m_default_bg;
|
QPixmap m_default_bg;
|
||||||
|
@ -91,14 +85,6 @@ private:
|
||||||
bool m_show_message;
|
bool m_show_message;
|
||||||
QPixmap m_img_message;
|
QPixmap m_img_message;
|
||||||
QRect m_rc_message;
|
QRect m_rc_message;
|
||||||
|
|
||||||
|
|
||||||
// QNetworkAccessManager m_nam;
|
|
||||||
// Downloader* m_dl;
|
|
||||||
|
|
||||||
// for test
|
|
||||||
TimeUseTest m_time_imgconvert_normal;
|
|
||||||
TimeUseTest m_time_imgconvert_compressed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
|
|
||||||
/* 1 byte bitmap decompress */
|
/* 1 byte bitmap decompress */
|
||||||
RD_BOOL
|
RD_BOOL
|
||||||
bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size)
|
bitmap_decompress1(uint8 * output, int width, int height, const uint8 * input, int size)
|
||||||
{
|
{
|
||||||
uint8 *end = input + size;
|
uint8 *end = input + size;
|
||||||
uint8 *prevline = NULL, *line = NULL;
|
uint8 *prevline = NULL, *line = NULL;
|
||||||
|
@ -272,7 +272,7 @@ bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int siz
|
||||||
|
|
||||||
/* 2 byte bitmap decompress */
|
/* 2 byte bitmap decompress */
|
||||||
RD_BOOL
|
RD_BOOL
|
||||||
bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size)
|
bitmap_decompress2(uint8 * output, int width, int height, const uint8 * input, int size)
|
||||||
{
|
{
|
||||||
uint8 *end = input + size;
|
uint8 *end = input + size;
|
||||||
uint16 *prevline = NULL, *line = NULL;
|
uint16 *prevline = NULL, *line = NULL;
|
||||||
|
@ -471,7 +471,7 @@ bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int siz
|
||||||
|
|
||||||
/* 3 byte bitmap decompress */
|
/* 3 byte bitmap decompress */
|
||||||
RD_BOOL
|
RD_BOOL
|
||||||
bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
|
bitmap_decompress3(uint8 * output, int width, int height, const uint8 * input, int size)
|
||||||
{
|
{
|
||||||
uint8 *end = input + size;
|
uint8 *end = input + size;
|
||||||
uint8 *prevline = NULL, *line = NULL;
|
uint8 *prevline = NULL, *line = NULL;
|
||||||
|
@ -863,7 +863,7 @@ process_plane(uint8 * in, int width, int height, uint8 * out, int size)
|
||||||
|
|
||||||
/* 4 byte bitmap decompress */
|
/* 4 byte bitmap decompress */
|
||||||
RD_BOOL
|
RD_BOOL
|
||||||
bitmap_decompress4(uint8 * output, int width, int height, uint8 * input, int size)
|
bitmap_decompress4(uint8 * output, int width, int height, const uint8 * input, int size)
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
int bytes_pro;
|
int bytes_pro;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef RLE_H
|
#ifndef RLE_H
|
||||||
#define RLE_H
|
#define RLE_H
|
||||||
|
|
||||||
#define RD_BOOL int
|
#define RD_BOOL int
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RD_BOOL bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size);
|
RD_BOOL bitmap_decompress1(uint8 * output, int width, int height, const uint8 * input, int size);
|
||||||
RD_BOOL bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size);
|
RD_BOOL bitmap_decompress2(uint8 * output, int width, int height, const uint8 * input, int size);
|
||||||
RD_BOOL bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size);
|
RD_BOOL bitmap_decompress3(uint8 * output, int width, int height, const 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, const 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);
|
||||||
|
|
|
@ -137,9 +137,9 @@ void ThrData::_run() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
UpdateData* dat = new UpdateData(TYPE_HEADER_INFO);
|
UpdateData* dat = new UpdateData(m_hdr);
|
||||||
dat->alloc_data(sizeof(TS_RECORD_HEADER));
|
// dat->alloc_data(sizeof(TS_RECORD_HEADER));
|
||||||
memcpy(dat->data_buf(), &m_hdr, sizeof(TS_RECORD_HEADER));
|
// memcpy(dat->data_buf(), &m_hdr, sizeof(TS_RECORD_HEADER));
|
||||||
emit signal_update_data(dat);
|
emit signal_update_data(dat);
|
||||||
|
|
||||||
|
|
||||||
|
@ -290,18 +290,34 @@ void ThrData::_run() {
|
||||||
qDebug("################## too bad.");
|
qDebug("################## too bad.");
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateData* dat = new UpdateData(TYPE_DATA);
|
QByteArray pkg_data = fdata->read(pkg.size);
|
||||||
dat->alloc_data(sizeof(TS_RECORD_PKG) + pkg.size);
|
if(pkg_data.size() != pkg.size) {
|
||||||
memcpy(dat->data_buf(), &pkg, sizeof(TS_RECORD_PKG));
|
|
||||||
read_len = fdata->read(reinterpret_cast<char*>(dat->data_buf()+sizeof(TS_RECORD_PKG)), pkg.size);
|
|
||||||
if(read_len != pkg.size) {
|
|
||||||
delete dat;
|
|
||||||
qDebug("invaid tp-rdp-%d.tpd file, read_len=%" PRId64 " (3).", file_idx+1, read_len);
|
qDebug("invaid tp-rdp-%d.tpd file, read_len=%" PRId64 " (3).", file_idx+1, read_len);
|
||||||
_notify_error(QString("%1\ntp-rdp-%2.tpd").arg(LOCAL8BIT("错误的录像数据文件!"), str_fidx));
|
_notify_error(QString("%1\ntp-rdp-%2.tpd").arg(LOCAL8BIT("错误的录像数据文件!"), str_fidx));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file_processed += pkg.size;
|
file_processed += pkg.size;
|
||||||
|
|
||||||
|
UpdateData* dat = new UpdateData();
|
||||||
|
if(!dat->parse(pkg, pkg_data)) {
|
||||||
|
qDebug("invaid tp-rdp-%d.tpd file (4).", file_idx+1);
|
||||||
|
_notify_error(QString("%1\ntp-rdp-%2.tpd").arg(LOCAL8BIT("错误的录像数据文件!"), str_fidx));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// UpdateData* dat = new UpdateData(TYPE_DATA);
|
||||||
|
// dat->alloc_data(sizeof(TS_RECORD_PKG) + pkg.size);
|
||||||
|
// memcpy(dat->data_buf(), &pkg, sizeof(TS_RECORD_PKG));
|
||||||
|
// read_len = fdata->read(reinterpret_cast<char*>(dat->data_buf()+sizeof(TS_RECORD_PKG)), pkg.size);
|
||||||
|
// if(read_len != pkg.size) {
|
||||||
|
// delete dat;
|
||||||
|
// qDebug("invaid tp-rdp-%d.tpd file, read_len=%" PRId64 " (3).", file_idx+1, read_len);
|
||||||
|
// _notify_error(QString("%1\ntp-rdp-%2.tpd").arg(LOCAL8BIT("错误的录像数据文件!"), str_fidx));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// file_processed += pkg.size;
|
||||||
|
|
||||||
// 跳过关键帧
|
// 跳过关键帧
|
||||||
// TODO: 拖动滚动条后,需要显示一次关键帧数据,然后跳过后续关键帧。
|
// TODO: 拖动滚动条后,需要显示一次关键帧数据,然后跳过后续关键帧。
|
||||||
if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
|
if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
|
||||||
|
@ -315,10 +331,12 @@ void ThrData::_run() {
|
||||||
if(dat) {
|
if(dat) {
|
||||||
m_locker.lock();
|
m_locker.lock();
|
||||||
m_data.enqueue(dat);
|
m_data.enqueue(dat);
|
||||||
qDebug("queue data count: %d", m_data.size());
|
// qDebug("queue data count: %d", m_data.size());
|
||||||
m_locker.unlock();
|
m_locker.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
// 如果此文件已经处理完毕,则关闭文件,这样下次处理一个新的文件
|
// 如果此文件已经处理完毕,则关闭文件,这样下次处理一个新的文件
|
||||||
// qDebug("C processed: %" PRId64 ", size: %" PRId64, file_processed, file_size);
|
// qDebug("C processed: %" PRId64 ", size: %" PRId64, file_processed, file_size);
|
||||||
if(file_processed >= file_size) {
|
if(file_processed >= file_size) {
|
||||||
|
@ -332,7 +350,7 @@ void ThrData::_run() {
|
||||||
UpdateData* dat = new UpdateData(TYPE_END);
|
UpdateData* dat = new UpdateData(TYPE_END);
|
||||||
m_locker.lock();
|
m_locker.lock();
|
||||||
m_data.enqueue(dat);
|
m_data.enqueue(dat);
|
||||||
qDebug("queue data count: %d", m_data.size());
|
// qDebug("queue data count: %d", m_data.size());
|
||||||
m_locker.unlock();
|
m_locker.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,8 +451,10 @@ UpdateData* ThrData::get_data() {
|
||||||
UpdateData* d = nullptr;
|
UpdateData* d = nullptr;
|
||||||
|
|
||||||
m_locker.lock();
|
m_locker.lock();
|
||||||
if(m_data.size() > 0)
|
if(m_data.size() > 0) {
|
||||||
|
// qDebug("get_data(), left: %d", m_data.size());
|
||||||
d = m_data.dequeue();
|
d = m_data.dequeue();
|
||||||
|
}
|
||||||
m_locker.unlock();
|
m_locker.unlock();
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
|
|
|
@ -23,7 +23,8 @@ ThrPlay::ThrPlay(MainWindow* mainwnd) {
|
||||||
m_mainwnd = mainwnd;
|
m_mainwnd = mainwnd;
|
||||||
m_need_stop = false;
|
m_need_stop = false;
|
||||||
m_need_pause = false;
|
m_need_pause = false;
|
||||||
m_speed = 2;
|
m_speed = 1;
|
||||||
|
m_skip = false;
|
||||||
// m_res = res;
|
// m_res = res;
|
||||||
// m_thr_data = nullptr;
|
// m_thr_data = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -67,13 +68,16 @@ void ThrPlay::run() {
|
||||||
|
|
||||||
ThrData* thr_data = m_mainwnd->get_thr_data();
|
ThrData* thr_data = m_mainwnd->get_thr_data();
|
||||||
bool first_run = true;
|
bool first_run = true;
|
||||||
|
uint32_t last_time_ms = 0;
|
||||||
|
uint32_t last_pass_ms = 0;
|
||||||
|
|
||||||
|
UpdateData* dat = nullptr;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(m_need_stop)
|
if(m_need_stop)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 1. 从ThrData的待播放队列中取出一个数据
|
// 1. 从ThrData的待播放队列中取出一个数据
|
||||||
UpdateData* dat = thr_data->get_data();
|
dat = thr_data->get_data();
|
||||||
if(dat == nullptr) {
|
if(dat == nullptr) {
|
||||||
msleep(20);
|
msleep(20);
|
||||||
continue;
|
continue;
|
||||||
|
@ -85,161 +89,73 @@ void ThrPlay::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 根据数据包的信息,等待到播放时间点
|
// 2. 根据数据包的信息,等待到播放时间点
|
||||||
|
uint32_t need_wait_ms = 0;
|
||||||
|
uint32_t this_time_ms = dat->get_time();
|
||||||
|
uint32_t this_pass_ms = last_time_ms;
|
||||||
|
if(this_time_ms > 0) {
|
||||||
|
need_wait_ms = this_time_ms - last_time_ms;
|
||||||
|
|
||||||
|
if(need_wait_ms > 0) {
|
||||||
|
uint32_t time_wait = 0;
|
||||||
|
|
||||||
|
// 如果设置了跳过无操作区间,将超过1秒的等待时间压缩至1秒。
|
||||||
|
if(m_skip) {
|
||||||
|
if(need_wait_ms > 1000)
|
||||||
|
need_wait_ms = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
time_wait = need_wait_ms > 10 ? 10 : need_wait_ms;
|
||||||
|
msleep(time_wait);
|
||||||
|
|
||||||
|
if(m_need_pause) {
|
||||||
|
while(m_need_pause) {
|
||||||
|
msleep(50);
|
||||||
|
if(m_need_stop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_need_stop)
|
||||||
|
break;
|
||||||
|
|
||||||
|
time_wait *= m_speed;
|
||||||
|
|
||||||
|
// 如果已经在等待长时间无操作区间内,用户设置了跳过无操作区间,则将超过0.5秒的等待时间压缩至0.5秒。
|
||||||
|
if(m_skip) {
|
||||||
|
if(need_wait_ms > 500)
|
||||||
|
need_wait_ms = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_pass_ms += time_wait;
|
||||||
|
if(this_pass_ms - last_pass_ms > 100) {
|
||||||
|
UpdateData* _passed_ms = new UpdateData(TYPE_PLAYED_MS);
|
||||||
|
_passed_ms->played_ms(this_pass_ms);
|
||||||
|
emit signal_update_data(_passed_ms);
|
||||||
|
last_pass_ms = this_pass_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(need_wait_ms <= time_wait)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
need_wait_ms -= time_wait;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_need_stop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_time_ms = this_time_ms;
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 将数据包发送给主UI界面进行显示
|
// 3. 将数据包发送给主UI界面进行显示
|
||||||
// qDebug("emit one package.");
|
|
||||||
if(dat->data_type() == TYPE_END) {
|
if(dat->data_type() == TYPE_END) {
|
||||||
_notify_message(LOCAL8BIT("播放结束"));
|
_notify_message(LOCAL8BIT("播放结束"));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit signal_update_data(dat);
|
emit signal_update_data(dat);
|
||||||
msleep(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//======================================
|
|
||||||
// 加载录像文件数据并播放
|
|
||||||
//======================================
|
|
||||||
|
|
||||||
uint32_t pkg_count = 0;
|
|
||||||
uint32_t time_pass = 0;
|
|
||||||
uint32_t time_last_pass = 0;
|
|
||||||
qint64 time_begin = QDateTime::currentMSecsSinceEpoch();
|
|
||||||
QString msg;
|
|
||||||
|
|
||||||
for(uint32_t fidx = 0; fidx < file_count; ++fidx) {
|
|
||||||
if(m_need_stop) {
|
|
||||||
qDebug() << "stop, user cancel 1.";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString tpd_filename;
|
if(dat != nullptr)
|
||||||
tpd_filename.sprintf("%stp-rdp-%d.tpd", path_base.toStdString().c_str(), fidx+1);
|
|
||||||
|
|
||||||
// // for test.
|
|
||||||
// msg = QString::fromLocal8Bit("无法打开录像数据文件!\n\n");
|
|
||||||
// //msg.sprintf("无法打开录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
|
|
||||||
// msg += tpd_filename.toStdString().c_str();
|
|
||||||
// _notify_message(msg);
|
|
||||||
|
|
||||||
QFile f_dat(tpd_filename);
|
|
||||||
if(!f_dat.open(QFile::ReadOnly)) {
|
|
||||||
qDebug() << "Can not open " << tpd_filename << " for read.";
|
|
||||||
// msg.sprintf("无法打开录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
|
|
||||||
msg = QString::fromLocal8Bit("无法打开录像数据文件!\n\n");
|
|
||||||
msg += tpd_filename.toStdString().c_str();
|
|
||||||
_notify_error(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
if(m_need_stop) {
|
|
||||||
qDebug() << "stop, user cancel 2.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_need_pause) {
|
|
||||||
msleep(50);
|
|
||||||
time_begin += 50;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TS_RECORD_PKG pkg;
|
|
||||||
read_len = f_dat.read((char*)(&pkg), sizeof(pkg));
|
|
||||||
if(read_len == 0)
|
|
||||||
break;
|
|
||||||
if(read_len != sizeof(TS_RECORD_PKG)) {
|
|
||||||
qDebug() << "invaid .tpd file (1).";
|
|
||||||
// msg.sprintf("错误的录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
|
|
||||||
msg = QString::fromLocal8Bit("错误的录像数据文件!\n\n");
|
|
||||||
msg += tpd_filename.toStdString().c_str();
|
|
||||||
_notify_error(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
|
|
||||||
qDebug("----key frame: %d", pkg.time_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateData* dat = new UpdateData(TYPE_DATA);
|
|
||||||
dat->alloc_data(sizeof(TS_RECORD_PKG) + pkg.size);
|
|
||||||
memcpy(dat->data_buf(), &pkg, sizeof(TS_RECORD_PKG));
|
|
||||||
read_len = f_dat.read((char*)(dat->data_buf()+sizeof(TS_RECORD_PKG)), pkg.size);
|
|
||||||
if(read_len != pkg.size) {
|
|
||||||
delete dat;
|
delete dat;
|
||||||
qDebug() << "invaid .tpd file.";
|
|
||||||
// msg.sprintf("错误的录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
|
|
||||||
msg = QString::fromLocal8Bit("错误的录像数据文件!\n\n");
|
|
||||||
msg += tpd_filename.toStdString().c_str();
|
|
||||||
_notify_error(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg_count++;
|
|
||||||
|
|
||||||
time_pass = (uint32_t)(QDateTime::currentMSecsSinceEpoch() - time_begin) * m_speed;
|
|
||||||
if(time_pass > total_ms)
|
|
||||||
time_pass = total_ms;
|
|
||||||
if(time_pass - time_last_pass > 200) {
|
|
||||||
UpdateData* _passed_ms = new UpdateData(TYPE_PLAYED_MS);
|
|
||||||
_passed_ms->played_ms(time_pass);
|
|
||||||
emit signal_update_data(_passed_ms);
|
|
||||||
time_last_pass = time_pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(time_pass >= pkg.time_ms) {
|
|
||||||
emit signal_update_data(dat);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 需要等待
|
|
||||||
uint32_t time_wait = pkg.time_ms - time_pass;
|
|
||||||
uint32_t wait_this_time = 0;
|
|
||||||
for(;;) {
|
|
||||||
if(m_need_pause) {
|
|
||||||
msleep(50);
|
|
||||||
time_begin += 50;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_this_time = time_wait;
|
|
||||||
if(wait_this_time > 10)
|
|
||||||
wait_this_time = 10;
|
|
||||||
|
|
||||||
if(m_need_stop) {
|
|
||||||
qDebug() << "stop, user cancel (2).";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
msleep(wait_this_time);
|
|
||||||
|
|
||||||
uint32_t _time_pass = (uint32_t)(QDateTime::currentMSecsSinceEpoch() - time_begin) * m_speed;
|
|
||||||
if(_time_pass > total_ms)
|
|
||||||
_time_pass = total_ms;
|
|
||||||
if(_time_pass - time_last_pass > 200) {
|
|
||||||
UpdateData* _passed_ms = new UpdateData(TYPE_PLAYED_MS);
|
|
||||||
_passed_ms->played_ms(_time_pass);
|
|
||||||
emit signal_update_data(_passed_ms);
|
|
||||||
time_last_pass = _time_pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_wait -= wait_this_time;
|
|
||||||
if(time_wait == 0) {
|
|
||||||
emit signal_update_data(dat);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pkg_count < total_pkg) {
|
|
||||||
qDebug() << "total-pkg:" << total_pkg << ", played:" << pkg_count;
|
|
||||||
// msg.sprintf("录像数据文件有误!\n\n部分录像数据缺失!");
|
|
||||||
msg = QString::fromLocal8Bit("录像数据文件有误!\n\n部分录像数据缺失!");
|
|
||||||
_notify_message(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
// qDebug("play end.");
|
|
||||||
// UpdateData* _end = new UpdateData(TYPE_END);
|
|
||||||
// emit signal_update_data(_end);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
void pause() {m_need_pause = true;}
|
void pause() {m_need_pause = true;}
|
||||||
void resume() {m_need_pause = false;}
|
void resume() {m_need_pause = false;}
|
||||||
void speed(int s) {if(s >= 1 && s <= 16) m_speed = s;}
|
void speed(int s) {if(s >= 1 && s <= 16) m_speed = s;}
|
||||||
|
void skip(bool s) {m_skip = s;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _notify_message(const QString& msg);
|
void _notify_message(const QString& msg);
|
||||||
|
@ -34,6 +35,7 @@ private:
|
||||||
bool m_need_stop;
|
bool m_need_stop;
|
||||||
bool m_need_pause;
|
bool m_need_pause;
|
||||||
int m_speed;
|
int m_speed;
|
||||||
|
bool m_skip;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // THR_PLAY_H
|
#endif // THR_PLAY_H
|
||||||
|
|
|
@ -1,17 +1,157 @@
|
||||||
#include "update_data.h"
|
#include "update_data.h"
|
||||||
|
#include "rle.h"
|
||||||
|
|
||||||
UpdateData::UpdateData(int data_type, QObject *parent) : QObject(parent)
|
#include <QImage>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
|
static QImage* _rdpimg2QImage(int w, int h, int bitsPerPixel, bool isCompressed, const uint8_t* dat, uint32_t len) {
|
||||||
|
QImage* out;
|
||||||
|
switch(bitsPerPixel) {
|
||||||
|
case 15:
|
||||||
|
if(isCompressed) {
|
||||||
|
uint8_t* _dat = reinterpret_cast<uint8_t*>(calloc(1, w*h*2));
|
||||||
|
if(!bitmap_decompress1(_dat, w, h, dat, len)) {
|
||||||
|
free(_dat);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
if(isCompressed) {
|
||||||
|
uint8_t* _dat = reinterpret_cast<uint8_t*>(calloc(1, w*h*2));
|
||||||
|
if(!bitmap_decompress2(_dat, w, h, dat, len)) {
|
||||||
|
free(_dat);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 这里需要进一步优化,直接操作QImage的buffer。
|
||||||
|
out = new 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;
|
||||||
|
out->setPixelColor(x, y, QColor(r,g,b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(_dat);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
case 32:
|
||||||
|
default:
|
||||||
|
qDebug() << "--------NOT support UNKNOWN bitsPerPix" << bitsPerPixel;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UpdateData::UpdateData() : QObject(nullptr)
|
||||||
{
|
{
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateData::UpdateData(int data_type) : QObject(nullptr)
|
||||||
|
{
|
||||||
|
_init();
|
||||||
m_data_type = data_type;
|
m_data_type = data_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateData::UpdateData(const TS_RECORD_HEADER& hdr) : QObject(nullptr)
|
||||||
|
{
|
||||||
|
_init();
|
||||||
|
m_data_type = TYPE_HEADER_INFO;
|
||||||
|
m_hdr = new TS_RECORD_HEADER;
|
||||||
|
memcpy(m_hdr, &hdr, sizeof(TS_RECORD_HEADER));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateData::_init() {
|
||||||
|
m_data_type = TYPE_UNKNOWN;
|
||||||
|
m_hdr = nullptr;
|
||||||
|
m_pointer = nullptr;
|
||||||
|
m_img = nullptr;
|
||||||
|
// m_img_info = nullptr;
|
||||||
|
|
||||||
m_data_buf = nullptr;
|
m_data_buf = nullptr;
|
||||||
m_data_len = 0;
|
m_data_len = 0;
|
||||||
|
m_time_ms = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateData::~UpdateData() {
|
UpdateData::~UpdateData() {
|
||||||
|
if(m_hdr)
|
||||||
|
delete m_hdr;
|
||||||
|
if(m_pointer)
|
||||||
|
delete m_pointer;
|
||||||
|
if(m_img)
|
||||||
|
delete m_img;
|
||||||
|
// if(m_img_info)
|
||||||
|
// delete m_img_info;
|
||||||
|
|
||||||
if(m_data_buf)
|
if(m_data_buf)
|
||||||
delete m_data_buf;
|
delete m_data_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UpdateData::parse(const TS_RECORD_PKG& pkg, const QByteArray& data) {
|
||||||
|
m_time_ms = pkg.time_ms;
|
||||||
|
|
||||||
|
if(pkg.type == TS_RECORD_TYPE_RDP_POINTER) {
|
||||||
|
m_data_type = TYPE_POINTER;
|
||||||
|
if(data.size() != sizeof(TS_RECORD_RDP_POINTER))
|
||||||
|
return false;
|
||||||
|
m_pointer = new TS_RECORD_RDP_POINTER;
|
||||||
|
memcpy(m_pointer, data.data(), sizeof(TS_RECORD_RDP_POINTER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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<const TS_RECORD_RDP_IMAGE_INFO*>(data.data());
|
||||||
|
const uint8_t* img_dat = reinterpret_cast<const uint8_t*>(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)
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// m_img_info = new TS_RECORD_RDP_IMAGE_INFO;
|
||||||
|
// memcpy(m_img_info, data.data(), sizeof(TS_RECORD_RDP_IMAGE_INFO));
|
||||||
|
// m_data_buf = new uint8_t[img_len];
|
||||||
|
// memcpy(m_data_buf, img_dat, img_len);
|
||||||
|
// m_data_len = img_len;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpdateData::alloc_data(uint32_t len) {
|
void UpdateData::alloc_data(uint32_t len) {
|
||||||
if(m_data_buf)
|
if(m_data_buf)
|
||||||
delete m_data_buf;
|
delete m_data_buf;
|
||||||
|
|
|
@ -1,23 +1,45 @@
|
||||||
#ifndef UPDATE_DATA_H
|
#ifndef UPDATE_DATA_H
|
||||||
#define UPDATE_DATA_H
|
#define UPDATE_DATA_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include "record_format.h"
|
||||||
|
|
||||||
#define TYPE_HEADER_INFO 0
|
#define TYPE_UNKNOWN 0
|
||||||
#define TYPE_DATA 1
|
#define TYPE_HEADER_INFO 1
|
||||||
#define TYPE_PLAYED_MS 2
|
#define TYPE_POINTER 10
|
||||||
#define TYPE_DOWNLOAD_PERCENT 3
|
#define TYPE_IMAGE 11
|
||||||
#define TYPE_END 4
|
#define TYPE_KEYFRAME 12
|
||||||
#define TYPE_MESSAGE 5
|
#define TYPE_PLAYED_MS 20
|
||||||
#define TYPE_ERROR 6
|
#define TYPE_DOWNLOAD_PERCENT 21
|
||||||
|
#define TYPE_END 50
|
||||||
|
#define TYPE_MESSAGE 90
|
||||||
|
#define TYPE_ERROR 91
|
||||||
|
|
||||||
class UpdateData : public QObject
|
class UpdateData : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit UpdateData(int data_type, QObject *parent = nullptr);
|
explicit UpdateData();
|
||||||
|
explicit UpdateData(int data_type);
|
||||||
|
explicit UpdateData(const TS_RECORD_HEADER& hdr);
|
||||||
virtual ~UpdateData();
|
virtual ~UpdateData();
|
||||||
|
|
||||||
|
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)
|
||||||
|
return false;
|
||||||
|
*img = m_img;
|
||||||
|
x = m_img_x;
|
||||||
|
y = m_img_y;
|
||||||
|
w = m_img_w;
|
||||||
|
h = m_img_h;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_time() {return m_time_ms;}
|
||||||
|
|
||||||
void alloc_data(uint32_t len);
|
void alloc_data(uint32_t len);
|
||||||
void attach_data(const uint8_t* dat, uint32_t len);
|
void attach_data(const uint8_t* dat, uint32_t len);
|
||||||
|
|
||||||
|
@ -32,6 +54,9 @@ public:
|
||||||
void message(const QString& msg) {m_msg = msg;}
|
void message(const QString& msg) {m_msg = msg;}
|
||||||
const QString message(){return m_msg;}
|
const QString message(){return m_msg;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _init(void);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -39,10 +64,24 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_data_type;
|
int m_data_type;
|
||||||
|
uint32_t m_time_ms;
|
||||||
uint8_t* m_data_buf;
|
uint8_t* m_data_buf;
|
||||||
uint32_t m_data_len;
|
uint32_t m_data_len;
|
||||||
uint32_t m_played_ms;
|
uint32_t m_played_ms;
|
||||||
QString m_msg;
|
QString m_msg;
|
||||||
|
|
||||||
|
// for HEADER
|
||||||
|
TS_RECORD_HEADER* m_hdr;
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// TS_RECORD_RDP_IMAGE_INFO* m_img_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpdateDataHelper {
|
class UpdateDataHelper {
|
||||||
|
|
Loading…
Reference in New Issue