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

📄 mpeg_demux.cpp

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