Exemplo n.º 1
0
void CMediaPlayer::PlayFunc(ThreadParam *pParam)
{
	CMediaSource *pSource;
	CMediaDecoder *pDecoder;
	CMediaRenderer *pRenderer;
	int nTime;
	bool bDrop;
	int nReadSize, nSrcSize, nDecSize, nRndSize;
	unsigned char *pSrcFrame, *pDecFrame, *pRndFrame;

	pSource = pParam->pSource;
	pDecoder = pParam->pDecoder;
	pRenderer = pParam->pRenderer;
	nTime = 0;
	bDrop = false;
	if (pDecoder != NULL)
	{
		nReadSize = pDecoder->GetInputSize();
		pSrcFrame = new unsigned char[nReadSize];
		nDecSize = pDecoder->GetOutputSize();
		pDecFrame = new unsigned char[nDecSize];
		pRndFrame = pDecFrame;
	}
	else
	{
		nReadSize = 0x1000;
		pSrcFrame = new unsigned char[nReadSize];
		pDecFrame = NULL;
		pRndFrame = pSrcFrame;
	}

	for (;;)
	{
		m_pSemaphore->Wait();  //when paused, this thread will be blocked here
		if (m_nState == STATE_STOP)
		{
			m_pSemaphore->Release();
			break;
		}

		if (!pParam->bReferenceClock)
			if (nTime + 100 < m_pClock->GetTime())  //time stamp behind the clock too much
				bDrop = true;
		m_pMutex->Lock();  //only one thread can read data from media source
		nSrcSize = pSource->ReadData(pParam->nIndex, bDrop? NULL : pSrcFrame, nReadSize);  //read a frame
		m_pMutex->Unlock();
		if (nSrcSize == 0)  //no more frame to render
		{
			pRenderer->Flush(true);
			m_pSemaphore->Release();
			break;
		}

		nTime = pSource->GetOutputTime(pParam->nIndex);
		if (bDrop)  //drop this frame
			bDrop = false;
		else
		{
			if (pDecoder != NULL)
			{
				if (pParam->type != RENDER_TYPE_SPDIF)
					nDecSize = pDecoder->Decode(pSrcFrame, nSrcSize, pDecFrame);
				else
					nDecSize = pDecoder->SPDIF(pSrcFrame, nSrcSize, pDecFrame);
			}
			else
				nDecSize = nSrcSize;
			nRndSize = nDecSize;

			if (!pParam->bReferenceClock)
				m_pClock->WaitFor(nTime);  //wait until this frame can be rendered
			pRenderer->Write(pRndFrame, nRndSize);  //render a frame
			if (pParam->bReferenceClock && nTime > 0)
				m_pClock->SetTime(nTime);  //update clock
		}

		m_pSemaphore->Release();
	}  //while

	if (pParam->pDecoder)
		pParam->pDecoder->Flush();
	delete[] pSrcFrame;
	delete[] pDecFrame;
}