Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
b25 patch for BonDriverProxy_Linux
diff --git a/+b25ini.txt b/+b25ini.txt
new file mode 100644
--- /dev/null
+++ b/+b25ini.txt
@@ -0,0 +1,14 @@
+; b25デコーダを有効にするには、
+; BonDriverProxy[Ex].iniに以下の設定を追加してください。
+
+[OPTION]
+
+; b25デコーダ(libarib25.dll)を使う=1 使わない=0(デフォルト)
+B25_DECODE = 1
+
+; b25デコーダでnullパケットを削除する=1 しない=0(デフォルト)
+B25_STRIP = 1
+
+; b25デコーダでEMMを処理する=1 しない=0(デフォルト)
+B25_EMM_PROC = 1
+
diff --git a/BonDriverProxy/B25Decoder.cpp b/BonDriverProxy/B25Decoder.cpp
new file mode 100644
--- /dev/null
+++ b/BonDriverProxy/B25Decoder.cpp
@@ -0,0 +1,307 @@
+#include "B25Decoder.h"
+
+#include <ctime>
+#include <cstring>
+#include <cassert>
+
+#ifdef _MSC_VER
+
+#define CPP11
+#include <mutex>
+#include <cstdarg>
+
+#include "arib_std_b25.h"
+#include "arib_std_b25_error_code.h"
+
+enum log_prio {
+ LOG_EMERG,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG
+};
+
+static void syslog(int prio, const char *fmt, ...) {
+ char log[256];
+ va_list ap;
+ va_start(ap, fmt);
+ ::wvsprintfA(log, fmt, ap);
+ va_end(ap);
+ ::OutputDebugStringA(log);
+}
+
+#else
+
+#include <syslog.h>
+#include <arib25/arib_std_b25.h>
+#include <arib25/arib_std_b25_error_code.h>
+
+#define nullptr 0
+
+#endif
+
+#define RETRY_INTERVAL 10 // 10sec interval
+
+struct B25Decoder::impl {
+ impl()
+ : _bcas(nullptr)
+ , _b25(nullptr)
+ , _data(nullptr)
+ , _reference_count(1) {
+ }
+ ~impl();
+
+ int init();
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+
+#ifdef CPP11
+ std::mutex _mtx;
+#endif
+ B_CAS_CARD *_bcas;
+ ARIB_STD_B25 *_b25;
+ BYTE *_data;
+ time_t _errtime;
+
+ int _reference_count;
+ impl *add_reference() {
+ if (this)
+ ++_reference_count;
+ return this;
+ }
+ void release_reference() {
+ if (this) {
+ if (--_reference_count <= 0)
+ delete this;
+ }
+ }
+};
+
+int B25Decoder::strip = 1;
+int B25Decoder::emm_proc = 0;
+int B25Decoder::multi2_round = 4;
+
+B25Decoder::B25Decoder() : _pimpl(nullptr) {
+}
+
+B25Decoder::~B25Decoder() {
+ _pimpl->release_reference();
+}
+
+B25Decoder::B25Decoder(const B25Decoder &ref) {
+ _pimpl = ref._pimpl->add_reference();
+}
+
+B25Decoder &B25Decoder::operator=(const B25Decoder &rhs) {
+ rhs._pimpl->add_reference();
+ _pimpl->release_reference();
+ _pimpl = rhs._pimpl;
+ return *this;
+}
+
+B25Decoder::impl::~impl() {
+ delete[] _data;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ _b25->release(_b25);
+
+ if (_bcas)
+ _bcas->release(_bcas);
+
+ syslog(LOG_DEBUG, "B25Decoder::dtor() : end");
+}
+
+void B25Decoder::release() {
+ _pimpl->release_reference();
+ _pimpl = nullptr;
+}
+
+int B25Decoder::init() {
+ if (!_pimpl)
+ _pimpl = new impl;
+
+ return _pimpl->init();
+}
+
+int B25Decoder::impl::init() {
+ int rc;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ return -2;
+
+ _bcas = create_b_cas_card();
+ if (!_bcas)
+ return -3;
+
+ rc = _bcas->init(_bcas);
+ if (rc < 0) {
+ syslog(LOG_ERR, "B25Decoder::init() : bcas init error / rc(%d)", rc);
+ rc = -4;
+ goto err;
+ }
+
+ _b25 = create_arib_std_b25();
+ if (!_b25) {
+ rc = -5;
+ goto err;
+ }
+
+ if (_b25->set_b_cas_card(_b25, _bcas) < 0) {
+ rc = -6;
+ goto err;
+ }
+
+ _b25->set_strip(_b25, strip);
+ _b25->set_emm_proc(_b25, emm_proc);
+ _b25->set_multi2_round(_b25, multi2_round);
+
+ syslog(LOG_DEBUG, "B25Decoder::init() : success");
+ return 0; // success
+
+err:
+ if (_b25) {
+ _b25->release(_b25);
+ _b25 = nullptr;
+ }
+
+ if (_bcas) {
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+
+ syslog(LOG_ERR, "B25Decoder::init() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return rc; // error
+}
+
+void B25Decoder::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_pimpl) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+
+ _pimpl->decode(pSrc, dwSrcSize, ppDst, pdwDstSize);
+}
+
+void B25Decoder::impl::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_b25) {
+ time_t now = time(nullptr);
+ if (difftime(now, _errtime) > RETRY_INTERVAL) {
+ if (init() < 0)
+ _errtime = now;
+ }
+
+ if (!_b25) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+ }
+
+ delete[] _data;
+ _data = nullptr;
+
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ const int rc = _b25->put(_b25, &buf);
+ if (rc < 0) {
+ if (rc >= ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+ else {
+ BYTE *p = nullptr;
+ _b25->withdraw(_b25, &buf); // withdraw src buffer
+ if (buf.size > 0) {
+ syslog(LOG_ERR, "B25Decoder::decode() : error / withdraw size(%u)", buf.size);
+ p = new BYTE[buf.size + dwSrcSize];
+ }
+
+ if (p) {
+ std::memcpy(p, buf.data, buf.size);
+ std::memcpy(p + buf.size, pSrc, dwSrcSize);
+ *ppDst = p;
+ *pdwDstSize = buf.size + dwSrcSize;
+ _data = p;
+ }
+ else {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+
+ if (rc == ARIB_STD_B25_ERROR_ECM_PROC_FAILURE) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+ }
+ syslog(LOG_ERR, "B25Decoder::decode() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return; // error
+ }
+
+ _b25->get(_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return; // success
+}
+
+void B25Decoder::reset() {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->reset(_pimpl->_b25);
+}
+
+int B25Decoder::put(BYTE *pSrc, DWORD dwSrcSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ return _pimpl->_b25->put(_pimpl->_b25, &buf);
+}
+
+int B25Decoder::get(BYTE **ppDst, DWORD *pdwDstSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ int rc = _pimpl->_b25->get(_pimpl->_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return rc;
+}
+
+int B25Decoder::flush() {
+ if (_pimpl && _pimpl->_b25)
+ return _pimpl->_b25->flush(_pimpl->_b25);
+ return 0;
+}
+
+void B25Decoder::setemm(bool flag) {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->set_emm_proc(_pimpl->_b25, flag ? 1 : 0);
+}
diff --git a/BonDriverProxy/B25Decoder.h b/BonDriverProxy/B25Decoder.h
new file mode 100644
--- /dev/null
+++ b/BonDriverProxy/B25Decoder.h
@@ -0,0 +1,41 @@
+#pragma once
+#ifndef _B25DECODER_H
+#define _B25DECODER_H
+
+// for BYTE, DWORD
+#ifdef _MSC_VER
+#include <windows.h>
+#else
+#include "typedef.h" // in BonDriverProxy_Linux source tree
+#endif
+
+class B25Decoder {
+ public:
+ B25Decoder();
+ ~B25Decoder();
+ B25Decoder(const B25Decoder &ref);
+ B25Decoder &operator=(const B25Decoder &rhs);
+
+ int init();
+ void release();
+
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+ void setemm(bool flag);
+
+ // libarib25 wrapper
+ void reset();
+ int put(BYTE *pSrc, DWORD dwSrcSize);
+ int get(BYTE **ppDst, DWORD *pdwDstSize);
+ int flush();
+
+ // initialize parameter
+ static int strip;
+ static int emm_proc;
+ static int multi2_round;
+
+ private:
+ struct impl;
+ struct impl *_pimpl;
+};
+
+#endif // _B25DECODER_H
diff --git a/BonDriverProxy/BonDriverProxy.cpp b/BonDriverProxy/BonDriverProxy.cpp
--- a/BonDriverProxy/BonDriverProxy.cpp
+++ b/BonDriverProxy/BonDriverProxy.cpp
@@ -1,6 +1,10 @@
#define _CRT_SECURE_NO_WARNINGS
#include "BonDriverProxy.h"
+#ifdef HAVE_LIBARIB25
+static BOOL g_b25_enable;
+#endif
+
#define STRICT_LOCK
#if _DEBUG
@@ -98,6 +102,12 @@
else
g_ThreadExecutionState = ES_SYSTEM_REQUIRED | ES_CONTINUOUS;
+#ifdef HAVE_LIBARIB25
+ g_b25_enable = GetPrivateProfileIntA("OPTION", "B25_DECODE", 0, szIniPath) != 0;
+ B25Decoder::strip = GetPrivateProfileIntA("OPTION", "B25_STRIP", 0, szIniPath);
+ B25Decoder::emm_proc = GetPrivateProfileIntA("OPTION", "B25_EMM_PROC", 0, szIniPath);
+ //B25Decoder::multi2_round = GetPrivateProfileIntA("OPTION", "B25_MULTI2ROUND", 4, szIniPath);
+#endif
return 0;
}
@@ -738,6 +748,10 @@
m_pTsReaderArg = new stTsReaderArg();
m_pTsReaderArg->TsReceiversList.push_back(this);
m_pTsReaderArg->pIBon = m_pIBon;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ m_pTsReaderArg->b25.init();
+#endif
m_hTsRead = ::CreateThread(NULL, 0, cProxyServer::TsReader, m_pTsReaderArg, 0, NULL);
if (m_hTsRead == NULL)
{
@@ -1012,12 +1026,24 @@
LOCK(TsLock);
if ((((now = ::GetTickCount()) - before) >= 1000) || ChannelChanged)
{
+#ifdef HAVE_LIBARIB25
+ if (ChannelChanged)
+ pArg->b25.reset();
+#endif
fSignalLevel = pIBon->GetSignalLevel();
before = now;
ChannelChanged = FALSE;
}
if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0))
{
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ {
+ pArg->b25.decode(pBuf, dwSize, &pBuf, &dwSize);
+ if (dwSize == 0)
+ goto next;
+ }
+#endif
if ((pos + dwSize) < TsPacketBufSize)
{
::memcpy(&pTsBuf[pos], pBuf, dwSize);
@@ -1071,6 +1097,9 @@
}
}
}
+#ifdef HAVE_LIBARIB25
+ next:
+#endif
if (dwRemain == 0)
::Sleep(WAIT_TIME);
}
diff --git a/BonDriverProxy/BonDriverProxy.h b/BonDriverProxy/BonDriverProxy.h
--- a/BonDriverProxy/BonDriverProxy.h
+++ b/BonDriverProxy/BonDriverProxy.h
@@ -14,6 +14,10 @@
#undef HAVE_UI
#endif
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
+
#if _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
@@ -53,6 +57,9 @@
std::list<cProxyServer *> TsReceiversList;
std::list<cProxyServer *> WaitExclusivePrivList;
cCriticalSection TsLock;
+#ifdef HAVE_LIBARIB25
+ B25Decoder b25;
+#endif
stTsReaderArg()
{
StopTsRead = FALSE;
diff --git a/BonDriverProxy/BonDriverProxy.vcxproj b/BonDriverProxy/BonDriverProxy.vcxproj
--- a/BonDriverProxy/BonDriverProxy.vcxproj
+++ b/BonDriverProxy/BonDriverProxy.vcxproj
@@ -150,14 +150,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SVC|Win32'">
@@ -166,14 +166,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -182,14 +182,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SVC|x64'">
@@ -198,14 +198,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -216,16 +216,16 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SVC|Win32'">
@@ -236,16 +236,16 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -255,9 +255,9 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
@@ -265,7 +265,7 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SVC|x64'">
@@ -275,9 +275,9 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
@@ -285,11 +285,12 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="BonDriverProxy.cpp" />
+ <ClCompile Include="B25Decoder.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\inc\BdpPacket.h" />
@@ -298,6 +299,7 @@
<ClInclude Include="..\inc\IBonDriver2.h" />
<ClInclude Include="..\inc\IBonDriver3.h" />
<ClInclude Include="BonDriverProxy.h" />
+ <ClInclude Include="B25Decoder.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BonDriverProxy.rc" />
diff --git a/BonDriverProxy/BonDriverProxy.vcxproj.filters b/BonDriverProxy/BonDriverProxy.vcxproj.filters
--- a/BonDriverProxy/BonDriverProxy.vcxproj.filters
+++ b/BonDriverProxy/BonDriverProxy.vcxproj.filters
@@ -18,6 +18,9 @@
<ClCompile Include="BonDriverProxy.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
+ <ClCompile Include="B25Decoder.cpp">
+ <Filter>ソース ファイル</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\inc\IBonDriver2.h">
@@ -38,6 +41,9 @@
<ClInclude Include="..\inc\BdpPacket.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
+ <ClInclude Include="B25Decoder.h">
+ <Filter>ヘッダー ファイル</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BonDriverProxy.rc">
diff --git a/+b25ini.txt b/+b25ini.txt
new file mode 100644
--- /dev/null
+++ b/+b25ini.txt
@@ -0,0 +1,14 @@
+; b25デコーダを有効にするには、
+; BonDriverProxy[Ex].iniに以下の設定を追加してください。
+
+[OPTION]
+
+; b25デコーダ(libarib25.dll)を使う=1 使わない=0(デフォルト)
+B25_DECODE = 1
+
+; b25デコーダでnullパケットを削除する=1 しない=0(デフォルト)
+B25_STRIP = 1
+
+; b25デコーダでEMMを処理する=1 しない=0(デフォルト)
+B25_EMM_PROC = 1
+
diff --git a/BonDriverProxyEx/B25Decoder.cpp b/BonDriverProxyEx/B25Decoder.cpp
new file mode 100644
--- /dev/null
+++ b/BonDriverProxyEx/B25Decoder.cpp
@@ -0,0 +1,307 @@
+#include "B25Decoder.h"
+
+#include <ctime>
+#include <cstring>
+#include <cassert>
+
+#ifdef _MSC_VER
+
+#define CPP11
+#include <mutex>
+#include <cstdarg>
+
+#include "arib_std_b25.h"
+#include "arib_std_b25_error_code.h"
+
+enum log_prio {
+ LOG_EMERG,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG
+};
+
+static void syslog(int prio, const char *fmt, ...) {
+ char log[256];
+ va_list ap;
+ va_start(ap, fmt);
+ ::wvsprintfA(log, fmt, ap);
+ va_end(ap);
+ ::OutputDebugStringA(log);
+}
+
+#else
+
+#include <syslog.h>
+#include <arib25/arib_std_b25.h>
+#include <arib25/arib_std_b25_error_code.h>
+
+#define nullptr 0
+
+#endif
+
+#define RETRY_INTERVAL 10 // 10sec interval
+
+struct B25Decoder::impl {
+ impl()
+ : _bcas(nullptr)
+ , _b25(nullptr)
+ , _data(nullptr)
+ , _reference_count(1) {
+ }
+ ~impl();
+
+ int init();
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+
+#ifdef CPP11
+ std::mutex _mtx;
+#endif
+ B_CAS_CARD *_bcas;
+ ARIB_STD_B25 *_b25;
+ BYTE *_data;
+ time_t _errtime;
+
+ int _reference_count;
+ impl *add_reference() {
+ if (this)
+ ++_reference_count;
+ return this;
+ }
+ void release_reference() {
+ if (this) {
+ if (--_reference_count <= 0)
+ delete this;
+ }
+ }
+};
+
+int B25Decoder::strip = 1;
+int B25Decoder::emm_proc = 0;
+int B25Decoder::multi2_round = 4;
+
+B25Decoder::B25Decoder() : _pimpl(nullptr) {
+}
+
+B25Decoder::~B25Decoder() {
+ _pimpl->release_reference();
+}
+
+B25Decoder::B25Decoder(const B25Decoder &ref) {
+ _pimpl = ref._pimpl->add_reference();
+}
+
+B25Decoder &B25Decoder::operator=(const B25Decoder &rhs) {
+ rhs._pimpl->add_reference();
+ _pimpl->release_reference();
+ _pimpl = rhs._pimpl;
+ return *this;
+}
+
+B25Decoder::impl::~impl() {
+ delete[] _data;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ _b25->release(_b25);
+
+ if (_bcas)
+ _bcas->release(_bcas);
+
+ syslog(LOG_DEBUG, "B25Decoder::dtor() : end");
+}
+
+void B25Decoder::release() {
+ _pimpl->release_reference();
+ _pimpl = nullptr;
+}
+
+int B25Decoder::init() {
+ if (!_pimpl)
+ _pimpl = new impl;
+
+ return _pimpl->init();
+}
+
+int B25Decoder::impl::init() {
+ int rc;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ return -2;
+
+ _bcas = create_b_cas_card();
+ if (!_bcas)
+ return -3;
+
+ rc = _bcas->init(_bcas);
+ if (rc < 0) {
+ syslog(LOG_ERR, "B25Decoder::init() : bcas init error / rc(%d)", rc);
+ rc = -4;
+ goto err;
+ }
+
+ _b25 = create_arib_std_b25();
+ if (!_b25) {
+ rc = -5;
+ goto err;
+ }
+
+ if (_b25->set_b_cas_card(_b25, _bcas) < 0) {
+ rc = -6;
+ goto err;
+ }
+
+ _b25->set_strip(_b25, strip);
+ _b25->set_emm_proc(_b25, emm_proc);
+ _b25->set_multi2_round(_b25, multi2_round);
+
+ syslog(LOG_DEBUG, "B25Decoder::init() : success");
+ return 0; // success
+
+err:
+ if (_b25) {
+ _b25->release(_b25);
+ _b25 = nullptr;
+ }
+
+ if (_bcas) {
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+
+ syslog(LOG_ERR, "B25Decoder::init() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return rc; // error
+}
+
+void B25Decoder::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_pimpl) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+
+ _pimpl->decode(pSrc, dwSrcSize, ppDst, pdwDstSize);
+}
+
+void B25Decoder::impl::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_b25) {
+ time_t now = time(nullptr);
+ if (difftime(now, _errtime) > RETRY_INTERVAL) {
+ if (init() < 0)
+ _errtime = now;
+ }
+
+ if (!_b25) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+ }
+
+ delete[] _data;
+ _data = nullptr;
+
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ const int rc = _b25->put(_b25, &buf);
+ if (rc < 0) {
+ if (rc >= ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+ else {
+ BYTE *p = nullptr;
+ _b25->withdraw(_b25, &buf); // withdraw src buffer
+ if (buf.size > 0) {
+ syslog(LOG_ERR, "B25Decoder::decode() : error / withdraw size(%u)", buf.size);
+ p = new BYTE[buf.size + dwSrcSize];
+ }
+
+ if (p) {
+ std::memcpy(p, buf.data, buf.size);
+ std::memcpy(p + buf.size, pSrc, dwSrcSize);
+ *ppDst = p;
+ *pdwDstSize = buf.size + dwSrcSize;
+ _data = p;
+ }
+ else {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+
+ if (rc == ARIB_STD_B25_ERROR_ECM_PROC_FAILURE) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+ }
+ syslog(LOG_ERR, "B25Decoder::decode() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return; // error
+ }
+
+ _b25->get(_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return; // success
+}
+
+void B25Decoder::reset() {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->reset(_pimpl->_b25);
+}
+
+int B25Decoder::put(BYTE *pSrc, DWORD dwSrcSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ return _pimpl->_b25->put(_pimpl->_b25, &buf);
+}
+
+int B25Decoder::get(BYTE **ppDst, DWORD *pdwDstSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ int rc = _pimpl->_b25->get(_pimpl->_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return rc;
+}
+
+int B25Decoder::flush() {
+ if (_pimpl && _pimpl->_b25)
+ return _pimpl->_b25->flush(_pimpl->_b25);
+ return 0;
+}
+
+void B25Decoder::setemm(bool flag) {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->set_emm_proc(_pimpl->_b25, flag ? 1 : 0);
+}
diff --git a/BonDriverProxyEx/B25Decoder.h b/BonDriverProxyEx/B25Decoder.h
new file mode 100644
--- /dev/null
+++ b/BonDriverProxyEx/B25Decoder.h
@@ -0,0 +1,41 @@
+#pragma once
+#ifndef _B25DECODER_H
+#define _B25DECODER_H
+
+// for BYTE, DWORD
+#ifdef _MSC_VER
+#include <windows.h>
+#else
+#include "typedef.h" // in BonDriverProxy_Linux source tree
+#endif
+
+class B25Decoder {
+ public:
+ B25Decoder();
+ ~B25Decoder();
+ B25Decoder(const B25Decoder &ref);
+ B25Decoder &operator=(const B25Decoder &rhs);
+
+ int init();
+ void release();
+
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+ void setemm(bool flag);
+
+ // libarib25 wrapper
+ void reset();
+ int put(BYTE *pSrc, DWORD dwSrcSize);
+ int get(BYTE **ppDst, DWORD *pdwDstSize);
+ int flush();
+
+ // initialize parameter
+ static int strip;
+ static int emm_proc;
+ static int multi2_round;
+
+ private:
+ struct impl;
+ struct impl *_pimpl;
+};
+
+#endif // _B25DECODER_H
diff --git a/BonDriverProxyEx/BonDriverProxyEx.cpp b/BonDriverProxyEx/BonDriverProxyEx.cpp
--- a/BonDriverProxyEx/BonDriverProxyEx.cpp
+++ b/BonDriverProxyEx/BonDriverProxyEx.cpp
@@ -1,6 +1,10 @@
#define _CRT_SECURE_NO_WARNINGS
#include "BonDriverProxyEx.h"
+#ifdef HAVE_LIBARIB25
+static BOOL g_b25_enable;
+#endif
+
#if _DEBUG
#define DETAILLOG 0
#define DETAILLOG2 1
@@ -168,6 +172,12 @@
else
g_ThreadExecutionState = ES_SYSTEM_REQUIRED | ES_CONTINUOUS;
+#ifdef HAVE_LIBARIB25
+ g_b25_enable = GetPrivateProfileIntA("OPTION", "B25_DECODE", 0, szIniPath) != 0;
+ B25Decoder::strip = GetPrivateProfileIntA("OPTION", "B25_STRIP", 0, szIniPath);
+ B25Decoder::emm_proc = GetPrivateProfileIntA("OPTION", "B25_EMM_PROC", 0, szIniPath);
+ //B25Decoder::multi2_round = GetPrivateProfileIntA("OPTION", "B25_MULTI2ROUND", 4, szIniPath);
+#endif
return 0;
}
@@ -936,6 +946,10 @@
m_pTsReaderArg = new stTsReaderArg();
m_pTsReaderArg->TsReceiversList.push_back(this);
m_pTsReaderArg->pIBon = m_pIBon;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ m_pTsReaderArg->b25.init();
+#endif
m_hTsRead = ::CreateThread(NULL, 0, cProxyServerEx::TsReader, m_pTsReaderArg, 0, NULL);
if (m_hTsRead == NULL)
{
@@ -1241,10 +1255,22 @@
{
fSignalLevel = pIBon->GetSignalLevel();
before = now;
+#ifdef HAVE_LIBARIB25
+ if (ChannelChanged)
+ pArg->b25.reset();
+#endif
ChannelChanged = FALSE;
}
if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0))
{
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ {
+ pArg->b25.decode(pBuf, dwSize, &pBuf, &dwSize);
+ if (dwSize == 0)
+ goto next;
+ }
+#endif
if ((pos + dwSize) < TsPacketBufSize)
{
::memcpy(&pTsBuf[pos], pBuf, dwSize);
@@ -1298,6 +1324,9 @@
}
}
}
+#ifdef HAVE_LIBARIB25
+ next:
+#endif
if (dwRemain == 0)
::Sleep(WAIT_TIME);
}
diff --git a/BonDriverProxyEx/BonDriverProxyEx.h b/BonDriverProxyEx/BonDriverProxyEx.h
--- a/BonDriverProxyEx/BonDriverProxyEx.h
+++ b/BonDriverProxyEx/BonDriverProxyEx.h
@@ -15,6 +15,10 @@
#undef HAVE_UI
#endif
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
+
#if _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
@@ -60,6 +64,9 @@
std::list<cProxyServerEx *> TsReceiversList;
std::list<cProxyServerEx *> WaitExclusivePrivList;
cCriticalSection TsLock;
+#ifdef HAVE_LIBARIB25
+ B25Decoder b25;
+#endif
stTsReaderArg()
{
StopTsRead = FALSE;
diff --git a/BonDriverProxyEx/BonDriverProxyEx.vcxproj b/BonDriverProxyEx/BonDriverProxyEx.vcxproj
--- a/BonDriverProxyEx/BonDriverProxyEx.vcxproj
+++ b/BonDriverProxyEx/BonDriverProxyEx.vcxproj
@@ -150,14 +150,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SVC|Win32'">
@@ -166,14 +166,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -182,14 +182,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SVC|x64'">
@@ -198,14 +198,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Debug\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -216,17 +216,17 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SVC|Win32'">
@@ -237,17 +237,17 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -258,17 +258,17 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SVC|x64'">
@@ -279,21 +279,22 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>BUILD_AS_SERVICE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>HAVE_LIBARIB25;BUILD_AS_SERVICE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\inc</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(LIBARIB25)\src;..\inc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>$(LIBARIB25)\$(Platform)\Release\libarib25.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="BonDriverProxyEx.cpp" />
+ <ClCompile Include="B25Decoder.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BonDriverProxyEx.rc" />
@@ -305,6 +306,7 @@
<ClInclude Include="..\inc\IBonDriver2.h" />
<ClInclude Include="..\inc\IBonDriver3.h" />
<ClInclude Include="BonDriverProxyEx.h" />
+ <ClInclude Include="B25Decoder.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/BonDriverProxyEx/BonDriverProxyEx.vcxproj.filters b/BonDriverProxyEx/BonDriverProxyEx.vcxproj.filters
--- a/BonDriverProxyEx/BonDriverProxyEx.vcxproj.filters
+++ b/BonDriverProxyEx/BonDriverProxyEx.vcxproj.filters
@@ -18,6 +18,9 @@
<ClCompile Include="BonDriverProxyEx.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
+ <ClCompile Include="B25Decoder.cpp">
+ <Filter>ソース ファイル</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BonDriverProxyEx.rc">
@@ -43,5 +46,8 @@
<ClInclude Include="..\inc\Common.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
+ <ClInclude Include="B25Decoder.h">
+ <Filter>ヘッダー ファイル</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
diff --git a/B25Decoder.cpp b/B25Decoder.cpp
new file mode 100644
--- /dev/null
+++ b/B25Decoder.cpp
@@ -0,0 +1,307 @@
+#include "B25Decoder.h"
+
+#include <ctime>
+#include <cstring>
+#include <cassert>
+
+#ifdef _MSC_VER
+
+#define CPP11
+#include <mutex>
+#include <cstdarg>
+
+#include "arib_std_b25.h"
+#include "arib_std_b25_error_code.h"
+
+enum log_prio {
+ LOG_EMERG,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG
+};
+
+static void syslog(int prio, const char *fmt, ...) {
+ char log[256];
+ va_list ap;
+ va_start(ap, fmt);
+ ::wvsprintfA(log, fmt, ap);
+ va_end(ap);
+ ::OutputDebugStringA(log);
+}
+
+#else
+
+#include <syslog.h>
+#include <arib25/arib_std_b25.h>
+#include <arib25/arib_std_b25_error_code.h>
+
+#define nullptr 0
+
+#endif
+
+#define RETRY_INTERVAL 10 // 10sec interval
+
+struct B25Decoder::impl {
+ impl()
+ : _bcas(nullptr)
+ , _b25(nullptr)
+ , _data(nullptr)
+ , _reference_count(1) {
+ }
+ ~impl();
+
+ int init();
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+
+#ifdef CPP11
+ std::mutex _mtx;
+#endif
+ B_CAS_CARD *_bcas;
+ ARIB_STD_B25 *_b25;
+ BYTE *_data;
+ time_t _errtime;
+
+ int _reference_count;
+ impl *add_reference() {
+ if (this)
+ ++_reference_count;
+ return this;
+ }
+ void release_reference() {
+ if (this) {
+ if (--_reference_count <= 0)
+ delete this;
+ }
+ }
+};
+
+int B25Decoder::strip = 1;
+int B25Decoder::emm_proc = 0;
+int B25Decoder::multi2_round = 4;
+
+B25Decoder::B25Decoder() : _pimpl(nullptr) {
+}
+
+B25Decoder::~B25Decoder() {
+ _pimpl->release_reference();
+}
+
+B25Decoder::B25Decoder(const B25Decoder &ref) {
+ _pimpl = ref._pimpl->add_reference();
+}
+
+B25Decoder &B25Decoder::operator=(const B25Decoder &rhs) {
+ rhs._pimpl->add_reference();
+ _pimpl->release_reference();
+ _pimpl = rhs._pimpl;
+ return *this;
+}
+
+B25Decoder::impl::~impl() {
+ delete[] _data;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ _b25->release(_b25);
+
+ if (_bcas)
+ _bcas->release(_bcas);
+
+ syslog(LOG_DEBUG, "B25Decoder::dtor() : end");
+}
+
+void B25Decoder::release() {
+ _pimpl->release_reference();
+ _pimpl = nullptr;
+}
+
+int B25Decoder::init() {
+ if (!_pimpl)
+ _pimpl = new impl;
+
+ return _pimpl->init();
+}
+
+int B25Decoder::impl::init() {
+ int rc;
+
+#ifdef CPP11
+ std::lock_guard<std::mutex> lock(_mtx);
+#endif
+
+ if (_b25)
+ return -2;
+
+ _bcas = create_b_cas_card();
+ if (!_bcas)
+ return -3;
+
+ rc = _bcas->init(_bcas);
+ if (rc < 0) {
+ syslog(LOG_ERR, "B25Decoder::init() : bcas init error / rc(%d)", rc);
+ rc = -4;
+ goto err;
+ }
+
+ _b25 = create_arib_std_b25();
+ if (!_b25) {
+ rc = -5;
+ goto err;
+ }
+
+ if (_b25->set_b_cas_card(_b25, _bcas) < 0) {
+ rc = -6;
+ goto err;
+ }
+
+ _b25->set_strip(_b25, strip);
+ _b25->set_emm_proc(_b25, emm_proc);
+ _b25->set_multi2_round(_b25, multi2_round);
+
+ syslog(LOG_DEBUG, "B25Decoder::init() : success");
+ return 0; // success
+
+err:
+ if (_b25) {
+ _b25->release(_b25);
+ _b25 = nullptr;
+ }
+
+ if (_bcas) {
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+
+ syslog(LOG_ERR, "B25Decoder::init() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return rc; // error
+}
+
+void B25Decoder::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_pimpl) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+
+ _pimpl->decode(pSrc, dwSrcSize, ppDst, pdwDstSize);
+}
+
+void B25Decoder::impl::decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize) {
+ if (!_b25) {
+ time_t now = time(nullptr);
+ if (difftime(now, _errtime) > RETRY_INTERVAL) {
+ if (init() < 0)
+ _errtime = now;
+ }
+
+ if (!_b25) {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ return;
+ }
+ }
+
+ delete[] _data;
+ _data = nullptr;
+
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ const int rc = _b25->put(_b25, &buf);
+ if (rc < 0) {
+ if (rc >= ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+ else {
+ BYTE *p = nullptr;
+ _b25->withdraw(_b25, &buf); // withdraw src buffer
+ if (buf.size > 0) {
+ syslog(LOG_ERR, "B25Decoder::decode() : error / withdraw size(%u)", buf.size);
+ p = new BYTE[buf.size + dwSrcSize];
+ }
+
+ if (p) {
+ std::memcpy(p, buf.data, buf.size);
+ std::memcpy(p + buf.size, pSrc, dwSrcSize);
+ *ppDst = p;
+ *pdwDstSize = buf.size + dwSrcSize;
+ _data = p;
+ }
+ else {
+ if (*ppDst != pSrc) {
+ *ppDst = pSrc;
+ *pdwDstSize = dwSrcSize;
+ }
+ }
+
+ if (rc == ARIB_STD_B25_ERROR_ECM_PROC_FAILURE) {
+ // pass through
+ _b25->release(_b25);
+ _b25 = nullptr;
+ _bcas->release(_bcas);
+ _bcas = nullptr;
+ }
+ }
+ syslog(LOG_ERR, "B25Decoder::decode() : error / rc(%d)", rc);
+ _errtime = time(nullptr);
+ return; // error
+ }
+
+ _b25->get(_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return; // success
+}
+
+void B25Decoder::reset() {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->reset(_pimpl->_b25);
+}
+
+int B25Decoder::put(BYTE *pSrc, DWORD dwSrcSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ buf.data = pSrc;
+ buf.size = dwSrcSize;
+ return _pimpl->_b25->put(_pimpl->_b25, &buf);
+}
+
+int B25Decoder::get(BYTE **ppDst, DWORD *pdwDstSize) {
+ assert(_pimpl);
+ ARIB_STD_B25_BUFFER buf;
+ int rc = _pimpl->_b25->get(_pimpl->_b25, &buf);
+ *ppDst = buf.data;
+ *pdwDstSize = buf.size;
+ return rc;
+}
+
+int B25Decoder::flush() {
+ if (_pimpl && _pimpl->_b25)
+ return _pimpl->_b25->flush(_pimpl->_b25);
+ return 0;
+}
+
+void B25Decoder::setemm(bool flag) {
+ if (_pimpl && _pimpl->_b25)
+ _pimpl->_b25->set_emm_proc(_pimpl->_b25, flag ? 1 : 0);
+}
diff --git a/B25Decoder.h b/B25Decoder.h
new file mode 100644
--- /dev/null
+++ b/B25Decoder.h
@@ -0,0 +1,41 @@
+#pragma once
+#ifndef _B25DECODER_H
+#define _B25DECODER_H
+
+// for BYTE, DWORD
+#ifdef _MSC_VER
+#include <windows.h>
+#else
+#include "typedef.h" // in BonDriverProxy_Linux source tree
+#endif
+
+class B25Decoder {
+ public:
+ B25Decoder();
+ ~B25Decoder();
+ B25Decoder(const B25Decoder &ref);
+ B25Decoder &operator=(const B25Decoder &rhs);
+
+ int init();
+ void release();
+
+ void decode(BYTE *pSrc, DWORD dwSrcSize, BYTE **ppDst, DWORD *pdwDstSize);
+ void setemm(bool flag);
+
+ // libarib25 wrapper
+ void reset();
+ int put(BYTE *pSrc, DWORD dwSrcSize);
+ int get(BYTE **ppDst, DWORD *pdwDstSize);
+ int flush();
+
+ // initialize parameter
+ static int strip;
+ static int emm_proc;
+ static int multi2_round;
+
+ private:
+ struct impl;
+ struct impl *_pimpl;
+};
+
+#endif // _B25DECODER_H
diff --git a/BonDriverProxy.cpp b/BonDriverProxy.cpp
--- a/BonDriverProxy.cpp
+++ b/BonDriverProxy.cpp
@@ -1,5 +1,10 @@
#include "BonDriverProxy.h"
+#ifdef HAVE_LIBARIB25
+#include <getopt.h>
+static int g_b25_enable = false;
+#endif
+
namespace BonDriverProxy {
#define STRICT_LOCK
@@ -29,6 +34,39 @@
static int Init(int ac, char *av[])
{
+#ifdef HAVE_LIBARIB25
+ static const struct option options[] = {
+ {"b25", no_argument, &g_b25_enable, 1},
+ {"strip", no_argument, &B25Decoder::strip, 1},
+ {"EMM", no_argument, &B25Decoder::emm_proc, 1},
+ {"round", required_argument, NULL, 'r'},
+ {0}
+ };
+
+ int opt;
+
+ while ((opt = getopt_long(ac, av, "", options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ case 0: // long options
+ break;
+ case 'r': // multi2 round
+ B25Decoder::multi2_round = strtoul(optarg, NULL, 10);
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (optind > 1)
+ {
+ int i = optind, j = 1;
+ while (i < ac)
+ av[j++] = av[i++];
+ ac -= optind - 1;
+ }
+#endif
if (ac < 3)
return -1;
::strncpy(g_Host, av[1], sizeof(g_Host) - 1);
@@ -642,6 +680,10 @@
m_pTsReaderArg = new stTsReaderArg();
m_pTsReaderArg->TsReceiversList.push_back(this);
m_pTsReaderArg->pIBon = m_pIBon;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ m_pTsReaderArg->b25.init();
+#endif
if (::pthread_create(&m_hTsRead, NULL, cProxyServer::TsReader, m_pTsReaderArg))
{
m_hTsRead = 0;
@@ -912,12 +954,24 @@
now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
if (((now - before) >= 1000) || ChannelChanged)
{
+#ifdef HAVE_LIBARIB25
+ if (ChannelChanged)
+ pArg->b25.reset();
+#endif
fSignalLevel = pIBon->GetSignalLevel();
before = now;
ChannelChanged = FALSE;
}
if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0))
{
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ {
+ pArg->b25.decode(pBuf, dwSize, &pBuf, &dwSize);
+ if (dwSize == 0)
+ goto next;
+ }
+#endif
if ((pos + dwSize) < TsPacketBufSize)
{
::memcpy(&pTsBuf[pos], pBuf, dwSize);
@@ -959,6 +1013,9 @@
}
}
}
+#ifdef HAVE_LIBARIB25
+ next:
+#endif
if (dwRemain == 0)
::nanosleep(&ts, NULL);
}
@@ -1170,7 +1227,12 @@
{
if (BonDriverProxy::Init(argc, argv) != 0)
{
+#ifdef HAVE_LIBARIB25
+ fprintf(stderr, "usage: %s [--b25 [--round N] [--strip] [--EMM]] "
+ "address port (packet_fifo_size tspacket_bufsize)\ne.g. $ %s 192.168.0.100 1192\n", argv[0],argv[0]);
+#else
fprintf(stderr, "usage: %s address port (packet_fifo_size tspacket_bufsize)\ne.g. $ %s 192.168.0.100 1192\n", argv[0],argv[0]);
+#endif
return 0;
}
diff --git a/BonDriverProxy.h b/BonDriverProxy.h
--- a/BonDriverProxy.h
+++ b/BonDriverProxy.h
@@ -23,6 +23,9 @@
#include <queue>
#include "typedef.h"
#include "IBonDriver3.h"
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
#if __APPLE__
#undef daemon
@@ -67,6 +70,9 @@
std::list<cProxyServer *> TsReceiversList;
std::list<cProxyServer *> WaitExclusivePrivList;
cCriticalSection TsLock;
+#ifdef HAVE_LIBARIB25
+ B25Decoder b25;
+#endif
stTsReaderArg()
{
StopTsRead = FALSE;
diff --git a/BonDriverProxyEx.cpp b/BonDriverProxyEx.cpp
--- a/BonDriverProxyEx.cpp
+++ b/BonDriverProxyEx.cpp
@@ -1,5 +1,10 @@
#include "BonDriverProxyEx.h"
+#ifdef HAVE_LIBARIB25
+#include <getopt.h>
+static int g_b25_enable = false;
+#endif
+
namespace BonDriverProxyEx {
#ifdef DEBUG
@@ -53,6 +58,39 @@
static int Init(int ac, char *av[])
{
+#ifdef HAVE_LIBARIB25
+ static const struct option options[] = {
+ {"b25", no_argument, &g_b25_enable, 1},
+ {"strip", no_argument, &B25Decoder::strip, 1},
+ {"EMM", no_argument, &B25Decoder::emm_proc, 1},
+ {"round", required_argument, NULL, 'r'},
+ {0}
+ };
+
+ int opt;
+
+ while ((opt = getopt_long(ac, av, "", options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ case 0: // long options
+ break;
+ case 'r': // multi2 round
+ B25Decoder::multi2_round = strtoul(optarg, NULL, 10);
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (optind > 1)
+ {
+ int i = optind, j = 1;
+ while (i < ac)
+ av[j++] = av[i++];
+ ac -= optind - 1;
+ }
+#endif
if (ac < 3)
return -1;
::strncpy(g_Host, av[1], sizeof(g_Host) - 1);
@@ -891,6 +929,10 @@
m_pTsReaderArg = new stTsReaderArg();
m_pTsReaderArg->TsReceiversList.push_back(this);
m_pTsReaderArg->pIBon = m_pIBon;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ m_pTsReaderArg->b25.init();
+#endif
if (::pthread_create(&m_hTsRead, NULL, cProxyServerEx::TsReader, m_pTsReaderArg))
{
m_hTsRead = 0;
@@ -1187,12 +1229,24 @@
now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
if (((now - before) >= 1000) || ChannelChanged)
{
+#ifdef HAVE_LIBARIB25
+ if (ChannelChanged)
+ pArg->b25.reset();
+#endif
fSignalLevel = pIBon->GetSignalLevel();
before = now;
ChannelChanged = FALSE;
}
if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0))
{
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ {
+ pArg->b25.decode(pBuf, dwSize, &pBuf, &dwSize);
+ if (dwSize == 0)
+ goto next;
+ }
+#endif
if ((pos + dwSize) < TsPacketBufSize)
{
::memcpy(&pTsBuf[pos], pBuf, dwSize);
@@ -1234,6 +1288,9 @@
}
}
}
+#ifdef HAVE_LIBARIB25
+ next:
+#endif
if (dwRemain == 0)
::nanosleep(&ts, NULL);
}
@@ -1724,7 +1781,12 @@
{
if (BonDriverProxyEx::Init(argc, argv) != 0)
{
+#ifdef HAVE_LIBARIB25
+ fprintf(stderr, "usage: %s [--b25 [--round N] [--strip] [--EMM]] "
+ "address port (opentuner_return_delay_time packet_fifo_size tspacket_bufsize)\ne.g. $ %s 192.168.0.100 1192\n", argv[0],argv[0]);
+#else
fprintf(stderr, "usage: %s address port (opentuner_return_delay_time packet_fifo_size tspacket_bufsize)\ne.g. $ %s 192.168.0.100 1192\n", argv[0],argv[0]);
+#endif
return 0;
}
diff --git a/BonDriverProxyEx.h b/BonDriverProxyEx.h
--- a/BonDriverProxyEx.h
+++ b/BonDriverProxyEx.h
@@ -26,6 +26,9 @@
#include <map>
#include "typedef.h"
#include "IBonDriver3.h"
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
#if __APPLE__
#undef daemon
@@ -74,6 +77,9 @@
std::list<cProxyServerEx *> TsReceiversList;
std::list<cProxyServerEx *> WaitExclusivePrivList;
cCriticalSection TsLock;
+#ifdef HAVE_LIBARIB25
+ B25Decoder b25;
+#endif
stTsReaderArg()
{
StopTsRead = FALSE;
diff --git a/BonDriver_DVB.conf b/BonDriver_DVB.conf
--- a/BonDriver_DVB.conf
+++ b/BonDriver_DVB.conf
@@ -2,6 +2,10 @@
#GETCNRMODE=0
#USELNB=0
#USESERVICEID=0
+; #B25=1
+; #STRIP=1
+; #EMM=1
+; #MULTI2ROUND=4
; 名称, BonDriverとしてのチャンネル番号, 周波数テーブル番号, TSID
; 記述はタブ区切り
#ISDB_S
diff --git a/BonDriver_DVB.cpp b/BonDriver_DVB.cpp
--- a/BonDriver_DVB.cpp
+++ b/BonDriver_DVB.cpp
@@ -1,4 +1,7 @@
#include "BonDriver_DVB.h"
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
namespace BonDriver_DVB {
@@ -14,6 +17,11 @@
static BOOL g_TsSync;
static DWORD g_dwDelFlag;
+#ifdef HAVE_LIBARIB25
+static BOOL g_b25_enable = false;
+static B25Decoder g_b25;
+#endif
+
static int Convert(char *src, char *dst, size_t dstsize)
{
iconv_t d = ::iconv_open("UTF-16LE", "UTF-8");
@@ -98,6 +106,14 @@
BOOL bmFlag = FALSE;
BOOL btFlag = FALSE;
BOOL bdFlag = FALSE;
+#ifdef HAVE_LIBARIB25
+ struct {
+ unsigned b25:1;
+ unsigned strip:1;
+ unsigned emm:1;
+ unsigned multi2round:1;
+ } b25flags = {0};
+#endif
while (::fgets(buf, sizeof(buf), fp))
{
if (buf[0] == ';')
@@ -187,6 +203,28 @@
delete[] pp;
bdFlag = TRUE;
}
+#ifdef HAVE_LIBARIB25
+ else if (!b25flags.b25 && IsTagMatch(buf, "#B25", &p))
+ {
+ g_b25_enable = ::atoi(p);
+ b25flags.b25 = 1;
+ }
+ else if (!b25flags.strip && IsTagMatch(buf, "#STRIP", &p))
+ {
+ B25Decoder::strip = ::atoi(p);
+ b25flags.strip = 1;
+ }
+ else if (!b25flags.emm && IsTagMatch(buf, "#EMM", &p))
+ {
+ B25Decoder::emm_proc = ::atoi(p);
+ b25flags.emm = 1;
+ }
+ else if (!b25flags.multi2round && IsTagMatch(buf, "#MULTI2ROUND", &p))
+ {
+ B25Decoder::multi2_round = ::atoi(p);
+ b25flags.multi2round = 1;
+ }
+#endif
else
{
int n = 0;
@@ -448,6 +486,10 @@
}
m_bTuner = TRUE;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ g_b25.init();
+#endif
return TRUE;
err0:
@@ -488,6 +530,9 @@
::close(m_fefd);
m_fefd = m_dmxfd = m_dvrfd = -1;
m_bTuner = FALSE;
+#ifdef HAVE_LIBARIB25
+ g_b25.release();
+#endif
}
}
@@ -560,6 +605,10 @@
b = FALSE;
}
}
+#ifdef HAVE_LIBARIB25
+ if (b)
+ g_b25.decode(*ppDst, *pdwSize, ppDst, pdwSize);
+#endif
return b;
}
@@ -720,6 +769,9 @@
goto err;
}
}
+#ifdef HAVE_LIBARIB25
+ g_b25.reset();
+#endif
m_dwSpace = dwSpace;
m_dwChannel = dwChannel;
diff --git a/BonDriver_LinuxPT.conf b/BonDriver_LinuxPT.conf
--- a/BonDriver_LinuxPT.conf
+++ b/BonDriver_LinuxPT.conf
@@ -1,6 +1,11 @@
#DEVICE=/dev/pt3video0
#USELNB=0
#USESERVICEID=0
+; #B25=1
+; #STRIP=1
+; #EMM=1
+; #MULTI2ROUND=4
+
; 名称, BonDriverとしてのチャンネル番号, 周波数テーブル番号, スロット番号/加算する周波数
; 記述はタブ区切り
#ISDB_S
diff --git a/BonDriver_LinuxPT.cpp b/BonDriver_LinuxPT.cpp
--- a/BonDriver_LinuxPT.cpp
+++ b/BonDriver_LinuxPT.cpp
@@ -1,5 +1,8 @@
#include "BonDriver_LinuxPT.h"
#include "plex.cpp"
+#ifdef HAVE_LIBARIB25
+#include "B25Decoder.h"
+#endif
namespace BonDriver_LinuxPT {
@@ -14,6 +17,11 @@
static BOOL g_ModPMT;
static DWORD g_dwDelFlag;
+#ifdef HAVE_LIBARIB25
+static BOOL g_b25_enable = false;
+static B25Decoder g_b25;
+#endif
+
static int Convert(char *src, char *dst, size_t dstsize)
{
iconv_t d = ::iconv_open("UTF-16LE", "UTF-8");
@@ -96,6 +104,14 @@
BOOL bsFlag = FALSE;
BOOL bmFlag = FALSE;
BOOL bdelFlag = FALSE;
+#ifdef HAVE_LIBARIB25
+ struct {
+ unsigned b25:1;
+ unsigned strip:1;
+ unsigned emm:1;
+ unsigned multi2round:1;
+ } b25flags = {0};
+#endif
while (::fgets(buf, sizeof(buf), fp))
{
if (buf[0] == ';')
@@ -206,6 +222,28 @@
delete[] pp;
bdelFlag = TRUE;
}
+#ifdef HAVE_LIBARIB25
+ else if (!b25flags.b25 && IsTagMatch(buf, "#B25", &p))
+ {
+ g_b25_enable = ::atoi(p);
+ b25flags.b25 = 1;
+ }
+ else if (!b25flags.strip && IsTagMatch(buf, "#STRIP", &p))
+ {
+ B25Decoder::strip = ::atoi(p);
+ b25flags.strip = 1;
+ }
+ else if (!b25flags.emm && IsTagMatch(buf, "#EMM", &p))
+ {
+ B25Decoder::emm_proc = ::atoi(p);
+ b25flags.emm = 1;
+ }
+ else if (!b25flags.multi2round && IsTagMatch(buf, "#MULTI2ROUND", &p))
+ {
+ B25Decoder::multi2_round = ::atoi(p);
+ b25flags.multi2round = 1;
+ }
+#endif
else
{
int n = 0;
@@ -363,6 +401,10 @@
if (g_UseLNB && (g_Type == 0) && (::ioctl(m_fd, LNB_ENABLE, 2) < 0))
::fprintf(stderr, "LNB ON failed: %s\n", g_Device);
m_bTuner = TRUE;
+#ifdef HAVE_LIBARIB25
+ if (g_b25_enable)
+ g_b25.init();
+#endif
return TRUE;
}
@@ -382,6 +424,9 @@
::close(m_fd);
m_bTuner = FALSE;
m_fd = -1;
+#ifdef HAVE_LIBARIB25
+ g_b25.release();
+#endif
}
}
@@ -454,6 +499,10 @@
b = FALSE;
}
}
+#ifdef HAVE_LIBARIB25
+ if (b)
+ g_b25.decode(*ppDst, *pdwSize, ppDst, pdwSize);
+#endif
return b;
}
@@ -544,6 +593,9 @@
::fprintf(stderr, "SetChannel() ioctl(SET_CHANNEL) error: %s\n", g_Device);
goto err;
}
+#ifdef HAVE_LIBARIB25
+ g_b25.reset();
+#endif
}
{
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,15 @@
sample: sample.o
$(CXX) $(CXXFLAGS) -rdynamic -o $@ $^ $(LIBS)
+ifdef B25
+CPPFLAGS += -DHAVE_LIBARIB25
+LIBS += -larib25
+SRCS += B25Decoder.cpp
+BonDriverProxy BonDriverProxyEx BonDriver_LinuxPT.$(EXT) BonDriver_DVB.$(EXT) sample: B25Decoder.o
+B25Decoder.o: B25Decoder.cpp
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ADDCOMPILEFLAGS) -fPIC -c -o $@ $<
+endif
+
util:
@cd util; make
diff --git a/sample.cpp b/sample.cpp
--- a/sample.cpp
+++ b/sample.cpp
@@ -1,5 +1,6 @@
/*
$ g++ -O2 -Wall -rdynamic -o sample sample.cpp -ldl
+$ g++ -O2 -Wall -rdynamic -o sample sample.cpp decoder.cpp -ldl -larib25 -DHAVE_LIBARIB25
*/
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
@@ -15,6 +16,80 @@
#include "typedef.h"
#include "IBonDriver2.h"
+static ssize_t write_full(int fd, const void *buf, size_t count);
+
+#ifdef HAVE_LIBARIB25
+#include <getopt.h>
+#include "B25Decoder.h"
+
+class B25Writer : public B25Decoder
+{
+public:
+ ssize_t operator()(int fd, void *buf, size_t count)
+ {
+ BYTE *out;
+ DWORD outlen;
+ B25Decoder::decode((BYTE*)buf, count, &out, &outlen);
+ if (outlen > 0)
+ {
+ ssize_t len;
+ if ((len = write_full(fd, out, outlen)) < 0)
+ return len;
+ }
+ return count;
+ }
+
+ int flush(int fd)
+ {
+ int code;
+ BYTE *out;
+ DWORD outlen;
+
+ if ((code = B25Decoder::flush()) < 0)
+ return code;
+
+ if ((code = B25Decoder::get(&out, &outlen)) < 0)
+ return code;
+
+ if (outlen > 0)
+ return write_full(fd, out, outlen);
+
+ return 0;
+ }
+};
+
+#else // HAVE_LIBARIB25
+
+class B25Writer
+{
+public:
+ ssize_t operator()(int fd, const void *buf, size_t count)
+ {
+ return write_full(fd, buf, count);
+ }
+};
+
+#endif // HAVE_LIBARIB25
+
+static ssize_t write_full(int fd, const void *buf, size_t count)
+{
+ size_t size_remain = count;
+ size_t offset = 0;
+
+ while (size_remain > 0)
+ {
+ ssize_t wc = ::write(fd, static_cast<const char*>(buf) + offset, size_remain);
+ if (wc < 0)
+ {
+ perror("write");
+ return wc;
+ }
+ size_remain -= wc;
+ offset += wc;
+ }
+ return count;
+}
+
static volatile BOOL bStop = FALSE;
static void handler(int sig)
{
@@ -23,7 +98,12 @@
void usage(char *p)
{
+#ifdef HAVE_LIBARIB25
+ fprintf(stderr, "usage: %s [--b25 [--round N] [--strip] [--EMM]] "
+ "[-b bondriver] [-s space_no] [-c channel_no] ( [-t sec] [-o filename] )\n", p);
+#else
fprintf(stderr, "usage: %s [-b bondriver] [-s space_no] [-c channel_no] ( [-t sec] [-o filename] )\n", p);
+#endif
exit(0);
}
@@ -38,10 +118,31 @@
bon = output = NULL;
bfind = sfind = cfind = ofind = 0;
dwSpace = dwChannel = 0;
+
+#ifdef HAVE_LIBARIB25
+ int b25_enable = false;
+ static const struct option options[] = {
+ {"b25", no_argument, &b25_enable, 1},
+ {"strip", no_argument, &B25Decoder::strip, 1},
+ {"EMM", no_argument, &B25Decoder::emm_proc, 1},
+ {"round", required_argument, NULL, 'r'},
+ {0}
+ };
+
+ while ((opt = getopt_long(argc, argv, "b:s:c:t:o:", options, NULL)) != -1)
+#else
while ((opt = getopt(argc, argv, "b:s:c:t:o:")) != -1)
+#endif
{
switch (opt)
{
+#ifdef HAVE_LIBARIB25
+ case 0: // long options
+ break;
+ case 'r': // multi2 round
+ B25Decoder::multi2_round = strtoul(optarg, NULL, 10);
+ break;
+#endif
case 'b': // BonDriver指定
bon = optarg;
bfind = 1;
@@ -150,6 +251,14 @@
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 10 * 1000 * 1000; // 10ms
+ B25Writer writer;
+#ifdef HAVE_LIBARIB25
+ if (b25_enable)
+ {
+ if (writer.init() < 0)
+ goto err;
+ }
+#endif
while (!bStop)
{
// TSストリーム取得
@@ -158,18 +267,8 @@
{
// この時点でpBufに長さdwSize分のTSストリームを取得した状態なので、それを書き出し
// (もしバッファリングやデスクランブルやTS分離処理を入れるならこの辺で)
- int len, left = (int)dwSize;
- do
- {
- len = write(wfd, pBuf, left);
- if (len < 0)
- {
- perror("write");
- goto err;
- }
- left -= len;
- pBuf += len;
- } while (left > 0);
+ if (writer(wfd, pBuf, dwSize) < 0)
+ goto err;
}
// 取得待ちTSデータが無ければ適当な時間待つ
if (dwRemain == 0)
@@ -187,18 +286,8 @@
dwSize = dwRemain = 0;
if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0))
{
- int len, left = (int)dwSize;
- do
- {
- len = write(wfd, pBuf, left);
- if (len < 0)
- {
- perror("write");
- goto err;
- }
- left -= len;
- pBuf += len;
- } while (left > 0);
+ if (writer(wfd, pBuf, dwSize) < 0)
+ goto err;
}
if (dwRemain == 0)
break;
@@ -206,6 +295,10 @@
#endif
err:
+#ifdef HAVE_LIBARIB25
+ writer.flush(wfd);
+ writer.release();
+#endif
close(wfd);
// インスタンス解放 & モジュールリリース
pIBon->Release();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.