|
@@ -1,673 +0,0 @@
|
|
-From 482d898333facf53bd3208cf5e44a0cf3e1f4f3b Mon Sep 17 00:00:00 2001
|
|
|
|
-From: phunkyfish <phunkyfish@gmail.com>
|
|
|
|
-Date: Thu, 8 Oct 2020 14:59:55 +0100
|
|
|
|
-Subject: [PATCH] Use std::thread, std::mutex, condition_variable instead of
|
|
|
|
- event
|
|
|
|
-
|
|
|
|
-Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
|
|
|
----
|
|
|
|
- src/lib/tsreader/DeMultiplexer.cpp | 2 +-
|
|
|
|
- src/lib/tsreader/DeMultiplexer.h | 4 +-
|
|
|
|
- src/lib/tsreader/FileReader.cpp | 2 +-
|
|
|
|
- src/lib/tsreader/MemoryBuffer.cpp | 15 +++--
|
|
|
|
- src/lib/tsreader/MemoryBuffer.h | 7 +-
|
|
|
|
- src/lib/tsreader/MemoryReader.h | 1 +
|
|
|
|
- src/lib/tsreader/MemorySink.cpp | 2 +-
|
|
|
|
- src/lib/tsreader/MemorySink.h | 4 +-
|
|
|
|
- src/lib/tsreader/MepoRTSPClient.cpp | 28 ++++----
|
|
|
|
- src/lib/tsreader/MepoRTSPClient.h | 10 ++-
|
|
|
|
- src/lib/tsreader/MultiFileReader.cpp | 9 ++-
|
|
|
|
- src/os-dependent.h | 95 ++++++++++++++++++++++++++++
|
|
|
|
- src/pvrclient-mediaportal.cpp | 29 ++++-----
|
|
|
|
- src/pvrclient-mediaportal.h | 21 +++---
|
|
|
|
- 14 files changed, 168 insertions(+), 61 deletions(-)
|
|
|
|
-
|
|
|
|
-diff --git a/src/lib/tsreader/DeMultiplexer.cpp b/src/lib/tsreader/DeMultiplexer.cpp
|
|
|
|
-index 436e452..3d0d9a2 100644
|
|
|
|
---- a/src/lib/tsreader/DeMultiplexer.cpp
|
|
|
|
-+++ b/src/lib/tsreader/DeMultiplexer.cpp
|
|
|
|
-@@ -104,7 +104,7 @@ namespace MPTV
|
|
|
|
- if (m_filter.IsSeeking())
|
|
|
|
- return 0; // Ambass : to check
|
|
|
|
-
|
|
|
|
-- P8PLATFORM::CLockObject lock(m_sectionRead);
|
|
|
|
-+ std::lock_guard<std::mutex> lock(m_sectionRead);
|
|
|
|
- if (NULL == m_reader)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
-diff --git a/src/lib/tsreader/DeMultiplexer.h b/src/lib/tsreader/DeMultiplexer.h
|
|
|
|
-index c7cd577..72ed87d 100644
|
|
|
|
---- a/src/lib/tsreader/DeMultiplexer.h
|
|
|
|
-+++ b/src/lib/tsreader/DeMultiplexer.h
|
|
|
|
-@@ -37,7 +37,7 @@
|
|
|
|
- #include "PacketSync.h"
|
|
|
|
- #include "TSHeader.h"
|
|
|
|
- #include "PatParser.h"
|
|
|
|
--#include "p8-platform/threads/mutex.h"
|
|
|
|
-+#include <mutex>
|
|
|
|
-
|
|
|
|
- namespace MPTV
|
|
|
|
- {
|
|
|
|
-@@ -60,7 +60,7 @@ namespace MPTV
|
|
|
|
- private:
|
|
|
|
- unsigned long long m_LastDataFromRtsp;
|
|
|
|
- bool m_bEndOfFile;
|
|
|
|
-- P8PLATFORM::CMutex m_sectionRead;
|
|
|
|
-+ std::mutex m_sectionRead;
|
|
|
|
- FileReader* m_reader;
|
|
|
|
- CPatParser m_patParser;
|
|
|
|
- CTsReader& m_filter;
|
|
|
|
-diff --git a/src/lib/tsreader/FileReader.cpp b/src/lib/tsreader/FileReader.cpp
|
|
|
|
-index 73b23af..358b05f 100644
|
|
|
|
---- a/src/lib/tsreader/FileReader.cpp
|
|
|
|
-+++ b/src/lib/tsreader/FileReader.cpp
|
|
|
|
-@@ -35,7 +35,7 @@
|
|
|
|
- #include "FileReader.h"
|
|
|
|
- #include <kodi/General.h> //for kodi::Log
|
|
|
|
- #include "TSDebug.h"
|
|
|
|
--#include "p8-platform/threads/threads.h"
|
|
|
|
-+#include "os-dependent.h"
|
|
|
|
- #include <algorithm> //std::min, std::max
|
|
|
|
- #include "utils.h"
|
|
|
|
- #include <errno.h>
|
|
|
|
-diff --git a/src/lib/tsreader/MemoryBuffer.cpp b/src/lib/tsreader/MemoryBuffer.cpp
|
|
|
|
-index 0e736f2..b5400da 100644
|
|
|
|
---- a/src/lib/tsreader/MemoryBuffer.cpp
|
|
|
|
-+++ b/src/lib/tsreader/MemoryBuffer.cpp
|
|
|
|
-@@ -29,7 +29,7 @@
|
|
|
|
-
|
|
|
|
- #ifdef LIVE555
|
|
|
|
-
|
|
|
|
--#include "p8-platform/threads/mutex.h"
|
|
|
|
-+#include "os-dependent.h"
|
|
|
|
- #include "MemoryBuffer.h"
|
|
|
|
- #include <kodi/General.h> //for kodi::Log
|
|
|
|
- #include "TSDebug.h"
|
|
|
|
-@@ -56,7 +56,7 @@ bool CMemoryBuffer::IsRunning()
|
|
|
|
-
|
|
|
|
- void CMemoryBuffer::Clear()
|
|
|
|
- {
|
|
|
|
-- P8PLATFORM::CLockObject BufferLock(m_BufferLock);
|
|
|
|
-+ std::lock_guard<std::mutex> BufferLock(m_BufferLock);
|
|
|
|
- std::vector<BufferItem *>::iterator it = m_Array.begin();
|
|
|
|
-
|
|
|
|
- for (auto& item : m_Array)
|
|
|
|
-@@ -104,14 +104,17 @@ size_t CMemoryBuffer::ReadFromBuffer(unsigned char *pbData, size_t lDataLength)
|
|
|
|
- {
|
|
|
|
- if (!m_bRunning)
|
|
|
|
- return 0;
|
|
|
|
-- m_event.Wait(5000);
|
|
|
|
-+
|
|
|
|
-+ std::unique_lock<std::mutex> lock(m_BufferLock);
|
|
|
|
-+ m_condition.wait_for(lock, std::chrono::milliseconds(5000));
|
|
|
|
-+
|
|
|
|
- if (!m_bRunning)
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // kodi::Log(ADDON_LOG_DEBUG, "get..%d/%d", lDataLength, m_BytesInBuffer);
|
|
|
|
- size_t bytesWritten = 0;
|
|
|
|
-- P8PLATFORM::CLockObject BufferLock(m_BufferLock);
|
|
|
|
-+ std::lock_guard<std::mutex> BufferLock(m_BufferLock);
|
|
|
|
-
|
|
|
|
- while (bytesWritten < lDataLength)
|
|
|
|
- {
|
|
|
|
-@@ -172,7 +175,7 @@ long CMemoryBuffer::PutBuffer(unsigned char *pbData, size_t lDataLength)
|
|
|
|
- memcpy(item->data, pbData, lDataLength);
|
|
|
|
- bool sleep = false;
|
|
|
|
- {
|
|
|
|
-- P8PLATFORM::CLockObject BufferLock(m_BufferLock);
|
|
|
|
-+ std::lock_guard<std::mutex> BufferLock(m_BufferLock);
|
|
|
|
- m_Array.push_back(item);
|
|
|
|
- m_BytesInBuffer += lDataLength;
|
|
|
|
-
|
|
|
|
-@@ -192,7 +195,7 @@ long CMemoryBuffer::PutBuffer(unsigned char *pbData, size_t lDataLength)
|
|
|
|
- }
|
|
|
|
- if (m_BytesInBuffer > 0)
|
|
|
|
- {
|
|
|
|
-- m_event.Broadcast();
|
|
|
|
-+ m_condition.notify_one();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-diff --git a/src/lib/tsreader/MemoryBuffer.h b/src/lib/tsreader/MemoryBuffer.h
|
|
|
|
-index 080553b..4f8708f 100644
|
|
|
|
---- a/src/lib/tsreader/MemoryBuffer.h
|
|
|
|
-+++ b/src/lib/tsreader/MemoryBuffer.h
|
|
|
|
-@@ -30,7 +30,8 @@
|
|
|
|
-
|
|
|
|
- #ifdef LIVE555
|
|
|
|
-
|
|
|
|
--#include "p8-platform/threads/mutex.h"
|
|
|
|
-+#include <condition_variable>
|
|
|
|
-+#include <mutex>
|
|
|
|
- #include <vector>
|
|
|
|
-
|
|
|
|
- class CMemoryBuffer
|
|
|
|
-@@ -55,9 +56,9 @@ class CMemoryBuffer
|
|
|
|
-
|
|
|
|
- protected:
|
|
|
|
- std::vector<BufferItem *> m_Array;
|
|
|
|
-- P8PLATFORM::CMutex m_BufferLock;
|
|
|
|
-+ std::mutex m_BufferLock;
|
|
|
|
- size_t m_BytesInBuffer;
|
|
|
|
-- P8PLATFORM::CEvent m_event;
|
|
|
|
-+ std::condition_variable m_condition;
|
|
|
|
- bool m_bRunning;
|
|
|
|
- };
|
|
|
|
- #endif //LIVE555
|
|
|
|
-diff --git a/src/lib/tsreader/MemoryReader.h b/src/lib/tsreader/MemoryReader.h
|
|
|
|
-index fef4f98..288984b 100644
|
|
|
|
---- a/src/lib/tsreader/MemoryReader.h
|
|
|
|
-+++ b/src/lib/tsreader/MemoryReader.h
|
|
|
|
-@@ -32,6 +32,7 @@
|
|
|
|
-
|
|
|
|
- #include "FileReader.h"
|
|
|
|
- #include "MemoryBuffer.h"
|
|
|
|
-+#include "os-dependent.h"
|
|
|
|
-
|
|
|
|
- namespace MPTV
|
|
|
|
- {
|
|
|
|
-diff --git a/src/lib/tsreader/MemorySink.cpp b/src/lib/tsreader/MemorySink.cpp
|
|
|
|
-index dafef56..af8b74c 100644
|
|
|
|
---- a/src/lib/tsreader/MemorySink.cpp
|
|
|
|
-+++ b/src/lib/tsreader/MemorySink.cpp
|
|
|
|
-@@ -84,7 +84,7 @@ void CMemorySink::addData(unsigned char* data, size_t dataSize, struct timeval U
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-- P8PLATFORM::CLockObject BufferLock(m_BufferLock);
|
|
|
|
-+ std::lock_guard<std::mutex> BufferLock(m_BufferLock);
|
|
|
|
-
|
|
|
|
- m_bReEntrant = true;
|
|
|
|
- m_buffer.PutBuffer(data, dataSize);
|
|
|
|
-diff --git a/src/lib/tsreader/MemorySink.h b/src/lib/tsreader/MemorySink.h
|
|
|
|
-index cc0f3c8..22d91c6 100644
|
|
|
|
---- a/src/lib/tsreader/MemorySink.h
|
|
|
|
-+++ b/src/lib/tsreader/MemorySink.h
|
|
|
|
-@@ -35,7 +35,7 @@
|
|
|
|
- #endif
|
|
|
|
-
|
|
|
|
- #include "MemoryBuffer.h"
|
|
|
|
--#include "p8-platform/threads/mutex.h"
|
|
|
|
-+#include <mutex>
|
|
|
|
-
|
|
|
|
- class CMemorySink: public MediaSink
|
|
|
|
- {
|
|
|
|
-@@ -57,7 +57,7 @@ class CMemorySink: public MediaSink
|
|
|
|
- private: // redefined virtual functions:
|
|
|
|
- virtual Boolean continuePlaying();
|
|
|
|
-
|
|
|
|
-- P8PLATFORM::CMutex m_BufferLock;
|
|
|
|
-+ std::mutex m_BufferLock;
|
|
|
|
- unsigned char* m_pSubmitBuffer;
|
|
|
|
- int m_iSubmitBufferPos;
|
|
|
|
- bool m_bReEntrant;
|
|
|
|
-diff --git a/src/lib/tsreader/MepoRTSPClient.cpp b/src/lib/tsreader/MepoRTSPClient.cpp
|
|
|
|
-index ccd6761..688ae84 100644
|
|
|
|
---- a/src/lib/tsreader/MepoRTSPClient.cpp
|
|
|
|
-+++ b/src/lib/tsreader/MepoRTSPClient.cpp
|
|
|
|
-@@ -54,7 +54,7 @@ CRTSPClient::CRTSPClient()
|
|
|
|
- m_env = NULL;
|
|
|
|
- m_fDuration = 0.0f;
|
|
|
|
- m_url[0] = '\0';
|
|
|
|
-- m_bRunning = false;
|
|
|
|
-+ m_running = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CRTSPClient::~CRTSPClient()
|
|
|
|
-@@ -496,7 +496,9 @@ void CRTSPClient::StartBufferThread()
|
|
|
|
-
|
|
|
|
- if (!m_BufferThreadActive)
|
|
|
|
- {
|
|
|
|
-- CreateThread();
|
|
|
|
-+ m_running = true;
|
|
|
|
-+ m_thread = std::thread([&] { Process(); });
|
|
|
|
-+
|
|
|
|
- m_BufferThreadActive = true;
|
|
|
|
- }
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::StartBufferThread done");
|
|
|
|
-@@ -505,11 +507,12 @@ void CRTSPClient::StartBufferThread()
|
|
|
|
- void CRTSPClient::StopBufferThread()
|
|
|
|
- {
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::StopBufferThread");
|
|
|
|
-- m_bRunning = false;
|
|
|
|
-+ m_running = false;
|
|
|
|
- if (!m_BufferThreadActive)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
-- StopThread();
|
|
|
|
-+ if (m_thread.joinable())
|
|
|
|
-+ m_thread.join();
|
|
|
|
-
|
|
|
|
- m_BufferThreadActive = false;
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::StopBufferThread done");
|
|
|
|
-@@ -539,25 +542,22 @@ void CRTSPClient::FillBuffer(unsigned long byteCount)
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::Fillbuffer...%d/%d\n", byteCount, m_buffer->Size() );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--void *CRTSPClient::Process()
|
|
|
|
-+void CRTSPClient::Process()
|
|
|
|
- {
|
|
|
|
- m_BufferThreadActive = true;
|
|
|
|
-- m_bRunning = true;
|
|
|
|
-
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient:: thread started");
|
|
|
|
-
|
|
|
|
-- while (m_env != NULL && !IsStopped())
|
|
|
|
-+ while (m_env != NULL && m_running)
|
|
|
|
- {
|
|
|
|
- m_env->taskScheduler().doEventLoop();
|
|
|
|
-- if (m_bRunning == false)
|
|
|
|
-+ if (m_running == false)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient:: thread stopped");
|
|
|
|
-
|
|
|
|
- m_BufferThreadActive = false;
|
|
|
|
--
|
|
|
|
-- return NULL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- void CRTSPClient::Continue()
|
|
|
|
-@@ -582,8 +582,12 @@ bool CRTSPClient::Pause()
|
|
|
|
- if (m_ourClient != NULL && m_session != NULL)
|
|
|
|
- {
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::Pause() stopthread");
|
|
|
|
-- StopThread(10000); // Ambass : sometimes 100mS ( prev value ) is not enough and thread is not stopped.
|
|
|
|
-- // now stopping takes around 5 secs ?!?! why ????
|
|
|
|
-+ // Ambass : sometimes 100mS ( prev value ) is not enough and thread is not stopped.
|
|
|
|
-+ // now stopping takes around 5 secs ?!?! why ????
|
|
|
|
-+ m_running = false;
|
|
|
|
-+ if (m_thread.joinable())
|
|
|
|
-+ m_thread.join();
|
|
|
|
-+
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "CRTSPClient::Pause() thread stopped");
|
|
|
|
- RTSPClient* rtspClient=(RTSPClient*)m_ourClient;
|
|
|
|
- rtspClient->pauseMediaSession(*m_session);
|
|
|
|
-diff --git a/src/lib/tsreader/MepoRTSPClient.h b/src/lib/tsreader/MepoRTSPClient.h
|
|
|
|
-index bd6e578..9bb0421 100644
|
|
|
|
---- a/src/lib/tsreader/MepoRTSPClient.h
|
|
|
|
-+++ b/src/lib/tsreader/MepoRTSPClient.h
|
|
|
|
-@@ -31,7 +31,8 @@
|
|
|
|
-
|
|
|
|
- #ifdef LIVE555
|
|
|
|
-
|
|
|
|
--#include "p8-platform/threads/threads.h"
|
|
|
|
-+#include <atomic>
|
|
|
|
-+#include <thread>
|
|
|
|
- #include "lib/tsreader/MemoryBuffer.h"
|
|
|
|
-
|
|
|
|
- #include "liveMedia.hh"
|
|
|
|
-@@ -41,7 +42,7 @@
|
|
|
|
-
|
|
|
|
- #define RTSP_URL_BUFFERSIZE 2048
|
|
|
|
-
|
|
|
|
--class CRTSPClient: public P8PLATFORM::CThread
|
|
|
|
-+class CRTSPClient
|
|
|
|
- {
|
|
|
|
- public:
|
|
|
|
- CRTSPClient();
|
|
|
|
-@@ -101,7 +102,7 @@ class CRTSPClient: public P8PLATFORM::CThread
|
|
|
|
-
|
|
|
|
- // Thread
|
|
|
|
- private:
|
|
|
|
-- virtual void *Process(void);
|
|
|
|
-+ void Process();
|
|
|
|
- void StartBufferThread();
|
|
|
|
- void StopBufferThread();
|
|
|
|
- bool m_BufferThreadActive;
|
|
|
|
-@@ -113,5 +114,8 @@ class CRTSPClient: public P8PLATFORM::CThread
|
|
|
|
- bool m_bRunning;
|
|
|
|
- bool m_bPaused;
|
|
|
|
- char m_outFileName[1000];
|
|
|
|
-+
|
|
|
|
-+ std::atomic<bool> m_running = {false};
|
|
|
|
-+ std::thread m_thread;
|
|
|
|
- };
|
|
|
|
- #endif //LIVE555
|
|
|
|
-diff --git a/src/lib/tsreader/MultiFileReader.cpp b/src/lib/tsreader/MultiFileReader.cpp
|
|
|
|
-index 21fd7b2..5106418 100644
|
|
|
|
---- a/src/lib/tsreader/MultiFileReader.cpp
|
|
|
|
-+++ b/src/lib/tsreader/MultiFileReader.cpp
|
|
|
|
-@@ -35,17 +35,16 @@
|
|
|
|
- #include "MultiFileReader.h"
|
|
|
|
- #include <kodi/General.h> //for kodi::Log
|
|
|
|
- #include <kodi/Filesystem.h>
|
|
|
|
-+#include <kodi/tools/EndTime.h>
|
|
|
|
- #include "TSDebug.h"
|
|
|
|
- #include <string>
|
|
|
|
- #include "utils.h"
|
|
|
|
- #include <algorithm>
|
|
|
|
--#include "p8-platform/threads/threads.h"
|
|
|
|
- #include <inttypes.h>
|
|
|
|
-+#include "os-dependent.h"
|
|
|
|
-
|
|
|
|
- #include <thread>
|
|
|
|
-
|
|
|
|
--using namespace P8PLATFORM;
|
|
|
|
--
|
|
|
|
- //Maximum time in msec to wait for the buffer file to become available - Needed for DVB radio (this sometimes takes some time)
|
|
|
|
- #define MAX_BUFFER_TIMEOUT 1500
|
|
|
|
-
|
|
|
|
-@@ -121,12 +120,12 @@ namespace MPTV
|
|
|
|
- if (RefreshTSBufferFile() == S_FALSE)
|
|
|
|
- {
|
|
|
|
- // For radio the buffer sometimes needs some time to become available, so wait and try it more than once
|
|
|
|
-- P8PLATFORM::CTimeout timeout(MAX_BUFFER_TIMEOUT);
|
|
|
|
-+ kodi::tools::CEndTime timeout(MAX_BUFFER_TIMEOUT);
|
|
|
|
-
|
|
|
|
- do
|
|
|
|
- {
|
|
|
|
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
-- if (timeout.TimeLeft() == 0)
|
|
|
|
-+ if (timeout.MillisLeft() == 0)
|
|
|
|
- {
|
|
|
|
- kodi::Log(ADDON_LOG_ERROR, "MultiFileReader: timed out while waiting for buffer file to become available");
|
|
|
|
- kodi::QueueNotification(QUEUE_ERROR, "", "Time out while waiting for buffer file");
|
|
|
|
-diff --git a/src/os-dependent.h b/src/os-dependent.h
|
|
|
|
-index cdc6980..28c162c 100644
|
|
|
|
---- a/src/os-dependent.h
|
|
|
|
-+++ b/src/os-dependent.h
|
|
|
|
-@@ -11,6 +11,13 @@
|
|
|
|
-
|
|
|
|
- #if (defined(_WIN32) || defined(_WIN64))
|
|
|
|
-
|
|
|
|
-+#include <wchar.h>
|
|
|
|
-+
|
|
|
|
-+/* Handling of 2-byte Windows wchar strings */
|
|
|
|
-+#define WcsLen wcslen
|
|
|
|
-+#define WcsToMbs wcstombs
|
|
|
|
-+typedef wchar_t Wchar_t; /* sizeof(wchar_t) = 2 bytes on Windows */
|
|
|
|
-+
|
|
|
|
- #ifndef _SSIZE_T_DEFINED
|
|
|
|
- #ifdef _WIN64
|
|
|
|
- typedef __int64 ssize_t;
|
|
|
|
-@@ -20,20 +27,108 @@ typedef _W64 int ssize_t;
|
|
|
|
- #define _SSIZE_T_DEFINED
|
|
|
|
- #endif
|
|
|
|
-
|
|
|
|
-+/* Prevent deprecation warnings */
|
|
|
|
-+#define strnicmp _strnicmp
|
|
|
|
-+
|
|
|
|
-+#define PATH_SEPARATOR_CHAR '\\'
|
|
|
|
-+
|
|
|
|
- #else
|
|
|
|
-
|
|
|
|
- #if (defined(TARGET_LINUX) || defined(TARGET_DARWIN))
|
|
|
|
- #include <sys/types.h>
|
|
|
|
- #include <chrono>
|
|
|
|
- #include <cstring>
|
|
|
|
-+
|
|
|
|
-+#define strnicmp(X,Y,N) strncasecmp(X,Y,N)
|
|
|
|
-+
|
|
|
|
- inline unsigned long long GetTickCount64(void)
|
|
|
|
- {
|
|
|
|
- auto now = std::chrono::steady_clock::now();
|
|
|
|
- return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
|
|
|
- };
|
|
|
|
-+
|
|
|
|
-+#define PATH_SEPARATOR_CHAR '/'
|
|
|
|
-+
|
|
|
|
-+#if defined(__APPLE__)
|
|
|
|
-+// for HRESULT
|
|
|
|
-+#include <CoreFoundation/CFPlugInCOM.h>
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+/* Handling of 2-byte Windows wchar strings on non-Windows targets
|
|
|
|
-+ * Used by The MediaPortal and ForTheRecord pvr addons
|
|
|
|
-+ */
|
|
|
|
-+typedef uint16_t Wchar_t; /* sizeof(wchar_t) = 4 bytes on Linux, but the MediaPortal buffer files have 2-byte wchars */
|
|
|
|
-+
|
|
|
|
-+/* This is a replacement of the Windows wcslen() function which assumes that
|
|
|
|
-+ * wchar_t is a 2-byte character.
|
|
|
|
-+ * It is used for processing Windows wchar strings
|
|
|
|
-+ */
|
|
|
|
-+inline size_t WcsLen(const Wchar_t *str)
|
|
|
|
-+{
|
|
|
|
-+ const unsigned short *eos = (const unsigned short*)str;
|
|
|
|
-+ while( *eos++ ) ;
|
|
|
|
-+ return( (size_t)(eos - (const unsigned short*)str) -1);
|
|
|
|
-+};
|
|
|
|
-+
|
|
|
|
-+/* This is a replacement of the Windows wcstombs() function which assumes that
|
|
|
|
-+ * wchar_t is a 2-byte character.
|
|
|
|
-+ * It is used for processing Windows wchar strings
|
|
|
|
-+ */
|
|
|
|
-+inline size_t WcsToMbs(char *s, const Wchar_t *w, size_t n)
|
|
|
|
-+{
|
|
|
|
-+ size_t i = 0;
|
|
|
|
-+ const unsigned short *wc = (const unsigned short*) w;
|
|
|
|
-+ while(wc[i] && (i < n))
|
|
|
|
-+ {
|
|
|
|
-+ s[i] = wc[i];
|
|
|
|
-+ ++i;
|
|
|
|
-+ }
|
|
|
|
-+ if (i < n) s[i] = '\0';
|
|
|
|
-+
|
|
|
|
-+ return (i);
|
|
|
|
-+};
|
|
|
|
-+
|
|
|
|
- #endif /* TARGET_LINUX || TARGET_DARWIN */
|
|
|
|
-
|
|
|
|
- #endif
|
|
|
|
-
|
|
|
|
-+typedef long LONG;
|
|
|
|
-+#if !defined(__APPLE__)
|
|
|
|
-+typedef LONG HRESULT;
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+#ifndef FAILED
|
|
|
|
-+#define FAILED(Status) ((HRESULT)(Status)<0)
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+#ifndef SUCCEEDED
|
|
|
|
-+#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+#define _FILE_OFFSET_BITS 64
|
|
|
|
-+#define FILE_BEGIN 0
|
|
|
|
-+#define FILE_CURRENT 1
|
|
|
|
-+#define FILE_END 2
|
|
|
|
-+
|
|
|
|
-+#ifndef S_OK
|
|
|
|
-+#define S_OK 0L
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+#ifndef S_FALSE
|
|
|
|
-+#define S_FALSE 1L
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+// Error codes
|
|
|
|
-+#define ERROR_FILENAME_EXCED_RANGE 206L
|
|
|
|
-+#define ERROR_INVALID_NAME 123L
|
|
|
|
-+
|
|
|
|
-+#ifndef E_OUTOFMEMORY
|
|
|
|
-+#define E_OUTOFMEMORY 0x8007000EL
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
-+#ifndef E_FAIL
|
|
|
|
-+#define E_FAIL 0x8004005EL
|
|
|
|
-+#endif
|
|
|
|
-+
|
|
|
|
- // Additional typedefs
|
|
|
|
- typedef uint8_t byte;
|
|
|
|
-diff --git a/src/pvrclient-mediaportal.cpp b/src/pvrclient-mediaportal.cpp
|
|
|
|
-index 851b940..c1052e3 100644
|
|
|
|
---- a/src/pvrclient-mediaportal.cpp
|
|
|
|
-+++ b/src/pvrclient-mediaportal.cpp
|
|
|
|
-@@ -28,8 +28,6 @@
|
|
|
|
- #include <kodi/General.h>
|
|
|
|
- #include <kodi/Filesystem.h>
|
|
|
|
-
|
|
|
|
--#include <thread>
|
|
|
|
--
|
|
|
|
- using namespace kodi::tools;
|
|
|
|
- using namespace std;
|
|
|
|
- using namespace MPTV;
|
|
|
|
-@@ -70,7 +68,6 @@ cPVRClientMediaPortal::cPVRClientMediaPortal(KODI_HANDLE instance, const std::st
|
|
|
|
- m_BackendTime = 0;
|
|
|
|
- m_tsreader = NULL;
|
|
|
|
- m_genretable = NULL;
|
|
|
|
-- m_iLastRecordingUpdate = 0;
|
|
|
|
- m_signalStateCounter = 0;
|
|
|
|
- m_iSignal = 0;
|
|
|
|
- m_iSNR = 0;
|
|
|
|
-@@ -99,7 +96,7 @@ string cPVRClientMediaPortal::SendCommand(const char* command)
|
|
|
|
-
|
|
|
|
- string cPVRClientMediaPortal::SendCommand(const string& command)
|
|
|
|
- {
|
|
|
|
-- P8PLATFORM::CLockObject critsec(m_mutex);
|
|
|
|
-+ std::lock_guard<std::mutex> critsec(m_mutex);
|
|
|
|
-
|
|
|
|
- if ( !m_tcpclient->send(command) )
|
|
|
|
- {
|
|
|
|
-@@ -174,10 +171,10 @@ ADDON_STATUS cPVRClientMediaPortal::TryConnect()
|
|
|
|
- case PVR_CONNECTION_STATE_SERVER_UNREACHABLE:
|
|
|
|
- kodi::Log(ADDON_LOG_ERROR, "Could not connect to MediaPortal TV Server backend.");
|
|
|
|
- // Start background thread for connecting to the backend
|
|
|
|
-- if (!IsRunning())
|
|
|
|
-+ if (!m_running)
|
|
|
|
- {
|
|
|
|
-- kodi::Log(ADDON_LOG_INFO, "Waiting for a connection in the background.");
|
|
|
|
-- CreateThread();
|
|
|
|
-+ m_running = true;
|
|
|
|
-+ m_thread = std::thread([&] { Process(); });
|
|
|
|
- }
|
|
|
|
- return ADDON_STATUS_LOST_CONNECTION;
|
|
|
|
- case PVR_CONNECTION_STATE_CONNECTING:
|
|
|
|
-@@ -190,7 +187,7 @@ ADDON_STATUS cPVRClientMediaPortal::TryConnect()
|
|
|
|
-
|
|
|
|
- PVR_CONNECTION_STATE cPVRClientMediaPortal::Connect(bool updateConnectionState)
|
|
|
|
- {
|
|
|
|
-- P8PLATFORM::CLockObject critsec(m_connectionMutex);
|
|
|
|
-+ std::lock_guard<std::mutex> critsec(m_connectionMutex);
|
|
|
|
-
|
|
|
|
- string result;
|
|
|
|
-
|
|
|
|
-@@ -317,9 +314,11 @@ void cPVRClientMediaPortal::Disconnect()
|
|
|
|
-
|
|
|
|
- kodi::Log(ADDON_LOG_INFO, "Disconnect");
|
|
|
|
-
|
|
|
|
-- if (IsRunning())
|
|
|
|
-+ if (m_running)
|
|
|
|
- {
|
|
|
|
-- StopThread(1000);
|
|
|
|
-+ m_running = false;
|
|
|
|
-+ if (m_thread.joinable())
|
|
|
|
-+ m_thread.join();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (m_tcpclient->is_valid() && m_bTimeShiftStarted)
|
|
|
|
-@@ -361,14 +360,14 @@ bool cPVRClientMediaPortal::IsUp()
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--void* cPVRClientMediaPortal::Process(void)
|
|
|
|
-+void cPVRClientMediaPortal::Process()
|
|
|
|
- {
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "Background thread started.");
|
|
|
|
-
|
|
|
|
- bool keepWaiting = true;
|
|
|
|
- PVR_CONNECTION_STATE state;
|
|
|
|
-
|
|
|
|
-- while (!IsStopped() && keepWaiting)
|
|
|
|
-+ while (m_running && keepWaiting)
|
|
|
|
- {
|
|
|
|
- state = Connect(false);
|
|
|
|
-
|
|
|
|
-@@ -396,8 +395,6 @@ void* cPVRClientMediaPortal::Process(void)
|
|
|
|
- SetConnectionState(state);
|
|
|
|
-
|
|
|
|
- kodi::Log(ADDON_LOG_DEBUG, "Background thread finished.");
|
|
|
|
--
|
|
|
|
-- return NULL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-@@ -1188,7 +1185,7 @@ PVR_ERROR cPVRClientMediaPortal::GetRecordings(bool deleted, kodi::addon::PVRRec
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-- m_iLastRecordingUpdate = P8PLATFORM::GetTimeMs();
|
|
|
|
-+ m_iLastRecordingUpdate = std::chrono::system_clock::now();
|
|
|
|
-
|
|
|
|
- return PVR_ERROR_NO_ERROR;
|
|
|
|
- }
|
|
|
|
-@@ -1383,7 +1380,7 @@ PVR_ERROR cPVRClientMediaPortal::GetTimers(kodi::addon::PVRTimersResultSet& resu
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-- if ( P8PLATFORM::GetTimeMs() > m_iLastRecordingUpdate + 15000)
|
|
|
|
-+ if ( std::chrono::system_clock::now() > m_iLastRecordingUpdate + std::chrono::milliseconds(15000))
|
|
|
|
- {
|
|
|
|
- kodi::addon::CInstancePVRClient::TriggerRecordingUpdate();
|
|
|
|
- }
|
|
|
|
-diff --git a/src/pvrclient-mediaportal.h b/src/pvrclient-mediaportal.h
|
|
|
|
-index 3087634..e5da832 100644
|
|
|
|
---- a/src/pvrclient-mediaportal.h
|
|
|
|
-+++ b/src/pvrclient-mediaportal.h
|
|
|
|
-@@ -7,6 +7,10 @@
|
|
|
|
-
|
|
|
|
- #pragma once
|
|
|
|
-
|
|
|
|
-+#include <atomic>
|
|
|
|
-+#include <chrono>
|
|
|
|
-+#include <mutex>
|
|
|
|
-+#include <thread>
|
|
|
|
- #include <vector>
|
|
|
|
-
|
|
|
|
- /* Master defines for client control */
|
|
|
|
-@@ -17,8 +21,6 @@
|
|
|
|
- #include "Cards.h"
|
|
|
|
- #include "epg.h"
|
|
|
|
- #include "channels.h"
|
|
|
|
--#include "p8-platform/threads/mutex.h"
|
|
|
|
--#include "p8-platform/threads/threads.h"
|
|
|
|
-
|
|
|
|
- /* Use a forward declaration here. Including RTSPClient.h via TSReader.h at this point gives compile errors */
|
|
|
|
- namespace MPTV
|
|
|
|
-@@ -28,9 +30,7 @@ namespace MPTV
|
|
|
|
- class cRecording;
|
|
|
|
-
|
|
|
|
- class ATTRIBUTE_HIDDEN cPVRClientMediaPortal
|
|
|
|
-- : public kodi::addon::CInstancePVRClient,
|
|
|
|
-- public P8PLATFORM::PreventCopy,
|
|
|
|
-- public P8PLATFORM::CThread
|
|
|
|
-+ : public kodi::addon::CInstancePVRClient
|
|
|
|
- {
|
|
|
|
- public:
|
|
|
|
- /* Class interface */
|
|
|
|
-@@ -110,7 +110,7 @@ class ATTRIBUTE_HIDDEN cPVRClientMediaPortal
|
|
|
|
-
|
|
|
|
- private:
|
|
|
|
- /* TVServerKodi Listening Thread */
|
|
|
|
-- void* Process(void);
|
|
|
|
-+ void Process();
|
|
|
|
- PVR_CONNECTION_STATE Connect(bool updateConnectionState = true);
|
|
|
|
-
|
|
|
|
- void LoadGenreTable(void);
|
|
|
|
-@@ -134,9 +134,9 @@ class ATTRIBUTE_HIDDEN cPVRClientMediaPortal
|
|
|
|
- time_t m_BackendTime;
|
|
|
|
- CCards m_cCards;
|
|
|
|
- CGenreTable* m_genretable;
|
|
|
|
-- P8PLATFORM::CMutex m_mutex;
|
|
|
|
-- P8PLATFORM::CMutex m_connectionMutex;
|
|
|
|
-- int64_t m_iLastRecordingUpdate;
|
|
|
|
-+ std::mutex m_mutex;
|
|
|
|
-+ std::mutex m_connectionMutex;
|
|
|
|
-+ std::chrono::system_clock::time_point m_iLastRecordingUpdate;
|
|
|
|
- MPTV::CTsReader* m_tsreader;
|
|
|
|
- std::map<int,cChannel> m_channels;
|
|
|
|
- int m_signalStateCounter;
|
|
|
|
-@@ -145,6 +145,9 @@ class ATTRIBUTE_HIDDEN cPVRClientMediaPortal
|
|
|
|
-
|
|
|
|
- cRecording* m_lastSelectedRecording;
|
|
|
|
-
|
|
|
|
-+ std::atomic<bool> m_running = {false};
|
|
|
|
-+ std::thread m_thread;
|
|
|
|
-+
|
|
|
|
- //Used for TV Server communication:
|
|
|
|
- std::string SendCommand(const char* command);
|
|
|
|
- std::string SendCommand(const std::string& command);
|
|
|