return 1;
}
+void PlayerVideoRec::threadStart()
+{
+ playerThreadMutex.lock();
+ threadReqQuit = false;
+ playerThread = std::thread([this]
+ {
+ playerThreadMutex.lock();
+ playerThreadMutex.unlock();
+ threadMethod();
+ });
+ playerThreadMutex.unlock();
+}
+
+void PlayerVideoRec::threadStop()
+{
+ playerThreadMutex.lock();
+ threadReqQuit = true;
+ playerThreadCond.notify_one();
+ playerThreadMutex.unlock();
+ playerThread.join();
+}
+
void PlayerVideoRec::setStartFrame(ULONG startFrame)
{
ULONG nextiframeNumber;
stateMutex.unlock();
}
- threadSignalNoLock();
+ playerThreadCond.notify_one();
}
}
if ((state == S_FFWD) || (state == S_FBWD))
{
- if (video->PTSIFramePlayback()) threadPTSFeedScan();
- else threadFeedScan();
- // if this returns then scan hit one end
+ bool hitEnd;
+ if (video->PTSIFramePlayback()) hitEnd = threadPTSFeedScan();
+ else hitEnd = threadFeedScan();
+
+ if (!hitEnd) return; // thread wants to exit normally
+
if (state == S_FFWD) // scan hit the end. stop
{
- threadCheckExit();
+ if (threadReqQuit) return;
Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
m->to = messageReceiver;
m->from = this;
Buffer threadBuffer;
+ std::unique_lock<std::mutex> ul(playerThreadMutex, std::defer_lock);
+
while(1)
{
thisRead = 0;
writeLength = 0;
thisWrite = 0;
- threadCheckExit();
+ if (threadReqQuit) return;
// If we havn't rescanned for a while..
if ((lastRescan + 60) < time(NULL))
startup = false;
}
- threadCheckExit();
+ if (threadReqQuit) return;
while(writeLength < thisRead)
{
if (!thisWrite)
{
// demuxer is full and can't take anymore
- threadLock();
- if (!threadActive) { threadUnlock(); threadCheckExit(); }
- threadWaitForSignal();
- threadUnlock();
+ playerThreadMutex.lock();
+ if (threadReqQuit) { playerThreadMutex.unlock(); return; }
+ playerThreadCond.wait(ul);
+ playerThreadMutex.unlock();
}
- threadCheckExit();
+ if (threadReqQuit) return;
}
threadBuffer.release();
MILLISLEEP(500); // I think this will solve a race
}
- threadCheckExit();
-
+ if (threadReqQuit) return;
Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
m->to = messageReceiver;
}
-void PlayerVideoRec::threadPTSFeedScan()
+bool PlayerVideoRec::threadPTSFeedScan()
{
// This method manipulates the PTS instead of waiting, this is for the android devices, maybe later for windows?
{
baseFrameNumber = currentfeedFrameNumber;
- threadCheckExit();
+ if (threadReqQuit) return false;
+
if (!vdr->getNextIFrame(baseFrameNumber, direction, &filePos, &iframeNumber, &iframeLength))
- return;
+ return true;
- if (iframeNumber >= lengthFrames) return;
- // scan has got to the end of what we knew to be there before we started scanning
+ if (iframeNumber >= lengthFrames) return true;
+ // scan has got to the end of what we knew to be there before we started scanning
baseFrameNumber = iframeNumber;
if (!vdr->isConnected())
{
doConnectionLost();
- break;
+ return false;
}
- threadCheckExit();
+ if (threadReqQuit) return false;
videoLength = demuxer->stripAudio(threadBuffer.ucharp(), amountReceived);
demuxer->changeTimes(threadBuffer.ucharp(), videoLength, playtime);
while (!video->displayIFrame(threadBuffer.ucharp(), videoLength)) // the device might block
{
MILLISLEEP(20);
- threadCheckExit();
+ if (threadReqQuit) return false;
count++;
if (count%300==0) {
ULLONG cur_time=video->getCurrentTimestamp();
-void PlayerVideoRec::threadFeedScan()
+bool PlayerVideoRec::threadFeedScan()
{
// This method is actually really simple - get frame from vdr,
// spit it at the video chip, wait for a time. Most of the code here
baseFrameNumber = currentFrameNumber;
do
{
- threadCheckExit();
+ if (threadReqQuit) return false;
+
if (!vdr->getNextIFrame(baseFrameNumber, direction, &filePos, &iframeNumber, &iframeLength))
- return;
+ return true;
- if (iframeNumber >= lengthFrames) return;
+ if (iframeNumber >= lengthFrames) return true;
// scan has got to the end of what we knew to be there before we started scanning
baseFrameNumber = iframeNumber;
if (!vdr->isConnected() || !amountReceived)
{
doConnectionLost();
- break;
+ return false;
}
#ifndef WIN32
sleepTime = clock2 + frameTimeOffset - disp_msec - clock1;
#endif
if (sleepTime < 0) sleepTime = 0;
- threadCheckExit();
+ if (threadReqQuit) return false;
MILLISLEEP(sleepTime);
logger->log("Player", Log::DEBUG, "XXX Slept for %d", sleepTime);