📄 ppffsrc.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: ppffsrc.cpp,v 1.3.30.1 2004/07/19 21:04:16 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** *//////////////////////////////////////////////////////////////////////////////// Defines//// #define _SYNC_TRACE#define MAX_BUFFERED_STREAM_PACKETS 30000#define UNLOCK_THRESHOLD_LEVEL 15000#define _USE_MASTER_STREAM_SYNC_SCHEME#define AUDIO_MIME_PREFIX "audio/"#define AUDIO_MIME_PREFIX_SIZE (sizeof(AUDIO_MIME_PREFIX) - 1)#define VIDEO_MIME_PREFIX "video/"#define VIDEO_MIME_PREFIX_SIZE (sizeof(VIDEO_MIME_PREFIX) - 1)#define STARTING_HX_TIMESTAMP 100000 // in ms/////////////////////////////////////////////////////////////////////////////// Includes//#include "hxtypes.h"#include "hxcom.h"#include "hxcomm.h"#include "hxprefs.h"#include "hxengin.h"#include "ihxpckts.h"#include "hxerror.h"#include "rtptypes.h"#include "rtpwrap.h"#include "hxrand.h"#include "hxslist.h"#include "hxstring.h"#include "hxstrutl.h"#include "chxpckts.h"#include "hxbuffer.h"#include "hxmime.h"#include "tconverter.h"#include "asmrulep.h"#include "hxtick.h"#include "netbyte.h"#include "rtcpmisc.h"#include "hxmon.h"//#include "hxengin.h"#include "hxmarsh.h"#include "mimechk.h"#include "scalmres.h" // in coreres...#include "carray.h"#include "ppffplin.h"#include "ppbin.h"#include "ppffsrc.h"#include "hxheap.h"#ifdef _DEBUG#undef HX_THIS_FILE static char HX_THIS_FILE[] = __FILE__;#endif#ifdef _SYNC_TRACEFILE* m_sfile = NULL;#endif // _SYNC_TRACEUINT32 GetCurrentSchedulerTimeInMsec(IHXScheduler* pScheduler) { if (!pScheduler) { HX_ASSERT(FALSE); return 0; } HXTimeval lTime = pScheduler->GetCurrentSchedulerTime(); return lTime.tv_sec * 1000 + lTime.tv_usec / 1000; }/******************************************************************* CPurePlaySource::CPurePlaySource** Constuctor finds the RTP type and sample size/bitrate for* timestamp conversion. Also acts as packet queue*/CPurePlaySource::CPurePlaySource( CPurePlayFileFormat* pPlugin, IHXValues* pHeader, UINT16 iStream, UINT32 ulRTPFactor, UINT32 ulHXFactor, BOOL bIsRMSource ) : m_lRefCount(0) , m_pPlugin(pPlugin) , m_pHeader(pHeader) , m_iStream(iStream) , m_pNet(NULL) , m_pResolver(NULL) , m_pRTPSock(NULL) , m_pRTCPSock(NULL) , m_pRTPResp(NULL) , m_pRTCPResp(NULL) , m_chRTPPayload(-1) , m_chTTL(DEFAULT_TTL) , m_uMultiPort(0) , m_ulMultiAddr(0) , m_ulInterfaceAddr(0) , m_pRules(NULL) , m_cRules(0) , m_bInitialPacket(TRUE) , m_ulRTPFactor(ulRTPFactor) , m_ulHXFactor(ulHXFactor) , m_ulLost(0) , m_bBeginPending(FALSE) , m_lHXOffset(0) , m_ulClipBandwidthID(0) , m_ulBandwidth(64000) , m_hStatusCallbackID(0) , m_ulThisSrcID(0) , m_pRTCPInterval(NULL) , m_pCName(NULL) , m_pName(NULL) , m_pTool(NULL) , m_pEmail(NULL) , m_bClosed(FALSE) , m_algorithm(ALGORITHM_B) , m_pByePkt(NULL) , m_bRTCPSent(FALSE) , m_ulBeginClockTick(0) , m_bTimeStampDelivery(FALSE) , m_bIsRMSource(bIsRMSource) , m_bIsEncryptedSource(FALSE) , m_ulStartedSourceCount(0) , m_ulHXMasterTime(0) , m_lHXOffsetToMaster(0) , m_bSyncDistributed(FALSE) , m_ulHXAnchorTime(0) , m_ulNTPHXTime(0) , m_bSyncAnchorDistributed(FALSE) , m_ulStartTime(0) , m_bStartTimeDistributed(FALSE) , m_StreamType(CStream::STREAM_TYPE_OTHER){ IHXBuffer* pBuffer = NULL; HX_RESULT retVal = HXR_OK; HX_ASSERT(m_pHeader != NULL); HX_ASSERT(m_pPlugin != NULL); HX_ASSERT(iStream >= 0); HX_ASSERT(ulRTPFactor >= 0); HX_ASSERT(ulHXFactor >= 0); #ifdef XXXGo_DEBUG static INT32 lCount = 1; char cFileName[30]; /* Flawfinder: ignore */ memset(cFileName, 0, 30); SafeSprintf(cFileName, 30, "c:\\temp\\fflog%d.txt", lCount); m_pFFLog = fopen(cFileName, "wt"); memset(cFileName, 0, 30); SafeSprintf(cFileName, 30, "c:\\temp\\ppff%d.txt", lCount++); m_pLogFile= fopen(cFileName, "wt"); int lByeWritten = fprintf(m_pLogFile, "File created\n");#endif m_pHeader->AddRef(); m_pPlugin->AddRef(); retVal = pHeader->GetPropertyCString("MimeType", pBuffer); // Determine the stream type if (SUCCEEDED(retVal)) { const char* pMimeType = (const char*) pBuffer->GetBuffer(); if (m_bIsRMSource) { CHXString mimeTypeString; mimeTypeString = pMimeType; m_bIsEncryptedSource = decryptMimeType(mimeTypeString); if (!hxMimeRootCmp(pMimeType, REALAUDIO_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALAUDIO_MULTIRATE_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALAUDIO_MULTIRATE_LIVE_MIME_TYPE)) { m_StreamType = CStream::STREAM_TYPE_AUDIO; } else if (!hxMimeRootCmp(pMimeType, REALVIDEO_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALVIDEO_MULTIRATE_MIME_TYPE)) { m_StreamType = CStream::STREAM_TYPE_VIDEO; } else if (!hxMimeRootCmp(pMimeType, IMAGEMAP_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALIMAGEMAP_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALIMAGEMAP_MULTIRATE_MIME_TYPE)) { m_StreamType = CStream::STREAM_TYPE_IMGMAP; } else if (!hxMimeRootCmp(pMimeType, SYNCMM_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALEVENT_MIME_TYPE) || !hxMimeRootCmp(pMimeType, REALEVENT_MULTIRATE_MIME_TYPE)) { m_StreamType = CStream::STREAM_TYPE_EVENT; } else { CStream::STREAM_TYPE_OTHER; } } else { if ((strlen(pMimeType) >= AUDIO_MIME_PREFIX_SIZE) && (strncasecmp(pMimeType, AUDIO_MIME_PREFIX, AUDIO_MIME_PREFIX_SIZE) == 0)) { m_StreamType = CStream::STREAM_TYPE_AUDIO; } else if ((strlen(pMimeType) >= VIDEO_MIME_PREFIX_SIZE) && (strncasecmp(pMimeType, VIDEO_MIME_PREFIX, VIDEO_MIME_PREFIX_SIZE) == 0)) { m_StreamType = CStream::STREAM_TYPE_VIDEO; } else { CStream::STREAM_TYPE_OTHER; } } }#ifdef _SYNC_TRACE if (!m_sfile) { m_sfile = fopen("c:\\live_s.txt", "wt"); }#endif // _SYNC_TRACE HX_RELEASE(pBuffer); } CPurePlaySource::~CPurePlaySource(){ HX_VECTOR_DELETE(m_pRules); HX_DELETE(m_pRTCPInterval);#ifdef _SYNC_TRACE if (m_sfile) { fclose(m_sfile); m_sfile = NULL; }#endif // _SYNC_TRACE#ifdef XXXGo_DEBUG if (m_pLogFile) { fprintf(m_pLogFile, "~CPurePlaySource()\n"); fclose(m_pLogFile); m_pLogFile = NULL; } if (m_pFFLog) { fclose(m_pFFLog); m_pFFLog = NULL; }#endif } // *** IUnknown methods *** ///////////////////////////////////////////////////////////////////////// // Method: // IUnknown::QueryInterface // Purpose: // Implement this to export the interfaces supported by your // object. // STDMETHODIMP CPurePlaySource::QueryInterface(REFIID riid, void** ppvObj) { if (IsEqualIID(riid, IID_IUnknown)) { AddRef(); *ppvObj = this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXResolverResponse)) { AddRef(); *ppvObj = (IHXResolverResponse*)this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXTransportSyncServer)) { if (m_pPlugin) { return m_pPlugin->QueryInterface(riid, ppvObj); } } *ppvObj = NULL; return HXR_NOINTERFACE; } ///////////////////////////////////////////////////////////////////////// // Method: // IUnknown::AddRef // Purpose: // Everyone usually implements this the same... feel free to use // this implementation. // STDMETHODIMP_(ULONG32) CPurePlaySource::AddRef() { return InterlockedIncrement(&m_lRefCount); } ///////////////////////////////////////////////////////////////////////// // Method: // IUnknown::Release // Purpose: // Everyone usually implements this the same... feel free to use // this implementation. // STDMETHODIMP_(ULONG32) CPurePlaySource::Release() { if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0; }HX_RESULTCPurePlaySource::Init(IUnknown* pContext, const char* pMultiAddr, UINT32 ulInterfaceAddr, UINT16 uMultiPort){ HX_ASSERT(pContext != NULL); pContext->AddRef(); pContext->QueryInterface(IID_IHXNetworkServices, (void**)&m_pNet); HX_ASSERT(m_pNet != NULL); pContext->QueryInterface(IID_IHXScheduler, (void**)&m_pScheduler); HX_ASSERT(m_pScheduler != NULL); UINT32 ulBitRate = 0; if (HXR_OK == m_pHeader->GetPropertyULONG32("AvgBitRate", ulBitRate)) { if (0 == ulBitRate) { // since this # is used to devide something later, can't be 0 m_ulBandwidth = 1; } else { m_ulBandwidth = ulBitRate; } } else { // takes a default } ULONG32 ulPayload; if (HXR_OK == m_pHeader->GetPropertyULONG32(PROP_RTP_PAYLOAD, ulPayload)) { m_chRTPPayload = (INT8)ulPayload; } else { m_pPlugin->ReportError(IDS_ERR_SM_UNEXPECTEDPAYLOAD, HXLOG_ERR, HXR_FAIL); return HXR_FAIL; } UINT32 ulTTL = 0; if (HXR_OK == m_pHeader->GetPropertyULONG32(PROP_MULTI_TTL, ulTTL)) { m_chTTL = (INT8)ulTTL; } else { // takes default } IHXPreferences* pPrefs = NULL; IHXBuffer* pBandwidth = NULL; pContext->QueryInterface(IID_IHXPreferences, (void**)&pPrefs); HX_ASSERT(pPrefs != NULL); HX_RELEASE(pContext); // take a smaller of two bandwidth info for RTCP interval // we don't waste any BW! if (HXR_OK == pPrefs->ReadPref("Bandwidth", pBandwidth)) { pBandwidth->AddRef(); UINT32 ulBW = atol((char*)pBandwidth->GetBuffer()); pBandwidth->Release(); if (ulBW < m_ulBandwidth) { m_pRTCPInterval = new CRTCPInterval(ulBW); } else { m_pRTCPInterval = new CRTCPInterval(m_ulBandwidth); } } else { // set up RTCP Interval m_pRTCPInterval = new CRTCPInterval(m_ulBandwidth); } HX_RELEASE(pPrefs); /* * Deal with ASMRuleBook */ /* * Get the dependencies from the rule book so we can tell when live * streams are sync'ed to the keyframe */ IHXBuffer* pRuleBuf = NULL; if (HXR_OK != m_pHeader->GetPropertyCString("ASMRuleBook", pRuleBuf)) { m_pRules = new RuleInfo[1]; m_cRules = 1; m_bTimeStampDelivery = TRUE; } else { ASMRuleBook rules((char*)pRuleBuf->GetBuffer()); m_cRules = rules.GetNumRules();#if 0#ifdef XXXGo_DEBUG // just for debug, see how many threshold exist UINT32 ulNumThreshold = 0; float pThreshold[128]; memset (pThreshold, 0xffffffff, sizeof(float) * 128); GetThresholdInfo(rules, pThreshold, ulNumThreshold); for (int j = 0; j < (int)ulNumThreshold; j++) { fprintf(m_pFFLog, "%.2f ", pThreshold[j]); } fprintf (m_pFFLog, "\n");#endif // get subscriptions for this bandwidth BOOL bSubInfo[128]; IHXValues* pValues = new CHXHeader(); pValues->AddRef(); UINT8 pBW[128]; sprintf((char*)pBW, "%ld", m_ulBandwidth); /* Flawfinder: ignore */ IHXBuffer* pBandwidth = new CHXBuffer(); pBandwidth->AddRef(); pBandwidth->Set(pBW, strlen((char*)pBW) + 1); pValues->SetPropertyCString("Bandwidth", pBandwidth); rules.GetSubscription(bSubInfo, pValues); for (int y = 0; y < (int)m_cRules; y++) {#ifdef XXXGo_DEBUG fprintf(m_pFFLog, " %d", bSubInfo[y]);#endif if (TRUE == bSubInfo[y]) { // yth rule number needs to be index into this socket } }#ifdef XXXGo_DEBUG fprintf(m_pFFLog, "\n");#endif HX_RELEASE(pValues); HX_RELEASE(pBandwidth);#endif // #if 0 // get subscriptions for this bandwidth BOOL bSubInfo[128]; IHXValues* pValues = new CHXHeader();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -