📄 ppffplin.cpp
字号:
* plug-in is opened. */STDMETHODIMPCPurePlayFileFormat::InitFileFormat( IHXRequest* /*IN*/ pRequest, IHXFormatResponse* /*IN*/ pFormatResponse, IHXFileObject* /*IN*/ pFileObject){ HX_RESULT theErr = HXR_OK; // used to create HTTP POST msg m_pRequest = pRequest; m_pRequest->AddRef();#ifdef XXXGo_DEBUG m_file = fopen("c:\\live.txt", "wt");#endif // XXXGo_DEBUG#if defined(_TIMELINE_TRACE) || defined(_GETPACKET_TRACE) m_tfile = fopen("c:\\live_t.txt", "wt");#endif // _TIMELINE_TRACE || _GETPACKET_TRACE /* * Create and save off the UDP socket, and start reading in * the file object to parse out to get the file and stream headers * when we successfully get the headers we will call * IHXFormatResponse::InitDone */ /* * Save off the user values for the RTCP SDES messages */ BOOL bAutoTransport = TRUE; IHXPreferences* pPrefs = NULL; IHXBuffer* pBuf = NULL; HX_VERIFY(HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences, (void**)&pPrefs)); if(HXR_OK == pPrefs->ReadPref("AutoTransport", pBuf)) { bAutoTransport = atoi((const char*) pBuf->GetBuffer()); } HX_RELEASE(pBuf); if (bAutoTransport) { m_bAttempMulticast = TRUE; } else { /* check the pref to see if Multicast is disabled */ if (SUCCEEDED(pPrefs->ReadPref("AttemptRTSPvMulticast", pBuf))) { HX_ASSERT(pBuf); m_bAttempMulticast = (BOOL)atol((const char*)pBuf->GetBuffer()); HX_RELEASE(pBuf); } if (m_bAttempMulticast && SUCCEEDED(pPrefs->ReadPref("AttemptPNAvMulticast", pBuf))) { HX_ASSERT(pBuf); m_bAttempMulticast = (BOOL)atol((const char*)pBuf->GetBuffer()); HX_RELEASE(pBuf); } } /* * Handle multiple interface... */ IHXNetworkInterfaceEnumerator* pIFEnum = NULL; if (SUCCEEDED(pPrefs->ReadPref("MulticastInterface", pBuf))) { m_pInterfaceMgr = new InterfaceManager(1); m_pInterfaceMgr->SetInterface (0, DwToHost(HXinet_addr((const char*)pBuf->GetBuffer()))); HX_RELEASE(pBuf); } else if (m_pContext->QueryInterface(IID_IHXNetworkInterfaceEnumerator, (void**)&pIFEnum) == HXR_OK) { const int initialBufferSize = 56; UINT32 ulNumIF = initialBufferSize; UINT32* pulIF = new UINT32[ulNumIF]; theErr = pIFEnum->EnumerateInterfaces(pulIF, ulNumIF); if (HXR_BUFFERTOOSMALL == theErr) { HX_ASSERT(ulNumIF > initialBufferSize); // well, try it again...We know exactly how many IFs there are HX_VECTOR_DELETE(pulIF); pulIF = new UINT32[ulNumIF]; theErr = pIFEnum->EnumerateInterfaces(pulIF, ulNumIF); } if (HXR_OK == theErr) { HX_ASSERT(ulNumIF); m_pInterfaceMgr = new InterfaceManager(ulNumIF); for (UINT32 i = 0; i < ulNumIF; i++) { m_pInterfaceMgr->SetInterface(i, pulIF[i]); } } HX_VECTOR_DELETE(pulIF); HX_RELEASE(pIFEnum); } if (!m_pInterfaceMgr) { // we have no choice... m_pInterfaceMgr = new InterfaceManager(1); m_pInterfaceMgr->SetInterface(0, HX_INADDR_ANY); } // sometimes, m_pCName gets just "" with size == 1 // This is not the right string to use. // so if the string is <= 1, assign a different one. if (HXR_OK != pPrefs->ReadPref(REG_CNAME, m_pCName) || m_pCName->GetSize() <= 1) { /* * Check to see if "UserAddress" exists and use that */ CHXString strTemp; strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"UserAddress"); if (HXR_OK != m_pRegistry->GetStrByName(strTemp, m_pCName) || m_pCName->GetSize() <= 1) { /* * Fill it with junk for now, XXXST Use better junk */ char szNewValue[256]; /* Flawfinder: ignore */ UINT16 cbNewValue; m_pCName = new CHXBuffer; m_pCName->AddRef(); CMultiplePrimeRandom randGen; cbNewValue = sprintf(szNewValue, "RealNetworks%ul", randGen.GetRandomNumber()); /* Flawfinder: ignore */ m_pCName->Set((unsigned char*)szNewValue, cbNewValue + 1); } pPrefs->WritePref(REG_CNAME, m_pCName); } if (HXR_OK != pPrefs->ReadPref(REG_USERNAME, m_pUserName)) { m_pUserName = new CHXBuffer; m_pUserName->AddRef(); m_pUserName->Set((unsigned char*)DEFAULT_USERNAME, strlen(DEFAULT_USERNAME) + 1); pPrefs->WritePref(REG_USERNAME, m_pUserName); } if (HXR_OK != pPrefs->ReadPref(REG_TOOL, m_pTool)) { m_pTool = new CHXBuffer; m_pTool->AddRef(); m_pTool->Set((unsigned char*)DEFAULT_TOOL, strlen(DEFAULT_TOOL) + 1); pPrefs->WritePref(REG_TOOL, m_pTool); } const char* pDefEmailVal = "Not Set"; if (HXR_OK != pPrefs->ReadPref(REG_EMAIL, m_pEmail)) { /* * Write an empty key so the user knows that it is available * to be set */ m_pEmail = new CHXBuffer; m_pEmail->AddRef(); m_pEmail->Set((unsigned char*)pDefEmailVal, strlen(pDefEmailVal) + 1); pPrefs->WritePref(REG_EMAIL, m_pEmail); m_pEmail->Release(); m_pEmail = NULL; } else { /* * Leave the key there but if there is no value then don't * store the string */ if (strcasecmp(pDefEmailVal, (char*)m_pEmail->GetBuffer()) == 0) { m_pEmail->Release(); m_pEmail = NULL; } } IHXBuffer* pBuffer = NULL; // Get server timeout, if available if (HXR_OK != pPrefs->ReadPref("ServerTimeOut", pBuffer)) { // we need a timeout value m_ulServerTimeout = 90000; } else { m_ulServerTimeout = (UINT32) (atol((const char*)pBuffer->GetBuffer()) * 1000); } HX_RELEASE(pBuffer); // done with prefs HX_RELEASE(pPrefs); /* * Find a stream description converter */ IHXPluginEnumerator* pEnum = NULL; IUnknown* pPlugin = NULL; m_pContext->QueryInterface(IID_IHXPluginEnumerator, (void**)&pEnum); HX_ASSERT(pEnum != NULL); HX_ASSERT(m_pStreamDesc == NULL); for (int i = pEnum->GetNumOfPlugins() - 1; i >= 0 && (m_pStreamDesc == NULL || m_pRTPInfo == NULL); i--) { HX_VERIFY(pEnum->GetPlugin(i, pPlugin) == HXR_OK); HX_ASSERT(pPlugin != NULL); if (!m_pStreamDesc) { pPlugin->QueryInterface(IID_IHXStreamDescription, (void**)&m_pStreamDesc); if (m_pStreamDesc) { ((IHXPlugin*) pPlugin)->InitPlugin(m_pContext); } } if (!m_pRTPInfo) { pPlugin->QueryInterface(IID_IHXRTPPayloadInfo, (void**)&m_pRTPInfo); } pPlugin->Release(); } pEnum->Release(); if (m_pStreamDesc == NULL || m_pRTPInfo == NULL) { theErr = HXR_INVALID_PARAMETER; ReportError(IDS_ERR_SM_NOSDPPLIN, HXLOG_ERR, theErr); Close(); goto bail; } m_pFFResponse = pFormatResponse; if (m_pFFResponse == NULL) { theErr = HXR_INVALID_PARAMETER; goto bail; } m_pFFResponse->AddRef(); m_pFileObject = pFileObject; if (m_pFileObject == NULL) { theErr = HXR_INVALID_PARAMETER; goto bail; } m_pFileObject->AddRef(); m_state = Init; m_uStatusCode = HX_STATUS_INITIALIZING; theErr = m_pFileObject->Init(0, this); bail: if (theErr != HXR_OK) m_pFFResponse->InitDone(theErr); return theErr;}/**************************************************************************** * IHXFileResponse::InitDone ref: hxfiles.h * * This routine notifies the RMA core that the initialization of the file is * done. It is called automatically when the initialization of the file * has completed. */STDMETHODIMPCPurePlayFileFormat::InitDone( HX_RESULT status){ HX_ASSERT(m_state == Init); if (SUCCEEDED(status)) { m_state = InitHeader; } m_pFFResponse->InitDone(status); return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::GetFileHeader ref: hxformt.h * * This routine returns to the RMA core an object containing the file * header information. Several routines are actually required to complete * the process due to the asynchronous nature of the RMA file system. This * method is called by the RMA core after the file has been initialized. */STDMETHODIMPCPurePlayFileFormat::GetFileHeader(){ if (m_state != InitHeader) { return m_pFFResponse->FileHeaderReady(HXR_UNEXPECTED, NULL); } // XXXMEH - previously we had just been reading 0xffff // (65535 bytes), and if the SDP file was longer than // that, then we just threw a general error. Ack. // So now we will continue to read 64K until we have read until // we get an error. m_state = PendingFileHeader; return m_pFileObject->Read(READ_SIZE);}HX_RESULT CPurePlayFileFormat::MakeHeader(HX_RESULT status){ if (m_state != PendingFileHeader) { return HXR_UNEXPECTED; } if (status != HXR_OK) { return Close(); } /* * RM: * As soon as we have received packets for all the streams, good to go. * After ServerTimeout and still haven't gotten packets for all the * streams, NO PRESENTATION * STANDARD: * As soon as we have received a first packet, we will wait extra 5 to * 10 sec to decide the number of streams for this presentation * After ServerTimeout and still haven't gotten any packet, * NO PRESENTATION: otherwise, go with whatever we've got */ // we have to wait for a while, so streams can decide how many senders // exist! CPurePlayFileFormat::CFileHeaderCallback* pFHCB = new CPurePlayFileFormat::CFileHeaderCallback(this); m_ulFileHeaderWaitStartTime = HX_GET_BETTERTICKCOUNT(); pFHCB->AddRef(); m_hFileHeader = m_pScheduler->RelativeEnter(pFHCB, PP_RM_TIMEOUT_MS); pFHCB->Release(); m_uStatusCode = HX_STATUS_CONTACTING; m_bInitialPacket = TRUE; return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::GetStreamHeader ref: hxformt.h * * This routine returns to the RMA core an object containing the stream * header information for a particular stream. Several routines are actually * required to complete the process due to the asynchronous nature of the * RMA file system. This method is called (after the file header has been * read) by the RMA core for each stream in the file format. */STDMETHODIMPCPurePlayFileFormat::GetStreamHeader(UINT16 unStreamNumber){ if (unStreamNumber > m_rgStreams.GetSize()) { m_pFFResponse->StreamHeaderReady(HXR_FAIL, NULL); } else { // get the right source CPurePlaySource* pSrc; pSrc = (CPurePlaySource*)m_rgStreams.GetAt(unStreamNumber); pSrc->AddRef(); IHXValues* pHeader = NULL; pSrc->GetHeader(pHeader, unStreamNumber); HX_ASSERT(pHeader != NULL);#ifdef XXXGo_DEBUG ULONG32 ulStrmNum = 1000; pHeader->GetPropertyULONG32("StreamNumber", ulStrmNum); if (pSrc->m_pFFLog) { fprintf(pSrc->m_pFFLog, "Sending Stream Header for stream %d (%d)\n", unStreamNumber, ulStrmNum); } #endif // it's ready!// HX_ASSERT(HXR_OK == m_pFFResponse->StreamHeaderReady(HXR_OK, pHeader)); if (m_pFFResponse->StreamHeaderReady(HXR_OK, pHeader) != HXR_OK) { HX_ASSERT(FALSE); } pHeader->Release(); pSrc->Release(); } return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::GetPacket ref: hxformt.h * * This routine returns to the RMA core an object containing the packet * data for a particular stream. Several routines are actually required to * complete the process due to the asynchronous nature of the RMA file * system. This method is called by the RMA core each time it needs another * packet. */STDMETHODIMPCPurePlayFileFormat::GetPacket(UINT16 unStreamNumber){#ifdef XXXGo_DEBUGstatic UINT32 ulCount = 0;#endif /* * There be packets wait'n for us on the socket */ if (m_bInitialPacket) { m_bInitialPacket = FALSE; /* * Get the registry ID for this source so we can update the * clip bandwidth info when we get time. */ IHXStreamSource* pSource = NULL; if (HXR_OK == m_pFFResponse->QueryInterface(IID_IHXStreamSource, (void**)&pSource)) { IHXRegistryID* pSourceRegistryID = NULL; pSource->QueryInterface(IID_IHXRegistryID, (void**)&pSourceRegistryID); if (pSourceRegistryID) { UINT32 ulSourceID = 0; IHXBuffer* pSourceRegName = NULL; IHXBuffer* pTransportName = NULL; char szTransportID[256]; /* Flawfinder: ignore */ /* Need to come from a resource file */ char szTransportName[] = "Scalable Multicast"; pSourceRegistryID->GetID(ulSourceID); m_pRegistry->GetPropName(ulSourceID, pSourceRegName); HX_ASSERT(pSourceRegName); if (pSourceRegName) { SafeSprintf(szTransportID, 256, "%s.TransportMode", pSourceRegName->GetBuffer()); pTransportName = new CHXBuffer; pTransportName->AddRef(); pTransportName->Set((UCHAR*) szTransportName, sizeof(szTransportName) + 1); m_pRegistry->SetStrByName(szTransportID, pTransportName); } HX_RELEASE(pTransportName); HX_RELEASE(pSourceRegName); HX_RELEASE(pSourceRegistryID); } UINT16 cStreams = pSource->GetStreamCount(); for (UINT16 iStream = 0; iStream < cStreams; iStream++) { IUnknown* pSrcUnk = NULL; IHXStream* pSrc = NULL; IHXRegistryID* pRegistryID = NULL; IHXBuffer* pSrcReg = NULL; CPurePlaySource* pPpSrc = NULL; CStream* pStream = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -