teleport/client/tp-player/thr_play.cpp

246 lines
8.1 KiB
C++
Raw Normal View History

2019-09-09 18:39:08 +00:00
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
2019-09-02 21:40:52 +00:00
#include "thr_play.h"
2019-10-31 17:45:17 +00:00
#include "thr_data.h"
2019-11-03 19:34:11 +00:00
#include "mainwindow.h"
2019-09-02 21:40:52 +00:00
#include "record_format.h"
2019-10-31 17:45:17 +00:00
#include "util.h"
2019-09-02 21:40:52 +00:00
2019-10-31 17:45:17 +00:00
/*
*
* - 线线
* + 线500100020ms500
* - 线UI
* + if( * ( - ) >= ( - ))
* + 33
*/
2019-11-03 19:34:11 +00:00
ThrPlay::ThrPlay(MainWindow* mainwnd) {
m_mainwnd = mainwnd;
2019-09-02 21:40:52 +00:00
m_need_stop = false;
m_need_pause = false;
m_speed = 2;
2019-10-31 17:45:17 +00:00
// m_res = res;
// m_thr_data = nullptr;
2019-09-16 05:53:27 +00:00
}
2019-10-31 17:45:17 +00:00
ThrPlay::~ThrPlay() {
2019-09-16 05:53:27 +00:00
stop();
2019-09-02 21:40:52 +00:00
}
2019-10-31 17:45:17 +00:00
void ThrPlay::stop() {
2019-09-16 05:53:27 +00:00
if(!isRunning())
return;
// warning: never call stop() inside thread::run() loop.
2019-09-02 21:40:52 +00:00
m_need_stop = true;
2019-09-16 05:53:27 +00:00
wait();
qDebug() << "play-thread end.";
2019-10-31 17:45:17 +00:00
// if(m_thr_data) {
// m_thr_data->stop();
// qDebug("delete thrData.");
// //m_thr_download->wait();
// delete m_thr_data;
// m_thr_data = nullptr;
// }
2019-09-02 21:40:52 +00:00
}
2019-10-31 17:45:17 +00:00
void ThrPlay::_notify_message(const QString& msg) {
UpdateData* _msg = new UpdateData(TYPE_MESSAGE);
2019-09-16 05:53:27 +00:00
_msg->message(msg);
emit signal_update_data(_msg);
}
2019-10-31 17:45:17 +00:00
void ThrPlay::_notify_error(const QString& msg) {
UpdateData* _msg = new UpdateData(TYPE_ERROR);
_msg->message(msg);
emit signal_update_data(_msg);
2019-09-16 05:53:27 +00:00
}
2019-10-31 17:45:17 +00:00
void ThrPlay::run() {
2019-09-16 05:53:27 +00:00
2019-11-03 19:34:11 +00:00
ThrData* thr_data = m_mainwnd->get_thr_data();
bool first_run = true;
2019-11-03 19:34:11 +00:00
for(;;) {
if(m_need_stop)
break;
2019-09-16 05:53:27 +00:00
2019-11-03 19:34:11 +00:00
// 1. 从ThrData的待播放队列中取出一个数据
UpdateData* dat = thr_data->get_data();
if(dat == nullptr) {
msleep(20);
continue;
2019-09-16 05:53:27 +00:00
}
2019-11-03 19:34:11 +00:00
if(first_run) {
first_run = false;
_notify_message("");
2019-09-17 16:51:22 +00:00
}
2019-11-03 19:34:11 +00:00
// 2. 根据数据包的信息,等待到播放时间点
// 3. 将数据包发送给主UI界面进行显示
// qDebug("emit one package.");
if(dat->data_type() == TYPE_END) {
_notify_message(LOCAL8BIT("播放结束"));
2019-09-17 16:51:22 +00:00
}
2019-09-16 05:53:27 +00:00
2019-09-02 21:40:52 +00:00
emit signal_update_data(dat);
2019-11-03 19:34:11 +00:00
msleep(5);
}
2019-09-02 21:40:52 +00:00
2019-11-03 19:34:11 +00:00
#if 0
2019-09-17 16:51:22 +00:00
//======================================
// 加载录像文件数据并播放
//======================================
2019-09-02 21:40:52 +00:00
2019-09-17 16:51:22 +00:00
uint32_t pkg_count = 0;
uint32_t time_pass = 0;
uint32_t time_last_pass = 0;
qint64 time_begin = QDateTime::currentMSecsSinceEpoch();
2019-09-17 16:51:22 +00:00
QString msg;
2019-09-17 16:51:22 +00:00
for(uint32_t fidx = 0; fidx < file_count; ++fidx) {
2019-09-02 21:40:52 +00:00
if(m_need_stop) {
2019-09-17 16:51:22 +00:00
qDebug() << "stop, user cancel 1.";
2019-09-02 21:40:52 +00:00
break;
}
2019-09-17 16:51:22 +00:00
QString tpd_filename;
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);
2019-09-02 21:40:52 +00:00
2019-09-17 16:51:22 +00:00
QFile f_dat(tpd_filename);
if(!f_dat.open(QFile::ReadOnly)) {
qDebug() << "Can not open " << tpd_filename << " for read.";
2019-10-13 19:41:35 +00:00
// msg.sprintf("无法打开录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
msg = QString::fromLocal8Bit("无法打开录像数据文件!\n\n");
msg += tpd_filename.toStdString().c_str();
2019-09-16 05:53:27 +00:00
_notify_error(msg);
2019-09-02 21:40:52 +00:00
return;
}
for(;;) {
2019-09-17 16:51:22 +00:00
if(m_need_stop) {
qDebug() << "stop, user cancel 2.";
break;
}
if(m_need_pause) {
msleep(50);
time_begin += 50;
continue;
}
2019-09-17 16:51:22 +00:00
TS_RECORD_PKG pkg;
read_len = f_dat.read((char*)(&pkg), sizeof(pkg));
if(read_len == 0)
break;
2019-09-17 16:51:22 +00:00
if(read_len != sizeof(TS_RECORD_PKG)) {
qDebug() << "invaid .tpd file (1).";
2019-10-13 19:41:35 +00:00
// msg.sprintf("错误的录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
msg = QString::fromLocal8Bit("错误的录像数据文件!\n\n");
msg += tpd_filename.toStdString().c_str();
2019-09-17 16:51:22 +00:00
_notify_error(msg);
return;
}
2019-10-13 19:41:35 +00:00
if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
qDebug("----key frame: %d", pkg.time_ms);
}
2019-09-17 16:51:22 +00:00
2019-10-31 17:45:17 +00:00
UpdateData* dat = new UpdateData(TYPE_DATA);
2019-09-17 16:51:22 +00:00
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;
qDebug() << "invaid .tpd file.";
2019-10-13 19:41:35 +00:00
// msg.sprintf("错误的录像数据文件!\n\n%s", tpd_filename.toStdString().c_str());
msg = QString::fromLocal8Bit("错误的录像数据文件!\n\n");
msg += tpd_filename.toStdString().c_str();
2019-09-17 16:51:22 +00:00
_notify_error(msg);
return;
}
2019-09-17 16:51:22 +00:00
pkg_count++;
2019-09-17 16:51:22 +00:00
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) {
2019-10-31 17:45:17 +00:00
UpdateData* _passed_ms = new UpdateData(TYPE_PLAYED_MS);
2019-09-17 16:51:22 +00:00
_passed_ms->played_ms(time_pass);
emit signal_update_data(_passed_ms);
2019-09-17 16:51:22 +00:00
time_last_pass = time_pass;
}
2019-09-17 16:51:22 +00:00
if(time_pass >= pkg.time_ms) {
emit signal_update_data(dat);
2019-09-17 16:51:22 +00:00
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) {
2019-10-31 17:45:17 +00:00
UpdateData* _passed_ms = new UpdateData(TYPE_PLAYED_MS);
2019-09-17 16:51:22 +00:00
_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;
}
}
2019-09-17 16:51:22 +00:00
}
2019-09-02 21:40:52 +00:00
}
2019-09-17 16:51:22 +00:00
if(pkg_count < total_pkg) {
qDebug() << "total-pkg:" << total_pkg << ", played:" << pkg_count;
2019-10-13 19:41:35 +00:00
// msg.sprintf("录像数据文件有误!\n\n部分录像数据缺失");
msg = QString::fromLocal8Bit("录像数据文件有误!\n\n部分录像数据缺失!");
2019-09-17 16:51:22 +00:00
_notify_message(msg);
}
2019-10-31 17:45:17 +00:00
#endif
2019-11-03 19:34:11 +00:00
// qDebug("play end.");
// UpdateData* _end = new UpdateData(TYPE_END);
// emit signal_update_data(_end);
2019-09-02 21:40:52 +00:00
}