📄 smlffpln.cpp
字号:
} HX_DELETE(m_pArrayOfPackets); } m_pArrayOfPackets = new CHXPtrArray; if ( m_pCurrentPacketData ) { HX_RELEASE(m_pCurrentPacketData->pBuffer); HX_DELETE(m_pCurrentPacketData); } m_ulCurrentBufferPos = 0; m_ulCurrentPacket = 0; // This file format is not a container type, so it only supports one // stream and therefore one header, but before we do that, we want to // make sure the file object is initialized; we can't actually return // the header count until the file init is done... (See InitDone). m_state = InitPending; // Note, we need to pass ourself to the FileObject, because this is its // first opportunity to know that we implement the IHXFileResponse // interface it will call for completed pending operations return m_pFileObject->Init( HX_FILE_READ, this);} STDMETHODIMP CSmilFileFormat::Close(){ HX_RELEASE(m_pContext); if (m_pFileObject) { m_pFileObject->Close(); HX_RELEASE(m_pFileObject); } if ( m_pArrayOfPackets ) { int s = m_pArrayOfPackets->GetSize(); for ( int i = s; i > 0; --i ) { PacketData* pckt = (PacketData*)(*m_pArrayOfPackets)[i-1]; HX_RELEASE(pckt->pBuffer); HX_DELETE(pckt); (*m_pArrayOfPackets)[i-1] = NULL; m_pArrayOfPackets->RemoveAt(i-1); } HX_DELETE(m_pArrayOfPackets); } if ( m_pCurrentPacketData ) { HX_RELEASE(m_pCurrentPacketData->pBuffer); m_pCurrentPacketData->pNumPos = NULL; HX_DELETE(m_pCurrentPacketData); } HX_RELEASE(m_pFFResponse); HX_RELEASE(m_pRequest); HX_RELEASE(m_pCommonClassFactory); HX_RELEASE(m_pStartOfFile); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetFileHeader// Purpose:// Called by controller to ask the file format for the number of// headers in the file. The file format should call the // IHXFileFormatSession::HeaderCountReady() for the IHXFileFormat-// Session object that was passed in during initialization, when the// header count is available.//STDMETHODIMP CSmilFileFormat::GetFileHeader(){ // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; IHXValues* pHeader = 0; if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void**)&pHeader)) { return HXR_UNEXPECTED; } pHeader->SetPropertyULONG32("StreamCount", 1); m_pFFResponse->FileHeaderReady(HXR_OK, pHeader); HX_RELEASE(pHeader); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetStreamHeader// Purpose:// Called by controller to ask the file format for the header for// a particular stream in the file. The file format should call // IHXFileFormatSession::StreamHeaderReady() for IHXFileFormatSession// object that was passed in during initialization, when the header// is available.//STDMETHODIMP CSmilFileFormat::GetStreamHeader(UINT16 unStreamNumber){ // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; IHXBuffer* pASM = 0; char pBook[256]; /* Flawfinder: ignore */ IHXValues* pHeader = 0; IHXBuffer* pBuffer = 0; if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void**)&pHeader)) { return HXR_UNEXPECTED; } if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pBuffer)) { return HXR_UNEXPECTED; } BOOL bBeta1Player = ::IsBeta1Player(m_pRequest); HX_RESULT pnrver = GetSMILFileVersion(); if (HXR_OK != pnrver || SMILFileVersionSmil10 == m_smilFileVersion) { if(bBeta1Player) { pBuffer->Set((const BYTE*) zm_pStreamMimeTypes[SMILFileVersionSmilBeta10], strlen(zm_pStreamMimeTypes[SMILFileVersionSmilBeta10])+1); } else { pBuffer->Set( (const BYTE*)zm_pStreamMimeTypes[SMILFileVersionSmil10], strlen(zm_pStreamMimeTypes[SMILFileVersionSmil10])+1); } } else if (SMILFileVersionSmil10Strict == m_smilFileVersion) { // /Send strictly-declared SMIL 1.0 streams to the SMIL 2.0 renderer pBuffer->Set((const BYTE*) zm_pStreamMimeTypes[SMILFileVersionSmil10Strict], strlen(zm_pStreamMimeTypes[SMILFileVersionSmil10Strict])+1); } else if (SMILFileVersionSmil20PreRec == m_smilFileVersion) { pBuffer->Set((const BYTE*) zm_pStreamMimeTypes[SMILFileVersionSmil20PreRec], strlen(zm_pStreamMimeTypes[SMILFileVersionSmil20PreRec])+1); } else if (SMILFileVersionSmil20 == m_smilFileVersion) { pBuffer->Set((const BYTE*) zm_pStreamMimeTypes[SMILFileVersionSmil20], strlen(zm_pStreamMimeTypes[SMILFileVersionSmil20])+1); } else // /Too high a version number as far as this ff is concerned: // /XXXEH: should we use the namespace (if there is one) to determine // the mime type and, if there is one, send it and let the player deal // with the auto update (if needed)? Or, should we encourage server // (hence smil ff) updating by just not serving the stream? That's // what I'm doing here: { pBuffer->Set((const BYTE*) zm_pStreamMimeTypes[SMILFileVersionUnknown], strlen(zm_pStreamMimeTypes[SMILFileVersionUnknown])+1); } pHeader->SetPropertyCString("MimeType", pBuffer); HX_RELEASE(pBuffer); pHeader->SetPropertyULONG32("StreamNumber", unStreamNumber); //XXXEH- removed 20000 (20sec) duration that BAB put in "to avoid problem // in core" in 1998(?). 0 milliseconds seems to work fine now (3/2000): pHeader->SetPropertyULONG32("Duration", 0); pHeader->SetPropertyULONG32("PreRoll", 1000); //XXXBAB 'cause Rahul told me to pHeader->SetPropertyULONG32("AvgBitRate", 1000); pHeader->SetPropertyULONG32("StreamVersion", m_ulStreamVersion); pHeader->SetPropertyULONG32("ContentVersion", m_ulContentVersion); // // set ASM rule book // sprintf(pBook, "TimestampDelivery=TRUE,priority=10;"); /* Flawfinder: ignore */ if(HXR_OK == m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pASM)) { pASM->Set((BYTE*)pBook, strlen(pBook)+1); pHeader->SetPropertyCString("ASMRuleBook", pASM); HX_RELEASE(pASM); } m_bHeaderSent = TRUE; m_pFFResponse->StreamHeaderReady(HXR_OK, pHeader); HX_RELEASE(pHeader); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetPacket// Purpose:// Called by controller to ask the file format for the next packet// for a particular stream in the file. The file format should call // IHXFileFormatSession::PacketReady() for the IHXFileFormatSession// object that was passed in during initialization, when the packet// is available.//STDMETHODIMP CSmilFileFormat::GetPacket(UINT16 unStreamNumber){ HX_RESULT result = HXR_OK; // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; if (!m_bHeaderSent) { return HXR_UNEXPECTED; } IHXPacket* pPacket = NULL; result = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**)&pPacket); if( SUCCEEDED(result) ) { if(m_ulCurrentPacket >= m_ulPacketCount) { m_pFFResponse->StreamDone(unStreamNumber); } else { PacketData* pckt = (PacketData*)(*m_pArrayOfPackets)[m_ulCurrentPacket++]; if ( pckt->pNumPos ) { char buf[10]; /* Flawfinder: ignore */ sprintf(buf, "%u", m_ulPacketCount); /* Flawfinder: ignore */ HX_ASSERT(strlen(buf) < 7); strncpy(pckt->pNumPos, buf, strlen(buf)); /* Flawfinder: ignore */ pckt->pNumPos = NULL; }#ifdef DUMPFILEFORMATOUTPUT FILE* stream = fopen( "C:\\PacketData.smil", "a" ); fprintf( stream, "%s\n", (const char*)pckt->pBuffer->GetBuffer()); fclose( stream );#endif pPacket->Set(pckt->pBuffer, 0, unStreamNumber, HX_ASM_SWITCH_ON, 0); m_pFFResponse->PacketReady(HXR_OK, pPacket); } } HX_RELEASE(pPacket); return result;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::Seek// Purpose:// Called by controller to tell the file format to seek to the // nearest packet to the requested offset. The file format should // call IHXFileFormatSession::SeekDone() for the IHXFileFormat-// Session object that was passed in during initialization, when // the seek has completed.//STDMETHODIMP CSmilFileFormat::Seek(ULONG32 ulOffset){ m_pFFResponse->SeekDone(HXR_OK); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileResponse::InitDone// Purpose:// Notification interface provided by users of the IHXFileObject// interface. This method is called by the IHXFileObject when the// initialization of the file is complete, and the Mime type is// available for the request file. If the URL is not valid for the// file system, the status HXR_FAILED should be returned,// with a mime type of NULL. If the URL is valid but the mime type// is unknown, then the status HXR_OK should be returned with// a mime type of NULL.//STDMETHODIMP CSmilFileFormat::InitDone( HX_RESULT status){ HX_RESULT rc = HXR_OK; // If we are not ready then something has gone wrong if (m_state != InitPending) return HXR_UNEXPECTED; // Now it's time to read the file m_state = ReadPending; if (status != HXR_OK) { rc = m_pFFResponse->InitDone(status); } else { // check to see if we have logged an error for this file // in the last hour. If we have we will not log an error. UpdateErrorCaching(); rc = m_pFileObject->Read(FileChunkSize); } return rc;}HX_RESULT CSmilFileFormat::UpdateErrorCaching(){ IHXValues* pRequestHeaders = NULL; UINT32 ulID = 0, ulSes = 0; IHXRegistry* pReg = NULL; m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pReg); HX_RESULT ret = m_pRequest->GetRequestHeaders(pRequestHeaders); if (!pRequestHeaders) { // succeeds even when there are no request headers. ret = HXR_FAIL; } if (SUCCEEDED(ret)) { IHXBuffer* pID = NULL; ret = pRequestHeaders->GetPropertyCString("ConnID", pID); if (SUCCEEDED(ret) && pID) { ulID = atoi((char*)pID->GetBuffer()); } HX_RELEASE(pID); } if (SUCCEEDED(ret)) { IHXBuffer* pSes = NULL; if (SUCCEEDED(pRequestHeaders->GetPropertyCString("SessionNumber", pSes))) { ulSes = atoi((char*)pSes->GetBuffer()); } else { // assume 0 ulSes = 0; } HX_RELEASE(pSes); } IHXBuffer* pURL = NULL; if (SUCCEEDED(ret)) { const char form[] = "client.%u.session.%u.URL"; char pRegkey[sizeof(form) + 20]; /* Flawfinder: ignore */ sprintf(pRegkey, form, ulID, ulSes); /* Flawfinder: ignore */ ret = pReg->GetStrByName(pRegkey, pURL); } char* buf = NULL; const char regtemp[] = "server.smilerrorlog."; if ( SUCCEEDED(ret) ) { buf = new char[sizeof(regtemp) + pURL->GetSize()]; if (!buf) { ret = HXR_OUTOFMEMORY; } } if (SUCCEEDED(ret)) { strcpy(buf, regtemp); /* Flawfinder: ignore */ char* pos = buf + sizeof(regtemp) - 1; const char* url = (const char*)pURL->GetBuffer(); // escape the '.'s while (*url && pos < buf + sizeof(regtemp) + pURL->GetSize()) { if (*url == '.' || *url == '/') { *pos++ = '%'; ++url; } else { *pos++ = *url++; } } *pos = '\0'; } if (SUCCEEDED(ret)) { INT32 lTime = 0; INT32 lNow = time(NULL); if (SUCCEEDED(pReg->GetIntByName(buf, lTime))) { if ((lNow - lTime) > 3600) { m_bLogErrors = TRUE; ret = pReg->SetIntByName(buf, lNow); } else { m_bLogErrors = FALSE; } } else { m_bLogErrors = TRUE; pReg->AddInt(buf, lNow); } } HX_RELEASE(pReg); HX_RELEASE(pRequestHeaders); HX_VECTOR_DELETE(buf); HX_RELEASE(pURL); return ret;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileResponse::CloseDone// Purpose:// Notification interface provided by users of the IHXFileObject// interface. This method is called by the IHXFileObject when the// close of the file is complete.//STDMETHODIMP CSmilFileFormat::CloseDone(HX_RESULT status){ return HXR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -