static void *TsReader(LPVOID pv) { IBonDriver *pIBon = static_cast<IBonDriver *>(pv); // TS取得開始 BYTE *pBuf; DWORD dwSize, dwRemain; timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10 * 1000 * 1000; // 10ms while (!bStop) { // TSストリーム取得 dwSize = dwRemain = 0; if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0)) { // この時点でpBufに長さdwSize分のTSストリームを取得した状態なので、それを書き出し // (もしバッファリングやデスクランブルやTS分離処理を入れるならこの辺で) int len, left = (int)dwSize; do { len = write(wfd, pBuf, left); if (len < 0) { perror("write"); bStop = TRUE; break; } left -= len; pBuf += len; } while (left > 0); } // 取得待ちTSデータが無ければ適当な時間待つ if (dwRemain == 0) nanosleep(&ts, NULL); } return NULL; }
DWORD WINAPI cProxyServer::TsReader(LPVOID pv) { stTsReaderArg *pArg = static_cast<stTsReaderArg *>(pv); IBonDriver *pIBon = pArg->pIBon; volatile BOOL &StopTsRead = pArg->StopTsRead; volatile BOOL &ChannelChanged = pArg->ChannelChanged; DWORD &pos = pArg->pos; std::list<cProxyServer *> &TsReceiversList = pArg->TsReceiversList; cCriticalSection &TsLock = pArg->TsLock; DWORD dwSize, dwRemain, now, before = 0; float fSignalLevel = 0; DWORD ret = 300; const DWORD TsPacketBufSize = g_TsPacketBufSize; BYTE *pBuf, *pTsBuf = new BYTE[TsPacketBufSize]; #if _DEBUG && DETAILLOG DWORD Counter = 0; #endif // 内部でCOMを使用しているBonDriverに対する対策 HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY); // TS読み込みループ while (!StopTsRead) { dwSize = dwRemain = 0; { LOCK(TsLock); if ((((now = ::GetTickCount()) - before) >= 1000) || ChannelChanged) { fSignalLevel = pIBon->GetSignalLevel(); before = now; ChannelChanged = FALSE; } if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0)) { if ((pos + dwSize) < TsPacketBufSize) { ::memcpy(&pTsBuf[pos], pBuf, dwSize); pos += dwSize; if (dwRemain == 0) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pTsBuf, pos, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket0() : %u : size[%x] / dwRemain[%d]\n", Counter++, pos, dwRemain); #endif pos = 0; } } else { DWORD left, dwLen = TsPacketBufSize - pos; ::memcpy(&pTsBuf[pos], pBuf, dwLen); for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pTsBuf, TsPacketBufSize, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket1() : %u : size[%x] / dwRemain[%d]\n", Counter++, TsPacketBufSize, dwRemain); #endif left = dwSize - dwLen; pBuf += dwLen; while (left >= TsPacketBufSize) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pBuf, TsPacketBufSize, fSignalLevel); #if _DEBUG && DETAILLOG _RPT2(_CRT_WARN, "makePacket2() : %u : size[%x]\n", Counter++, TsPacketBufSize); #endif left -= TsPacketBufSize; pBuf += TsPacketBufSize; } if (left != 0) { if (dwRemain == 0) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pBuf, left, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket3() : %u : size[%x] / dwRemain[%d]\n", Counter++, left, dwRemain); #endif left = 0; } else ::memcpy(pTsBuf, pBuf, left); } pos = left; } } } if (dwRemain == 0) ::Sleep(WAIT_TIME); } if (SUCCEEDED(hr)) ::CoUninitialize(); delete[] pTsBuf; return ret; }