📄 pe_consumer_dvd.cpp
字号:
/**
* If active start consuming and presenting AV data. Wakes up dataProc.
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::Run(void)
{
VDVD_ERROR error = VDVD_SUCCESS;
PE_STATUS status = PE_SUCCESS;
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run (%d)\n", m_ConsumerInput));
if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == FALSE)
{
m_fFirstPlay = TRUE;
/* start the PSDemux */
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run - start the PSDemux (%d)\n", m_ConsumerInput));
pcDemux->Start();
/* start the subpic decoder */
if (m_spu_decoder != NULL)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run - start the subpic decoder (%d)\n", m_ConsumerInput));
SPUStart(m_spu_decoder);
}
/* start the decoder */
if (m_videoDecode[0] != NULL)
{
/* TODO-SDK - Configure and start the primary decoder */
DECODER_SETTINGS_TYPE settings;
settings.streamType = DECODER_STREAM_TYPE_MPEG2;
error = m_videoDecode[0]->Setup(&settings);
if (VDVD_IS_ERROR(error))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::Run() - decode setup FAILED! (%d)\n", m_ConsumerInput));
status = PE_FAILURE;
}
/* if we are in I-Frame trick mode this causes a problem so skip it */
if (m_playrate.discontiguous == FALSE)
{
// setup a/v sync
}
else
{
/* SKD TODO: Mute CC during any trickplay*/
}
}
if (m_videoDecode[1] != NULL)
{
/* TODO-SDK - Configure and start the secondary decoder */
DECODER_SETTINGS_TYPE settings;
settings.streamType = DECODER_STREAM_TYPE_MPEG2;
error = m_videoDecode[1]->Setup(&settings);
if (VDVD_IS_ERROR(error))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::Run() - decode setup FAILED! (%d)\n", m_ConsumerInput));
status = PE_FAILURE;
}
/* if we are in I-Frame trick mode this causes a problem so skip it */
if (m_playrate.discontiguous == FALSE)
{
// setup a/v sync
}
else
{
/* SDK: TODO: Mute CC during any trickplay*/
}
}
}
if (status == PE_SUCCESS)
{
/* update state info */
m_fPrefill = FALSE;
m_fSuspend = FALSE;
m_fStillOn = FALSE;
m_fPauseAfterVOBU = FALSE;
m_ConsumerState = PE_CONSUMER_STATE_RUN;
m_fWasPaused = FALSE;
m_SPULastNavPackTime = 0;
}
return (status);
} /* end cPEConsumer_DVD::Run() */
/**
* If active start consuming and presenting AV data.
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::Stop(BOOLEAN fHoldPicture)
{
VDVD_ERROR error = VDVD_SUCCESS;
PE_STATUS peStatus = PE_SUCCESS;
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop()\n"));
/* clear prefill since we are going to stop state */
m_fPrefill = FALSE;
m_fSuspend = FALSE;
m_fWasPaused = FALSE;
m_SPULastNavPackTime = 0;
if ( (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) && (m_fStop == FALSE) )
{
PEINPUTMESSAGE *pMessage = NULL;
ULONG ulSPDStatus = 0;
/* tell the consumer data task it should stop */
m_fStop = TRUE;
m_fAbort = TRUE;
/* flush nav packs */
m_fFlushNavPacks = TRUE;
m_fFlushPlayback = TRUE;
/* kick the dataProc so it won't wait */
pMessage = (PEINPUTMESSAGE*)m_InputStream->GetMsg(OS_NO_WAIT);
if (pMessage != NULL)
{
m_InputStream->Write(pMessage);
}
/* stop the PSDemux */
pcDemux->Stop();
/* Stop the spu decoder
* NOTE: disable forced subpics so the the current spu doesn't get displayed during the flush */
if (m_spu_decoder != NULL)
{
ULONG ulSPDStatus;
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if ((ulSPDStatus & SPU_STATE_MASK) != SPU_STATE_STOPPED)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() stop spu decoder, pids %d %d\n", m_spu_pesID, m_spu_subID));
SPUDisableForced(m_spu_decoder);
SPUStop(m_spu_decoder);
}
}
/* wait for transition to stopped state */
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - wait for transition to stopped state\n"));
while (m_fStop == TRUE)
{
OS_TaskYield();
}
/* Make sure the playback task has stopped */
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Make sure the playback task has stopped\n"));
while (m_fFlushPlayback == TRUE)
{
OS_TaskYield();
}
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Make sure the navpack task has stopped\n"));
while (m_fFlushNavPacks == TRUE)
{
OS_TaskYield();
}
/* stop the decoder */
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - stop the decoder\n"));
if (m_videoDecode[0] != NULL)
{
/* TODO-SDK - Flush out the data channel and stop the primary decoder. */
error = m_videoDecode[0]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
error = m_videoDecode[0]->Stop(fHoldPicture);
}
if (m_videoDecode[1] != NULL)
{
/* TODO-SDK - Flush out the data channel and stop the primary decoder. */
error = m_videoDecode[1]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
error = m_videoDecode[1]->Stop(fHoldPicture);
}
/* TODO-SDK - wait until outstanding payloads are released */
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - wait until outstanding payloads are released\n"));
/* make sure the SPU has stopped */
if (m_spu_decoder != NULL)
{
/* if the subpic stop is still in progress wait for it to complete */
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
while ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_STOPPING)
{
OS_TaskDelayMsec(100);
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if (m_fKillDataProc == TRUE)
{
break;
}
}
/* restore Forced SPU display */
SPUEnableForced(m_spu_decoder);
}
m_fAbort = FALSE;
m_fFirstPlay = TRUE;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Exit\n"));
return (PE_SUCCESS);
} /* end cPEConsumer_DVD::Stop() */
/**
* Flush the decoder and all related streams.
* Returns to the RUN state once completed.
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::Flush(void)
{
VDVD_ERROR error = VDVD_SUCCESS;
DBGPRINT(DBG_ON(DBG_TRACE), (("cPEConsumer_DVD::Flush\n" )));
if ( (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) && (m_fStop == FALSE) )
{
PEINPUTMESSAGE *pMessage = NULL;
ULONG ulSPDStatus = 0;
/* tell the consumer data task it should stop */
m_fStop = TRUE;
m_fAbort = TRUE;
/* flush nav packs */
m_fFlushNavPacks = TRUE;
m_fFlushPlayback = TRUE;
/* kick the dataProc so it won't wait */
pMessage = (PEINPUTMESSAGE*)m_InputStream->GetMsg(OS_NO_WAIT);
if (pMessage != NULL)
{
m_InputStream->Write(pMessage);
}
/* stop the PSDemux */
pcDemux->Stop();
/* Flush the spu decoder
* NOTE: disable forced subpics so the the current spu doesn't get displayed during the flush */
if (m_spu_decoder != NULL)
{
SPUDisableForced(m_spu_decoder);
SPUFlush(m_spu_decoder);
}
/* wait for transition to stopped state */
DBGPRINT(DBG_ON(DBG_TRACE), (("cPEConsumer_DVD::Flush() - wait for transition to stopped state\n" )));
while (m_fStop == TRUE)
{
OS_TaskYield();
}
/* restart the PSDemux
* We do this here because the call to Start will wait for the stop
* to complete before restarting. This will make sure the demux has
* consumed all data before we flush the decoder */
pcDemux->Start();
/* if the subpic flush is still in progress wait for it to complete */
if (m_spu_decoder != NULL)
{
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
while ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_FLUSHING)
{
OS_TaskDelayMsec(100);
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if (m_fKillDataProc == TRUE)
{
break;
}
}
/* restore SPU */
SPUEnableForced(m_spu_decoder);
}
/* Make sure the playback/navpack task has stopped */
while (m_fFlushPlayback == TRUE)
{
OS_TaskYield();
}
while (m_fFlushNavPacks == TRUE)
{
OS_TaskYield();
}
/* flush the decoder */
if (m_videoDecode[0] != NULL)
{
/* TODO-SDK - Flush the decoder. */
error = m_videoDecode[0]->Flush(DECODER_TYPE_VIDEO, DECODE_FLUSH_MODE_DISCARD);
error = m_videoDecode[0]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
}
if (m_videoDecode[1] != NULL)
{
/* TODO-SDK - Flush the decoder. */
error = m_videoDecode[1]->Flush(DECODER_TYPE_VIDEO, DECODE_FLUSH_MODE_DISCARD);
error = m_videoDecode[1]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
}
/* TODO-SDK - wait until outstanding payloads are released */
m_fAbort = FALSE;
/* restore the run state */
m_ConsumerState = PE_CONSUMER_STATE_RUN;
m_fPauseAfterVOBU = FALSE;
m_fFirstPlay = TRUE;
}
return (PE_SUCCESS);
} /* end cPEConsumer_DVD::Flush() */
/**
* cPEConsumer_DVD::SetRate
*
* @param PE_ISTREAMCTRL_PLAYRATE *pPlayRate
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::SetRate(PE_ISTREAMCTRL_PLAYRATE *pPlayRate)
{
PE_STATUS status;
status = cPEConsumer::SetRate(pPlayRate);
if (status == PE_SUCCESS)
{
if (pPlayRate->rate > PLAY_RATE_PAUSE)
{
m_fPauseAfterVOBU = FALSE;
}
}
return (status);
}
/**
* Handles trick mode changes for DVD
*
* @param rate - The new rate requested.
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::SetVideoDecodeRate(PE_ISTREAMCTRL_PLAYRATE *pPlayRate)
{
PE_STATUS status = PE_SUCCESS;
if (pPlayRate == NULL)
{
status = PE_FAILURE;
}
else
{
/* step is handled slightly differently than the rest of the trick modes - and especially for DVD */
if ( (pPlayRate->rate == PLAY_RATE_STEP) && (pPlayRate->direction == PE_ISTREAMCTRL_DIRECTION_BACKWARD) &&
( (m_playrate.rate == PLAY_RATE_STEP) ) )
{
m_fPauseAfterVOBU = FALSE;
}
else
{
status = cPEConsumer::SetVideoDecodeRate(pPlayRate);
}
}
return (status);
}
/**
* Perform dvd specific processing of end of stream, then call
* the base class consumer for additional processing.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -