⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlffpln.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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;
}

/////////////////////////////////////////////////////////////////////////
//  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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -