📄 mpeg_demux.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2006 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file mpeg_demux.cpp
*
* MPEG Demux source file.
*
* $Id: mpeg_demux.cpp,v 1.70 2007/01/11 19:48:06 jared Exp $
*/
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "cStream.h"
#include "cDemux.h"
#include "mpgstruct.h"
#include "mpeg_demux.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/*
* MPEG Demux Macros
*****************************************************************************/
#define DBG_MPEG_DEMUX DBG_ERROR
#define DBG_ON(x) (DBG_MPEG_DEMUX >= x)
#define COULD_BE_START_CODE(x) ((x & 0xFFFFFF00) == 0x00000100)
/*
* MPEG Demux Private Variables
*****************************************************************************/
static ULONG ulDemuxErrorCnt = 0;
/******************************************************************************
*******************************************************************************
** **
** MPEG Demux Forward Function Declarations **
** **
*******************************************************************************
******************************************************************************/
static void MPEG_StreamDump( DEMUXINFO *pDemuxInfo );
static void MPEG_DemuxInfoUpdate(DEMUXINFO *pDemuxInfo, LONG lDataOffset, BYTE bUpdate, ULONG ulLine);
static void MPEG_UpdateOutputPins(DEMUXINFO *pDemuxInfo);
#if ENABLE_DEMUX_REMAP_FEATURE
static void MPEG_UpdateRemap(DEMUXINFO *pDemuxInfo);
#endif
static void MPEG_ResetDataInfo(DEMUXINFO *pDemuxInfo);
#if DBG_MPEG_DEMUX >= DBG_TRACE
static void MPEG_ConfigurationDataDump( DEMUXCONFIGINFO *pDemuxConfigInfo );
#endif
/******************************************************************************
*******************************************************************************
** **
** MPEG Demux Input Function **
** **
*******************************************************************************
******************************************************************************/
/**
* MPEG_WaitForMoreData Function. Retrieves data from the stream interface
* and loads the Demux information structure.
*
* @param
* DEMUXINFO *pDemuxInfo - Demux information
*
* @retval
* None.
*
* @remark
* Should this function check the input pin pointer to make sure it is
* not NULL?
*
* @verified
* Yes.
*/
static void MPEG_WaitForMoreData( DEMUXINFO *pDemuxInfo )
{
DEMUXIOSTREAM *pInputPin = NULL;
DEMUXINPUTMESSAGE *pInMessage = NULL;
DEMUXIOSTREAM *pOutputPin = NULL;
DEMUXOUTPUTMESSAGE *pOutMessage = NULL;
int i;
/* Finish processing the current input message and release its payload */
if (pDemuxInfo->tInMessage.payload != NULL)
{
TCH_PAYLOAD(pDemuxInfo->tInMessage.payload);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState == DEMUX_STARTED)
{
/* if there is a bypass output pin send it all of the data from this payload */
for (i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
if (pDemuxInfo->tConfigInfo.tOutputPin[i].tStreamType == BYPASS)
{
pOutputPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_WAIT_FOREVER);
if (pOutMessage != NULL)
{
pOutMessage->Encryption = pDemuxInfo->tInMessage.Encryption;
pOutMessage->ulVobuCC = pDemuxInfo->tInMessage.ulVobuCC;
pOutMessage->fIsVobuStill = pDemuxInfo->tInMessage.fIsVobuStill;
/* 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)
{
/* set the read pointer to the correct location */
pOutMessage->payload->set_rd_ptr((PVOID)pDemuxInfo->pbBypassData);
break;
}
OS_TaskDelay(OS_WAIT_1S / 50);
}
if (pOutputPin->Write( (PVOID)pOutMessage ) != OS_OK)
{
if (pOutMessage->payload != NULL)
{
delete (pOutMessage->payload);
pOutMessage->payload = NULL;
}
pOutputPin->ReleaseMsg(pOutMessage);
pOutMessage = NULL;
}
}
break;
}
}
}
TCH_PAYLOAD(pDemuxInfo->tInMessage.payload);
/* Check flags of current message and send empty messages (no payload) to the output pins if needed */
if ((pDemuxInfo->tInMessage.DiscontinuityAtEnd == TRUE) ||
(pDemuxInfo->tInMessage.EndOfStream == TRUE) ||
(pDemuxInfo->tInMessage.SequenceEnd != FALSE) )
{
int semCnt = 0;
for (i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
pOutputPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_WAIT_FOREVER);
if (pOutMessage != NULL)
{
if (pDemuxInfo->tInMessage.semMsgDone)
{
pOutMessage->semMsgDone = pDemuxInfo->pDynamicConfigInfo->semPinSync;
semCnt++;
}
pOutMessage->payload = NULL;
pOutMessage->ulVobuCC = pDemuxInfo->tInMessage.ulVobuCC;
pOutMessage->fIsVobuStill = pDemuxInfo->tInMessage.fIsVobuStill;
pOutMessage->DiscontinuityAtEnd = pDemuxInfo->tInMessage.DiscontinuityAtEnd;
pOutMessage->EndOfStream = pDemuxInfo->tInMessage.EndOfStream;
pOutMessage->SequenceEnd = pDemuxInfo->tInMessage.SequenceEnd;
pOutMessage->Encryption = pDemuxInfo->tInMessage.Encryption;
pOutMessage->StreamContext = pDemuxInfo->tInMessage.StreamContext;
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);
}
}
/* release the payload */
if (pDemuxInfo->tInMessage.payload != NULL)
{
TCH_PAYLOAD(pDemuxInfo->tInMessage.payload);
delete (pDemuxInfo->tInMessage.payload);
pDemuxInfo->tInMessage.payload = NULL;
}
}
/* Grab a pointer to the Demux input pin */
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("MPEG_WaitForMoreData: Grab a pointer to the Demux input pin\n"));
#endif
pInputPin = pDemuxInfo->tConfigInfo.tInputPin;
/* Get a new message with more data */
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("MPEG_WaitForMoreData: Get a new message with more data\n"));
#endif
do
{
pInMessage = (DEMUXINPUTMESSAGE *)pInputPin->Read(OS_GetTicksPerSecond()/10);
if (pInMessage != NULL)
{
TCH_PAYLOAD(pInMessage->payload);
}
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("DEMUX: Abort\n"));
if (pInMessage != NULL)
{
if (pInMessage->payload != NULL)
{
delete (pInMessage->payload);
pInMessage->payload = NULL;
}
if (pInMessage->semMsgDone)
{
OS_SemGive(pInMessage->semMsgDone);
}
pInputPin->ReleaseMsg(pInMessage);
pInMessage = NULL;
}
pDemuxInfo->pbData = NULL;
pDemuxInfo->pbPack = NULL;
pDemuxInfo->pbPacket = NULL;
pDemuxInfo->ulDataLength = 0;
return;
}
if (pInMessage != NULL)
{
/* check to see if the message has a payload
* or is an info packet containing a "metadata" payload */
if ( (pInMessage->payload == NULL) || (pInMessage->fInfoPayload == TRUE) )
{
int semCnt = 0;
TCH_PAYLOAD(pInMessage->payload);
/* Messages with no payload should be passed directly to the output pins without
* being processed by the psdemux since these are just for passing discontinuity
* or end of stream information */
for (i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
if ( (pInMessage->fInfoPayload != TRUE) ||
(pDemuxInfo->tConfigInfo.tOutputPin[i].tStreamType == BYPASS) )
{
pOutputPin = pDemuxInfo->tConfigInfo.tOutputPin[i].pDestStream;
pOutMessage = (DEMUXOUTPUTMESSAGE *)pOutputPin->GetMsg(OS_WAIT_FOREVER);
if (pOutMessage != NULL)
{
pOutMessage->payload = NULL;
while (pInMessage->payload != NULL)
{
pOutMessage->payload = pInMessage->payload->REF_PAYLOAD;
if (pOutMessage->payload != NULL)
{
break;
}
OS_TaskDelay(OS_WAIT_1S / 50);
}
if (pInMessage->semMsgDone)
{
pOutMessage->semMsgDone = pDemuxInfo->pDynamicConfigInfo->semPinSync;
semCnt++;
}
pOutMessage->fInfoPayload = pInMessage->fInfoPayload;
pOutMessage->ulVobuCC = pInMessage->ulVobuCC;
pOutMessage->fIsVobuStill = pInMessage->fIsVobuStill;
pOutMessage->DiscontinuityAtBeginning = pInMessage->DiscontinuityAtBeginning;
pOutMessage->DiscontinuityAtEnd = pInMessage->DiscontinuityAtEnd;
pOutMessage->EndOfStream = pInMessage->EndOfStream;
pOutMessage->SequenceEnd = pInMessage->SequenceEnd;
pOutMessage->Encryption = pInMessage->Encryption;
pOutMessage->StreamContext = pInMessage->StreamContext;
if (pOutputPin->Write( (PVOID)pOutMessage ) != OS_OK)
{
pOutputPin->ReleaseMsg(pOutMessage);
pOutMessage = NULL;
}
}
}
}
/* wait for all outputs to process the message */
if (pInMessage->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(pInMessage->semMsgDone);
}
/* release the payload if there was one */
if (pInMessage->payload != NULL)
{
delete (pInMessage->payload);
}
/* release the input message */
pInputPin->ReleaseMsg(pInMessage);
pInMessage = NULL;
}
else
{
TCH_PAYLOAD(pInMessage->payload);
/* if there is a payload, check input message for discontinuity at beginning flag.
* If set then send a blank message (no payload) with the flag set to all output pins. */
if (TRUE == pInMessage->DiscontinuityAtBeginning)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -