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

📄 dr_prefetch_bdrom.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        /*
         * TODO: call DRM lib to get the key for the current play item
         */
        status = DR_FAILURE;
        DbgPrint(("%s:%d - NO DRM SUPPORT\n", __FILE__, __LINE__));

        /* send the key to the PE */
        if (status == DR_SUCCESS)
        {
            INFOPAYLOAD *infoPayload;

            infoPayload = (INFOPAYLOAD*)pStreamPayload->get_base_ptr();

            infoPayload->bType  = INFOTYPE_CRYPTKEY;

            /*
             * TODO: put the key info into the payload
             */
            /* infoPayload->data_packet.data = key for the playitem (might be a handle etc) */
            /* infoPayload->data_packet.size = size of the key or key handle being passed   */

            /* transfer the payload to the PE */
            if (drSendStream(streamMessage, pStreamPayload) != DR_SUCCESS)
            {
                status = DR_FAILURE;
            }
        }

        /* delete the payload */
        delete pStreamPayload;
    }

    /* Done getting the key */
    DBGPRINT(DBG_ON(DBG_TRACE), ("DRCommandProc: DR_KEY -- Done getting key\n"));

    return (status);
}
#endif

/**
 * GetAndSend - gets data from the file and sends it to the output stream
 *
 * @param fileHandle    - the file handle to get data from
 * @param inbyte        - the start byte to read from
 * @param outbyte       - the end byte to read to
 *
 * @retval none
 *
 * @remarks none.
 */
LONG DRPrefetch_BDROM::GetAndSend(LOADER_FILE_HANDLE hFileHandle, ULONGLONG boFirst, ULONGLONG boLast, BOOLEAN fDataDiscontinuity, BOOLEAN fTrickPlay, PVOID pvContext)
{
    BOOLEAN                 fReadOk                   = FALSE;
    ULONGLONG               ullBytesLeft              = 0;     /* bytes left to read from this playitem */
    ULONG                   ulBytesToRead             = 0;     /* bytes to read on this loop through */
    ULONG                   ulBytesToRead_ret         = 0;     /* bytes read on this loop through (only different if error) */
    ULONG                   ulReadSize                = 0;     /* bytes read on this loop through (only different if error) */
    ULONGLONG               boCurrentPosition;
    ULONG                   ulPayloadSize;
    cPayload                *pStreamPayload           = NULL;
    DROUTPUTMESSAGE         streamMessage;
    LOADER_ERR              ldrStatus;
    DR_ERROR                stream_status             = DR_SUCCESS;

    CLIPINFO_db             *pClipInfo                = NULL;
    BOOLEAN                 fGotDevSem                = FALSE;
    USHORT                  usLoopMax;
    USHORT                  usLoopCount               = 0;
    BOOLEAN                 fRecheck;
    ULONG                   ulBufferLevel;
    BOOLEAN                 fLoaderError              = FALSE;
    LONG                    lPayloadsSent             = 0;


    /* Get clipinfo of loaded clip */
    m_clpInfo.ClpInfoGet_ClipInfo(&pClipInfo);

    ulBufferLevel = (ULONG)((BD_TJUMP_BSS_MAX) * 192 / 188 * pClipInfo->TS_recording_rate) + 1;
    usLoopMax     = (USHORT)((ulBufferLevel / (PAYLOAD_SIZE * 1024) ) + 5);


    /* initialize stream flags */
    streamMessage.DataDiscontinuity        = fDataDiscontinuity;
    streamMessage.StreamContext            = pvContext;
    streamMessage.TimeDiscontinuity        = FALSE;                 /* TODO:  use this flag */

#ifdef DRM_SUPPORT
    ULONGLONG boFirstRounded = (boFirst / AU_SIZE) * AU_SIZE;
    ULONGLONG offset         = boFirst - boFirstRounded;

    boFirst = boFirstRounded;
#endif

    /* everyone takes the semaphore before the loader seek (so there's only one seek at a time) */
    OS_SemTake(m_semDevice, OS_WAIT_FOREVER);
    DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("START - SEM TAKE %u!!\n", m_idnum));
    fGotDevSem = TRUE;

    /* seek to the starting point */
    if (LOADER_SUCCESS != LoaderFileSeek(m_loader, hFileHandle, LOADER_SEEK_SET, boFirst) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("dataRetrieve() -- Error Seeking in File\n"));
        goto errout;
    }

    /* start at the beginning */
    boCurrentPosition  = boFirst;

#ifdef DRM_SUPPORT
    DBGPRINT(DBG_ON(DBG_TRACE), ("DR_PLAY -- boFirst=%llu, boFirstRounded=%llu, boLast=%llu\n", boFirst, boFirst-offset, boLast));
#endif

    /* set the LocalContext */
    streamMessage.LocalContext              = (PVOID)m_lcManager.NewLocalContext();
    m_clpInfo.ClpInfoGet_ClipNum(&((LocalContext*)(streamMessage.LocalContext))->ulClipNum);
    ((LocalContext*)(streamMessage.LocalContext))->pvContext    = pvContext;
    ((LocalContext*)(streamMessage.LocalContext))->spnOfPayload = (ULONG)(boCurrentPosition / BD_TSPACKETSIZE);

    /* up to (but not including) the boLast byte of the read */
    do
    {
        /* if we should stop, then stop before we get a payload */
        if (m_fAbort == TRUE)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
            break;
        }

        /* Get a buffer from the stream */
        pStreamPayload = drGetPayload();

        if (pStreamPayload == NULL)
        {
            break;
        }

#ifdef DRM_SUPPORT
        if (offset != 0)
        {
            pStreamPayload->set_rd_ptr((BYTE*)pStreamPayload->get_rd_ptr() + offset);
            offset = 0;
        }
#endif

        /* how many bytes remain? */
        ullBytesLeft = (boLast - boCurrentPosition);

        /* how big is each payload? */
        ulPayloadSize = (ULONG)((pStreamPayload->get_max_size()));

        /* if the payload is bigger than what's left, get all the remaining data */
        if (ulPayloadSize > ullBytesLeft)
        {
            DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s() -- ulBytesLeft=%llu, ulBytesToRead=%d\n", __FUNCTION__, ullBytesLeft, ulBytesToRead));
            ulBytesToRead = (ULONG)(ullBytesLeft);

#define MASK 0x7ff
            ulReadSize = ulBytesToRead;
            if (ulReadSize & MASK)
            {
                ulReadSize += MASK;
                ulReadSize &= ~MASK;
                DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s() -- ulBytesLeft=%llu, ulReadSize=%d\n", __FUNCTION__, ullBytesLeft, ulReadSize));
            }
        }
        else
        {
            ulBytesToRead = ulPayloadSize;         /* otherwise, just get as much as we can */
            ulReadSize    = ulBytesToRead;
        }

        /* set the payload's user data to the start position */
        pStreamPayload->set_user_data( (ULONG)(boCurrentPosition) );

        /* This should never happen */
        if (boCurrentPosition % BD_TSPACKETSIZE != 0)
        {
            DbgPrint(("\n\nROUNDING ERROR!!!!\n"));
            DbgPrint(("boCurrentPosition: %llu\n\n", boCurrentPosition));
        }

        /* take care of the device semaphore */
        fRecheck = TRUE;
        do
        {
            if (fGotDevSem == TRUE)
            {
                if ( (m_prefetchStream->EmptyStatus() == 0) || (usLoopCount == usLoopMax) )
                {
                    fGotDevSem = FALSE;
                    DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("SEM GIVE %u!!\n", m_idnum));
                    OS_SemGive(m_semDevice);
                    OS_TaskDelayMsec(20);
                }
                else
                {
                    fRecheck = FALSE;
                }
            }

            if (fGotDevSem == FALSE)
            {
                OS_SemTake(m_semDevice, OS_WAIT_FOREVER);
                DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("SEM TAKE %u!!\n", m_idnum));
                fGotDevSem = TRUE;
                usLoopCount = 0;
            }
        }
        while( (fRecheck == TRUE) && (m_fAbort == FALSE) );

        if (m_fAbort == TRUE)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
            break;
        }

        /* to get here you must have the device semaphore */
        usLoopCount++;

        /* do the read */
        ldrStatus = LoaderFileRead(m_loader, hFileHandle, (BYTE*)pStreamPayload->get_wr_ptr(), ulReadSize, &ulBytesToRead_ret);

        switch (ldrStatus)
        {
        case LOADER_SUCCESS:                  /* loader reports data retrieved successfully */
            boCurrentPosition += ulBytesToRead_ret;
            fReadOk = TRUE;

            /* check that the returned size of the read is the same as we asked for */
            if (ulBytesToRead > ulBytesToRead_ret)
            {
                /* Occurs when the end of file is reached during the read */
                DbgPrint(("\n\nLoaderFileRead: incorrect amount of data read. UNEXPECTED EOF LIKELY - ERROR!\n\n"));
                DbgPrint(("ulBytesToRead: %u\n", ulBytesToRead));
                DbgPrint(("ulBytesToRead_ret: %u\n", ulBytesToRead_ret));

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

            /* check that the read begins with good data (transport stream start code) */
            if (((BYTE*)(pStreamPayload->get_wr_ptr()))[4] != 0x47)
            {
                fReadOk = FALSE;
                fLoaderError = TRUE;
                DbgPrint(("\nLoaderFileRead: bad data read from disk.\n\n"));

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

            break;

        case LOADER_NULL_PTR:                 /* something is configured wrong.  Abort without sending */
        case LOADER_FILE_EOF:                 /* occurs when EOF flag is already set before we begin reading.  Abort without sending */
            DbgPrint(("\n\nDR: LoaderFileRead Error: %i\n", ldrStatus));

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

            /* don't report loader error - just want to stop playing right here */
            boCurrentPosition = boLast;
            fReadOk = FALSE;
            break;

        case LOADER_FILE_ERROR:               /* generalized file error - might just be bad sector.  jump ahead and try again (but don't send current) */
        default:
            DbgPrint(("\n\nDR: LoaderFileRead Error, byte offset = %llu\n", boCurrentPosition));

            if (m_event != NULL)
            {
                m_event(m_pContext, DR_EVENT_ERROR, NULL);   /* send event */
            }
            /* @todo : instead - jump forward to next I-frame */
            boCurrentPosition += ulBytesToRead;       /* jump ahead to whatever we should have read */

            if (LOADER_SUCCESS != LoaderFileSeek(m_loader, hFileHandle, LOADER_SEEK_SET, boCurrentPosition) )
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("dataRetrieve() -- Error Seeking in File\n"));
                goto errout;
            }
            fLoaderError = TRUE;
            fReadOk = FALSE;                          /* but don't send it */
            break;
        }

        if (m_fAbort == TRUE)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
            break;
        }

        /* Update the write pointer */
        if (TRUE == fReadOk)
        {
            pStreamPayload->add_data(ulBytesToRead);
        }

        /* send the EndOfStream flag */
        if ( ( (boCurrentPosition >= boLast)    ||  /* playing fwd reached end of sectors */
               (boCurrentPosition < boFirst)  ) )   /* playing rev reached beg of sectors */
        {
            if (fTrickPlay)
            {
                streamMessage.SequenceEnd = TRUE;
            }
        }

#ifdef DRM_BDPLUS_SUPPORT
        /*
         * TODO: If BD+ is running compute the fixup table and send it to the PE
         * drGetAndSendFixup(&m_clpInfo, boCurrentPosition, ulBytesToRead);
         */
        DbgPrint(("%s:%d - NO DRM_BDPLUS_SUPPORT\n", __FILE__, __LINE__));
#endif

        /* transfer the payload to the PE */
        stream_status = drSendStream(streamMessage, pStreamPayload);

⌨️ 快捷键说明

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