2,新增“Apps”; 3,新增“Common”; 4,新增“FileList”; 5,新增“MediaX”; 6,新增“OpenSource”; 7,新增“Samples”; 8,新增“SoftwareBusinessLines”.
437 lines
11 KiB
C++
437 lines
11 KiB
C++
#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;
|
||
}
|