📄 ppffplin.cpp
字号:
UINT32 ulStreamRegID = 0; char szClipID[256]; /* Flawfinder: ignore */ UINT32 ulClipID = 0; UINT16 uStreamNum = 0; if (HXR_OK != pSource->GetStream(iStream, pSrcUnk)) goto NextSource; if (HXR_OK != pSrcUnk->QueryInterface(IID_IHXStream, (void**)&pSrc)) goto NextSource; if (HXR_OK != pSrc->QueryInterface(IID_IHXRegistryID, (void**)&pRegistryID)) goto NextSource; if (HXR_OK != pRegistryID->GetID(ulStreamRegID)) goto NextSource; // save this id so we can get stream stats later.// m_ulStreamRegID = ulStreamRegID; // deal with bandwidth reg key if (HXR_OK != m_pRegistry->GetPropName(ulStreamRegID, pSrcReg)) goto NextSource; SafeSprintf(szClipID, 256, "%s.ClipBandwidth", pSrcReg->GetBuffer()); // Get corresponding CPurePlaySource uStreamNum = pSrc->GetStreamNumber(); pPpSrc = (CPurePlaySource*) m_rgStreams[uStreamNum]; HX_ASSERT(pPpSrc); if (!pPpSrc) goto NextSource; pPpSrc->AddRef(); // Get the CStream pStream = pPpSrc->GetStreamByStrmId(uStreamNum); HX_ASSERT(pStream); if (!pStream) goto NextSource; // save the StreamRegID, so we can get stream stats later. pStream->m_ulStreamRegId = ulStreamRegID; // if this is Standard payload, then "AvgBitRate" is hard coded // in sdpplin, and so can't trust them. // Also, pPpSrc->m_ulBandwidth of 1 suggest the absence of // "AvgBitRate" in SDP file if ((!pPpSrc->IsRMSource()) || 1 == pPpSrc->GetBandwidth()) { ulClipID = m_pRegistry->GetId(szClipID); if (ulClipID == 0) goto NextSource; pStream->m_ulClipBandwidthID = ulClipID; } else { HX_ASSERT(pPpSrc->GetBandwidth() != 1); // trust bandwidth in the header pStream->m_ulClipBandwidthID = 0; m_pRegistry->SetIntByName(szClipID, pPpSrc->GetBandwidth()); } NextSource: HX_RELEASE(pPpSrc); HX_RELEASE(pSrcReg); HX_RELEASE(pRegistryID); HX_RELEASE(pSrc); HX_RELEASE(pSrcUnk); } pSource->Release(); } }#ifdef XXXGo_DEBUGif (m_file){ fprintf(m_file, "\t\t\t\t\t%u: GetPacket(): streamNumber = %u\n", ulCount++, unStreamNumber);}#endif ULONG32 ulTimeNow = HX_GET_BETTERTICKCOUNT();#ifdef _GETPACKET_TRACE /* if (m_tfile) { fprintf(m_tfile, "**GetPacket strm=%u RT=%u\n", unStreamNumber, ulTimeNow - m_ulStartTimeMS); } */#endif // _GETPACKET_TRACE CPurePlaySource* pSrc = (CPurePlaySource*)m_rgStreams.GetAt(unStreamNumber); pSrc->AddRef(); pSrc->SetPendingFlag(unStreamNumber, TRUE); pSrc->UpdateStatistics(m_pRegistry, ulTimeNow); pSrc->Release(); return ProcessPendingPackets(FALSE, ulTimeNow);}/**************************************************************************** * IHXFileResponse::SeekDone ref: hxfiles.h * * This routine is automatically called when the Seek() operation in the * file is complete. Other actions are then taken dependent on the current * processing state. */STDMETHODIMPCPurePlayFileFormat::SeekDone(HX_RESULT status){ return HXR_NOTIMPL;}/**************************************************************************** * IHXFileResponse::ReadDone ref: hxfiles.h * * This routine is automatically called when the Read() from the file is * done. Other actions are then taken dependent on the current processing * state. */STDMETHODIMPCPurePlayFileFormat::ReadDone( HX_RESULT status, IHXBuffer* pBuffer){ HX_ASSERT(m_state == PendingFileHeader); HX_ASSERT(m_pStreamDesc != NULL); HX_RESULT theErr = HXR_OK; UINT16 cHeaders = 0; IHXValues** ppHeaders = NULL; // all the headers CHXSimpleList newConns; UINT32 ulAddr = 0; IHXBuffer* pFileAddr = NULL; IHXUDPResponse* pResp = NULL; int i = 0; IHXPreferences* pPrefs = NULL; IHXBuffer* pBandwidth = NULL; IHXValues** ppRealHeaders = NULL;;// headers of right BW UINT32* pulSubscriptionBW = NULL; // XXXMEH - we are reading READ_SIZE (64k) bytes // at a time. When we finally fail, then we will aggregate // all our 64K buffers into one and then continue below. IHXBuffer* pAggBuffer = NULL; if (SUCCEEDED(status)) { // Do we have a file buffer list? if (!m_pFileBufferList) { m_pFileBufferList = new CHXSimpleList(); } if (m_pFileBufferList) { // AddRef the buffer before it goes on the list pBuffer->AddRef(); // Put it on the list m_pFileBufferList->AddTail((void*) pBuffer); // Was this read less than READ_SIZE? if (pBuffer->GetSize() < READ_SIZE) { // We've hit the end of the file, go // ahead and aggregate AggregateBuffers(pAggBuffer); } else { // Set the state m_state = PendingFileHeader; // Read another READ_SIZE bytes return m_pFileObject->Read(READ_SIZE); } } } else { // Aggregate the buffers. The only time we should // hit this is if the .sdp file is exactly a multiple // of READ_SIZE AggregateBuffers(pAggBuffer); } // Now we can clear the buffer list ClearFileBufferList(); HX_DELETE(m_pFileBufferList); if (!pAggBuffer) { return m_pFFResponse->FileHeaderReady(HXR_FAIL, NULL); } /* NULL terminate the description buffer */ m_pSDPDesc = new CHXBuffer; m_pSDPDesc->AddRef(); m_pSDPDesc->SetSize(pAggBuffer->GetSize() + 1); ::memcpy(m_pSDPDesc->GetBuffer(), pAggBuffer->GetBuffer(), pAggBuffer->GetSize()); /* Flawfinder: ignore */ m_pSDPDesc->GetBuffer()[pAggBuffer->GetSize()] = '\0'; // Release the aggregated buffer HX_RELEASE(pAggBuffer); /* * Now that we have a file, create the stream and file headers */ theErr = m_pStreamDesc->GetValues(m_pSDPDesc, cHeaders, ppHeaders); if (theErr != HXR_OK || cHeaders == 0 || ppHeaders == NULL) { theErr = HXR_INVALID_FILE; ReportError(IDS_ERR_SM_BADSDPFILE, HXLOG_ERR, theErr); goto bail; } /* * A SDP file open may not contain a stream that we can play at all. * so, make sure there is at least one stream in this header. * If there is no strearm for presentation, tell the user and quit */ if (1 == cHeaders) { // there is only file header theErr = HXR_INVALID_FILE; ReportError(IDS_ERR_SM_NOPLAYTYPE, HXLOG_ERR, theErr); goto bail; } /* * Save off the headers then try to find our custom file attributes * which will allow us to setup a network socket * * ppHeaders[0] == File Header * ppHeaders[1-N] == Stream Headers */ m_pFileHeader = ppHeaders[0]; if (m_pFileHeader == NULL) { theErr = HXR_INVALID_FILE; goto bail; } m_pFileHeader->AddRef(); /* check to see if we wanna try this feed at all */ if (!m_bAttempMulticast) { m_tryUnicast = NO_MULTICAST; goto bail; } HX_VERIFY(HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences, (void**)&pPrefs)); // Client stats enabled? // m_bWantClientStats defaults to FALSE UINT32 ul; if (HXR_OK == m_pFileHeader->GetPropertyULONG32("StatsStyle", ul) && HXR_OK == m_pFileHeader->GetPropertyULONG32("StatsMask", ul)) { IHXBuffer* pPrefBuffer = NULL; if (SUCCEEDED(pPrefs->ReadPref("SendStatistics", pPrefBuffer))) { m_bWantClientStats = (BOOL)atoi((const char*) pPrefBuffer->GetBuffer()); HX_RELEASE(pPrefBuffer); } } BOOL bFoundBW; if (HXR_OK != pPrefs->ReadPref("Bandwidth", pBandwidth)) { bFoundBW = FALSE; HX_ASSERT(FALSE); pBandwidth = new CHXBuffer(); pBandwidth->AddRef(); pBandwidth->Set((const unsigned char*)"64000", strlen("64000")); } else { bFoundBW = TRUE; } HX_RELEASE(pPrefs); /* Timeout */ if (SUCCEEDED(m_pFileHeader->GetPropertyULONG32("Timeout", ul))) { // it's in sec m_ulFailoverTimeout = ul * 1000; } else { m_ulFailoverTimeout = m_ulServerTimeout; } /* * The connection line could be stored in the session header * rather than the media description so try to get it even if fails */ m_pFileHeader->GetPropertyCString(PROP_MULTI_ADDRESS, pFileAddr); /* * Since we only server live streams make sure the core knows this * The stream count may not be included in the SDP file so add it * here */ m_pFileHeader->SetPropertyULONG32("LiveStream", 1); /* * Get a number of streams in this presentation */ ULONG32 ulNumStreams; ulNumStreams = 0; // don't trust the "StreamCount" // cHeaders will represent a number of m= line in SDP // ulNumStreams is actual number of streams in this presentation // They will be different on sure stream presentation becacause we are // duplicating headers for each bandwidth. // we have to iterate over the stream headers... if (GetStreamCountNoTrust(&ppHeaders[1], cHeaders - 1, ulNumStreams) != TRUE) { // Well, This is not a SDP file generated by pplyfobj.cpp. // Trust the StreamCount! m_pFileHeader->GetPropertyULONG32("StreamCount", ulNumStreams); ppRealHeaders = new IHXValues*[ulNumStreams]; for ( i = 0; i < (int)ulNumStreams; i++) { ppRealHeaders[i] = ppHeaders[i+1]; ppRealHeaders[i]->AddRef(); } } else { // we should have at least one stream HX_ASSERT(ulNumStreams > 0); // set the StreamCount m_pFileHeader->SetPropertyULONG32("StreamCount", ulNumStreams); /* * Get a BW for each stream to "subscribe" to */ pulSubscriptionBW = new UINT32[ulNumStreams]; memset(pulSubscriptionBW, 0, sizeof(UINT32) * ulNumStreams); if (GetSubscriptionBW(m_pFileHeader, &ppHeaders[1], cHeaders - 1, pulSubscriptionBW, ulNumStreams, pBandwidth) != TRUE) { // this should never happen theErr = HXR_FAIL; goto bail; } // if we have gotten BW info from pref., then check for an actual // BW info. if (bFoundBW) { UINT32 ulBW = 0; for (UINT32 i = 0; i < ulNumStreams; i++) { ulBW += pulSubscriptionBW[i]; } if (ulBW > (UINT32)atol((const char*)pBandwidth->GetBuffer())) { // this will end a presentation theErr = HXR_FAIL; ReportError(IDS_ERR_SM_NOTENOUGHBANDWIDTH, HXLOG_ERR, theErr); goto bail; } } /************************** * Get right stream headers to pass to CPurePlaySource * We have figured out BW to use for each stream * This is expensive, but...hey, it's done only once * Iterate over all the stream headers AGAIN, and Get right stream headers * for each stream depending on subscription BW */ if (GetRightHeaders(ppRealHeaders, ulNumStreams, &ppHeaders[1], cHeaders - 1, pulSubscriptionBW) != TRUE) { // this should never happen theErr = HXR_FAIL; goto bail; } } m_bRMPresentation = DetermineIfRMPresentation( ppHeaders[0], &(ppHeaders[1]), ulNumStreams); /* * Almost done! * Now that we have the right headers, create CPurePlaySource * for each stream */ UINT32 ulRTPPayload; ulRTPPayload = 0; for (i = 0; i < (int)ulNumStreams; i++) { HX_ASSERT(NULL != ppRealHeaders[i]); if (NULL == ppRealHeaders[i]) { theErr = HXR_FAIL; goto bail; } /* * CPurePlaySource will addref the header */ IHXValues* pSrcHeader; IHXBuffer* pSrcAddr; UINT32 ulPort; UINT32 ulRTPFactor; UINT32 ulHXFactor; ULONG32 ulPreroll; ulRTPFactor = 0; ulHXFactor = 0; ulPreroll = 0; pSrcHeader = ppRealHeaders[i]; pSrcHeader->AddRef(); theErr = pSrcHeader->GetPropertyULONG32(PROP_RTP_PAYLOAD, ulRTPPayload); if (HXR_OK != theErr) { HX_ASSERT(FALSE); ReportError(IDS_ERR_SM_NOTFOUNDPAYLOAD, HXLOG_ERR, theErr); goto bail; } theErr = pSrcHeader->GetPropertyCString(PROP_MULTI_ADDRESS, pSrcAddr); if (theErr != HXR_OK) { /* * It is OK for now that we don't have the address * we'll use it from the file header if there */ if (pFileAddr == NULL) { pSrcHeader->Release(); ReportError(IDS_ERR_SM_NOTFOUNDADDRESS, HXLOG_ERR, theErr); goto bail; } pSrcAddr = pFileAddr; pSrcAddr->AddRef(); theErr = HXR_OK; } theErr = pSrcHeader->GetPropertyULONG32(PROP_MULTI_PORT, ulPort); if (theErr != HXR_OK) { /* * This is a problem. No port, no play */ pSrcHeader->Release(); ReportError(IDS_ERR_SM_NOTFOUNDPORT, HXLOG_ERR, theErr); goto bail; } /* * Get the RTP->RMA timestamp conversion ratio from the stream * headers. */ pSrcHeader->GetPropertyULONG32(PROP_RTP_FACTOR, ulRTPFactor); pSrcHeader->GetPropertyULONG32(PROP_HX_FACTOR, ulHXFactor); if ((ulRTPFactor == 0) || (ulHXFactor == 0)) { ulHXFactor = 1000; if (!m_bRMPresentation) { pSrcHeader->GetPropertyULONG32("SamplesPerSecond", ulRTPFactor);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -