📄 mp3ff.cpp
字号:
pRegistryId->GetID(ulPlayerRegistryID);
HX_RELEASE(pRegistryId);
}
// Get the core's registry
pHXCore->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry);
if (m_pRegistry)
{
if (ulPlayerRegistryID)
{
m_pRegistry->GetPropName(ulPlayerRegistryID, m_szPlayerReg);
m_szPlayerReg->SetSize(m_szPlayerReg->GetSize() + 25);
strcat((char*)m_szPlayerReg->GetBuffer(), ".Author"); /* Flawfinder: ignore */
}
}
#endif /* #if defined(HELIX_FEATURE_REGISTRY) */
pPlayer->Release();
m_bStreaming = 0;
m_bLicensed = 1;
}
#if defined (MPA_FMT_DRAFT00) && defined(HELIX_FEATURE_REGISTRY)
else
{
// Query registry interface
INT32 nLicensed = 0;
IHXRegistry *pRegistry = NULL;
pHXCore->QueryInterface(IID_IHXRegistry, (void**)&pRegistry);
if (!pRegistry)
return HXR_UNEXPECTED;
// On the Server, check the license section of the registry
if (HXR_OK != pRegistry->GetIntByName(REGISTRY_REALMPA_ENABLED, nLicensed))
nLicensed = LICENSE_REALMPA_ENABLED;
m_bLicensed = (nLicensed) ? (TRUE) : (FALSE);
HX_RELEASE(pRegistry);
}
#endif //MPA_FMT_DRAFT00
pHXCore->QueryInterface(IID_IHXErrorMessages, (void**)&m_pError);
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IHXFileFormatObject::InitFileFormat ref: hxformt.h
//
// This routine initializes the file, and stores references to objects used
// throughout the example. It is called whenever an URL associated with this
// plug-in is opened.
//
STDMETHODIMP
CRnMp3Fmt::InitFileFormat(IHXRequest* pRequest,
IHXFormatResponse* pFormatResponse,
IHXFileObject* pFileObject)
{
// The format response object is used to notify RMA core of our status
m_pStatus = pFormatResponse;
if (m_pStatus != NULL)
m_pStatus->AddRef();
#if defined(HELIX_FEATURE_MP3FF_ONDEMANDMETAINFO)
// See if meta info has been requested
BOOL bAcceptMetaInfo = m_bAcceptMetaInfo;
BOOL bAllMetaInfo = m_bAllMetaInfo;
CheckMetaInfoRequest(pRequest,
m_pClassFactory,
bAcceptMetaInfo,
bAllMetaInfo,
m_pMetaProps);
m_bAcceptMetaInfo = bAcceptMetaInfo;
m_bAllMetaInfo = bAllMetaInfo;
#endif /* #if defined(HELIX_FEATURE_MP3FF_ONDEMANDMETAINFO) */
// The file object is used to handle file I/O
m_pFileObj = pFileObject;
if (m_pFileObj != NULL)
{
m_pFileObj->AddRef();
// Initialize and check validity of file. Also, associate the file
// with a response object which is notified when the file operation is
// complete.
m_bClosed = FALSE;
m_State = InitPending;
m_pFileObj->Init(HX_FILE_READ | HX_FILE_BINARY, this); // asynchronous
// Since this class was designated at the response object, this
// class's IHXFileResponse::InitDone method will be called when
// the initialization of the file is complete. (See InitDone).
}
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IHXFileResponse::InitDone ref: hxfiles.h
//
// This routine notifies the RMA core that the initialization of the file is
// done. It is called automatically when the initialization of the file
// has completed.
//
STDMETHODIMP
CRnMp3Fmt::InitDone(HX_RESULT status)
{
if (m_State != InitPending)
return HXR_UNEXPECTED;
IHXFileStat *pStat = NULL;
m_pFileObj->QueryInterface(IID_IHXFileStat, (void**)&pStat);
if (pStat)
{
pStat->Stat((IHXFileStatResponse*)this);
pStat->Release();
}
// Notify RMA core that intialization started in InitFileFormat is done
m_State = Ready;
AddRef();
m_pStatus->InitDone(status);
#if defined (MPA_FMT_DRAFT00)
if (!m_bClosed && m_bStreaming && !m_bRtp)
m_pFmtBuf = new CIHXRingBuffer(m_pClassFactory, 8192, (1024<<1)+512);
#endif //MPA_FMT_DRAFT00
Release();
// There are 2 ways to get a packet buffer: a heap optimal way
// (the 'new' way), or the 'old' way, which involves making a
// whole new buffer. We can't optimize heap usage (by re-using
// the read buffer) if m_bRtp is true, because that requires
// increasing the buffer size: see code under comment 'Copy the
// rtp payload header'. We do this here because m_bRtp is set in
// SetPacketFormat, which will have been called at this point.
// We also use the 'old' packet buffer getter if we are running
// as part of the server (m_bStreaming -- bad name), or if we are
// playing a metadata file.
if( m_bStreaming || m_bRtp || m_pMp3Fmt->GetMetaRepeat() )
{
m_pCreatePacketFunction = &OldPacketBufferGetter;
}
else
{
m_pCreatePacketFunction = &NewPacketBufferGetter;
}
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IHXFileFormatObject::GetFileHeader ref: hxformt.h
//
// This routine returns to the RMA core an object containing the file
// header information. Several routines are actually required to complete
// the process due to the asynchronous nature of the RMA file system. This
// method is called by the RMA core after the file has been initialized.
//
STDMETHODIMP
CRnMp3Fmt::GetFileHeader(void)
{
if (m_State != Ready)
return HXR_UNEXPECTED;
// For local files, look for ID3 v1 tags
if (m_pFileObj->Advise(HX_FILEADVISE_RANDOMACCESS) != HXR_ADVISE_PREFER_LINEAR &&
m_ulFileSize > ID3HeaderLen)
{
m_State = GetId3HeaderSeekPending;
// Inform the file system that we need an actual seek. An http seek
// may download all the data to the seek point which is bad especially
// on a huge seek.
m_pFileObj->Advise(HX_FILEADVISE_RANDOMACCESSONLY);
// For some reason, http 1.1 servers on mp3.com do not give us data if
// we seek to the last 128 bytes. So, fudge this to seek to 129
// bytes from the end (ID3HeaderLen-1) and adjust the read pointer
// in ReadDone.
m_pFileObj->Seek(m_ulFileSize-ID3HeaderLen-BytesBeforeID3Header, FALSE);
return HXR_OK;
}
// Since Seek() is asynchronous we need to note our state in order to
// correctly respond in SeekDone() when finished.
m_State = GetFileHeaderSeekPending;
// Move to the beginning of the header data in the file
m_pFileObj->Seek(MY_FILE_HEADER_START+m_ulFileOffset, FALSE);
return HXR_OK;
}
///////////////////////////////////////////////////////////////////////////////
// CRnMp3Fmt::MyCreateFileHeaderObj_hr ref: filefmt1.h
//
// This routine creates a "file header" object and passes it off to the
// RMA core, which in turn transports it to the renderer. This object must
// contain a property stating the number of streams contained in this file
// format. Any additional header information read from the file can also be
// placed in this object. This method is called after the header data from
// the file has been completely read.
//
HX_RESULT
CRnMp3Fmt::MyCreateFileHeaderObj_hr(HX_RESULT status,
IHXBuffer* pHeader)
{
// We are in the process of handling the GetFileHeader() request...
// See GetFileHeader(), SeekDone(), and ReadDone() for previous steps.
m_State = Ready;
// Create new object containing the header data
IHXValues* pHeaderObj = NULL;
m_pClassFactory->CreateInstance(CLSID_IHXValues, (void**)&pHeaderObj);
if (pHeaderObj != NULL)
{
char pUpgrade[16] = "\0";
HRESULT hr = HXR_OK;
INT16 wStreams = InitStream_n(pHeader, &m_Info, hr, pUpgrade, sizeof(pUpgrade));
// The header proceeding the data is too large for
// our buffer. So seek past header and try again.
if (!wStreams)
{
pHeaderObj->Release();
if (m_ulFileOffset)
{
m_State = GetFileHeaderSeekPending;
m_pFileObj->Seek(MY_FILE_HEADER_START+m_ulFileOffset, FALSE);
return hr;
}
// Server is full
else
{
m_pError->Report(HXLOG_ERR, HXR_NOT_AUTHORIZED, 0,
"The requested server is full.",
MY_MORE_INFO_URL);
return HXR_NOT_AUTHORIZED;
}
}
// Invalid stream
else if (wStreams < 0)
{
pHeaderObj->Release();
#if defined (MPA_FMT_DRAFT00)
// Print to common display if we are running on a server
if (m_bStreaming)
printf("Unsupported File Type. The selected file is not a valid MPEG audio file.\n");
#endif //MPA_FMT_DRAFT00
// Send a player AU request if necessary
IHXPlayer *pPlayer = NULL;
m_pContext->QueryInterface(IID_IHXPlayer, (void**)&pPlayer);
if (pPlayer && strlen(pUpgrade))
{
IHXUpgradeCollection* pUpgradeCol = NULL;
pPlayer->QueryInterface(IID_IHXUpgradeCollection, (void**)&pUpgradeCol);
if (pUpgradeCol)
{
IHXBuffer *pText = NULL;
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pText);
if (!pText)
return HXR_FAIL;
pText->Set((const unsigned char*)pUpgrade, strlen(pUpgrade)+1);
pUpgradeCol->Add(eUT_FileTypeNotSupported, pText, 0,0);
pText->Release();
}
HX_RELEASE(pUpgradeCol);
}
HX_RELEASE(pPlayer);
m_pStatus->FileHeaderReady(hr, NULL);
return hr;
}
pHeaderObj->SetPropertyULONG32("StreamCount", 1);
// Disable slider for "live" streams (http streaming)
if (m_bLive)
pHeaderObj->SetPropertyULONG32("LiveStream", 1);
// Set title
int nLen = 0;
char* pszTmp = (char*) m_pMp3Fmt->GetId3Title(nLen);
if (nLen)
{
SetCStringProperty(pHeaderObj,
"Title",
(const char*) pszTmp,
m_pContext,
TRUE); // Forces a SetPropertyBuffer()
}
// Set artist
nLen = 0;
pszTmp = (char*) m_pMp3Fmt->GetId3Artist(nLen);
if (nLen)
{
SetCStringProperty(pHeaderObj,
"Author",
(const char*) pszTmp,
m_pContext,
TRUE); // Forces a SetPropertyBuffer()
}
// Set album
nLen = 0;
pszTmp = (char*) m_pMp3Fmt->GetId3Album(nLen);
if (nLen)
{
SetCStringProperty(pHeaderObj,
"Abstract",
(const char*) pszTmp,
m_pContext,
TRUE); // Forces a SetPropertyBuffer()
}
// Set genre
nLen = 0;
pszTmp = (char*) m_pMp3Fmt->GetId3Genre(nLen);
if (nLen)
{
SetCStringProperty(pHeaderObj,
"Genre",
(const char*) pszTmp,
m_pContext,
TRUE); // Forces a SetPropertyBuffer()
}
// Optional Property: "OpaqueData"
// Any other user defined data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -