欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

atomizer.cpp

著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
CPP
第 1 页 / 共 2 页
字号:
    BOOL bLoop = FALSE;

    if (SUCCEEDED(status) && (m_State != ATMZR_Offline))
    {
	HX_ASSERT(pBuffer);

	pBuffer->Get(pData, ulDataLen);
	ulNormalizedLen = ulDataLen;

	do
	{
	    bLoop = FALSE;

	    switch (m_State)
	    {
	    case ATMZR_ProcNewHeader:
		ulNormalizedLen -= (QT_NEW_HEADER_SIZE - QT_HEADER_SIZE);
		{
		    QTNewHeader *pHeader = (QTNewHeader *) (pData);

		    ulAtomID = CQTAtom::GetUL32(pHeader->pAtomID);
		    uChildCount = CQTAtom::GetUI16(pHeader->pChildCount);
		}
		// drop to case below

	    case ATMZR_ProcHeader:
		if (ulNormalizedLen == QT_HEADER_SIZE)
		{
		    QTHeader *pHeader = (QTHeader *) (pData);

		    AtomType = CQTAtom::GetUL32(pHeader->pType);
		    ulAtomSize = CQTAtom::GetUL32(pHeader->pSize);

		    if (AtomType == 0)
		    {
			if (m_State == ATMZR_ProcHeader)
			{
			    // Try to interpret this as CQTNewAtom
			    m_State = ATMZR_ProcNewHeader;
			    SeekDataCB(QT_NEW_HEADER_GAP, ATMZR_SEEK_RELATIVE);
			    return retVal;
			}
			status = HXR_PARSE_ERROR;
		    }
		    else if (ulAtomSize == 1)
		    {
			// This must be the Atom with extended size
			m_State = ATMZR_ProcExtendedSize;
			m_AtomType = AtomType;
			ReadDataCB(QT_EXTENDED_SIZE);
			return retVal;
		    }
		    else if (ulAtomSize == 0)
		    {
			// This Atom extends to the of enclosing container
			ulAtomSize = ATOMIZE_ALL;
		    }

		    // drop to case below;
		    m_State = ATMZR_MakeAtom;
		}
		else
		{
		    break;
		}

	    case ATMZR_MakeAtom:
		{
		    QTAtomizerCmd AtomCmd;

		    HX_ASSERT(!m_pNewAtom);

		    AtomCmd = m_pCommander->GetAtomCommand( AtomType,
							    m_pCurrentRoot);

		    if (ulAtomSize == ATOMIZE_ALL)
		    {
			if (m_pCurrentRoot->GetSize() != ATOMIZE_ALL)
			{
			    ulAtomSize = m_pCurrentRoot->GetOffset() +
					 m_pCurrentRoot->GetSize() -
					 m_ulNewAtomOffset;

			    HX_ASSERT(ulAtomSize != 0);

			    if (ulAtomSize == 0)
			    {
				status = HXR_PARSE_ERROR;
				break;
			    }
			}
		    }

		    switch (AtomCmd)
		    {
		    case ATMZR_CMD_LOAD:
		    case ATMZR_CMD_OUTLINE:
			m_pNewAtom = CreateQTAtom(  AtomType,
						    m_ulNewAtomOffset,
						    ulAtomSize,
						    NULL, // no parent
						    ulAtomID,
						    uChildCount);

			if (m_pNewAtom != NULL)
			{
			    if (m_pNewAtom->IsLeafType())
			    {
				// A Leaf Atom
				if (AtomCmd == ATMZR_CMD_LOAD)
				{
				    m_ulNewAtomDataSize = 0;
				    if (ulAtomSize != ATOMIZE_ALL)
				    {
					m_ulNewAtomDataSize = ulAtomSize - ulDataLen;
				    }

#ifndef QTCONFIG_NO_PAGING
				    if ((m_ulNewAtomDataSize > ATMZR_PAGING_THRESHOLD)
					&& m_pNewAtom->IsPagingAtom()
#ifdef QTCONFIG_NO_ASYNC_PAGING
					&& m_bSyncAccessEnabled
#endif	// QTCONFIG_NO_ASYNC_PAGING
					&& (m_ulNewAtomDataSize != ATOMIZE_ALL)
				       )
				    {
					CMemPager* pMemPager = new CMemPager;

					status = HXR_OUTOFMEMORY;
					if (pMemPager)
					{
					    pMemPager->AddRef();
					    status = pMemPager->Init(m_pFileSwitcher,
								     m_ulCurrentOffset,
								     m_ulNewAtomDataSize);
					    if (SUCCEEDED(status))
					    {
						m_pNewAtom->AddRef();
						m_State = ATMZR_ProcBody;
						m_pNewAtom->SetMemPager(pMemPager);
						status = pMemPager->LoadPage((IHXFileResponse*) this);
					    }

					    pMemPager->Release();

					    if (SUCCEEDED(status))
					    {
						return retVal;
					    }
					}
					// Failure
					HX_ASSERT(status != HXR_OK);
					break;
				    }
				    else
#endif	// QTCONFIG_NO_PAGING
				    if ((m_ulNewAtomDataSize != 0) ||
					(ulAtomSize == ATOMIZE_ALL))
				    {
					// Leaf atom with data
					m_pNewAtom->AddRef();
					m_State = ATMZR_ProcBody;
					if (m_ulNewAtomDataSize != 0)
					{
					    ReadDataCB(m_ulNewAtomDataSize);
					    return retVal;
					}
					else
					{
					    ReadDataCB(ATMZR_MAX_FILE_SIZE - m_ulCurrentOffset);
					    return retVal;
					}
				    }
				    else
				    {
					// Leaf atom with no data
					m_pCurrentRoot->AddPresentChild(m_pNewAtom);
					m_ulNewAtomOffset = m_ulCurrentOffset;
					m_pNewAtom = NULL;
					m_State = ATMZR_ProcHeader;
					ReadDataCB(QT_HEADER_SIZE);
				    }
				}
				else
				{
				    // We are not to load the data
				    // so we are ready to attach the atom shell
				    // to the atom tree.
				    m_pCurrentRoot->AddPresentChild(m_pNewAtom);
				    m_pNewAtom = NULL;

				    if (ulAtomSize != ATOMIZE_ALL)
				    {
					m_ulNewAtomOffset = m_ulCurrentOffset +
							    ulAtomSize -
							    ulDataLen;

					m_State = ATMZR_ProcHeader;
					SeekDataCB(m_ulNewAtomOffset);
					return retVal;
				    }

				    // Location of the end of file - unknown
				    m_ulNewAtomOffset = ATOMIZE_ALL;
				}
			    }
			    else
			    {
				// A Non Leaf Atom - has no direct data
				m_pCurrentRoot->AddPresentChild(m_pNewAtom);

				m_pCurrentRoot = m_pNewAtom;
				m_ulNewAtomOffset = m_ulCurrentOffset;
				m_pNewAtom = NULL;
				m_State = ATMZR_ProcHeader;
				ReadDataCB(QT_HEADER_SIZE);
				return retVal;
			    }

			    break;
			}

			// If we couldn't create the atom, skip it.
			// Drop down to case below.

		    case ATMZR_CMD_SKIP:
			if (ulAtomSize != ATOMIZE_ALL)
			{
			    m_ulNewAtomOffset = m_ulCurrentOffset +
						ulAtomSize -
						ulDataLen;
			    m_State = ATMZR_ProcHeader;

			    /* Check to see if we are trying to skip
			     * an mdat atom while using a file object
			     * that prefers linear access (ie. HTTP/1.0)
			     */
			    if (m_bPreferLinearAccess && (QT_mdat == AtomType))
			    {
				HX_RESULT completionRes = HXR_INVALID_FILE;

				if ((m_pCurrentRoot) &&
				    (m_pCurrentRoot->FindPresentChild(QT_moov)))
				{
				    /* We have the moov atom already so
				     * this file is likely formatted for 
				     * progressive download
				     */
				    completionRes = HXR_OK;
				}
				
				CompleteAtomization(completionRes);
			    }
			    else
			    {
				SeekDataCB(m_ulNewAtomOffset);
			    }
			    return retVal;
			}
			else
			{
			    m_ulNewAtomOffset = ATOMIZE_ALL;
			    break;
			}

			// If we couldn't skip the atom, stop.
			// Drop to case below

		    case ATMZR_CMD_STOP:
			break;

		    default:
			status = HXR_INVALID_PARAMETER;
			break;
		    }
		}
		break;

	    case ATMZR_ProcExtendedSize:
		if (ulNormalizedLen == QT_EXTENDED_SIZE)
		{
		    AtomType = m_AtomType;
		    ulAtomSize = CQTAtom::GetUL32(pData);

		    HX_ASSERT(ulAtomSize == 0);

		    if (ulAtomSize == 0)
		    {
			ulAtomSize = CQTAtom::GetUL32(pData + 4);
			m_State = ATMZR_MakeAtom;
			bLoop = TRUE;
		    }
		    else
		    {
			// can't handle atom size beyond 4GB
			status = HXR_ABORT;
		    }
		}
		break;

	    case ATMZR_ProcBody:
		HX_ASSERT(m_pNewAtom);

		if (m_ulNewAtomDataSize != ATOMIZE_ALL)
		{
		    if ((!m_pNewAtom->IsPagingEnabled()) &&
			(ulDataLen == m_ulNewAtomDataSize))
		    {
			HX_ASSERT(pBuffer);

			m_pNewAtom->SetBuffer(pBuffer);
			m_pCurrentRoot->AddPresentChild(m_pNewAtom);
			m_ulNewAtomOffset = m_ulCurrentOffset;
			m_pNewAtom->Release();
			m_pNewAtom = NULL;
			m_State = ATMZR_ProcHeader;
			ReadDataCB(QT_HEADER_SIZE);
			return retVal;
		    }
		    else if (m_pNewAtom->IsPagingEnabled() &&
			     (ulDataLen != 0))
		    {
			m_ulCurrentOffset += ulDataLen;
			m_pCurrentRoot->AddPresentChild(m_pNewAtom);
			HX_ASSERT(m_ulNewAtomDataSize >= ulDataLen);
			m_ulNewAtomOffset = m_ulCurrentOffset +
					    m_ulNewAtomDataSize -
					    ulDataLen;
			m_pNewAtom->Release();
			m_pNewAtom = NULL;
			m_State = ATMZR_ProcHeader;
			if (m_ulNewAtomOffset != m_ulCurrentOffset)
			{
			    SeekDataCB(m_ulNewAtomOffset);
			}
			else
			{
			    ReadDataCB(QT_HEADER_SIZE);
			}
			return retVal;
		    }
		}
		else if (ulDataLen > 0)
		{
		    // Body extended to the end of file - stop here
		    HX_ASSERT(pBuffer);

		    m_ulNewAtomDataSize = ulDataLen;

		    m_pNewAtom->SetBuffer(pBuffer);
		    m_pNewAtom->SetSize(m_ulNewAtomDataSize);
		    m_ulNewAtomOffset = m_ulCurrentOffset;
		    m_pNewAtom->Release();
		    m_pNewAtom = NULL;
		}

		break;

	    default:
		status = HXR_FAIL;
		retVal = HXR_UNEXPECTED;
		break;
	    }
	} while (bLoop);
    }
    else
    {
	// Did not clear for processing
	if (m_State == ATMZR_Offline)
	{
	    return HXR_UNEXPECTED;
	}
	else
	{
	    // The read must have failed - complete atomization as is
	    status = HXR_OK;
	}
    }

    CompleteAtomization(status);

    return retVal;
}


/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXFileResponse::SeekDone
//  Purpose:
//	Notification interface provided by users of the IHXFileObject
//	interface. This method is called by the IHXFileObject when the
//	last seek in the file is complete.
//
STDMETHODIMP CAtomizer::SeekDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_OK;

    if (SUCCEEDED(status) && (m_State != ATMZR_Offline))
    {
	// We seek headers only, so start the read of a header
	switch(m_State)
	{
	case ATMZR_ProcHeader:
	    ReadDataCB(QT_HEADER_SIZE);
	    return retVal;
	case ATMZR_ProcNewHeader:
	    ReadDataCB(QT_NEW_HEADER_SIZE);
	    return retVal;
	default:
	    status = HXR_FAIL;
	    retVal = HXR_UNEXPECTED;
	    break;
	}
    }
    else
    {
	// Did not clear for processing
	if (m_State == ATMZR_Offline)
	{
	    return HXR_UNEXPECTED;
	}
	else
	{
	    // The seek must have failed - complete atomization as is
	    status = HXR_OK;
	}
    }

    CompleteAtomization(status);

    return retVal;
}


/****************************************************************************
 *  IUnknown methods
 */
/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::QueryInterface
//
STDMETHODIMP CAtomizer::QueryInterface(REFIID riid, void** ppvObj)
{
    if (IsEqualIID(riid, IID_IHXFileResponse))
    {
	AddRef();
	*ppvObj = (IHXFileResponse*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXAtomizationCommander))
    {
	AddRef();
	*ppvObj = (IHXAtomizationCommander*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXThreadSafeMethods))
    {
	AddRef();
	*ppvObj = (IHXThreadSafeMethods*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IUnknown))
    {
	AddRef();
	*ppvObj = this;
	return HXR_OK;
    }

    *ppvObj = NULL;

    return HXR_NOINTERFACE;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::AddRef
//
STDMETHODIMP_(ULONG32) CAtomizer::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::Release
//
STDMETHODIMP_(ULONG32) CAtomizer::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}

///////////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXThreadSafeMethods::IsThreadsafe
//
//  Purpose:
//	This routine returns threadsafeness information about the file object
//	which is used by the server for improved performance.
//
STDMETHODIMP_(UINT32)
CAtomizer::IsThreadSafe()
{
    return HX_THREADSAFE_METHOD_FF_GETPACKET | HX_THREADSAFE_METHOD_FSR_READDONE;
}


/****************************************************************************
 *  Class CAtomizer::RecursionCallback
 */
#ifdef QTCONFIG_RECURSION_PROTECTION
/****************************************************************************
 *  Constructor/Destructor
 */
CAtomizer::CRecursionCallback::CRecursionCallback(CAtomizer *pAtomizer)
    : m_pAtomizer(pAtomizer)
    , m_lRefCount(0)
{
    HX_ASSERT(m_pAtomizer);
    m_pAtomizer->AddRef();
}

CAtomizer::CRecursionCallback::~CRecursionCallback(void)
{
    HX_RELEASE(m_pAtomizer);
}

/****************************************************************************
 *  IHXCallback methods
 */
/****************************************************************************
 *  Func
 */
STDMETHODIMP CAtomizer::CRecursionCallback::Func(void)
{
    switch (m_pAtomizer->m_CallbackStep)
    {
    case ATMZR_CBSTEP_Read:
	m_pAtomizer->ReadData(m_pAtomizer->m_ulSize);
	return HXR_OK;
    case ATMZR_CBSTEP_Seek:
	m_pAtomizer->SeekData(m_pAtomizer->m_ulSize,
			      m_pAtomizer->m_bRelative);
	return HXR_OK;
    default:
	// nothing to do
	break;
    }

    return HXR_UNEXPECTED;
}

/****************************************************************************
 *  IUnknown methods
 */
/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::QueryInterface
//
STDMETHODIMP CAtomizer::CRecursionCallback::QueryInterface(
    REFIID riid,
    void** ppvObj)
{
    if (IsEqualIID(riid, IID_IUnknown))
    {
	AddRef();
	*ppvObj = this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXCallback))
    {
        AddRef();
        *ppvObj = (IHXCallback*)this;
        return HXR_OK;
    }

    *ppvObj = NULL;

    return HXR_NOINTERFACE;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::AddRef
//
STDMETHODIMP_(ULONG32) CAtomizer::CRecursionCallback::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::Release
//
STDMETHODIMP_(ULONG32) CAtomizer::CRecursionCallback::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}
#endif	// QTCONFIG_RECURSION_PROTECTION

⌨️ 快捷键说明

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