📄 mpeg_demux.cpp
字号:
{
int semCnt = 0;
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_WaitForMoreData: Detected Discontinuity\n"));
/* notify all output pins */
for (i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
/* so that we don't send 2 discontinuity at beginning messages on the first packet
* of a new pin that already has this flag set */
if (pDemuxInfo->tConfigInfo.tOutputPin[i].fFirstPayload == TRUE)
{
/* clear flag */
pDemuxInfo->tConfigInfo.tOutputPin[i].fFirstPayload = FALSE;
}
pOutputPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_WAIT_FOREVER);
if (pOutMessage != NULL)
{
/* check the wait for completion flag */
if (pDemuxInfo->tInMessage.semMsgDone)
{
pOutMessage->semMsgDone = pDemuxInfo->pDynamicConfigInfo->semPinSync;
semCnt++;
}
pOutMessage->payload = NULL;
pOutMessage->ulVobuCC = pInMessage->ulVobuCC;
pOutMessage->fIsVobuStill = pInMessage->fIsVobuStill;
pOutMessage->DiscontinuityAtBeginning = TRUE;
pOutMessage->Encryption = pInMessage->Encryption;
if (pOutputPin->Write( (PVOID)pOutMessage ) != OS_OK)
{
pOutputPin->ReleaseMsg(pOutMessage);
pOutMessage = NULL;
}
}
}
/* wait for all outputs to process the message */
if (pDemuxInfo->tInMessage.semMsgDone)
{
for (i = 0; i < semCnt; i++)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("*********** MPEG_WaitForMoreData: WaitForCompletion\n"));
while (pDemuxInfo->pDynamicConfigInfo->ulDemuxState == DEMUX_STARTED)
{
if (OS_SemTake(pDemuxInfo->pDynamicConfigInfo->semPinSync, OS_WAIT_1S/4) == OS_OK)
{
break;
}
}
DBGPRINT(DBG_ON(DBG_TRACE), ("*********** MPEG_WaitForMoreData: Completed\n"));
}
OS_SemGive(pDemuxInfo->tInMessage.semMsgDone);
}
}
}
}
} while (pInMessage == NULL);
/* Make a local copy of the new message */
pDemuxInfo->tInMessage = *pInMessage;
pDemuxInfo->pbData = (BYTE *)pInMessage->payload->get_rd_ptr();
pDemuxInfo->pbPack = pDemuxInfo->pbData;
pDemuxInfo->pbPacket = pDemuxInfo->pbData;
pDemuxInfo->pbBypassData = pDemuxInfo->pbData;
pDemuxInfo->ulDataLength = (ULONG)pInMessage->payload->get_size();
pDemuxInfo->tDataEncryption = pInMessage->Encryption;
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("**********************************\n"));
DbgPrint(("DEMUX MESSAGE\n"));
DbgPrint(("**********************************\n"));
DbgPrint(("Data: 0x%08x\n", (ULONG)pDemuxInfo->pbData));
DbgPrint(("Check: 0x%08x\n", MAKE_DWORD(pDemuxInfo->pbData)));
DbgPrint(("Length: %d\n", pDemuxInfo->ulDataLength));
DbgPrint(("Encrypted: %d\n", pDemuxInfo->tDataEncryption));
#endif
/* Release the new message */
pInputPin->ReleaseMsg(pInMessage);
pInMessage = NULL;
}
/******************************************************************************
*******************************************************************************
** **
** MPEG Demux Output Function **
** **
*******************************************************************************
******************************************************************************/
/**
* MPEG_SendData Function. Uses the Demux information structure to send the
* demuxed data to the appropriate location via the stream interface.
*
* @param
* DEMUXINFO *pDemuxInfo - Demux information
*
* @retval
* None.
*
* @verified
* Yes.
*/
static void MPEG_SendData( DEMUXINFO *pDemuxInfo )
{
int iLoopCount = 0;
ULONG ulPayloadDataLength = 0;
ULONG ulPacketHeaderSize = 0;
ULONG ulSendDataLength = 0;
DEMUXIOSTREAM *pOutputPin = NULL;
DEMUXOUTPUTMESSAGE *pOutMessage = NULL;
DEMUXOUTPUTPIN *pOutPin = NULL;
DEMUX_TIMESTAMP_TYPE tTimeType = DEMUX_ANY;
OUTPUT_STREAM_TYPE tStreamType = UNDEFINED;
/* Locate the output pin assigned to the given PES_ID, SUB_ID combination */
if (pDemuxInfo->fSystemHeaderFound == TRUE)
{
for (int i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
if (pDemuxInfo->tConfigInfo.tOutputPin[i].bPesID == pDemuxInfo->bPesID)
{
if (pDemuxInfo->tConfigInfo.tOutputPin[i].bSubID == pDemuxInfo->bSubID)
{
pOutPin = &(pDemuxInfo->tConfigInfo.tOutputPin[i]);
pOutputPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
tTimeType = pDemuxInfo->tConfigInfo.tOutputPin[i].tTimeType;
tStreamType = pDemuxInfo->tConfigInfo.tOutputPin[i].tStreamType;
break;
}
}
}
}
/* Update the read pointer of the payload and find the payload data length */
TCH_PAYLOAD(pDemuxInfo->tInMessage.payload);
pDemuxInfo->tInMessage.payload->set_rd_ptr((PVOID)pDemuxInfo->pbData);
ulPayloadDataLength = pDemuxInfo->tInMessage.payload->get_size();
/* If an output pin could not be located, throw away the data and return */
if (pOutputPin == NULL)
{
/* Print out information about the data to be thrown away */
// DBGPRINT(DBG_MPEG_DEMUX, ("MPEG_SendData: No output pin "));
// DBGPRINT(DBG_MPEG_DEMUX, ("(0x%02x, 0x%02x)\n", pDemuxInfo->bPesID, pDemuxInfo->bSubID));
/* Skip the data, which may span multiple payloads */
while (pDemuxInfo->ulPacketDataLength > 0)
{
/* if we're in the process of being stopped just return */
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
if (ulPayloadDataLength < pDemuxInfo->ulPacketDataLength)
{
MPEG_DemuxInfoUpdate(pDemuxInfo, ulPayloadDataLength, UPDATE_PDL, __LINE__);
}
else
{
MPEG_DemuxInfoUpdate(pDemuxInfo, pDemuxInfo->ulPacketDataLength, UPDATE_PDL, __LINE__);
}
ulPayloadDataLength = pDemuxInfo->tInMessage.payload->get_size();
iLoopCount++;
}
/* DEBUG: Print out the number of messages sent */
if (iLoopCount > 1)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("DEMUX: Sent (%d) output messages!\n", iLoopCount));
}
/* Exit MPEG_SendData() */
return;
}
/* if this is the first payload sent to the downstream decoder then send a discontinuity
* message first to indicate this */
if (pOutPin->fFirstPayload == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_SendData: fFirstPayload\n"));
/* clear flag */
pOutPin->fFirstPayload = FALSE;
/* send discontinuity message */
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_WAIT_FOREVER);
if (pOutMessage != NULL)
{
pOutMessage->payload = NULL;
pOutMessage->ulVobuCC = pDemuxInfo->tInMessage.ulVobuCC;
pOutMessage->fIsVobuStill = pDemuxInfo->tInMessage.fIsVobuStill;
pOutMessage->DiscontinuityAtBeginning = TRUE;
pOutMessage->Encryption = NONE;
if (pOutputPin->Write( (PVOID)pOutMessage ) != OS_OK)
{
pOutputPin->ReleaseMsg(pOutMessage);
}
pOutMessage = NULL;
}
}
/* Otherwise, send the data to the appropriate output pin */
while (pDemuxInfo->ulPacketDataLength > 0)
{
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
/* Grab an empty message from the output pin */
do
{
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_GetTicksPerSecond()/10);
/* if we are being deleting don't bother processing any further */
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
if (pOutMessage != NULL)
{
pOutputPin->ReleaseMsg(pOutMessage);
pOutMessage = NULL;
}
return;
}
} while (pOutMessage == NULL);
/* init payload pointer to NULL */
pOutMessage->payload = NULL;
/* Load the empty message with a pointer to the payload and its length */
while (1)
{
pOutMessage->payload = pDemuxInfo->tInMessage.payload->REF_PAYLOAD;
if (pOutMessage->payload != NULL)
{
break;
}
OS_TaskDelay(OS_WAIT_1S / 50);
}
/* if this is a nav pack we process this a little different */
if ( (NVPCK == tStreamType) || (HDNVPCK == tStreamType) )
{
/* if there is a bypass output pin send it all of the data up to this point */
for (int i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
if (pDemuxInfo->pbBypassData == pDemuxInfo->pbPack)
{
break;
}
/* if we're in the process of being stopped then abort */
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
break;
}
if (pDemuxInfo->tConfigInfo.tOutputPin[i].tStreamType == BYPASS)
{
DEMUXIOSTREAM* pBypassPin;
DEMUXOUTPUTMESSAGE* pBypassMsg;
pBypassPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
pBypassMsg = (DEMUXOUTPUTMESSAGE *)pBypassPin->GetMsg(OS_WAIT_FOREVER);
if (pBypassMsg != NULL)
{
pBypassMsg->Encryption = pDemuxInfo->tInMessage.Encryption;
pBypassMsg->ulVobuCC = pDemuxInfo->tInMessage.ulVobuCC;
pBypassMsg->fIsVobuStill = pDemuxInfo->tInMessage.fIsVobuStill;
/* Load the empty message with a pointer to the payload and its length */
while (1)
{
pBypassMsg->payload = pDemuxInfo->tInMessage.payload->REF_PAYLOAD;
if (pBypassMsg->payload != NULL)
{
/* set the read pointer to the correct location */
pBypassMsg->payload->set_rd_ptr((PVOID)pDemuxInfo->pbBypassData);
pBypassMsg->payload->set_wr_ptr((PVOID)pDemuxInfo->pbPack);
break;
}
OS_TaskDelay(OS_WAIT_1S / 50);
}
if (pBypassPin->Write( (PVOID)pBypassMsg, OS_WAIT_FOREVER ) != OS_OK)
{
if (NULL != pBypassMsg->payload)
{
delete (pBypassMsg->payload);
pBypassMsg->payload = NULL;
}
pBypassPin->ReleaseMsg(pBypassMsg);
pBypassMsg = NULL;
}
/* update bypass pointer */
pDemuxInfo->pbBypassData = pDemuxInfo->pbPack;
}
break;
}
}
/* Calculate the packet header size */
ulPacketHeaderSize = pDemuxInfo->pbData - pDemuxInfo->pbPacket;
/* Calculate the amount of data to be sent to the output pin. */
if (ulPayloadDataLength < (pDemuxInfo->ulPacketDataLength + ulPacketHeaderSize) )
{
ulSendDataLength = ulPayloadDataLength;
}
else
{
/* not adding the packet header size on purpose. The demux doesn't need to know we are sending this data,
* we just need to be sure there is enough room in the payload buffer for it */
ulSendDataLength = pDemuxInfo->ulPacketDataLength;
}
/* Set the read pointer of the outgoing payload appropriately */
pOutMessage->payload->set_rd_ptr((PVOID)(pDemuxInfo->pbData - 7));
if (NVPCK == tStreamType)
{
/* Set the write pointer of the outgoing payload appropriately */
pOutMessage->payload->set_wr_ptr((PVOID)(pDemuxInfo->pbData + 2003));
}
else
{
/* Set the write pointer of the outgoing payload appropriately */
pOutMessage->payload->set_wr_ptr((PVOID)(pDemuxInfo->pbData + 2000));
}
}
else
{
/* Calculate the packet header size */
if ( (PES == tStreamType) && (iLoopCount == 0) )
{
PVOID pBasePtr = pOutMessage->payload->get_base_ptr();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -