📄 dr_prefetch.cpp
字号:
char filenameN[24];
sprintf(filenameN, "%s%u", drfilename, m_idnum);
fdrout[m_idnum] = open(filenameN, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdrout[m_idnum] < 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("DROutput::Configure - error opening capture file\n"));
}
#endif
return(DR_SUCCESS);
errout:
destroy();
return(DR_FAILURE);
}
/**
* GetStatus - Get the prefetch status
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch::GetStatus (DR_STATCMD cmd, uint32 *pStatus)
{
uint32 bf32tmpStatus=0;
if(pStatus == NULL)
{
return(DR_INVALID_PARAM);
}
switch(cmd)
{
case DR_STATCMD_STATE:
*pStatus = m_State; /* note that the state is not semaphore protected - this is just a snapshot */
break;
case DR_STATCMD_BUFFERS:
if ( (m_prefetchStream->FullStatus() == 0) )
{
bf32tmpStatus |= DR_STATUS_TRACK_BUFFER_EMPTY;
}
/* check play queue */
if (m_prefetchPlayQueue->FullStatus() > 0)
{
bf32tmpStatus |= DR_STATUS_QUEUE_BUFFER;
}
*pStatus = bf32tmpStatus;
break;
case DR_STATCMD_CONTEXT:
*pStatus = (uint32)GetContext();
break;
case DR_STATCMD_NEXT_CONTEXT:
*pStatus = (uint32)GetNextContext();
break;
case DR_STATCMD_RATE:
*pStatus = GetPlayRate();
break;
case DR_STATCMD_CELL_POSITION:
*pStatus = (uint32)GetCellPosition();
break;
default:
break;
}
return(DR_SUCCESS);
}
/**
* QueueControl - enable, disable, or clear the play queue
*
* @param cmd - the command (enable, disable, or clear).
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch::QueueControl (DR_QUEUE_CMD cmd)
{
PLAYMSG *pMessage;
DR_ERROR status = DR_FAILURE;
switch(cmd)
{
case DR_QUEUE_CMD_ENABLE:
if(!m_fPlayQueueEnabled)
{
OS_SemGive(m_semPlayQueueEnabled);
m_fPlayQueueEnabled = TRUE;
status = DR_SUCCESS;
}
break;
case DR_QUEUE_CMD_DISABLE:
if(m_fPlayQueueEnabled)
{
OS_SemTake(m_semPlayQueueEnabled, OS_WAIT_FOREVER);
m_fPlayQueueEnabled = FALSE;
status = DR_SUCCESS;
}
break;
case DR_QUEUE_CMD_CLEAR:
do
{
pMessage = (PLAYMSG *)m_prefetchPlayQueue->Remove();
if (pMessage != NULL)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d: QueueControl, Removed one from the queue: ulData0 = %lx, ulData1 = %lx, ulData2 = %lx\n",
__FILE__, __LINE__, (long)pMessage->play.anon.ulData0, (long)pMessage->play.anon.ulData1, (long)pMessage->play.anon.ulData2));
m_prefetchPlayQueue->ReleaseMsg(pMessage);
status = DR_SUCCESS;
}
} while (pMessage != NULL);
break;
}
return(status);
}
/**
* Play - play as specified in the "play" parameter
*
* @param blocking - should we wait for this play to be started before returning?
* @param play - the paramters for playback.
*
* @retval none
*
* @remarks none.
*/
void DRPrefetch::Play(PLAYCMD play, BOOLEAN fBlockonPlay)
{
PLAYMSG *pMessage = NULL;
/* get a prefetchPlayQueue Message */
pMessage = (PLAYMSG*)m_prefetchPlayQueue->GetMsg((ULONG)OS_WAIT_FOREVER);
pMessage->ulSemID = (fBlockonPlay == TRUE) ? m_semPlayBlock : 0;
pMessage->play = play;
m_prefetchPlayQueue->Write((PVOID)pMessage, OS_WAIT_FOREVER);
if (fBlockonPlay)
{
OS_SemTake(m_semPlayBlock, OS_WAIT_FOREVER);
}
}
/**
* Abort - Abort playback
*
* @retval BOOLEAN - was the playqueue enabled prior to Aborting
*
* @remarks none.
*/
BOOLEAN DRPrefetch::Abort(void)
{
PLAYMSG *pMessage = NULL;
BOOLEAN fPlayQueueWasEnabled;
/* Abort Current Play */
m_fAbort = TRUE;
/* Save the Current State (so we can restore it later) */
fPlayQueueWasEnabled = m_fPlayQueueEnabled;
/* Wait for the Abort command to finish */
QueueControl(DR_QUEUE_CMD_DISABLE);
/* kick the prefetch thread so it won't wait */
pMessage = (PLAYMSG*)m_prefetchPlayQueue->GetMsg((ULONG)OS_NO_WAIT);
if (pMessage != NULL)
{
m_prefetchPlayQueue->Write((PVOID)pMessage, OS_NO_WAIT);
}
while (m_State != DRPRE_STATE_IDLE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u: waiting for stop\n", __FUNCTION__, __LINE__, m_idnum));
OS_TaskDelay(OS_GetTicksPerSecond()/5);
}
/* be sure the queue is cleared */
QueueControl(DR_QUEUE_CMD_CLEAR);
/* Reset Flag */
m_fAbort = FALSE;
return(fPlayQueueWasEnabled);
}
/**
* Flush - Flush buffers
*
* @retval BOOLEAN - succeessful completion?
*
* @remarks none.
*/
BOOLEAN DRPrefetch::Flush(BOOLEAN fGracefully, ULONG ulFlushLevel, ULONG ulClipNum, ULONG *spnIn, PVOID *pvContext)
{
DROUTPUTMESSAGE *pStreamMessage = NULL;
BOOLEAN fSuccess = TRUE;
DbgAssert( (fGracefully && (spnIn != NULL) && (pvContext != NULL) ) || (!fGracefully) );
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u: flush prefetch stream\n", __FUNCTION__, __LINE__, m_idnum));
DBGPRINT(DBG_ON(DBG_TRACE), ("stream level before flush: %u\n", m_prefetchStream->FullStatus()));
do
{
pStreamMessage = (DROUTPUTMESSAGE *)m_prefetchStream->Remove();
if (pStreamMessage != NULL)
{
if (fGracefully)
{
if ( (pStreamMessage->LocalContext == 0) || (((LocalContext*)(pStreamMessage->LocalContext))->ulClipNum != ulClipNum))
{
m_prefetchStream->Write(pStreamMessage);
fSuccess = FALSE;
break;
}
*spnIn = ((LocalContext*)(pStreamMessage->LocalContext))->spnOfPayload;
*pvContext = ((LocalContext*)(pStreamMessage->LocalContext))->pvContext;
}
if (pStreamMessage->payload != NULL)
{
delete (pStreamMessage->payload);
pStreamMessage->payload = NULL;
}
m_prefetchStream->ReleaseMsg(pStreamMessage);
}
} while ( (m_prefetchStream->FullStatus() > ulFlushLevel) && (pStreamMessage != NULL) );
DBGPRINT(DBG_ON(DBG_TRACE), ("stream level after flush: %u\n", m_prefetchStream->FullStatus()));
return(fSuccess);
}
/**
* Stop - empty the play queue, stop the prefetch thread, and flush the prefetch stream
*
* @param reset - flag to reset the playback parameters? (unly currently used for DVD)
*
* @retval none
*
* @remarks none.
*/
void DRPrefetch::Stop (BOOLEAN reset)
{
BOOLEAN fPlayQueueWasEnabled;
/* Abort() also clears and disables the queue */
fPlayQueueWasEnabled = Abort();
Flush(FALSE, 0, 0, NULL, NULL);
if (reset)
{
ResetParams();
}
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u: Stop Command Completed\n", __FUNCTION__, __LINE__, m_idnum));
if(fPlayQueueWasEnabled == TRUE)
{
QueueControl(DR_QUEUE_CMD_ENABLE);
}
}
/**
* PrefetchThread - The Prefetch Thread. Reads play commands and executes them, putting data into the prefetch stream
*
* @retval none
*
* @remarks none.
*/
ULONG DRPrefetch::PrefetchThread(void)
{
PLAYMSG *pInputMessage;
PLAYCMD playCmd;
ULONG ulSemID;
while(!m_fKill)
{
/* we're starting out (or just finished) - we're idle */
m_State = DRPRE_STATE_IDLE;
OS_SemTake(m_semPlayQueueEnabled, OS_WAIT_FOREVER);
pInputMessage = NULL;
if (!m_fKill && !m_fAbort)
{
pInputMessage = (PLAYMSG*)m_prefetchPlayQueue->Read(OS_WAIT_1S / 10);
if ( (NULL != pInputMessage) && (m_fKill == FALSE) )
{
/* we've read - so we're running */
m_State = DRPRE_STATE_RUNNING;
/* copy the info and release the message*/
playCmd = pInputMessage->play;
ulSemID = pInputMessage->ulSemID;
m_prefetchPlayQueue->ReleaseMsg(pInputMessage);
pInputMessage = NULL;
/* If the prefetch Play() command was configured as a blocking call, this releases it */
if (ulSemID != 0)
{
OS_SemGive(ulSemID);
}
/* If buffer is empty, send buffer empty event */
if (m_prefetchPlayQueue->FullStatus() == 0)
{
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_COMMAND_BUFFER_EMPTY, NULL);
}
}
/* Do the data retrieval requested by playCmd */
if (DR_SUCCESS != dataRetrieve(playCmd))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PrefetchThread() -- Error in Data Retrieve\n"));
}
}
else
{
OS_TaskDelay(OS_WAIT_1S / 25);
DBGPRINT(DBG_ON(DBG_VERBOSE), ("PrefetchThread():%u - ticked off!\n", m_idnum));
}
}
/* give the sem here in case it isn't given inside of dataRetrieve (we're aborting or ticking off) */
OS_SemGive(m_semPlayQueueEnabled);
if (!m_fKill)
{
OS_TaskDelay(OS_WAIT_1S / 50);
}
}
m_State = DRPRE_STATE_IDLE;
OS_TaskExit();
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -