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

📄 dr_prefetch_bdrom.cpp

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

        ULONGLONG   boStart_of_read;
        ULONGLONG   boEnd_of_read;
        ULONGLONG   boNext_fine;

        LONG        fiLoopHigh;
        LONG        fiLoopLow;

        BOOLEAN     fReverse  = m_BDspeed.fReverse;
        BYTE        bDiscrete = m_BDspeed.bDiscrete;
        BYTE        bApp2loop;

        DBGPRINT(DBG_ON(DBG_TRACE), ("DR: TRICK PLAY Begin!\n"));
        DBGPRINT(DBG_ON(DBG_TRACE), (" discrete: %u\n", bDiscrete));
        DBGPRINT(DBG_ON(DBG_TRACE), (" reverse:  %u\n", fReverse));

        fDataDiscontinuity = TRUE;


        /* Get the EP Coarse */
        if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoGet_EPMapCoarse(EPMAP_STREAMINDEX,  &pClpInfoEpMapCoarse, &ulNumCoarseEntries) )
        {
            DBGPRINT(DBG_ON(DBG_ERROR), (" ClpInfoGet_EPMapCoarse Failed"));
            status = FAILURE;
            goto out;
        }

        /* Get the EP Fine */
        if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoGet_EPMapFine(EPMAP_STREAMINDEX, &pClpInfoEpMapFine, &ulNumFineEntries) )
        {
            DBGPRINT(DBG_ON(DBG_ERROR), (" ClpInfoGet_EPMapFine Failed"));
            status = FAILURE;
            goto out;
        }

        /* based on the INtime and OUTtime that were passed into the clpinfodb, get the edges of the EPmap */
        ciTrickLow   = m_clpInfo.ClpInfoGet_ciStart();
        ciTrickHigh  = m_clpInfo.ClpInfoGet_ciEnd();
        fiTrickLow   = m_clpInfo.ClpInfoGet_fiStart();
        fiTrickHigh  = m_clpInfo.ClpInfoGet_fiEnd();

        ciTrickStart = (!fReverse) ? ciTrickLow   : ciTrickHigh;
        ciTrickEnd   = (!fReverse) ? ciTrickHigh  : ciTrickLow;
        fiTrickStart = (!fReverse) ? fiTrickLow   : fiTrickHigh;
        fiTrickEnd   = (!fReverse) ? fiTrickHigh  : fiTrickLow;

        increment    = (!fReverse) ? 1            : -1;

        DBGPRINT(DBG_ON(DBG_TRACE), ("\nciTrickStart:   %u\n", ciTrickStart));
        DBGPRINT(DBG_ON(DBG_TRACE), ("ciTrickEnd:     %u\n", ciTrickEnd));
        DBGPRINT(DBG_ON(DBG_TRACE), ("fiTrickStart:   %u\n", fiTrickStart));
        DBGPRINT(DBG_ON(DBG_TRACE), ("fiTrickEnd:     %u\n", fiTrickEnd));


        /* sanity checks for trick start and end */
        DbgAssert( (fiTrickStart >= pClpInfoEpMapCoarse[ciTrickStart].ref_to_EP_fine_id) || (fiTrickStart < ( (ciTrickStart+1 != ulNumCoarseEntries) ? pClpInfoEpMapCoarse[ciTrickStart+1].ref_to_EP_fine_id : ulNumFineEntries) ) );
        DbgAssert( (fiTrickEnd   >= pClpInfoEpMapCoarse[ciTrickEnd].ref_to_EP_fine_id)   || (fiTrickEnd   < ( (ciTrickEnd+1   != ulNumCoarseEntries) ? pClpInfoEpMapCoarse[ciTrickEnd+1  ].ref_to_EP_fine_id : ulNumFineEntries) ) );


        /* Trick Loop */
        LONG ci = ciTrickStart;
        LONG fi = fiTrickStart;
        while ( (!fReverse && (ci <= (LONG)ciTrickEnd) && (fi <= (LONG)fiTrickEnd) ) ||
                ( fReverse && (ci >= (LONG)ciTrickEnd) && (fi >= (LONG)fiTrickEnd) )  )
        {
            /* find last fi of loop */

            /* forward movement */
            if ((ci + 1) >= (LONG)ulNumCoarseEntries)
            {
                fiLoopHigh = ulNumFineEntries;
            }
            else
            {
                fiLoopHigh = pClpInfoEpMapCoarse[ci+1].ref_to_EP_fine_id;
            }

            /* reverse movement */
            fiLoopLow = pClpInfoEpMapCoarse[ci].ref_to_EP_fine_id - 1;

            DBGPRINT(DBG_ON(DBG_VERBOSE), ("\nci: %u\n", ci));
            DBGPRINT(DBG_ON(DBG_VERBOSE), ("fiLoopHigh: %i\n", fiLoopHigh));
            DBGPRINT(DBG_ON(DBG_VERBOSE), ("fiLoopLow: %i\n",  fiLoopLow));

            /* loop till that fi */
            while ( (!fReverse && (fi < fiLoopHigh) && (fi <= (LONG)fiTrickEnd) ) ||
                    ( fReverse && (fi > fiLoopLow)  && (fi >= (LONG)fiTrickEnd) )  )
            {
                //DbgAssert((ci+1 < ulNumCoarseEntries) ? fi < pClpInfoEpMapCoarse[ci+1].ref_to_EP_fine_id : 1);
                //DbgAssert(fi >= pClpInfoEpMapCoarse[ci].ref_to_EP_fine_id);
                DBGPRINT(DBG_ON(DBG_VERBOSE), ("fi: %u\n", fi));

                spnCurr = ( (pClpInfoEpMapCoarse[ci].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi].SPN_EP_fine);

                if (fi+1 >= (LONG)fiLoopHigh)
                {
                    if (fi+1 > (LONG)fiTrickHigh)
                    {
                        spnNext = (ULONG)(boLast / BD_TSPACKETSIZE);
                    }
                    else
                    {
                        spnNext = ( (pClpInfoEpMapCoarse[ci+1].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi+1].SPN_EP_fine);
                    }
                }
                else
                {
                    spnNext = ( (pClpInfoEpMapCoarse[ci].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi+1].SPN_EP_fine);
                }


                /* find starting point of read */
                boStart_of_read = (ULONGLONG)( spnCurr ) * BD_TSPACKETSIZE;

                /* find maximum ending point of read */
                boNext_fine = (ULONGLONG)( spnNext ) * BD_TSPACKETSIZE;

                /***
                 * For timebased slideshow (apptype==2), we need to play from the boFirst that was calculated
                 * above even if this is not the start of the EP_map.  This is to fix content where IG (or other
                 * in-mux data) is encoded before the start of the EP_map.
                 ***/
                if ( (bAppType == 2) && (ci == 0) && (fi == 0) )
                {
                    boStart_of_read = boFirst;
                }

                /* initialization of boEnd_of_read not really necessary, but removes a compiler warning */
                boEnd_of_read = boStart_of_read;

                /***
                 * For timebased slideshow (apptype==2), we need to send two sets of data for each browsing unit.
                 *  One for the I-frame (and signal seq-end), and one for the rest of the data in the browsing unit.
                 *
                 * Normal trickmode playback will only do this loop once and will signal seq-end.
                 ***/
                bApp2loop = 0;
                do
                {
                    bApp2loop++;
                    if (bApp2loop == 2)
                    {
                        boStart_of_read = boEnd_of_read;
                    }

                    /* find ending point of read (depends on mode and I_end_position_offset) */
                    if ( (bDiscrete || ( (bAppType == 2) && (bApp2loop == 1) ) ) && (pClpInfoEpMapFine[fi].I_end_position_offset != 0) && (pClpInfoEpMapFine[fi].I_end_position_offset != 7))
                    {
                        /* if we're in discrete mode and the I_end_position_offset is valid, read from the posiiton of the fine to the I_end_posiiton_offset */
                        boEnd_of_read = boStart_of_read + I_tp_size[pClpInfoEpMapFine[fi].I_end_position_offset];
                        if (boEnd_of_read > boNext_fine)
                        {
                            boEnd_of_read = boNext_fine;
                            bApp2loop = 2;
                        }
                    }
                    else
                    {
                        /* if not, read from the position of the fine to the position of the next fine (or, if we're at the end, read to the end) */
                        boEnd_of_read = boNext_fine;
                    }

                    /* Handle "soft" edge conditions */
                    if (boStart_of_read < boFirst)
                    {
                        boStart_of_read = boFirst;
                    }
                    if (boEnd_of_read > boLast)
                    {
                        boEnd_of_read = boLast;
                    }

                    /* handle "hard" edge conditions - this could potentially happen briefly at edges, so don't cause failure, just notify */
                    if ( (boStart_of_read <= boLast) && (boEnd_of_read >= boFirst) && (boStart_of_read < boEnd_of_read) )
                    {
                        GetAndSend(hFileHandle, boStart_of_read, boEnd_of_read, fDataDiscontinuity, (bApp2loop == 1), pvContext);
                    }
                    else
                    {
                        DbgPrint(("Attempt to read off of or at the edge of trick boundaries (ok to see this print once at each edge condition)\n"));
                        DbgPrint(("boStart_of_read: %llu\n", boStart_of_read));
                        DbgPrint(("boFirst:         %llu\n", boFirst));
                        DbgPrint(("boEnd_of_read:   %llu\n", boEnd_of_read));
                        DbgPrint(("boLast:          %llu\n", boLast));
                        /* if this happens, don't do the second half of the timebased slideshow loop */
                        break;
                    }

                }while( (bAppType == 2) && (bDiscrete == 0) && (bApp2loop < 2) );

                /* if we should stop, then stop */
                if (m_fAbort == TRUE)
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("%s() -- abort\n", __FUNCTION__));
                    goto out;
                }

                /* increment the fine index */
                fi += (bDiscrete != 0) ? (increment * bDiscrete) : increment;
            }
            /* increment the coarse index */
            ci += increment;
        }
    }
    else  /* continuous normal forward playback */
    {
        ULONGLONG boStart_of_read = boFirst;
        ULONG spnIn, spnOut, ciNewStart, fiNewStart;
        LocalContext   *lcTemp;
        BOOLEAN fLoop;
        ULONG   ulJumpIndex = 0;
        LONG    lPayloadsSent;

        /* disk error handling loop */
        do
        {
            fLoop = FALSE;

            /* normal call to play - returns with the number of payloads sent (negative if ended in error) */
            lPayloadsSent = GetAndSend(hFileHandle, boStart_of_read, boLast, fDataDiscontinuity, FALSE, pvContext);

            /* if GetAndSend ended in error */
            if ((lPayloadsSent <= 0) && (m_fAbort != TRUE))
            {
                /* if more than the specified number of payloads were sent on this last try, reset the loop counter */
                if(lPayloadsSent < (-1*RESETJUMP))
                {
                    ulJumpIndex = 0;
                }

                DBGPRINT(DBG_ON(DBG_ERROR), ("\nGetAndSend Failure - Disk Error %u! - Jumping %u EP_map entries to avoid errors.\n", ulJumpIndex, ERROR_JUMP(ulJumpIndex)+1));


                lcTemp = m_lcManager.CurrentLocalContext();
                spnIn  = lcTemp->spnOfPayload;

                /* find current EP map location */
                if ( CLPINFO_SUCCESS ==  m_clpInfo.ClpInfoSearch_CoarseAndFineForSPN(spnIn, &ciNewStart, &fiNewStart))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("currently at: (%u , %u) = 0x%x\n", ciNewStart, fiNewStart, spnIn));

                    ULONG fiNext;
                    ULONG ciNext;

                    fiNext = fiNewStart + (ULONG)(ERROR_JUMP(ulJumpIndex));

                    if (CLPINFO_SUCCESS != m_clpInfo.ClpInfoSearch_CoarseForFine(ciNewStart, m_clpInfo.ClpInfoGet_ciEnd(), fiNext, &ciNext, &spnOut))
                    {
                        DbgPrint(("ERROR - UNHANDLED ERROR"));
                    }

                    DBGPRINT(DBG_ON(DBG_ERROR), ("new position at: (%u , %u) = 0x%x\n", ciNext, fiNext, spnOut));
                    boStart_of_read = (ULONGLONG)spnOut * BD_TSPACKETSIZE;
                    ulJumpIndex++;
                    fLoop=TRUE;
                }

                if (m_event != NULL)
                {
                    m_event(m_pContext, DR_EVENT_ERROR, (PVOID)DR_DISK_ERROR);  /* send event */
                }

                /* Tell the PE that there was an error - opportunity for a decoder flush */
                streamMessage.ErrorDiscontinuity = TRUE;
                streamMessage.DataDiscontinuity  = TRUE;
                streamMessage.BegOfStream        = FALSE;
                streamMessage.EndOfStream        = FALSE;
                streamMessage.StreamContext      = pvContext;
                drSendStream(streamMessage, NULL);
                streamMessage.ErrorDiscontinuity = FALSE;
                streamMessage.DataDiscontinuity  = FALSE;
            }
            fDataDiscontinuity = FALSE;
        }while(fLoop == TRUE);
    }

    if ((fSendEOS) && (m_fAbort == FALSE))
    {
        streamMessage.BegOfStream   = FALSE;
        streamMessage.EndOfStream   = TRUE;
        streamMessage.StreamContext = pvContext;
        drSendStream(streamMessage, NULL);
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("end of dataRetrieve\n"));


out:

    if (hFileHandle != 0)
    {
        if (LOADER_SUCCESS != LoaderFileClose(m_loader, hFileHandle) )
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("\ndataRetrieve() -- ERROR Closing File: 0x%x\n\n", hFileHandle));
        }
        hFileHandle = 0;
    }

    return(status);
}

#ifdef DRM_SUPPORT
/**
 * drGetKey - get the key for the current play item
 *
 * @param playList_id   - the current play list id
 * @param playItem_id   - the current play Item id
 * @param cps_unit      - the current cps unit
 *
 * @retval none
 *
 * @remarks none.
 *
 */
DR_ERROR DRPrefetch_BDROM::drGetKey(ULONG playList_id, ULONG playItem_id, ULONG title_num, ULONGLONG boFirst)
{
    cPayload           *pStreamPayload  = NULL;
    DROUTPUTMESSAGE     streamMessage;
    DR_ERROR            status          = DR_SUCCESS;

    streamMessage.fInfoPayload  = TRUE;

    /* Get a payload buffer to work with */
    pStreamPayload = drGetPayload();

    if (NULL != pStreamPayload)

⌨️ 快捷键说明

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