📄 mp3ff.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 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
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (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.
*
* 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 INITGUID // Interface ID's
///////////////////////////////////////////////////////////////////////////////
// Includes
#include "hlxclib/string.h" // strrchr
#include "hlxclib/stdlib.h" // atol
#include "hlxclib/stdio.h" // sprintf
#include "hxtypes.h" // Standard Real types
#include "hxcom.h" // IUnknown
#include "hxcomm.h" // IHXCommonClassFactory
#include "ihxpckts.h" // IHXBuffer, IHXPacket, IHXValues
#include "hxplugn.h" // IHXPlugin
#include "hxfiles.h" // IHXFileResponse
#include "hxformt.h" // IHXFileFormatObject
#include "hxcore.h" // IHXPlayer
#include "hxerror.h" // IHXErrorMessages
#include "hxmon.h" // IHXRegistry
#include "defslice.h" // Registry types
#include "dbcsutil.h" // Double byte char set functions
#include "hxver.h"
#include "hxupgrd.h" // IHXUpgradeCollection
#include "hxbuffer.h"
#include "ringbuf.h"
#include "mp3format.h" // CMp3Format
#include "mp3ff.h" // CRnMp3Fmt
#include "mhead.h" // MP3 header info
#include "dxhead.h" // Xing MP3 header info
#include "pckunpck.h"
#include "metautil.h"
#include "hxstrutl.h"
#define MP3FF_4BYTE_SYSTEM 0x000001ba
#define MP3FF_4BYTE_VIDEO 0x000001b3
#define MP3FF_4BYTE_RIFF 0x52494646
#define MP3FF_4BYTE_CDXA 0x43445841
#define MP3FF_4BYTE_free 0x66726565
#define MP3FF_4BYTE_skip 0x736B6970
#define MP3FF_4BYTE_pnot 0x706e6f74
#define MP3FF_4BYTE_mdat 0x6d646174
#define MP3FF_4BYTE_moov 0x6d6f6f76
//#include "rmfftype.h" // for the HX_SAVE_ENABLED flag
#ifdef _AIX
#include "dllpath.h"
ENABLE_MULTILOAD_DLLACCESS_PATHS(Rnmp3fmt);
#endif
IHXBuffer* NewPacketBufferGetter(
IHXCommonClassFactory * pClassFactory, // not used for new version
IHXBuffer * pExistingBuffer,
UCHAR * pModFrameStart,
int nModFrameSize
)
{
IHXBuffer * pPacketBuffer = new CHXBufferFragment(
pExistingBuffer,
pModFrameStart,
nModFrameSize);
pPacketBuffer->AddRef();
return pPacketBuffer;
}
IHXBuffer* OldPacketBufferGetter(
IHXCommonClassFactory * pClassFactory,
IHXBuffer * pExistingBuffer, // not used for old version
UCHAR * pModFrameStart, // not used for old version
int nModFrameSize // not used for old version
)
{
IHXBuffer * pPacketBuffer = NULL;
pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**)&pPacketBuffer);
return pPacketBuffer;
}
///////////////////////////////////////////////////////////////////////////////
// HXCreateInstance ref: hxplugn.h
//
// This routine creates a new instance of the CRnMp3Fmt class.
// It is called when the RMA core application is launched, and whenever
// an URL associated with this plug-in is opened.
STDAPI ENTRYPOINT
(HXCREATEINSTANCE)(IUnknown** ppExFileFormatObj)
{
*ppExFileFormatObj = (IUnknown*)(IHXPlugin*)new CRnMp3Fmt();
if (*ppExFileFormatObj != NULL)
{
(*ppExFileFormatObj)->AddRef();
return HXR_OK;
}
return HXR_OUTOFMEMORY;
}
/****************************************************************************
*
* Function:
*
* CanUnload2()
*
* Purpose:
*
* Function implemented by all plugin DLL's if it returns HXR_OK
* then the pluginhandler can unload the DLL
*
*/
STDAPI ENTRYPOINT(CanUnload2)(void)
{
return (CHXBaseCountingObject::ObjectsActive() > 0 ? HXR_FAIL : HXR_OK );
}
///////////////////////////////////////////////////////////////////////////////
// CRnMp3Fmt static variables ref: filefmt1.h
//
// These variables are passed to the RMA core to provide information about
// this plug-in. They are required to be static in order to remain valid
// for the lifetime of the plug-in.
const char* const CRnMp3Fmt::zm_pDescription = MY_DESCRIPTION;
const char* const CRnMp3Fmt::zm_pCopyright = HXVER_COPYRIGHT;
const char* const CRnMp3Fmt::zm_pMoreInfoURL = HXVER_MOREINFO;
const char* const CRnMp3Fmt::zm_pFileMimeTypes[] = MY_FILE_MIME_TYPES;
const char* const CRnMp3Fmt::zm_pFileExtensions[] = MY_FILE_EXTENSIONS;
const char* const CRnMp3Fmt::zm_pFileOpenNames[] = MY_FILE_OPEN_NAMES;
// Leave rtp out until the bug is fixed that makes it always get used.
//const char* CRnMp3Fmt::zm_pPacketFormats[] = {"rdt", "rtp", NULL};
const char* const CRnMp3Fmt::zm_pPacketFormats[] = {"rdt", NULL};
///////////////////////////////////////////////////////////////////////////////
// CRnMp3Fmt::CRnMp3Fmt ref: filefmt1.h
//
// Constructor
//
CRnMp3Fmt::CRnMp3Fmt(void)
: m_RefCount (0),
m_pClassFactory (NULL),
m_pFileObj (NULL),
m_pStatus (NULL),
m_pError (NULL),
m_pRegistry (NULL),
m_szPlayerReg (NULL),
m_State (Ready),
m_ulNextPacketDeliveryTime(0),
m_ulFileSize(0),
m_ulMetaReadSize(0),
m_ulNextMetaPos((UINT32)-1),
m_ulMetaLength(0),
m_ulMaxSampRate(0),
m_ulBytesRead(0),
m_ulFileOffset(0),
m_nChannels(0),
m_dNextPts(0.0),
m_bEOF(0),
m_bRtp(0),
m_bHasVbrHdr(0),
m_bSkipVbrHdr(0),
m_bStreaming(0),
m_bMetaPacket(0),
m_bNeedPacket(0),
m_bCheckBadData(0),
m_bLive(0),
m_bLicensed(0),
m_pFmtBuf(NULL),
m_pMp3Fmt(NULL),
m_ulGarbageBytesRead(0),
m_bAcceptMetaInfo(FALSE),
m_bAllMetaInfo(FALSE),
m_pMetaProps(NULL),
m_pContext(NULL),
m_bIsVBR(FALSE),
m_bFirstMeta(FALSE),
m_bClosed(TRUE),
m_pCreatePacketFunction(NULL)
{
memset(&m_ReadBuf, 0, sizeof(m_ReadBuf));
memset(&m_Info, 0, sizeof(m_Info));
memset(&m_RtpPackets, 0, sizeof(m_RtpPackets));
m_pMp3Fmt = new CMp3Format;
}
#if defined(MPA_FMT_DRAFT00)
///////////////////////////////////////////////////////////////////////////
// IHXPacketFormat Interface Methods ref: rmaformat.h
///////////////////////////////////////////////////////////////////////////
STDMETHODIMP CRnMp3Fmt::GetSupportedPacketFormats(REF(const char**) pFormats)
{
pFormats = (const char**) zm_pPacketFormats;
return HXR_OK;
}
STDMETHODIMP CRnMp3Fmt::SetPacketFormat(const char* pFormat)
{
if (!strcmp(pFormat, "rtp"))
m_bRtp = 1;
else
m_bRtp = 0;
return HXR_OK;
}
#endif /* #if defined(MPA_FMT_DRAFT00) */
///////////////////////////////////////////////////////////////////////////////
// IHXPlugin::GetPluginInfo ref: hxplugn.h
//
// This routine returns descriptive information about the plug-in, most
// of which is used in the About box of the user interface. It is called
// when the RMA core application is launched.
//
STDMETHODIMP
CRnMp3Fmt::GetPluginInfo(REF(int) bLoadMultiple,
REF(const char*) pDescription,
REF(const char*) pCopyright,
REF(const char*) pMoreInfoURL,
REF(UINT32) versionNumber)
{
// File Format plug-ins MUST be able to be multiply instantiated
bLoadMultiple = TRUE;
pDescription = (const char*) zm_pDescription;
pCopyright = (const char*) zm_pCopyright;
pMoreInfoURL = (const char*) zm_pMoreInfoURL;
versionNumber = MY_PLUGIN_VERSION;
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IHXThreadSafeMethods::IsThreadsafe ref: hxengin.h
//
// This routine returns threadsafeness informaiton about the plugin
// which is used by the server for improved performance.
//
STDMETHODIMP_(UINT32)
CRnMp3Fmt::IsThreadSafe()
{
return HX_THREADSAFE_METHOD_FF_GETPACKET | HX_THREADSAFE_METHOD_FSR_READDONE;
}
///////////////////////////////////////////////////////////////////////////////
// IHXFileFormatObject::GetFileFormatInfo ref: hxformt.h
//
// This routine returns crucial information required to associate this
// plug-in with a given MIME type. This information tells the core which
// File Format plug-in to use for a particular URL. The routine is called
// when the RMA core application is launched.
//
STDMETHODIMP
CRnMp3Fmt::GetFileFormatInfo(REF(const char**) pFileMimeTypes,
REF(const char**) pFileExtensions,
REF(const char**) pFileOpenNames)
{
pFileMimeTypes = (const char**) zm_pFileMimeTypes;
pFileExtensions = (const char**) zm_pFileExtensions;
pFileOpenNames = (const char**) zm_pFileOpenNames;
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IHXPlugin::InitPlugin ref: hxplugn.h
//
// This routine performs initialization steps such as determining whether
// required interfaces are available. It is called when the RMA core
// application is launched, and whenever an URL associated with this
// plug-in is opened.
//
STDMETHODIMP
CRnMp3Fmt::InitPlugin(IUnknown* pHXCore)
{
HX_RELEASE(m_pContext);
m_pContext = pHXCore;
m_pContext->AddRef();
pHXCore->QueryInterface(IID_IHXCommonClassFactory,
(void**)&m_pClassFactory);
if (m_pClassFactory == NULL)
return HXR_NOTIMPL;
m_bStreaming = 1;
// Check if we are being loaded by the player or ther server. If
// the context contains IHXPlayer, we are in the player, else, we
// are in the server. This determines whether packet loss is possilbe
// or not (only possible in the server). So, if m_bStreaming is
// set to 1, we must do data reformatting to handle packet loss in the
// render plugin.
//
// Also, check the server license for streaming mpa
IHXPlayer *pPlayer = NULL;
pHXCore->QueryInterface(IID_IHXPlayer, (void**)&pPlayer);
if (pPlayer)
{
#if defined(HELIX_FEATURE_REGISTRY)
// Get the player's registry
IHXRegistryID *pRegistryId = NULL;
pPlayer->QueryInterface(IID_IHXRegistryID, (void**)&pRegistryId);
UINT32 ulPlayerRegistryID = 0;
if (pRegistryId)
{
// Get the player's base registry name
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -