⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg_demux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 + -