Esempio n. 1
0
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;
}
Esempio n. 2
0
UINT WINAPI CBonDriverUtil::DriverThread(LPVOID param)
{
	//BonDriverがCOMを利用するかもしれないため
	CoInitialize(NULL);

	CBonDriverUtil* sys = (CBonDriverUtil*)param;
	IBonDriver* bonIF = NULL;
	sys->bon2IF = NULL;
	HMODULE hModule = LoadLibrary((sys->loadDllFolder + L"\\" + sys->loadDllFileName).c_str());
	if( hModule == NULL ){
		OutputDebugString(L"★BonDriverがロードできません\r\n");
	}else{
		IBonDriver* (*funcCreateBonDriver)() = (IBonDriver*(*)())GetProcAddress(hModule, "CreateBonDriver");
		if( funcCreateBonDriver == NULL ){
			OutputDebugString(L"★GetProcAddressに失敗しました\r\n");
		}else if( (bonIF = funcCreateBonDriver()) != NULL &&
		          (sys->bon2IF = dynamic_cast<IBonDriver2*>(bonIF)) != NULL ){
			if( sys->bon2IF->OpenTuner() == FALSE ){
				OutputDebugString(L"★OpenTunerに失敗しました\r\n");
			}else{
				sys->initChSetFlag = false;
				//チューナー名の取得
				LPCWSTR tunerName = sys->bon2IF->GetTunerName();
				sys->loadTunerName = tunerName ? tunerName : L"";
				Replace(sys->loadTunerName, L"(",L"(");
				Replace(sys->loadTunerName, L")",L")");
				//チャンネル一覧の取得
				sys->loadChList.clear();
				for( DWORD countSpace = 0; ; countSpace++ ){
					LPCWSTR spaceName = sys->bon2IF->EnumTuningSpace(countSpace);
					if( spaceName == NULL ){
						break;
					}
					sys->loadChList.push_back(pair<wstring, vector<wstring>>(spaceName, vector<wstring>()));
					for( DWORD countCh = 0; ; countCh++ ){
						LPCWSTR chName = sys->bon2IF->EnumChannelName(countSpace, countCh);
						if( chName == NULL ){
							break;
						}
						sys->loadChList.back().second.push_back(chName);
					}
				}
				sys->hwndDriver = CreateWindow(L"BonDriverUtilWorker", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), sys);
				if( sys->hwndDriver == NULL ){
					sys->bon2IF->CloseTuner();
				}
			}
		}
	}
	if( sys->hwndDriver == NULL ){
		//Openできなかった
		if( bonIF ){
			bonIF->Release();
		}
		if( hModule ){
			FreeLibrary(hModule);
		}
		CoUninitialize();
		return 0;
	}

	//メッセージループ
	MSG msg;
	while( GetMessage(&msg, NULL, 0, 0) > 0 ){
		DispatchMessage(&msg);
	}
	sys->bon2IF->CloseTuner();
	bonIF->Release();
	FreeLibrary(hModule);

	CoUninitialize();
	return 0;
}
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;
}
Esempio n. 4
0
bool CDriverInfo::LoadTuningSpaceList(LoadTuningSpaceListMode Mode)
{
	CAppMain &App=GetAppClass();
	LPCTSTR pszFileName=m_FileName.c_str();

	bool fUseDriver;
	if (Mode==LOADTUNINGSPACE_NOLOADDRIVER) {
		fUseDriver=false;
	} else if (Mode==LOADTUNINGSPACE_USEDRIVER) {
		fUseDriver=true;
	} else {
		CDriverManager::TunerSpec Spec;
		if (App.DriverManager.GetTunerSpec(pszFileName,&Spec)
				&& (Spec.Flags & CDriverManager::TunerSpec::FLAG_NOENUMCHANNEL)!=0)
			fUseDriver=false;
		else
			fUseDriver=true;
	}

	if (!m_fChannelFileLoaded) {
		TCHAR szChannelFileName[MAX_PATH];

		App.Core.GetChannelFileName(pszFileName,szChannelFileName,lengthof(szChannelFileName));
		if (m_TuningSpaceList.LoadFromFile(szChannelFileName)) {
#if 0
			if (fUseDriver && Mode==LOADTUNINGSPACE_DEFAULT) {
				const int NumSpaces=m_TuningSpaceList.NumSpaces();
				int i;
				for (i=0;i<NumSpaces;i++) {
					if (m_TuningSpaceList.GetTuningSpaceName(i)==NULL
							|| m_TuningSpaceList.GetChannelList(i)->NumChannels()==0)
						break;
				}
				if (i==NumSpaces)
					fUseDriver=false;
			}
#else
			if (Mode==LOADTUNINGSPACE_DEFAULT)
				fUseDriver=false;
#endif
			m_fChannelFileLoaded=true;
		} else {
			if (!fUseDriver && !m_fDriverSpaceLoaded)
				return false;
		}
	}

	if (fUseDriver && !m_fDriverSpaceLoaded) {
		TCHAR szFilePath[MAX_PATH];

		if (::PathIsRelative(pszFileName)) {
			TCHAR szTemp[MAX_PATH];
			App.Core.GetDriverDirectory(szTemp,lengthof(szTemp));
			::PathAppend(szTemp,pszFileName);
			::PathCanonicalize(szFilePath,szTemp);
		} else {
			::lstrcpy(szFilePath,pszFileName);
		}

		HMODULE hLib=::GetModuleHandle(szFilePath);
		if (hLib!=NULL) {
			TCHAR szCurDriverPath[MAX_PATH];

			if (App.CoreEngine.GetDriverPath(szCurDriverPath,lengthof(szCurDriverPath))
					&& IsEqualFileName(szFilePath,szCurDriverPath)) {
				m_DriverSpaceList=*App.ChannelManager.GetDriverTuningSpaceList();
				m_fDriverSpaceLoaded=true;
			}
		} else if ((hLib=::LoadLibrary(szFilePath))!=NULL) {
			CreateBonDriverFunc pCreate=
				reinterpret_cast<CreateBonDriverFunc>(::GetProcAddress(hLib,"CreateBonDriver"));
			IBonDriver *pBonDriver;

			if (pCreate!=NULL && (pBonDriver=pCreate())!=NULL) {
				IBonDriver2 *pBonDriver2=dynamic_cast<IBonDriver2*>(pBonDriver);

				if (pBonDriver2!=NULL) {
					int NumSpaces;

					for (NumSpaces=0;pBonDriver2->EnumTuningSpace(NumSpaces)!=NULL;NumSpaces++);
					m_DriverSpaceList.Reserve(NumSpaces);
					TVTest::StringUtility::Assign(m_TunerName,pBonDriver2->GetTunerName());
					for (int i=0;i<NumSpaces;i++) {
						CTuningSpaceInfo *pTuningSpaceInfo=m_DriverSpaceList.GetTuningSpaceInfo(i);
						LPCTSTR pszName=pBonDriver2->EnumTuningSpace(i);

						pTuningSpaceInfo->SetName(pszName);
						CChannelList *pChannelList=pTuningSpaceInfo->GetChannelList();
						for (int j=0;(pszName=pBonDriver2->EnumChannelName(i,j))!=NULL;j++) {
							pChannelList->AddChannel(CChannelInfo(i,j,j+1,pszName));
						}
					}
					m_fDriverSpaceLoaded=true;
				}
				pBonDriver->Release();
			}
			::FreeLibrary(hLib);
		}
		for (int i=0;i<m_TuningSpaceList.NumSpaces();i++) {
			if (m_TuningSpaceList.GetTuningSpaceName(i)==NULL)
				m_TuningSpaceList.GetTuningSpaceInfo(i)->SetName(m_DriverSpaceList.GetTuningSpaceName(i));
		}
	}
	if (!m_fChannelFileLoaded && !m_fDriverSpaceLoaded)
		return false;
	return true;
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
    int opt, bfind, ofind;
    char *bon, *output;
    DWORD dwSpace, dwChannel;

    // パラメータ処理
    bon = output = NULL;
    bfind = ofind = 0;
    dwSpace = dwChannel = 0;
    while ((opt = getopt(argc, argv, "b:s:o:")) != -1)
    {
        switch (opt)
        {
        case 'b':	// BonDriver指定
            bon = optarg;
            bfind = 1;
            break;
        case 's':	// 使用スペース指定(デフォルトは0)
            dwSpace = strtoul(optarg, NULL, 10);
            break;
        case 'o':	// 出力先指定
            output = optarg;
            ofind = 1;
            break;
        default:
            usage(argv[0]);
        }
    }
    if (!bfind)
        usage(argv[0]);

    // モジュールロード
    void *hModule = dlopen(bon, RTLD_LAZY);
    if (!hModule)
    {
        fprintf(stderr, "dlopen error: %s\n", dlerror());
        return -1;
    }

    // 出力先指定無しなら標準出力へ
    if (!ofind)
        wfd = 1;
    else
    {
        wfd = open(output, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
        if (wfd < 0)
        {
            perror("open");
            dlclose(hModule);
            return -2;
        }
    }

    // インスタンス作成
    IBonDriver *pIBon;
    IBonDriver2 *pIBon2;
    pIBon = pIBon2 = NULL;
    char *err;
    IBonDriver *(*f)() = (IBonDriver *(*)())dlsym(hModule, "CreateBonDriver");
    if ((err = dlerror()) == NULL)
    {
        pIBon = f();
        if (pIBon)
            pIBon2 = dynamic_cast<IBonDriver2 *>(pIBon);
    }
    else
    {
        fprintf(stderr, "dlsym error: %s\n", err);
        dlclose(hModule);
        close(wfd);
        return -2;
    }
    if (!pIBon || !pIBon2)
    {
        fprintf(stderr, "CreateBonDriver error: pIBon[%p] pIBon2[%p]\n", pIBon, pIBon2);
        dlclose(hModule);
        close(wfd);
        return -3;
    }

    // ここから実質のチューナオープン & TS取得処理
    BOOL b = pIBon->OpenTuner();
    if (!b)
    {
        fputs("OpenTuner error\n", stderr);
        pIBon->Release();
        dlclose(hModule);
        close(wfd);
        return -3;
    }

    // チャンネル名列挙
    std::vector<std::string> vChName;
    char buf[128];
    LPCTSTR name;
    DWORD ch = 0;
    while (1)
    {
        name = pIBon2->EnumChannelName(dwSpace, ch++);
        if (name == NULL)
            break;
        RevConvert((char *)name, buf, sizeof(buf));
        vChName.push_back(buf);
    }
    for (unsigned int i = 0; i < vChName.size(); i++)
    {
        fprintf(stderr, "[ %u : %s ] ", i, vChName[i].c_str());
        if (i && (((i+1) % 3) == 0))
            fputc('\n', stderr);
    }
    if ((vChName.size() % 3) != 0)
        fputc('\n', stderr);
    fputs("[ p : チャンネル一覧再表示 ] [ q : 終了 ]\n", stderr);

    // 停止シグナル用ハンドラ登録
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handler;
//	sa.sa_flags = SA_RESTART;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);

    // チャンネル選択ループ
    pthread_t hTsRead = 0;
    while (!bStop)
    {
        if (fgets(buf, sizeof(buf), stdin) == NULL)
            continue;
        if (buf[0] < '0' || buf[0] > '9')
        {
            if (buf[0] == 'q')
            {
                bStop = TRUE;
                break;
            }
            if (buf[0] == 'p')
            {
                for (unsigned int i = 0; i < vChName.size(); i++)
                {
                    fprintf(stderr, "[ %u : %s ] ", i, vChName[i].c_str());
                    if (i && (((i+1) % 3) == 0))
                        fputc('\n', stderr);
                }
                if ((vChName.size() % 3) != 0)
                    fputc('\n', stderr);
                fputs("[ p : チャンネル一覧再表示 ] [ q : 終了 ]\n", stderr);
                continue;
            }
            fprintf(stderr, "ch_no select error.\n");
            continue;
        }
        dwChannel = strtoul(buf, NULL, 10);
        if (dwChannel < vChName.size())
        {
            if (pIBon2->SetChannel(dwSpace, dwChannel) == TRUE)
            {
                if (!hTsRead)
                {
                    if (pthread_create(&hTsRead, NULL, TsReader, pIBon))
                    {
                        perror("pthread_create");
                        goto err;
                    }
                }
            }
            else
                fprintf(stderr, "SetChannel(%u, %u) error.\n", dwSpace, dwChannel);
        }
        else
            fprintf(stderr, "ch_no select error.\n");
    }

    pthread_join(hTsRead, NULL);

err:
    if (ofind)
        close(wfd);
    // チューナクローズ
    pIBon->CloseTuner();
    // インスタンス解放 & モジュールリリース
    pIBon->Release();
    dlclose(hModule);
    return 0;
}