344 lines
9.1 KiB
C++
344 lines
9.1 KiB
C++
#include "PlayThread.h"
|
|
#include "QApplication"
|
|
#include "stdio.h"
|
|
#include <time.h>
|
|
#include<sys/time.h>
|
|
|
|
#include <iostream>
|
|
#include <chrono>
|
|
|
|
#include "PerformanceTimer.h"
|
|
|
|
/*
|
|
#include "mmsystem.h"
|
|
|
|
#pragma comment(lib,"winmm.lib")
|
|
*/
|
|
|
|
static quint64 getcurtime()
|
|
{
|
|
auto now = std::chrono::steady_clock::now();
|
|
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
|
|
auto ms = now_ms.time_since_epoch().count();
|
|
|
|
//std::cout << "当前时间(毫秒精度): " << ms << " 毫秒" << std::endl;
|
|
|
|
return ms;
|
|
}
|
|
|
|
static quint64 gettime_t()
|
|
{
|
|
struct timeval time_now = {0};
|
|
long time_sec = 0;//秒
|
|
long time_mil = 0;//1毫秒 = 1秒/1000
|
|
long time_mic = 0;//1微秒 = 1毫秒/1000
|
|
|
|
gettimeofday(&time_now,NULL);
|
|
time_sec = time_now.tv_sec;
|
|
time_mil = time_sec * 1000 + time_now.tv_usec/1000;
|
|
time_mic = time_now.tv_sec*1000*1000 + time_now.tv_usec;
|
|
|
|
return time_mil;
|
|
}
|
|
|
|
|
|
//播放线程
|
|
PlayThread::PlayThread(QObject *parent) : QObject(parent)
|
|
{
|
|
setAutoDelete(true);
|
|
|
|
qRegisterMetaType<QMap<QDateTime,QByteArray>>("QMap<QDateTime,QByteArray>");
|
|
|
|
FrameData.clear();
|
|
|
|
time_tick= 0;
|
|
|
|
setplay_control(true);
|
|
|
|
}
|
|
|
|
PlayThread::~PlayThread()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void PlayThread::run()
|
|
{
|
|
qint64 last_time_gap = 0;
|
|
|
|
quint8 count = 0;
|
|
|
|
QElapsedTimer elapstimer;
|
|
|
|
|
|
qDebug() << "PlayThread:" << QThread::currentThreadId();
|
|
|
|
union{uint8_t B[8];qint16 h[4];quint16 H[4]; qint32 i[2];quint32 I[2];qint64 q;quint64 Q;}src;
|
|
|
|
QByteArray data;
|
|
QByteArray frame;
|
|
|
|
//int CurrentProgress = 0;
|
|
uint32_t index = 0;
|
|
|
|
while(play_control)
|
|
{
|
|
while (play_start) {
|
|
elapstimer.start();
|
|
//for 不允许自加,需要后面逻辑判断增加
|
|
|
|
currentTick = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
for (QList<QByteArray>::iterator i = FrameData.begin(); i != FrameData.end();)
|
|
{
|
|
//记录一下运行到延迟之前用了多少时间,需要减掉这部分时间
|
|
//elapstimer.start();
|
|
|
|
//CurrentProgress = FrameData.indexOf(*i);
|
|
|
|
data.clear();
|
|
data = *i;
|
|
|
|
index = 0;
|
|
|
|
src.B[0] = data[index++];
|
|
src.B[1] = data[index++];
|
|
src.B[2] = data[index++];
|
|
src.B[3] = data[index++];
|
|
src.B[4] = data[index++];
|
|
src.B[5] = data[index++];
|
|
src.B[6] = data[index++];
|
|
src.B[7] = data[index++];
|
|
qint64 time_ts =src.Q;
|
|
|
|
QDateTime time = QDateTime::fromMSecsSinceEpoch(time_ts);
|
|
|
|
if((time.toMSecsSinceEpoch() - time_tick) > 1000)//第一次
|
|
{
|
|
time_tick = time.toMSecsSinceEpoch();
|
|
QDateTime::currentMSecsSinceEpoch();
|
|
}
|
|
|
|
emit timestamp(time);
|
|
|
|
/*
|
|
src.B[0] = data[index++];
|
|
src.B[1] = data[index++];
|
|
src.B[2] = data[index++];
|
|
src.B[3] = data[index++];
|
|
src.B[4] = data[index++];
|
|
src.B[5] = data[index++];
|
|
src.B[6] = data[index++];
|
|
src.B[7] = data[index++];
|
|
qint64 save_count =src.Q;
|
|
*/
|
|
index += 8;//跳过某些数据,以节省时间
|
|
|
|
src.B[0] = data[index++];
|
|
src.B[1] = data[index++];
|
|
src.B[2] = data[index++];
|
|
src.B[3] = data[index++];
|
|
quint32 ip = src.I[0];
|
|
|
|
|
|
src.B[0] = data[index++];
|
|
src.B[1] = data[index++];
|
|
quint16 port =src.H[0];
|
|
|
|
|
|
|
|
//frame.clear();
|
|
//frame.append(data.mid(index));
|
|
frame = data.mid(index);
|
|
|
|
//中断播放,一般只有要播放新的文件才会出现这种情况
|
|
if(play_state == 0)
|
|
{
|
|
//CurrentProgress = 0;
|
|
break;
|
|
}
|
|
else if(play_state == 1)//正常播放
|
|
{
|
|
//CurrentProgress = FrameData.indexOf(*i);
|
|
CurrentProgress++;
|
|
emit progress(FrameData.size() - 1,CurrentProgress);
|
|
++i;
|
|
if(i == FrameData.end())
|
|
{
|
|
play_state = 0;
|
|
break;
|
|
}
|
|
}
|
|
else if(play_state == 2)//暂停
|
|
{
|
|
time_tick = time.toMSecsSinceEpoch();
|
|
while(play_state == 2)
|
|
{
|
|
CurrentProgress = FrameData.indexOf(*i);
|
|
emit progress(FrameData.size() - 1,CurrentProgress);
|
|
QThread::msleep(100);
|
|
|
|
last_time_gap = 0;
|
|
if(isChangedPos)
|
|
{
|
|
i += (newpos - CurrentProgress);
|
|
//qDebug() << CurrentProgress << newpos << FrameData.indexOf(*i);
|
|
|
|
if(i == FrameData.end())
|
|
{
|
|
play_state = 0;
|
|
isChangedPos = false;
|
|
break;
|
|
}
|
|
|
|
data = *i;//最后一个?
|
|
|
|
index = 0;
|
|
src.B[0] = data[index++];
|
|
src.B[1] = data[index++];
|
|
src.B[2] = data[index++];
|
|
src.B[3] = data[index++];
|
|
src.B[4] = data[index++];
|
|
src.B[5] = data[index++];
|
|
src.B[6] = data[index++];
|
|
src.B[7] = data[index++];
|
|
qint64 time_t =src.Q;
|
|
|
|
QDateTime time = QDateTime::fromMSecsSinceEpoch(time_t);
|
|
time_tick = time.toMSecsSinceEpoch();
|
|
|
|
emit timestamp(time);
|
|
|
|
isChangedPos = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//发出去
|
|
emit transmit(QHostAddress(ip),port,frame);
|
|
|
|
//延迟处理
|
|
|
|
qint64 time_gap = 0;
|
|
//假设上面那个成勋运行1ms时间,减掉,因为上面那一段运行时间不到1ms
|
|
time_gap = time.toMSecsSinceEpoch() - time_tick;
|
|
|
|
time_tick = time.toMSecsSinceEpoch();
|
|
|
|
|
|
qint64 elapstime = (qint64)(elapstimer.elapsed());
|
|
|
|
//qDebug() << "time:" << time_gap << last_time_gap << elapstime;
|
|
|
|
if(time_gap > 1000)//第一次
|
|
{
|
|
time_gap = 1000;
|
|
}
|
|
|
|
|
|
if(time_gap > 0)
|
|
{
|
|
last_time_gap = 0;
|
|
|
|
int64_t time_tick = (time_gap/times) - last_time_gap;
|
|
|
|
if(time_tick > 0)
|
|
{
|
|
while(elapstime < time_tick)
|
|
{
|
|
//QApplication::processEvents();
|
|
elapstime = (qint64)(elapstimer.elapsed());
|
|
//qDebug() << "tick:" << time_tick << elapstime;
|
|
//QThread::msleep(1);
|
|
count += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
last_time_gap -= time_tick;
|
|
}
|
|
|
|
elapstimer.start();
|
|
}
|
|
else
|
|
{
|
|
last_time_gap += elapstime;
|
|
}
|
|
|
|
//qDebug() << "time:" << time_gap << last_time_gap << elapstime;
|
|
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
currentTick = QDateTime::currentMSecsSinceEpoch();
|
|
frame_count++;
|
|
}
|
|
play_state = 0;
|
|
isChangedPos = false;
|
|
time_tick = 0;
|
|
//FrameData.clear();
|
|
play_start = false;
|
|
break;//退出,结束播放
|
|
}
|
|
QThread::msleep(1);
|
|
}
|
|
}
|
|
|
|
|
|
void PlayThread::resetData()
|
|
{
|
|
|
|
|
|
time_tick= 0;
|
|
|
|
play_start = false;
|
|
|
|
CurrentProgress = 0;
|
|
|
|
play_state = 0;
|
|
|
|
Sleep(100);
|
|
|
|
FrameData.clear();
|
|
|
|
}
|
|
|
|
|
|
void PlayThread::playData(QList<QByteArray> data,QMap<quint16,QList<QByteArray>> data2)
|
|
{
|
|
//收到数据后对数据进行分类,重新生成子线程进行解析
|
|
|
|
port_data.clear();
|
|
port_data = data2;
|
|
|
|
|
|
FrameData.clear();
|
|
FrameData = data;
|
|
|
|
time_tick= 0;
|
|
|
|
play_state = 1;
|
|
|
|
emit progress(FrameData.size() - 1,0);
|
|
|
|
}
|
|
|
|
void PlayThread::appendPlayData(quint32 ip, quint16 port, QByteArray data)
|
|
{
|
|
//收到数据后对数据进行分类,重新生成子线程进行解析
|
|
//qDebug() << "PlayThread:" << QThread::currentThreadId();
|
|
|
|
//FrameData.clear();
|
|
//FrameData.append(data);
|
|
FrameData.push_back(data);
|
|
|
|
emit progress(size() - 1,0);
|
|
}
|
|
|
|
|
|
|
|
|