📄 mp3rend.cpp
字号:
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pValue);
if (pValue)
{
UCHAR pCodecName[] = "MPEG Audio";
pValue->Set((const UCHAR*)pCodecName, strlen((const char*)pCodecName)+1);
m_pRegistry->SetStrById(m_ulCodecRegID, pValue);
pValue->Release();
}
}
}
return HXR_OK;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS */
}
/************************************************************************
* IHXUpdateProperties Methods
*/
/************************************************************************
* UpdatePacketTimeOffset
* Call this method to update the timestamp offset of cached packets
*/
STDMETHODIMP CRnMp3Ren::UpdatePacketTimeOffset(INT32 lTimeOffset)
{
m_lTimeLineOffset -= lTimeOffset;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXUpdateProperties::UpdatePlayTimes
* Purpose:
* Call this method to update the playtime attributes
*/
STDMETHODIMP CRnMp3Ren::UpdatePlayTimes(IHXValues* pProps)
{
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// CRnMp3Ren::~CRnMp3Ren ref: ff1rendr.h
//
// Destructor
//
CRnMp3Ren::~CRnMp3Ren(void)
{
//--_gbInit;
EndStream();
}
// IUnknown COM Interface Methods
///////////////////////////////////////////////////////////////////////////////
// IUnknown::AddRef ref: hxcom.h
//
// This routine increases the object reference count in a thread safe
// manner. The reference count is used to manage the lifetime of an object.
// This method must be explicitly called by the user whenever a new
// reference to an object is used.
//
STDMETHODIMP_(UINT32)
CRnMp3Ren::AddRef(void)
{
return InterlockedIncrement(&m_RefCount);
}
///////////////////////////////////////////////////////////////////////////////
// IUnknown::Release ref: hxcom.h
//
// This routine decreases the object reference count in a thread safe
// manner, and deletes the object if no more references to it exist. It must
// be called explicitly by the user whenever an object is no longer needed.
//
STDMETHODIMP_(UINT32)
CRnMp3Ren::Release(void)
{
if (InterlockedDecrement(&m_RefCount) > 0)
return m_RefCount;
delete this;
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// IUnknown:]Interface ref: hxcom.h
//
// This routine indicates which interfaces this object supports. If a given
// interface is supported, the object's reference count is incremented, and
// a reference to that interface is returned. Otherwise a NULL object and
// error code are returned. This method is called by other objects to
// discover the functionality of this object.
//
STDMETHODIMP
CRnMp3Ren::QueryInterface(REFIID interfaceID,
void** ppInterfaceObj)
{
// By definition all COM objects support the IUnknown interface
if (IsEqualIID(interfaceID, IID_IUnknown))
{
AddRef();
*ppInterfaceObj = (IUnknown*)(IHXPlugin*)this;
return HXR_OK;
}
// IHXPlugin interface is supported
else if (IsEqualIID(interfaceID, IID_IHXPlugin))
{
AddRef();
*ppInterfaceObj = (IHXPlugin*)this;
return HXR_OK;
}
// IHXInterruptSafe interface is supported
else if (IsEqualIID(interfaceID, IID_IHXInterruptSafe))
{
AddRef();
*ppInterfaceObj = (IHXInterruptSafe*)this;
return HXR_OK;
}
// IHXRenderer interface is supported
else if (IsEqualIID(interfaceID, IID_IHXRenderer))
{
AddRef();
*ppInterfaceObj = (IHXRenderer*)this;
return HXR_OK;
}
else if (IsEqualIID(interfaceID, IID_IHXDryNotification))
{
AddRef();
*ppInterfaceObj = (IHXDryNotification*)this;
return HXR_OK;
}
#if defined(HELIX_FEATURE_STATS)
else if (IsEqualIID(interfaceID, IID_IHXStatistics))
{
AddRef();
*ppInterfaceObj = (IHXStatistics*)this;
return HXR_OK;
}
#endif /* #if defined(HELIX_FEATURE_STATS) */
else if (IsEqualIID(interfaceID, IID_IHXUpdateProperties))
{
AddRef();
*ppInterfaceObj = (IHXUpdateProperties*)this;
return HXR_OK;
}
else if (IsEqualIID(interfaceID, IID_IHXPacketHookHelper))
{
if(!m_pDefaultPacketHookHelper)
{
m_pDefaultPacketHookHelper = new CHXDefaultPacketHookHelper;
if(m_pDefaultPacketHookHelper)
{
m_pDefaultPacketHookHelper->AddRef();
m_pDefaultPacketHookHelper->Initialize(m_pContext);
}
}
if(m_pDefaultPacketHookHelper)
return m_pDefaultPacketHookHelper->QueryInterface(interfaceID, ppInterfaceObj);
}
// No other interfaces are supported
*ppInterfaceObj = NULL;
return HXR_NOINTERFACE;
}
STDMETHODIMP
CRnMp3Ren::CheckStreamVersions(IHXValues* pHeader)
{
// check stream and content versions so an upgrade can
// be called if necessary...
HX_RESULT pnr = HXR_OK;
BOOL bVersionOK = TRUE;
UINT32 ulStreamVersion = 0;
UINT32 ulContentVersion = 0;
if(HXR_OK == pHeader->GetPropertyULONG32("StreamVersion",
ulStreamVersion))
{
UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion);
UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion);
if((ulMajorVersion > STREAM_MAJOR_VERSION) ||
(ulMinorVersion > STREAM_MINOR_VERSION &&
ulMajorVersion == STREAM_MAJOR_VERSION))
{
bVersionOK = FALSE;
}
}
if(bVersionOK &&
HXR_OK == pHeader->GetPropertyULONG32("ContentVersion",
ulContentVersion))
{
UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);
UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);
if((ulMajorVersion > CONTENT_MAJOR_VERSION) ||
(ulMinorVersion > CONTENT_MINOR_VERSION &&
ulMajorVersion == CONTENT_MAJOR_VERSION))
{
bVersionOK = FALSE;
}
}
if(!bVersionOK)
{
AddToAutoUpgradeCollection(zm_pStreamMimeTypes[0], m_pContext);
pnr = HXR_FAIL;
}
return pnr;
}
BOOL
CRnMp3Ren::InitAudioStream(HXAudioFormat audioFmt)
{
if(m_pAudioStream)
{
// if already inited, don't do anything
return TRUE;
}
// If we could not create the stream in OnHeader
// Create our audio stream
m_pAudioPlayer->CreateAudioStream(&m_pAudioStream);
if (!m_pAudioStream)
return FALSE;
m_pAudioStream->Init(&audioFmt, m_pHeader);
#ifdef PCM_CAPTURE
#ifdef _WIN32
char szFile[64] = "c:\\temp.wav"; /* Flawfinder: ignore */
#elif _MACINTOSH
char szFile[64] = "temp.wav"; /* Flawfinder: ignore */
#endif
fpOut = fopen(szFile, "wb");
write_pcm_header_wave(fpOut,
lPCMSampRate,
nPCMChannels,
nBitsPerSample,
0);
g_dwTotalPcmBytes = 0;
#endif // PCM_CAPTURE
m_pAudioStream->AddDryNotification(this);
m_bDiscontinuity = TRUE;
return TRUE;
}
BOOL
CRnMp3Ren::ReInitAudioStream(HXAudioFormat audioFmt)
{
#if defined _DEBUG && defined _WIN32
OutputDebugString(TEXT("Dynamic audio src change\n"));
#endif
IHXAudioStream2 *pStream = NULL;
m_pAudioStream->QueryInterface(IID_IHXAudioStream2, (void**)&pStream);
if (pStream)
{
pStream->RemoveDryNotification((IHXDryNotification*)this);
pStream->Release();
}
m_pAudioStream = m_aAudStreamList[++m_wAudStream];
return InitAudioStream(audioFmt);
}
void CRnMp3Ren::Render(IHXBuffer* pPCMBuffer, double dTime)
{
#ifdef PCM_CAPTURE
if (fpOut)
{
fwrite(pPCMBuffer->GetBuffer(), dwPCM, 1, fpOut);
g_dwTotalPcmBytes += dwPCM;
}
#endif //PCM_CAPTURE
// Write to Audio Services
HXAudioData audioData;
audioData.pData = pPCMBuffer;
audioData.ulAudioTime = (UINT32)dTime;
#ifdef _DEBUG
++m_ulFramesDecoded;
#endif
#if defined _DEBUG && defined _WIN32
//wsprintf(szTmp, "Audio Pts %ld\n", audioData.ulAudioTime);
//OutputDebugString(szTmp);
#endif
if (m_bDiscontinuity)
{
audioData.uAudioStreamType = TIMED_AUDIO;
m_bDiscontinuity = FALSE;
}
else
audioData.uAudioStreamType = STREAMING_AUDIO;
audioData.ulAudioTime = AdjustTimestamp( (ULONG32) dTime, m_lTimeLineOffset );
m_pAudioStream->Write(&audioData);
}
void
CRnMp3Ren::SetPacketFormat(const char* szMimeType)
{
if(!szMimeType)
{
return;
}
int i, j;
for (i=0; zm_pStreamMimeTypes[i] != NULL; i++)
if (!strcasecmp(szMimeType, zm_pStreamMimeTypes[i]))
break;
if(zm_pStreamMimeTypes[i] == NULL)
{
return;
}
for (j=0; MIME_FMT_BASIC[j] != -1; j++)
{
if(MIME_FMT_BASIC[j] == i)
{
#if defined (MPA_FMT_DRAFT00)
m_pPacketParser = new CFmtPacketParser();
#if defined(HELIX_FEATURE_MIN_HEAP)
m_ulPreroll = 0;
m_pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
#endif
#endif //MPA_FMT_DRAFT00
return;
}
}
for (j=0; MIME_MPA_BASIC[j] != -1; j++)
{
if(MIME_MPA_BASIC[j] == i)
{
#if defined (MPA_FMT_RAW)
m_pPacketParser = new CMpaPacketParser();
#if defined(HELIX_FEATURE_MIN_HEAP)
m_ulPreroll = 0;
m_pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
#endif
#endif //MPA_FMT_RAW
return;
}
}
for (j=0; MIME_FMT_3119[j] != -1; j++)
{
if(MIME_FMT_3119[j] == i)
{
#if defined (MPA_FMT_RFC3119)
m_pPacketParser = new CRobustPacketParser();
#endif //MPA_FMT_RFC3119
return;
}
}
for (j=0; MIME_MPA_2250[j] != -1; j++)
{
if(MIME_MPA_2250[j] == i)
{
#if defined (MPA_FMT_RFC2250)
m_pPacketParser = new C2250PacketParser();
#if defined(HELIX_FEATURE_MIN_HEAP)
m_ulPreroll = 0;
m_pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
#endif
#endif //MPA_FMT_RFC2250
return;
}
}
#ifdef DEMUXER
for (j=0; MIME_MPG1_2250[j] != -1; j++)
{
if(MIME_MPG1_2250[j] == i)
{
#if defined (MPA_FMT_RFC2250_SYSTEM)
m_pPacketParser = (CPacketParser*)(CSysPacketParser*)
(new C2250SysPacketParser(FALSE, m_pRegistry));
#if defined(HELIX_FEATURE_MIN_HEAP)
m_ulPreroll = 0;
m_pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
#endif
#endif //MPA_FMT_RFC2250_SYSTEM
return;
}
}
for (j=0; MIME_MPG2_2250[j] != -1; j++)
{
if(MIME_MPG2_2250[j] == i)
{
#if defined (MPA_FMT_RFC2250_SYSTEM)
m_pPacketParser = (CPacketParser*)(CSysPacketParser*)
(new C2250SysPacketParser(TRUE, m_pRegistry));
#if defined(HELIX_FEATURE_MIN_HEAP)
m_ulPreroll = 0;
m_pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
#endif
#endif //MPA_FMT_RFC2250_SYSTEM
return;
}
}
for (j=0; MIME_MPG1_SYS[j] != -1; j++)
{
if(MIME_MPG1_SYS[j] == i)
{
#if defined (MPA_FMT_SYSTEM)
m_pPacketParser = new CSysPacketParser(FALSE, m_pRegistry);
#endif //MPA_FMT_SYSTEM
return;
}
}
for (j=0; MIME_MPG2_SYS[j] != -1; j++)
{
if(MIME_MPG2_SYS[j] == i)
{
#if defined (MPA_FMT_SYSTEM)
m_pPacketParser = new CSysPacketParser(TRUE, m_pRegistry);
#endif //MPA_FMT_SYSTEM
return;
}
}
#endif // DEMUXER
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -