Files
capture/PlayThread.cpp
T
2024-10-28 15:33:11 +08:00

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);
}