📄 rtffplin.cpp
字号:
m_ulCurrentTime = ulOffset; m_ulSizeOfNextReadAfterSeek = 1L + ulPktEndByte - ulPktStartByte; // Actually seek... m_ulNextPacketSeekPoint = ulPktStartByte; //m_ulLastByteParsedInFile;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"Seek back to byte %lu in file at time: %lu\n", m_ulNextPacketSeekPoint, m_ulCurrentTime); fflush(m_logfile); }#endif#endif m_pFileObject->Seek(m_ulNextPacketSeekPoint, FALSE); // See SeekDone() for next "step" of the Seek() process. } 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 CRealTextFileFormat::InitDone( HX_RESULT status){ // If we are not ready then something has gone wrong if (m_state != InitPending) return HXR_UNEXPECTED; // get a new file object for this file const char* pFilename; m_pFileObject->GetFilename(pFilename); m_RTSourceFileExtension = rtx_extension; if(pFilename) { UINT16 len = strlen(pFilename); if(len>3) //5 is min length of acceptable file "a.rtx" { char* pNextDot = (char*)strchr(pFilename, '.'); char* pLastDot = NULL; while(pNextDot) { pLastDot = pNextDot; pNextDot = (char*)strchr(++pNextDot, '.'); } if(pLastDot) { if(!strncasecmp((const char*)pLastDot,".txt", 4)) { m_RTSourceFileExtension = txt_extension; m_bIsTextPlainStreamMimeType = TRUE; } //".htm" or ".html" are handled by looking at first 4 chars: else if(!strncasecmp((const char*)pLastDot,".htm", 4)) { m_RTSourceFileExtension = html_extension; } else { m_RTSourceFileExtension = rtx_extension; } } } } // Get an IHXFileStat interface from the IHXFileObject interface: HX_RELEASE(m_pFileStatObj); HX_ASSERT(m_pFileObject); HX_RESULT retVal = m_pFileObject->QueryInterface(IID_IHXFileStat, (void **) &m_pFileStatObj); if (retVal != HXR_OK || m_pFileStatObj == NULL) { m_state = Ready; return retVal; //we can't proceed if we can't see the file size! } // Call IHXFileStat::Stat() to get the size of the RT file: m_pFileStatObj->Stat((IHXFileStatResponse *) this); //See ::StatDone() for result of Stat() call. // XXXMEH - well, calling Stat() (an async method) in a // synchronous way above is a no-no, so I'll the supposition // that two wrongs cancel each other out to call FindMimeType // in a synchronous way as well. When we change the above to add // another state for StatDone() before calling InitDone(), then // we should change this as well. IHXFileMimeMapper* pMapper = NULL; m_pFileObject->QueryInterface(IID_IHXFileMimeMapper, (void**) &pMapper); if (pMapper) { // Get the URL const char* pszURL = NULL; m_pRequest->GetURL(pszURL); if (pszURL) { // Get our own response interface IHXFileMimeMapperResponse* pResponse = NULL; QueryInterface(IID_IHXFileMimeMapperResponse, (void**) &pResponse); if (pResponse) { // Call FindMimeType - look in MimeTypeFound for // the response pMapper->FindMimeType(pszURL, pResponse); } HX_RELEASE(pResponse); } } HX_RELEASE(pMapper); // This file format is not a container type, so it only supports one // stream and therefore one header, since we now know the file is // initialized we can return the header count to the controller... m_state = Ready; m_pFFResponse->InitDone(status); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// 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 CRealTextFileFormat::CloseDone(HX_RESULT status){ return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileResponse::ReadDone// Purpose:// Notification interface provided by users of the IHXFileObject// interface. This method is called by the IHXFileObject when the// last read from the file is complete and a buffer is available.//STDMETHODIMP CRealTextFileFormat::ReadDone( HX_RESULT status, IHXBuffer* pBuffer){ HX_RESULT result = HXR_OK; // Note, the read may be done because we needed to read to produce // a header or a packet. We need to remember why we tried to read and // respond accordingly... switch (m_state) { case GetFileHeaderReadPending: { // We are in the process of responding to a GetFileHeader() // request and the read has completed, which means we // are done and can go back to the ready state... m_state = Ready; if (status == HXR_OK) //added this check { IHXValues* pHeader; IHXCommonClassFactory* pCommonClassFactory; if (HXR_OK == m_pContext->QueryInterface( IID_IHXCommonClassFactory, (void **)&pCommonClassFactory)) { if(HXR_OK == pCommonClassFactory->CreateInstance( CLSID_IHXValues, (void**)&pHeader)) { SetDuration(DEFAULT_DURATION_MSEC); char szLoppedHdr[MAX_HEADER_SIZE+5] = ""; /* Flawfinder: ignore */ //Go through the pBuffer and find "duration=some val" // & set m_ulDuration to that value: // and also look for version="x.y" in header: ULONG32 bufSize = pBuffer->GetSize(); ULONG32 indx=0; if(bufSize > MAX_HEADER_SIZE) { //this line should never get hit!: bufSize = MAX_HEADER_SIZE; } memcpy(szLoppedHdr, (char*)(pBuffer->GetBuffer()), /* Flawfinder: ignore */ bufSize); szLoppedHdr[bufSize] = '\0'; // /If this is not plain text, then look for file header: if (!m_bIsTextPlainStreamMimeType) { //This parses the <window> tag and gets the duration, // window width & height, ...etc. from it: DealWithFileHeader(szLoppedHdr, bufSize); _CHAR ch; ULONG32 ulTmpDuration; BOOL bEndTimeTagFound=FALSE; m_ulHeaderSize = bufSize; for (indx=0; indx<bufSize; indx++) { ch = szLoppedHdr[indx]; if(!bEndTimeTagFound) { if(' ' == ch || '\t' == ch || '\n' == ch || '\r' == ch) { if (indx<bufSize-10) { _CHAR ch1 = szLoppedHdr[indx+1]; //Look for "endtime" or "duration": if('E'==ch1 || 'e'==ch1 || 'D'==ch1 || 'd'==ch1) { ulTmpDuration = GetEndTime( &szLoppedHdr[indx]); if(ulTmpDuration > 0L) { SetDuration(ulTmpDuration); bEndTimeTagFound = TRUE; } } } } } if('>' == szLoppedHdr[indx]) { m_ulHeaderSize = indx+1; break; } } } if(GetDuration() <= 0) { SetDuration(DEFAULT_DURATION_MSEC); } ULONG32 ulAvgBitRate = 0; if (GetDuration() > 0) { ulAvgBitRate = (ULONG32)( HEADER_OVERHEAD_FACTOR * (double((8.0 * m_ulTotalFileSizeInBytes) / ((double)GetDuration() / 1000.0)))); } if(ulAvgBitRate < 8) ulAvgBitRate = 9; pHeader->SetPropertyULONG32("AvgBitRate", ulAvgBitRate); pHeader->SetPropertyULONG32("StreamCount", 1); pHeader->SetPropertyULONG32("IsRealDataType", 1); //Set the .rt file's author-specified width & height // (which may not have been explicitly specified; in // that case the default value, which depends on the // window type, is used): pHeader->SetPropertyULONG32("Width", !m_bIsTextPlainStreamMimeType? m_txtWin.getWidth() : DEFAULT_WINDOWWIDTH); pHeader->SetPropertyULONG32("Height", !m_bIsTextPlainStreamMimeType? m_txtWin.getHeight() : DEFAULT_WINDOWHEIGHT); // Tell the FormatResponse of our success in // getting the header. m_pFFResponse->FileHeaderReady(HXR_OK, pHeader); // Release our reference on the header! HX_RELEASE(pHeader); } else { return HXR_UNEXPECTED; } pCommonClassFactory->Release(); } else { return HXR_UNEXPECTED; } } else {#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"FileHeader read failed.\n"); fflush(m_logfile); }#endif#endif // Tell the FormatResponse that the read failed so we're // at the end of the file: m_pFFResponse->FileHeaderReady(HXR_INVALID_FILE, NULL); } } break; case GetStreamHeaderReadPending: { // We are in the process of responding to a GetStreamHeader() // request and the read has completed, which means we // are done and can go back to the ready state... m_state = Ready; if (status == HXR_OK) //added this check { // We now need to form a "header" object and pass it // off to our controller. Notice since our header data // comes straight out of the file as is, we don't need // to copy data at all, the IHXBuffer returned by read // can be placed into the header object and passed off. // Create header object here, notice that we call the // CreateInstance method of the controller, but we could // have implemented our own object that exposed the // IRMAHeader interface. IHXValues* pHeader; IHXBuffer* pMTBuf; IHXBuffer* pSNBuf; IHXCommonClassFactory* pCommonClassFactory; if (HXR_OK == m_pContext->QueryInterface( IID_IHXCommonClassFactory, (void **)&pCommonClassFactory)) { if((HXR_OK == pCommonClassFactory->CreateInstance( CLSID_IHXValues, (void**)&pHeader)) && (HXR_OK == pCommonClassFactory->CreateInstance( CLSID_IHXBuffer, (void**)&pMTBuf)) && (HXR_OK == pCommonClassFactory->CreateInstance( CLSID_IHXBuffer, (void**)&pSNBuf))) { // Remember that we have sent the header so packets // can now be sent... (just a little bit of // sanity checking). m_bHeaderSent = TRUE; UINT16 uStreamNumber = 0; //changed from float to double: double timePerPcktInSeconds = double(TIME_PER_PACKET)/1000.0; ULONG32 ulMaxBitRate = ULONG32(MAX_PACKET_SIZE * (8.0*timePerPcktInSeconds)); ULONG32 ulMaxPacketSize = MAX_PACKET_SIZE; ULONG32 ulAvgPacketSize = AVG_PACKET_SIZE; ULONG32 ulStartTime = 0; ULONG32 ulPreroll = DEFAULT_PREROLL_MSEC; char szStreamName[] = "RealText1"; char szMimeType[64]; /* Flawfinder: ignore */ szMimeType[0] = '\0'; if(IsBeta1Player()) { SafeStrCpy(szMimeType, zm_pFileMimeTypes[1], 64); } else { SafeStrCpy(szMimeType, zm_pFileMimeTypes[0], 64); } // If we have found that the mime type of the // file is "text/plain", then we want to SEND // "text/plain" as the STREAM mime type. if (m_pszFileMimeType && 0 == stricmp(m_pszFileMimeType, "text/plain")) { m_bIsTextPlainStreamMimeType = TRUE; strcpy(szMimeType, m_pszFileMimeType); /* Flawfinder: ignore */ } // /Handle .txt files as text/plain as well: if (txt_extension == m_RTSourceFileExtension) { m_bIsTextPlainStreamMimeType = TRUE; strcpy(szMimeType, "text/plain"); /* Flawfinder: ignore */ } IHXBuffer* pLoppedHdr = NULL; char szLoppedHdr[MAX_HEADER_SIZE+5] = ""; /* Flawfinder: ignore */ ULONG32 bufSize = pBuffer->GetSize(); ULONG32 indx=0; //Go through the pBuffer and find first // '>' (which should be the end of the <WINDOW ...> // header tag), and send everything up to that point: if(bufSize > MAX_HEADER_SIZE) { //this line should never get hit!: bufSize = MAX_HEADER_SIZE; } memcpy(szLoppedHdr, (char*)(pBuffer->GetBuffer()), /* Flawfinder: ignore */ bufSize); szLoppedHdr[bufSize] = '\0'; //(Moved <window>-tag-handling code out and into // GetFileHeaderReadPending handler, above. so that // width and height could be passed out via file hdr)#if OLD_SCHOOL_AVGBITRATE_CALCULATION ULONG32 ulAvgBitRate = ulMaxBitRate;#else ULONG32 ulAvgBitRate = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -