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

📄 mpeg_demux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

/**
 * MPEG_ScanForAndSkipStartCode Function. Scans the MPEG stream for the next
 * valid start code. This start code, once found, is stored in the Demux
 * information structure and the MPEG data stream pointer is updated
 * appropriately.
 *
 * @param
 *    DEMUXINFO *pDemuxInfo - Demux information
 *
 * @retval
 *    None.
 *
 * @verified
 *    No.
 */
static void MPEG_ScanForAndSkipStartCode( DEMUXINFO *pDemuxInfo )
{
    BYTE bStartCodePtr[MPEG_START_CODE_LENGTH]  = {0};
    BYTE bWrapDataPtr[3]                        = {0};
    BYTE bWrapOffset                            = 0;
    ULONG ulDataNeeded                          = 0;
    ULONG ulWrapDataLength                      = 0;
    ULONG ulStartCode                           = 0;
    ULONG ulSkipBytes;
    BOOLEAN fFoundStartCode                     = FALSE;
    static BOOLEAN fFirstStartCode              = TRUE;
    static BOOLEAN fHadToScan                   = FALSE;
    static ULONG ulLastStartCode                = 0;

    /* Search for a valid start code */
    while (FALSE == fFoundStartCode)
    {
        if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
        {
            DBGPRINT(DBG_MPEG_DEMUX, ("MPEG_ScanForAndSkipStartCode: ABORTED\n"));
            return;
        }

        /* If there is zero bytes of data left, wait for
         * more data, then look for a start code. */
        if (0 == pDemuxInfo->ulDataLength)
        {
            MPEG_WaitForMoreData(pDemuxInfo);
            if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
            {
                return;
            }
        }

        /* If there is less than four bytes of data left, grab the remaining
         * data as wrap data and use it to look for a start code. */
        else if (pDemuxInfo->ulDataLength < MPEG_START_CODE_LENGTH)
        {
            /* Grab the wrap data and the wrap data length. */
            ulWrapDataLength = pDemuxInfo->ulDataLength;
            memcpy(bWrapDataPtr, pDemuxInfo->pbData, ulWrapDataLength);
            MPEG_DemuxInfoUpdate(pDemuxInfo, ulWrapDataLength, UPDATE_NONE, __LINE__);
            if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
            {
                return;
            }

            /* Use the wrap data to look for a start code. */
            while ( (ulWrapDataLength != 0) && !fFoundStartCode )
            {
                if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
                {
                    return;
                }

                ulDataNeeded = MPEG_START_CODE_LENGTH - ulWrapDataLength;
                memcpy(bStartCodePtr, &bWrapDataPtr[bWrapOffset], ulWrapDataLength);
                memcpy(bStartCodePtr + ulWrapDataLength, pDemuxInfo->pbData, ulDataNeeded);
                ulStartCode = MAKE_DWORD( bStartCodePtr );

                if ( COULD_BE_START_CODE(ulStartCode) == TRUE)
                {
                    /* Verify we've found a valid start code. */
                    if ( TRUE == MPEG_IsStartCodeValid(ulStartCode) )
                    {
#if ENABLE_DEMUX_REMAP_FEATURE
                        /* Remap the stream ID in the stream, if necessary. */
                        if ( pDemuxInfo->tConfigInfo.bRemapStreamID == (BYTE)(ulStartCode & 0x000000ff) )
                        {
                            DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(1): BEFORE (0x%02x)\n",
                                *(pDemuxInfo->pbData + ulDataNeeded - 1)));

                            *(pDemuxInfo->pbData + ulDataNeeded - 1) = pDemuxInfo->tConfigInfo.bRemapStreamIDValue;

                            DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(1): AFTER (0x%02x)\n",
                                *(pDemuxInfo->pbData + ulDataNeeded - 1)));
                        }
#endif

                        fFoundStartCode = TRUE;
                        MPEG_DemuxInfoUpdate(pDemuxInfo, ulDataNeeded, UPDATE_NONE, __LINE__);
                        if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
                        {
                            return;
                        }
                    }
                }

                /* Did not find a valid start code, look at the next group of four bytes. */
                if (fFoundStartCode == FALSE)
                {
                    if (FALSE == fHadToScan)
                    {
                        fHadToScan = TRUE;
                    }

                    ulWrapDataLength--;
                    bWrapOffset++;
                }
                memset( bStartCodePtr, 0, MPEG_START_CODE_LENGTH );
            }

            /* Clear the wrap data. */
            memset( bWrapDataPtr, 0, 3 );
        }

        /* There is enough data to look for a start code. */
        else
        {
            /* Read and return the next four bytes. */
            ulStartCode = MAKE_DWORD( pDemuxInfo->pbData );

            if ( COULD_BE_START_CODE(ulStartCode) == TRUE)
            {
                /* Verify we've found a valid start code. */
                if ( TRUE == MPEG_IsStartCodeValid(ulStartCode) )
                {
#if ENABLE_DEMUX_REMAP_FEATURE
                    /* Remap the stream ID in the stream, if necessary. */
                    if ( pDemuxInfo->tConfigInfo.bRemapStreamID == (BYTE)(ulStartCode & 0x000000ff) )
                    {
                        DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(2): BEFORE (0x%02x)\n",
                            *(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1)));

                        *(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1) = pDemuxInfo->tConfigInfo.bRemapStreamIDValue;

                        DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(2): AFTER (0x%02x)\n",
                            *(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1)));
                    }
#endif

                    fFoundStartCode = TRUE;
                    MPEG_DemuxInfoUpdate(pDemuxInfo, MPEG_START_CODE_LENGTH, UPDATE_NONE, __LINE__);
                    if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
                    {
                        return;
                    }
                }
            }

            /* Did not find a valid start code, look at the next group of four bytes. */
            if (fFoundStartCode == FALSE)
            {
                if( (CSS == pDemuxInfo->tDataEncryption) && (MPEG_PACK_HEADER_START_CODE != ulLastStartCode) )
                {
                    ulSkipBytes = 2048 - ((ULONG)pDemuxInfo->pbData - (ULONG)pDemuxInfo->pbPack);
                    MPEG_DemuxInfoUpdate(pDemuxInfo, ulSkipBytes, UPDATE_NONE, __LINE__);
                    if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
                    {
                        return;
                    }
                }
                else
                {
                    if (FALSE == fHadToScan)
                    {
                        fHadToScan = TRUE;
                    }

                    MPEG_DemuxInfoUpdate(pDemuxInfo, 1, UPDATE_NONE, __LINE__);
                    if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
                    {
                        return;
                    }
                }
            }
        }
    }

    /* Notify scanning done, if necessary. */
    if (TRUE == fHadToScan)
    {
        MPEG_StreamDump(pDemuxInfo);
        fHadToScan = FALSE;
    }

    /* Print out the first valid start code. */
    if (TRUE == fFirstStartCode)
    {
        fFirstStartCode = FALSE;
    }

    /* Save the start code just found. */
    ulLastStartCode = ulStartCode;

    /* Return the valid start code and associated PES ID */
    pDemuxInfo->ulStartCode = ulStartCode;
    pDemuxInfo->bPesID      = (BYTE)(ulStartCode & 0x000000ff);
}

/**
 * MPEG_IsStreamDesired Function. Examines the current start code to see if the
 * stream is desired. This is determined by looking at the Demux configuration
 * data.
 *
 * @param
 *    DEMUXINFO *pDemuxInfo - Demux information
 *
 * @retval
 *    TRUE if the stream is desired
 *    FALSE if the stream is not desired
 *
 * @verified
 *    No.
 */
static BOOLEAN MPEG_IsStreamDesired( DEMUXINFO *pDemuxInfo )
{
    BOOLEAN fRetVal = FALSE;

    /* If the last start code fetched was that of a pack header or a system
     * header, always return TRUE. */
    if ((pDemuxInfo->ulStartCode == MPEG_PACK_HEADER_START_CODE)  ||
        (pDemuxInfo->ulStartCode == MPEG_SYSTEM_HEADER_START_CODE) )
    {
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("MPEG_IsStreamDesired: TRUE -- ID=%x\n", pDemuxInfo->ulStartCode));
#endif
        return TRUE;
    }

    /*
     *  Examine the configuration data to see if the stream is desired
     */
    for (int i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
    {
        if (pDemuxInfo->tConfigInfo.tOutputPin[i].bPesID == pDemuxInfo->bPesID)
        {
#if DBG_ON(DBG_VERBOSE)
            DbgPrint(("MPEG_IsStreamDesired: TRUE -- ID=%x, PesID=%x\n", pDemuxInfo->ulStartCode, pDemuxInfo->bPesID));
#endif
            fRetVal = TRUE;
            break;
        }
        else
        {
            fRetVal = FALSE;
        }
    }

    /* Return whether or not the stream is desired */
    return (fRetVal);
}

/**
 * MPEG_IdentifyStream Function. Uses the current start code to determine
 * which parse state to move to.
 *
 * @param
 *    DEMUXINFO *pDemuxInfo - Demux information
 *
 * @retval
 *    None.
 *
 * @remark
 *    This function will need to scan through the Demux output pins to
 *    see if the identified stream is needed. May need a skip stream state
 *    to skip over a stream if it is not desired.
 *
 * @verified
 *    No.
 */
static void MPEG_IdentifyStream( DEMUXINFO *pDemuxInfo )
{
    switch( pDemuxInfo->ulStartCode )
    {
    case MPEG_PACK_HEADER_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** PACK_HEADER ***\n"));
#endif
        pDemuxInfo->pbPack   = (pDemuxInfo->pbData - 4);
        pDemuxInfo->pbPacket = pDemuxInfo->pbPack;
        pDemuxInfo->ulDemuxState = PACK_HEADER;
        break;

    case MPEG_SYSTEM_HEADER_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** SYSTEM_HEADER ***\n"));
#endif
        pDemuxInfo->ulDemuxState = SYSTEM_HEADER;
        break;

    case MPEG_PADDING_STREAM_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** PADDING_STREAM ***\n"));
#endif
        pDemuxInfo->ulDemuxState = PADDING_STREAM;
        break;

    case MPEG_PRIVATE_STREAM_1_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** PRIVATE_STREAM_1 ***\n"));
#endif
        pDemuxInfo->ulDemuxState = PRIVATE_STREAM_1;
        pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
        break;

    case MPEG_PRIVATE_STREAM_2_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** PRIVATE_STREAM_2 ***\n"));
#endif
        pDemuxInfo->ulDemuxState = PRIVATE_STREAM_2;
        pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
        break;

    case MPEG_PROGRAM_STREAM_MAP_START_CODE:
#if DBG_ON(DBG_VERBOSE)
        DbgPrint(("*** PROGRAM_STREAM_MAP ***\n"));
#endif
        pDemuxInfo->ulDemuxState = SKIP_STREAM;
        break;

    default:
        if( (pDemuxInfo->ulStartCode >= MPEG_AUDIO1_PACKET_START_CODE_BEGIN) &&
            (pDemuxInfo->ulStartCode <= MPEG_AUDIO1_PACKET_START_CODE_END) )
        {
            pDemuxInfo->ulDemuxState = DATA_STREAM;
            pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
        }
        else if( (pDemuxInfo->ulStartCode >= MPEG_AUDIO2_PACKET_START_CODE_BEGIN) &&
            (pDemuxInfo->ulStartCode <= MPEG_AUDIO2_PACKET_START_CODE_END) )
        {
            pDemuxInfo->ulDemuxState = DATA_STREAM;
            pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
        }
        else if( (pDemuxInfo->ulStartCode >= MPEG_VIDEO_PACKET_START_CODE_BEGIN) &&
            (pDemuxInfo->ulStartCode <= MPEG_VIDEO_PACKET_START_CODE_END) )
        {
            pDemuxInfo->ulDemuxState = DATA_STREAM;
            pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
        }
        else if(pDemuxInfo->ulStartCode == MPEG_VIDEO_VC1_PACKET_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -