📄 pe_consumer_dvd.cpp
字号:
pcDemux->DetachOutputStream(m_pBypassStream);
/* detach the input stream from the demux */
DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: detach the input stream from the demux\n"));
pcDemux->DetachInputStream();
/* now it is safe to delete the demux */
DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: Tell demux to delete\n"));
if (pcDemux->Delete() != DEMUX_PASS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: cDemux::Delete FAILED!\n", __FUNCTION__));
}
if (m_semPSDemxMsgSync != 0)
{
OS_SemDelete(m_semPSDemxMsgSync);
m_semPSDemxMsgSync = 0;
}
if (m_semNavPackState != 0)
{
OS_SemDelete(m_semNavPackState);
m_semNavPackState = 0;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: delete the demux class\n"));
delete pcDemux;
pcDemux = NULL;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: Finished\n"));
return (PE_SUCCESS);
}
/**
* Private function that creates any required cStreams.
*
* @param None
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::CreateStreams(void)
{
/* Create the subpic decoder input stream */
m_pSPUStream = new cStream;
m_pSPUStreamBuffer = OS_MemAlloc(sizeof(cSPUStreamMessage) * SUBPIC_NUM_MESSAGES);
if ((NULL == m_pSPUStream) || (NULL == m_pSPUStreamBuffer))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create subpic cStream\n"));
goto error_out;
}
/* Create a stream for receiving nav packs from the PSDemux */
m_pNvPckStream = new cStream;
m_pNvPckStreamBuffer = OS_MemAlloc(sizeof(DEMUXOUTPUTMESSAGE) * NVPACK_NUM_MESSAGES);
if ( (m_pNvPckStream == NULL) || (m_pNvPckStreamBuffer == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create navpack cStream\n"));
goto error_out;
}
/* Create the stream for feeding decode playback */
m_pBypassStream = (cStream*) new cStream;
m_pBypassStreamBuffer = OS_MemAlloc(sizeof(DEMUXOUTPUTMESSAGE) * BYPASS_NUM_MESSAGES);
if ( (m_pBypassStream == NULL) || (m_pBypassStreamBuffer == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create bypass cStream\n"));
goto error_out;
}
/* create the input stream for the PSDemux */
m_pDemuxInStream = new DEMUXIOSTREAM;
m_pDemuxStreamBuffer = OS_MemAlloc(sizeof(DEMUXINPUTMESSAGE) * INPUT_STREAM_DEPTH);
if ((m_pDemuxInStream == NULL) || (m_pDemuxStreamBuffer == NULL))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create PSDemux cStream\n"));
goto error_out;
}
/* Initialize the new streams */
m_pSPUStream->Initialize(m_pSPUStreamBuffer, SUBPIC_NUM_MESSAGES, sizeof(cSPUStreamMessage), "SPUStream");
m_pNvPckStream->Initialize(m_pNvPckStreamBuffer, NVPACK_NUM_MESSAGES, sizeof(DEMUXOUTPUTMESSAGE), "NvPckStream");
m_pBypassStream->Initialize(m_pBypassStreamBuffer, BYPASS_NUM_MESSAGES, sizeof(DEMUXOUTPUTMESSAGE), "BypassStream");
m_pDemuxInStream->Initialize(m_pDemuxStreamBuffer, INPUT_STREAM_DEPTH, sizeof(DEMUXINPUTMESSAGE), "DemuxStream");
return (PE_SUCCESS);
error_out:
DeleteStreams();
return (PE_FAILURE);
}
/**
* Private function that deletes cStreams created by CreateStreams().
*
* @param None
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::DeleteStreams(void)
{
/* Delete the PSDemux stream */
if (NULL != m_pDemuxInStream)
{
DEMUXINPUTMESSAGE *message;
while (1)
{
message = (DEMUXINPUTMESSAGE*)m_pDemuxInStream->Read(OS_NO_WAIT);
if (message == NULL)
{
break;
}
if (NULL != message->payload)
{
delete(message->payload);
message->payload = NULL;
}
}
m_pDemuxInStream->Destroy();
delete (m_pDemuxInStream);
m_pDemuxInStream = NULL;
}
if (NULL != m_pDemuxStreamBuffer)
{
OS_MemFree(m_pDemuxStreamBuffer);
m_pDemuxStreamBuffer = NULL;
}
/* Delete the bypass stream */
if (NULL != m_pBypassStream)
{
DEMUXOUTPUTMESSAGE *message;
while (1)
{
message = (DEMUXOUTPUTMESSAGE*)m_pBypassStream->Read(OS_NO_WAIT);
if (message == NULL)
{
break;
}
if (NULL != message->payload)
{
delete(message->payload);
message->payload = NULL;
}
}
m_pBypassStream->Destroy();
delete (m_pBypassStream);
m_pBypassStream = NULL;
}
if (NULL != m_pBypassStreamBuffer)
{
OS_MemFree(m_pBypassStreamBuffer);
m_pBypassStreamBuffer = NULL;
}
/* delete navpack stream */
if (NULL != m_pNvPckStream)
{
DEMUXOUTPUTMESSAGE *message;
while (1)
{
message = (DEMUXOUTPUTMESSAGE*)m_pNvPckStream->Read(OS_NO_WAIT);
if (message == NULL)
{
break;
}
if (NULL != message->payload)
{
delete(message->payload);
message->payload = NULL;
}
}
m_pNvPckStream->Destroy();
delete m_pNvPckStream;
m_pNvPckStream = NULL;
}
if (NULL != m_pNvPckStreamBuffer)
{
OS_MemFree(m_pNvPckStreamBuffer);
m_pNvPckStreamBuffer = NULL;
}
/* delete SPU stream */
if (NULL != m_pSPUStream)
{
DEMUXOUTPUTMESSAGE *message;
while (1)
{
message = (DEMUXOUTPUTMESSAGE*)m_pSPUStream->Read(OS_NO_WAIT);
if (message == NULL)
{
break;
}
if (NULL != message->payload)
{
delete(message->payload);
message->payload = NULL;
}
}
m_pSPUStream->Destroy();
delete m_pSPUStream;
m_pSPUStream = NULL;
}
if (NULL != m_pSPUStreamBuffer)
{
OS_MemFree(m_pSPUStreamBuffer);
m_pSPUStreamBuffer = NULL;
}
return (PE_SUCCESS);
}
/**
* DemuxAddSubpicPS
*
* @param LONG lPID
* @param LONG lSubID
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::DemuxAddSubpicPS(LONG lPesID, LONG lSubID, PVOID pDecoder)
{
PE_STATUS status = PE_SUCCESS;
ULONG ulSPDStatus;
if (pDecoder == NULL)
{
return (PE_NULL_POINTER);
}
/* If we are already demuxing a subpic first cancel the old one */
if (m_spu_decoder != NULL)
{
/* the decoder should not change */
DbgAssert(m_spu_decoder == pDecoder);
if (m_spu_pesID != -1)
{
/* Remove the current subpic demux */
pcDemux->DetachOutputStream(m_pSPUStream);
}
}
else
{
/* store pointer to the spu decoder */
m_spu_decoder = pDecoder;
}
/* if the decoder hasn't been configured do it now */
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if ((ulSPDStatus & SPU_STATE_MASK) < SPU_STATE_REALIZED)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::DemuxAddSubpicPS - Configure SPU Decoder\n"));
/* attach the input stream */
if (SPUAttachInputStream(m_spu_decoder, m_pSPUStream) != SPU_SUCCESS)
{
DbgPrint(("SPDecoderAttachInputStream FAILED!\n"));
}
/* attach the spu sync callback */
if (SPUAttachSyncCallback(m_spu_decoder, peConsumerDVDSubpicSyncCallback, this) != SPU_SUCCESS)
{
DbgPrint(("SPDecoderAttachSyncCallback FAILED!\n"));
}
}
/* if a SPU flush is in progress wait for it to complete */
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;
}
}
/* if consumer state is running, but the SPU is stopped then start it now */
if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE)
{
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if ((ulSPDStatus & SPU_STATE_MASK) != SPU_STATE_RUN)
{
/* start the subpic decoder */
SPUStart(m_spu_decoder);
}
}
/* configure ps demux */
if (pcDemux->AttachOutputStream( (BYTE)(lPesID), (BYTE)(lSubID), DEMUX_ANY, UNDEFINED, m_pSPUStream) != DEMUX_PASS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::DemuxAddSubpicPS - Could not add SUBPIC Demux\n"));
status = PE_FAILURE;
}
/* reset spu pointer */
m_spu_pesID = lPesID;
m_spu_subID = lSubID;
return (status);
}
/**
* DemuxRemoveSubpicPS
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::DemuxRemoveSubpicPS(void)
{
if (m_spu_decoder != NULL)
{
ULONG ulSPDStatus = 0;
SPUGetStatus(m_spu_decoder, &ulSPDStatus);
if ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_STOPPED)
{
/* Remove the subpic demux */
m_spu_pesID = -1;
m_spu_subID = -1;
/* remove the subpic stream from the decoder */
pcDemux->DetachOutputStream(m_pSPUStream);
/* flush sub pic decoder, this is necessary to prevent highlights
from reappearing when the next highlight enable goes to the SPU */
SPUFlush(m_spu_decoder);
return PE_SUCCESS;
}
SPUStop(m_spu_decoder);
/* Remove the subpic demux */
pcDemux->DetachOutputStream(m_pSPUStream);
/* flush sub pic decoder */
SPUFlush(m_spu_decoder);
/* wait for the subpic decoder to finish stopping */
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;
}
}
}
/* reset spu pointer
* TODO: can't do this because it prevents the spu from being cleaned up properly
* when we delete the dvd consumer. I need to study this and figure out a better
* solution. This patch is a temp solution, but will not work for hd-dvd since it
* has multiple consumers. */
// m_spu_decoder = NULL;
m_spu_pesID = -1;
m_spu_subID = -1;
return (PE_SUCCESS);
}
/**
* Return status of SPU demux for this consumer
*
* @return PE_STATUS
*/
PE_STATUS cPEConsumer_DVD::DemuxGetSubpicPS(LONG *plPesID, LONG *plSubID, BOOLEAN *pfIsActive)
{
/* the decoder handle is null if we are not actively demuxing */
if ( (m_spu_decoder != NULL) && (m_spu_pesID != -1) )
{
*pfIsActive = TRUE;
*plPesID = m_spu_pesID;
*plSubID = m_spu_subID;
}
else
{
*pfIsActive = FALSE;
*plPesID = m_spu_pesID;
*plSubID = m_spu_subID;
}
return (PE_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -