📄 ppffplin.cpp
字号:
HX_RELEASE(pSrcH); } if (!bFound) { // this should never haappen ppRealHeaders[i] = NULL; HX_ASSERT(FALSE); return FALSE; } } return TRUE;}/**************************************************************************** * IHXFileFormatObject::Seek ref: hxformt.h * * This routine moves to the packet nearest to the requested time in the * file. It is called, for example, in response to the user moving the * slider to a different location in the playback timeline. */STDMETHODIMPCPurePlayFileFormat::Seek(UINT32 ulOffset){ m_pFFResponse->SeekDone(HXR_NOTIMPL); return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::Close ref: hxformt.h * * This routine handles any cleanup required before closing the plug-in. All * references to objects should be released and memory deallocated. This is * called by the RMA core when the playback is finished or stopped. */STDMETHODIMPCPurePlayFileFormat::Close(){ /* * Release all of our resources that were allocated in * InitFileFormat and along the way */ AddRef(); if (m_state != Closed) { PurePlayFFState incommingState = m_state; BOOL bUnicastLaunched = FALSE; m_state = Closed; if (m_tryUnicast != NO_TRY) { if (HXR_OK == SwitchToUnicast()) { bUnicastLaunched = TRUE; } else { HX_ASSERT(!m_bFileHeaderReadyCalled); switch (m_tryUnicast) { case TIMEOUT: ReportError(IDS_ERR_SM_NOACTIVESENDERS, HXLOG_ERR, HXR_FAIL); break; case SOCKET_FAIL: // there is no way to put address/port info through // FileHeaderReady(), so just display error here. ReportErrorWithFormat(IDS_ERR_SM_SOCKFAILED, m_strLastErr, HXLOG_ERR, HXR_FAIL); break; case NO_MULTICAST: ReportError(IDS_ERR_SM_NOMULTICAST, HXLOG_ERR, HXR_FAIL); break; default: HX_ASSERT(!"Don't know this m_tryUnicast"); ReportError(IDS_ERR_SM_GENERAL, HXLOG_ERR, HXR_FAIL); } HX_ASSERT(m_pFFResponse); } m_tryUnicast = NO_TRY; } if (!bUnicastLaunched) { if (incommingState == PendingFileHeader) { if (m_pFFResponse) { m_pFFResponse->FileHeaderReady(HXR_FAIL, NULL); } } } if (m_hFileHeader) { m_pScheduler->Remove(m_hFileHeader); m_hFileHeader = 0; } HX_ASSERT((m_rgStreams.IsEmpty() && m_pInterfaceMgr) || (!m_rgStreams.IsEmpty() && !m_pInterfaceMgr)); if (m_rgStreams.GetSize() >= 1 && WantClientStats()) { SendStatistics(); } for (int i = m_rgStreams.GetSize() - 1; i >= 0; i--) { m_pFFResponse->StreamDone(i); CPurePlaySource* pSrc = (CPurePlaySource*)m_rgStreams.GetAt(i); pSrc->Close(); pSrc->Release(); } m_rgStreams.RemoveAll(); HX_DELETE(m_pInterfaceMgr); HX_VECTOR_DELETE(m_ppInterfacesReady); m_ulNumInterfacesReady = 0; HX_RELEASE(m_pLog); HX_RELEASE(m_pScheduler); HX_RELEASE(m_pRegistry); HX_RELEASE(m_pClassFactory); HX_RELEASE(m_pStreamDesc); HX_RELEASE(m_pRTPInfo); HX_RELEASE(m_pFFResponse); if (m_pFileObject) { m_pFileObject->Close(); HX_RELEASE(m_pFileObject); } ClearFileBufferList(); HX_DELETE(m_pFileBufferList); HX_RELEASE(m_pSDPDesc); HX_RELEASE(m_pFileHeader); HX_RELEASE(m_pStatusDesc); HX_RELEASE(m_pRequest); HX_RELEASE(m_pCName); HX_RELEASE(m_pUserName); HX_RELEASE(m_pTool); HX_RELEASE(m_pEmail); }#ifdef XXXGo_DEBUG if (m_file) { fclose(m_file); }#endif // XXXGo_DEBUG#if defined(_TIMELINE_TRACE) || defined(_GETPACKET_TRACE) if (m_tfile) { fclose(m_tfile); }#endif // _TIMELINE_TRACE || _GETPACKET_TRACE Release(); return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::CloseDone ref: hxformt.h * */STDMETHODIMPCPurePlayFileFormat::CloseDone(HX_RESULT status){ // it should have been released in ReadDone() HX_ASSERT(m_pFileObject); return HXR_OK;}/**************************************************************************** * IHXFileFormatObject::WriteDone ref: hxformt.h * */STDMETHODIMPCPurePlayFileFormat::WriteDone(HX_RESULT status){ return HXR_UNEXPECTED;}/**************************************************************************** * IHXASMSource::Subscribe ref: hxasm.h * */STDMETHODIMPCPurePlayFileFormat::Subscribe( UINT16 uStreamNumber, UINT16 uRuleNumber){ return HXR_NOTIMPL;}/**************************************************************************** * IHXASMSource::Unsubscribe ref: hxasm.h * */STDMETHODIMPCPurePlayFileFormat::Unsubscribe( UINT16 uStreamNumber, UINT16 uRuleNumber){ return HXR_NOTIMPL;}STDMETHODIMPCPurePlayFileFormat::GetStatus( REF(UINT16) uStatusCode, REF(IHXBuffer*) pStatusDesc, REF(UINT16) ulPercentDone){ // The message given here will be deleted by the core // "Loading (%)" message once we start returning packets to the core uStatusCode = m_uStatusCode; if (uStatusCode == HX_STATUS_CONTACTING) { pStatusDesc = new CHXBuffer(); pStatusDesc->AddRef(); CHXString statusDesc; statusDesc.Format("Connecting..."); pStatusDesc->Set((UCHAR*)(const char*) statusDesc, strlen((const char*) statusDesc) + 1); } else if (uStatusCode == HX_STATUS_BUFFERING) { ulPercentDone = (100 * (HX_GET_BETTERTICKCOUNT() - m_ulListeningWaitStartTime)) / LISTENINING_TIME_INTERVAL; if (ulPercentDone > 99) { ulPercentDone = 99; } pStatusDesc = new CHXBuffer(); pStatusDesc->AddRef(); CHXString statusDesc; statusDesc.Format("Listening"); pStatusDesc->Set((UCHAR*)(const char*) statusDesc, strlen((const char*) statusDesc) + 1); } return HXR_OK;}/*** First figure out the stream with the smallest TS to send to the core.** If packet is pending for the stream with smallest TS, send it.*/HX_RESULTCPurePlayFileFormat::ProcessPendingPackets(BOOL bUseAutoTime, ULONG32 ulTimeNow){ /* we need to look for a packet with the smallest TS */ INT32 j; UINT32 ulTS = 0; HX_RESULT theErr = HXR_OK; CPurePlaySource* pSource = NULL; CStream* pStream = NULL; if (bUseAutoTime) { ulTimeNow = HX_GET_BETTERTICKCOUNT(); } /* * We may be waiting for a packet off the wire or we already have the * packet and need to send it to the core. In GetPacket, the pending * flag is set for each stream that the core needs. DataFromSocket will * add the packets for each stream to the pending list. */ if (m_state == Closed) { // Since we have to send BYE msg right before we stop, and since we get // what we send from the same socket, this pkt is our RTCP_BYE msg. return HXR_CLOSED; } if (0 >= m_uActiveStreams) { // there is no active stream. return HXR_OK; } HX_ASSERT(m_uActiveStreams == m_rgStreams.GetSize()); if (!m_bFirstPktRcvd) { m_bFirstPktRcvd = TRUE; m_ulStartTimeMS = HX_GET_BETTERTICKCOUNT(); m_ulHXOffset = 0; } /* Check if we need to look for a packet with the smallest TS */ if (m_lSmallestTSStrm == -1) { INT32 lSmallest = -1; ULONG32 ulSmallest = 0; INT32 lLargest = -1; ULONG32 ulLargest = 0; BOOL bInitial = TRUE; BOOL bIsLost = FALSE; // Find the stream with the smallest time stamp // iterate through all the streams and compare the TS's for (j = 0; j < m_rgStreams.GetSize(); j++) { if ((pSource = (CPurePlaySource*)m_rgStreams.GetAt(j)) && (pStream = pSource->GetStreamByStrmId(j))) { theErr = pStream->GetNextTS(ulTS, ulTimeNow); if (HXR_OK == theErr) { if (bInitial) { ulSmallest = ulTS; lSmallest = j; ulLargest = ulTS; lLargest = j; bInitial = FALSE; } else { if (!IS_TS1_LESS_THAN_EQUAL_TS2(ulSmallest, ulTS)) { ulSmallest = ulTS; lSmallest = j; } else if (!IS_TS1_LESS_THAN_EQUAL_TS2(ulTS, ulLargest)) { ulLargest = ulTS; lLargest = j; } } } else if (HXR_BUFFERING == theErr) { // We must fullfill buffering for all streams before // proceeding to successfully resequence any // out-of-order packets. However, if we have nothing // in the transport buffer, there is no limit to // how long we may need to wait, so we do not wait // in such case. if (pStream->GetBufferedPacketCount() > 0) {#ifdef _TIMELINE_TRACE if (m_tfile) { fprintf(m_tfile, "BUFFERING #%d BufSze=%d BufAge=%d\n", j, pStream->GetBufferedPacketCount(), pStream->GetBufferAge(ulTimeNow)); } #endif // _TIMELINE_TRACE // if (!m_bFirstPktSent) { // During initial buffering make sure we wait // long enough to have good selection of the // smallest time stamped packet lSmallest = -1; break; } }#ifdef _TIMELINE_TRACE else if (m_tfile) { fprintf(m_tfile, "EMPTY #%d\n", j); } #endif // _TIMELINE_TRACE } else if (HXR_STREAM_DONE == theErr) { pSource->RemoveSource(pStream->m_ulSSRC);#ifdef _TIMELINE_TRACE if (m_tfile) { fprintf(m_tfile, "STREAM_DONE #%d\n", j); } #endif // _TIMELINE_TRACE } else { // this packet is lost... // Since a TS for next packet is unknown, we will use Last // TS for this stream -> this stream has to be the one with // the smallest TS as a packet with this TS has already been sent to // the core. lSmallest = j; bIsLost = TRUE;#ifdef _TIMELINE_TRACE if (m_tfile) { fprintf(m_tfile, "LOST #%d\n", j); }#endif // _TIMELINE_TRACE break; } } } m_lSmallestTSStrm = lSmallest; // Handle Offset and Resync (only on data of non-lost packets) if ((!bIsLost) && (m_lSmallestTSStrm != -1)) {#ifdef _ALLOW_TS_OFFSETTING#ifdef _DO_RESYNC if (m_bFirstPktSent) { LONG32 lTSDelta = (LONG32) (ulSmallest - m_ulSmallestTS); // If there is a jolt in the timeline - resync if ((!m_bDisableOffsetting) && ((lTSDelta > MAX_TIME_GAP_FORWARD) || (lTSDelta < (-MAX_TIME_GAP_BACKWARD)))) { // Resync m_ulHXOffset += lTSDelta; #ifdef _TIMELINE_TRACE if (m_tfile) { fprintf(m_tfile, "RESYNC #%d by %dms\n", m_lSmallestTSStrm, lTSDelta); }#endif // _TIMELINE_TRACE if (!m_bRMPresentation) { // Time stamps do not have to be ordered m_ulHXOffset -= STANDARD_START_HXOFFSET; } }#ifdef _DO_BUFFER_OCCUPANCY_CHECKS else { lTSDelta = (LONG32) (ulLargest - m_ulSmallestTS); if (lTSDelta > MAX_TIME_GAP_FORWARD) { if ((pSource = (CPurePlaySource*) m_rgStreams.GetAt(lLargest)) && (pStream = pSource->GetStreamByStrmId(lLargest))) { if (pStream->GetBufferedPacketCount() > MAX_SUSPENDED_BUFFER_SIZE) { // We have large number of packets accumulated in the // transport buffer and no chance of reducing the // buffer count any time soon. // Remove a packet from this stream. IHXPacket* pPacket = NULL; pStream->GetPacket(pPacket, ulTimeNow); HX_RELEASE(pPacket); } } } }#endif // _DO_BUFFER_OCCUPANCY_CHECKS }#endif // _DO_RESYNC#endif // _ALLOW_TS_OFFSETTING m_ulSmallestTS = ulSmallest; } } // Check if we found the smallest time stamp stream if (m_lSmallestTSStrm != -1) { pSource = (CPurePlaySource*)m_rgStreams.GetAt(m_lSmallestTSStrm); if (pSource->GetPendingFlag(m_lSmallestTSStrm)) { pStream = pSource->GetStreamByStrmId(m_lSmallestTSStrm); HX_ASSERT(pStream); IHXPacket* pPacket = NULL; theErr = pStream->G
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -