Files
CodeRepository/Apps/App_GeneralDataInjectionApp/Common/IO/FileStream/Raw/FileStream.cpp
chenzhen 222dda1e43 1,新增“App_ThermalImageSystem”;
2,新增“Apps”;
3,新增“Common”;
4,新增“FileList”;
5,新增“MediaX”;
6,新增“OpenSource”;
7,新增“Samples”;
8,新增“SoftwareBusinessLines”.
2026-02-14 23:03:23 +08:00

437 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "FileStream.h"
#include <QVector>
#include <QDir>
#include <QDebug>
#include <QThread>
#include <QEventLoop>
#include <QTimer>
#include <QDateTime>
FileStream::FileStream(bool bDirectoryOnly,
bool bRecyclePlay,
const QString& strFileName,
const GFrameFormat& varRawFileParam,
pCallBack_Progress pCallBack,
void* pOwner)
: m_bDirectoryOnly(bDirectoryOnly),
m_bRecyclePlay(bRecyclePlay),
m_strFileName_Playback(strFileName),
m_varRawFileParam(varRawFileParam),
m_pCallBack(pCallBack),
m_pOwner(pOwner)
{
const int c_nPixelBytes = GetByteOfPixel(m_varRawFileParam.ePT);
m_nFrameSize = m_varRawFileParam.nImageWidth * (m_varRawFileParam.nImageHeight + m_varRawFileParam.nParamLineCount) * c_nPixelBytes;
m_pFile = nullptr;
m_nFrameCount = 0;
m_nCurrentIndex = 0;
m_bOpen = false;
m_pFullData = nullptr;
m_varQueueFrameData.InitQueue(m_nFrameSize, DEFAULT_QUEUE_SIZE);
m_bThreadRunning = false;
// m_pThread = nullptr;
m_ePlayState = ePS_Stop;
if (varRawFileParam.nFrameRate <= 25)
{
m_iThreadSleepMsec = 5;
}
else if (varRawFileParam.nFrameRate > 25 && varRawFileParam.nFrameRate <= 50)
{
m_iThreadSleepMsec = 3;
}
else if (varRawFileParam.nFrameRate > 50 && varRawFileParam.nFrameRate <= 100)
{
m_iThreadSleepMsec = 2;
}
else if (varRawFileParam.nFrameRate > 100)
{
m_iThreadSleepMsec = 1;
}
}
FileStream::~FileStream()
{
Stop();
}
int FileStream::GetByteOfPixel(ePixelType ePT)
{
switch (ePT)
{
case ePT_Y16:
case ePT_YUV422:
{
return 2;
}
case ePT_Y8:
{
return 1;
}
case ePT_BGR24:
case ePT_Y16Y8:
{
return 3;
}
default:
{
break;
}
}
return 1;
}
void FileStream::SleepAccurate(int milliseconds)
{
QEventLoop loop;
QTimer::singleShot(milliseconds, &loop, &QEventLoop::quit);
loop.exec();
}
void FileStream::ThreadEntry(ThreadRunFunPtr pRunFun, void* pOwner)
{
FileStream* pRunClass = reinterpret_cast<FileStream*>(pOwner);
if (nullptr == pOwner)
{
return;
}
(pRunClass->*pRunFun)();
}
void FileStream::ThreadFun()
{
// ::timeBeginPeriod(1);
bool bTriggerPausedState = false;
while (m_bThreadRunning)
{
if (ePS_Play != m_ePlayState)
{
SleepAccurate(1);
// 暂停播放
if (bTriggerPausedState)
{
bTriggerPausedState = false;
m_pCallBack(m_nCurrentIndex, m_nFrameCount, m_pOwner, m_varRawFileParam.nChannelIndex);
}
continue;
}
// 单文件
if (!m_bDirectoryOnly)
{
OpenFiles(m_strFileName_Playback);
ReadFileData(m_bRecyclePlay);
CloseFiles();
// qDebug() << ">>>>>>>FileStream-777" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
if (!m_bRecyclePlay)
{
bTriggerPausedState = true;
m_ePlayState = ePS_Pause;
}
}
// 遍历文件夹
else
{
QVector<QString> vecFileList;
EnumFiles(m_strFileName_Playback, vecFileList);
while (true)
{
if (vecFileList.empty())
{
break; //
}
QString strPlaybackFile = vecFileList.at(0);
QString strFilePrefix = strPlaybackFile.left(strPlaybackFile.size() - strlen("1.raw"));
for (QVector<QString>::iterator iter = vecFileList.begin();
iter != vecFileList.end();
)
{
int nPos = iter->indexOf(strFilePrefix);
if (-1 == nPos)
{
++iter;
}
else
{
iter = vecFileList.erase(iter);
}
}
strPlaybackFile = strFilePrefix + "1.raw";
// OpenFiles
if (!OpenFiles(strPlaybackFile))
{
continue;
}
ReadFileData(false);
CloseFiles();
}
if (!m_bRecyclePlay)
{
m_ePlayState = ePS_Pause;
}
}
}
// ::timeEndPeriod(1);
}
bool FileStream::OpenFiles(QString strFileName_Playback)
{
CloseFiles();
QString strFileName = strFileName_Playback.left(strFileName_Playback.length() - strlen("1.raw"));
m_strFileName = strFileName_Playback;
/*
* 视频文件
*/
if (!QFile::exists(m_strFileName))
{
return false;
}
m_pFile = new QFile(m_strFileName);
if (!m_pFile->open(QIODevice::ReadOnly))
{
return false;
}
// 计算4个文件最小大小
unsigned long long nSize = m_pFile->size();
//
m_nFrameCount = nSize / m_nFrameSize;
m_bOpen = true;
return true;
}
//uint m_pFraIndex = 0;
bool FileStream::ReadFileData(bool bReplay)
{
if (!m_bOpen)
{
return false;
}
for (m_nCurrentIndex = 0; m_nCurrentIndex < m_nFrameCount; m_nCurrentIndex++)
{
// qDebug() << ">>>>>>>FileStream-111" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
// 退出线程
if (!m_bThreadRunning)
{
break;
}
// qDebug() << ">>>>>>>FileStream-222" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
if (ePS_Play != m_ePlayState)
{
SleepAccurate(m_iThreadSleepMsec);
m_nCurrentIndex--;
continue;
}
// qDebug() << ">>>>>>>FileStream-333" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
if (m_varQueueFrameData.Size() >= (DEFAULT_QUEUE_SIZE - 1))
{
SleepAccurate(m_iThreadSleepMsec);
m_nCurrentIndex--;
// qDebug() << "m_varQueueFrameData.Size() >= 5 : " << m_varQueueFrameData.Size() << "index: " <<m_nCurrentIndex;
continue;
}
// qDebug() << ">>>>>>>FileStream-444" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
ReadFrameData(m_nCurrentIndex);
// qDebug() << ">>>>>>>FileStream-555" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
if (nullptr != m_pCallBack)
{
m_pCallBack(m_nCurrentIndex + 1, m_nFrameCount, m_pOwner, m_varRawFileParam.nChannelIndex);
// qDebug() << "m_varQueueFrameData.Size() : ----- m_nCurrentIndex " << m_varQueueFrameData.Size() << " " << m_nCurrentIndex;
}
// 循环播放
if (bReplay && (m_nCurrentIndex >= m_nFrameCount))
{
m_nCurrentIndex = 0;
}
// qDebug() << ">>>>>>>FileStream-666" << " " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
// SleepAccurate(m_iThreadSleepMsec); //
}
return true;
}
bool FileStream::ReadFrameData(int nFrameIndex)
{
if (!m_bOpen)
{
return false;
}
// 文件偏移
unsigned long long offset = nFrameIndex;
offset *= m_nFrameSize;
memset(m_pFrameBuffer, 0, m_nFrameSize);
m_pFile->seek(offset);
m_pFile->read(m_pFrameBuffer, m_nFrameSize);
// memcpy(m_pFullData, m_pFrameBuffer, m_nFrameSize);
//
int nRes = 0;
bool issuccess = true;
issuccess = m_varQueueFrameData.PushBack((uchar*)m_pFrameBuffer, m_nFrameSize, nRes);
if (!issuccess)
{
// qDebug() << "File stream push failed" ;
}
return true;
}
void FileStream::CloseFiles()
{
/*
* 视频文件
*/
if (nullptr != m_pFile)
{
if (m_pFile->isOpen())
{
m_pFile->close();
}
delete m_pFile;
m_pFile = nullptr;
}
m_bOpen = false;
}
bool FileStream::EnumFiles(QString strDir, QVector<QString>& vecFileList)
{
QDir varDir(strDir);
if (!varDir.exists())
{
return false;
}
varDir.setFilter(QDir::Dirs | QDir::Files);
varDir.setSorting(QDir::DirsFirst);
QFileInfoList varFileInfoList = varDir.entryInfoList();
int i = 0;
do
{
QFileInfo varFileInfo = varFileInfoList.at(i);
if ("." == varFileInfo.fileName() || ".." == varFileInfo.fileName())
{
i++;
continue;
}
if (varFileInfo.isDir())
{
EnumFiles(varFileInfo.filePath(), vecFileList);
}
else
{
vecFileList.push_back(varFileInfo.filePath());
}
i++;
} while (i < varFileInfoList.size());
return true;
}
void FileStream::Play()
{
if (ePS_Stop == m_ePlayState)
{
Stop();
m_pFrameBuffer = new char[m_nFrameSize + 4096];
m_bThreadRunning = true;
m_futureThreadRun = QtConcurrent::run(&m_varThreadPool, &FileStream::ThreadEntry, &FileStream::ThreadFun, (void*)this);
m_ePlayState = ePS_Play;
}
else
{
m_ePlayState = ePS_Play;
}
}
void FileStream::Stop()
{
if (!m_bThreadRunning)
{
return;
}
if (m_bThreadRunning)
{
m_bThreadRunning = false;
m_futureThreadRun.waitForFinished();
}
//
SleepAccurate(40);
if (nullptr != m_pFrameBuffer)
{
delete[]
m_pFrameBuffer;
m_pFrameBuffer = nullptr;
}
CloseFiles();
m_ePlayState = ePS_Stop;
}
void FileStream::Pause()
{
m_ePlayState = ePS_Pause;
}
bool FileStream::Previous()
{
if (!m_bOpen)
{
return false;
}
if (m_nCurrentIndex - 1 >= 0)
{
m_nCurrentIndex -= 1;
ReadFrameData(m_nCurrentIndex);
if (nullptr != m_pCallBack)
{
m_pCallBack(m_nCurrentIndex, m_nFrameCount, m_pOwner, m_varRawFileParam.nChannelIndex);
}
// 循环播放
if (m_nCurrentIndex <= 0)
{
m_nCurrentIndex = m_nFrameCount - 1;
}
}
return true;
}
bool FileStream::Next()
{
if (!m_bOpen)
{
return false;
}
if (m_nCurrentIndex + 1 < m_nFrameCount)
{
m_nCurrentIndex += 1;
ReadFrameData(m_nCurrentIndex);
if (nullptr != m_pCallBack)
{
m_pCallBack(m_nCurrentIndex, m_nFrameCount, m_pOwner, m_varRawFileParam.nChannelIndex);
}
// 循环播放
if (m_nCurrentIndex >= m_nFrameCount)
{
m_nCurrentIndex = 0;
}
}
return true;
}
bool FileStream::Seek(uint frameNo)
{
if (!m_bOpen || (frameNo > m_nFrameCount))
{
return false;
}
m_nCurrentIndex = frameNo;
ReadFrameData(m_nCurrentIndex);
if (nullptr != m_pCallBack)
{
m_pCallBack(m_nCurrentIndex, m_nFrameCount, m_pOwner, m_varRawFileParam.nChannelIndex);
}
}
GCycleQueue& FileStream::GetFrameQueue()
{
return m_varQueueFrameData;
}
ePlayState FileStream::GetPlayState()
{
return m_ePlayState;
}