]> git.vomp.tv Git - vompclient.git/commitdiff
Convert PlayerVideoRec to std::thread
authorChris Tallon <chris@vomp.tv>
Tue, 10 Mar 2020 18:28:18 +0000 (18:28 +0000)
committerChris Tallon <chris@vomp.tv>
Tue, 10 Mar 2020 18:28:18 +0000 (18:28 +0000)
playervideorec.cc
playervideorec.h

index b5ffa0409b30c4b13be1c6daac95302a1d1b0042..75df8896d830b0ac760f54c47411f1c5fc777e73 100644 (file)
@@ -116,6 +116,28 @@ int PlayerVideoRec::shutdown()
   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;
@@ -1008,7 +1030,7 @@ void PlayerVideoRec::call(void* caller)
       stateMutex.unlock();
     }
 
-    threadSignalNoLock();
+    playerThreadCond.notify_one();
   }
 }
 
@@ -1022,12 +1044,15 @@ void PlayerVideoRec::threadMethod()
 
   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;
@@ -1071,13 +1096,15 @@ void PlayerVideoRec::threadFeedPlay()
 
   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))
@@ -1127,7 +1154,7 @@ void PlayerVideoRec::threadFeedPlay()
       startup = false;
     }
 
-    threadCheckExit();
+    if (threadReqQuit) return;
 
     while(writeLength < thisRead)
     {
@@ -1139,13 +1166,13 @@ void PlayerVideoRec::threadFeedPlay()
       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();
@@ -1161,8 +1188,7 @@ void PlayerVideoRec::threadFeedPlay()
     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;
@@ -1174,7 +1200,7 @@ void PlayerVideoRec::threadFeedPlay()
 }
 
 
-void PlayerVideoRec::threadPTSFeedScan()
+bool PlayerVideoRec::threadPTSFeedScan()
 {
   // This method manipulates the PTS instead of waiting, this is for the android devices, maybe later for windows?
 
@@ -1206,12 +1232,13 @@ void PlayerVideoRec::threadPTSFeedScan()
   {
     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;
 
@@ -1224,10 +1251,10 @@ void PlayerVideoRec::threadPTSFeedScan()
     if (!vdr->isConnected())
     {
       doConnectionLost();
-      break;
+      return false;
     }
 
-    threadCheckExit();
+    if (threadReqQuit) return false;
 
     videoLength = demuxer->stripAudio(threadBuffer.ucharp(), amountReceived);
     demuxer->changeTimes(threadBuffer.ucharp(), videoLength, playtime);
@@ -1235,7 +1262,7 @@ void PlayerVideoRec::threadPTSFeedScan()
     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();
@@ -1264,7 +1291,7 @@ void PlayerVideoRec::threadPTSFeedScan()
 
 
 
-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
@@ -1303,11 +1330,12 @@ void PlayerVideoRec::threadFeedScan()
     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;
@@ -1335,7 +1363,7 @@ void PlayerVideoRec::threadFeedScan()
     if (!vdr->isConnected() || !amountReceived)
     {
       doConnectionLost();
-      break;
+      return false;
     }
     
 #ifndef WIN32
@@ -1350,7 +1378,7 @@ void PlayerVideoRec::threadFeedScan()
       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);
 
index 0ea99c0189c2b7332e2e4d246164d6201b2f02f4..f91269d7e812261d2305ceb923e381d897b7adf2 100644 (file)
@@ -28,8 +28,8 @@
 #endif
 #include <time.h>
 #include <mutex>
-
-#include "threadsystem.h"
+#include <thread>
+#include <condition_variable>
 
 #include "callback.h"
 #include "defines.h"
@@ -49,7 +49,7 @@ class OSDReceiver;
 class DVBSubtitles;
 class Channel;
 
-class PlayerVideoRec : public Thread_TYPE, public Callback
+class PlayerVideoRec : public Callback
 {
   public:
     PlayerVideoRec(MessageQueue* messageQueue, void* messageReceiver, OSDReceiver* osdReceiver);
@@ -120,15 +120,13 @@ class PlayerVideoRec : public Thread_TYPE, public Callback
     void test2();
 #endif
 
-  protected:
-    void threadMethod();
-
   private:
     void switchState(UCHAR newState, ULONG jumpFrame=0);
 
+    void threadMethod();
     void threadFeedPlay();
-    void threadFeedScan();
-    void threadPTSFeedScan();
+    bool threadFeedScan();
+    bool threadPTSFeedScan();
 
     void doConnectionLost();
     void restartAtFrame(ULONG newFrame);
@@ -159,6 +157,13 @@ class PlayerVideoRec : public Thread_TYPE, public Callback
 
     std::mutex stateMutex;
 
+    std::thread playerThread;
+    std::mutex playerThreadMutex;
+    std::condition_variable playerThreadCond;
+    bool threadReqQuit;
+    void threadStart();
+    void threadStop();
+
     ULLONG lengthBytes{};
     ULONG lengthFrames{};
     ULONG currentFrameNumber{};