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

📄 dr_prefetch_bdrom.cpp

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

        /* reset flags */
        streamMessage.DataDiscontinuity    = FALSE;

        /* set the LocalContext */
        if (stream_status == DR_SUCCESS)
        {
            lPayloadsSent++;

            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);
        }

    } while ((boCurrentPosition < boLast) && (boCurrentPosition >= boFirst) && (fLoaderError == FALSE));


errout:
    if (pStreamPayload != NULL)
    {
        delete pStreamPayload;
        pStreamPayload = NULL;
    }
    if (fGotDevSem == TRUE)
    {
        DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("EXIT - SEM GIVE %u!!\n", m_idnum));
        OS_SemGive(m_semDevice);
    }
    if (fLoaderError == TRUE)
    {
        lPayloadsSent *= -1;
    }

    return (lPayloadsSent);
}


DR_ERROR DRPrefetch_BDROM::drSendSubtextInfo(UBYTE numFiles, UBYTE *font_names, ULONG tIn, PVOID pvContext)
{
    ULONG               ulPayloadSize;
    DROUTPUTMESSAGE     streamMessage;
    cPayload            *pStreamPayload    = NULL;
    BYTE                *wrPtr;
    INFOPAYLOAD         *infoPayload;
    ULONG               ulBytesToWrite;

    /* these are used */
    streamMessage.fInfoPayload             = TRUE;
    streamMessage.StreamContext            = pvContext;


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

    if (pStreamPayload == NULL)
    {
        return (DR_FAILURE);
    }

    /* check that the font list can fit into a single payload (shouldn't fail unless the payloads are made super-small) */
    ulPayloadSize = (ULONG)((pStreamPayload->get_max_size()));
    ulBytesToWrite = ((ULONG)numFiles * 5) + 1 + sizeof(ULONG);
    DbgAssert(ulPayloadSize >= ulBytesToWrite);

    /* get the payload's write pointer */
    infoPayload = (INFOPAYLOAD*)pStreamPayload->get_base_ptr();

    /* set the type */
    infoPayload->bType = INFOTYPE_FONTLIST;

    /* set the data pointer */
    wrPtr = infoPayload->data_packet.data;

    /* write to the payload */
    wrPtr[0] = numFiles;                            /* the number of font files */
    memcpy(&wrPtr[1], font_names, numFiles * 5);    /* copy in the font names */
    memcpy(&wrPtr[ulBytesToWrite - sizeof(ULONG)], &tIn, sizeof(ULONG));     /* copy in a ULONG for time */

    /* Set the size of the data */
    infoPayload->data_packet.size = ulBytesToWrite;

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

    /* delete the payload */
    delete pStreamPayload;
    pStreamPayload = NULL;

    return(DR_SUCCESS);
}






/**
 * StopAtChangePoint - stop at next change point
 *
 * @param fAngle                 - look for angle change point or just end of current I-frame
 * @param ulAngleChangePointPTS  - the PTS of the angle change point found
 *
 * @retval DR_FAILURE if no angle change point was found (ulAngleChangePointPTS is useless)
 *         DR_SUCCESS an angle change point was successfully found
 *
 * @remarks none.
 */
DR_ERROR DRPrefetch_BDROM::StopAtChangePoint(BOOLEAN fAngle, ULONG *ulAngleChangePointPTS, PVOID *ret_pvContext)
{
    DR_ERROR status         = DR_SUCCESS;;
    ULONG    spnOut         = 0;
    ULONG    ciAnglePoint;
    ULONG    fiAnglePoint;
    ULONG    ulBufferLevel;

    ULONG spnIn;
    ULONG ptsOut;
    PVOID pvContext = NULL;
    ULONG ulClipNum;

    BOOLEAN fPlayQueueWasEnabled;
    PLAYCMD play;

    CLIPINFO_db *pClipInfo = NULL;

    DBGPRINT(DBG_ON(DBG_TRACE), ("\nStopAtChangePoint:\n"));


    /* Abort() also clears and disables the queue */
    fPlayQueueWasEnabled = Abort();


    m_clpInfo.ClpInfoGet_ClipNum(&ulClipNum);

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

    /*
     * Calculate the level to drain the buffer down to.  This level should
     * be the minimum amount of data needed to guarantee seamless playback of data
     * during the angle change.
     */
    ulBufferLevel = (ULONG)((BD_TJUMP_ANGLE_MAX) * 192 / 188 * pClipInfo->TS_recording_rate) + 1;

    /*
     * @TODO: Account for buffering in the decoder.
     */

    /* Determine how many payloads are needed for this buffer level */
    ulBufferLevel = (ulBufferLevel / (PAYLOAD_SIZE * 1024) ) + 1;

    /* Drain buffer down to calculated level */
    if (FALSE == Flush(TRUE, ulBufferLevel, ulClipNum, &spnIn, &pvContext) )
    {
        return(DR_FAILURE);
    }

    if (pvContext == NULL)
    {
        LocalContext   *lcTemp;

        lcTemp = m_lcManager.CurrentLocalContext();

        spnIn     = lcTemp->spnOfPayload;
        pvContext = lcTemp->pvContext;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("spnIn: 0x%x\n", spnIn));

    /* if we're in a discrete mode, don't worry about an angle change point - just change at the next i-frame */
    if (m_BDspeed.fReverse || m_BDspeed.bDiscrete)
    {
        fAngle = FALSE;
    }

    /* find an angle change point to read up to */
    if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoSearch_ChangePoint(fAngle, m_BDspeed.fReverse, spnIn, &spnOut, &ptsOut, &ciAnglePoint, &fiAnglePoint) )
    {
        /* no change point found */
        DBGPRINT(DBG_ON(DBG_TRACE), ("StopAtChangePoint FAILED\n"));
        status = DR_FAILURE;

        spnOut = m_clpInfo.ClpInfoGet_spnLast();     /* play what's left of the playitem */
        play.bdrom.playFlag     = PLAYFLAG_SPNEOF;
    }
    else
    {   /* change point found */
        play.bdrom.playFlag     = PLAYFLAG_SPN;
    }


    DBGPRINT(DBG_ON(DBG_TRACE), ("\nptsOut: 0x%x\n", ptsOut));
    DBGPRINT(DBG_ON(DBG_TRACE), ("spnOut: 0x%x\n\n", spnOut));


    if (spnOut != spnIn)
    {
        /* PLAY THE "small" PLAY CHUNK */
        QueueControl(DR_QUEUE_CMD_ENABLE);

        play.bdrom.strmType     = DR_STREAM_MAIN;
        play.bdrom.fReverse     = 0;
        play.bdrom.bDiscrete    = 0;
        play.bdrom.playItem_id  = 0;
        play.bdrom.playList_id  = 0;
        play.bdrom.title_num    = 0;
        play.bdrom.ulFilenum    = ulClipNum;
        play.bdrom.spnIn        = spnIn;
        play.bdrom.spnOut       = spnOut;
        play.bdrom.ubRefToSTC   = 0;                 /* not needed for spn playback */
        play.bdrom.connectCond  = VDVD_CONNECTION_6;
        play.bdrom.pvContext    = pvContext;

        Play(play, TRUE);       /* Blocks until play command has been received */


        /* return the playqueue to the original state */
        if(fPlayQueueWasEnabled == TRUE)
        {
            QueueControl(DR_QUEUE_CMD_ENABLE);
        }
        else
        {
            QueueControl(DR_QUEUE_CMD_DISABLE);
        }
    }


    *ulAngleChangePointPTS = ptsOut;
    *ret_pvContext         = pvContext;

    return(status);
}




/**
 * GetPlayRate - return the play rate
 *
 * @param none
 *
 * @retval the play rate as a field of two 16-bit values.
 *
 * @remarks none.
 */
uint32 DRPrefetch_BDROM::GetPlayRate(void)
{
    return((m_BDspeed.fReverse << 8) | m_BDspeed.bDiscrete);
}



/**
 * GetContext - return the current context
 *
 * @param none
 *
 * @retval the context.
 *
 * @remarks none.
 */
PVOID DRPrefetch_BDROM::GetContext(void)
{
    return(m_pvPlayContext);
}


/**
 * GetNextContext - return the next context
 *
 * @param none
 *
 * @retval the context if it exists, NULL otherwise
 *
 * @remarks Queue must be disabled before this call!
 */
PVOID DRPrefetch_BDROM::GetNextContext(void)
{
    PLAYMSG *pInputMessage  = NULL;
    PVOID   pvContext       = NULL;

    pInputMessage = (PLAYMSG*)m_prefetchPlayQueue->Read(OS_NO_WAIT);

    if (pInputMessage != NULL)
    {
        /* if there's something in the queue, record its context */
        pvContext = pInputMessage->play.bdrom.pvContext;

        /* now put the message back into the queue */
        m_prefetchPlayQueue->Write((PVOID)pInputMessage, OS_WAIT_FOREVER);
    }

    return (pvContext);
}

#ifdef DRM_BDPLUS_SUPPORT
/**
 * drGetAndSendFixup - Get fixups for the current play item. Send the info to PE.
 *
 * @param clpInfo               - the current clpInfo object
 * @param boCurrentPosition     - the current byte offset
 * @param ulbytesRead           - the size of the data
 *
 * @retval DR_ERROR
 *
 * @remarks none.
 *
 */
DR_ERROR DRPrefetch_BDROM::drGetAndSendFixup(ClpInfo* clpInfo, ULONGLONG boCurrentPosition, ULONG ulbytesRead)
{
    /*
     * TODO: Compute BD+ fixup table and send to PE
     */

    /* NOT IMPLEMENTED */
    DbgPrint(("%s:%d - NO DRM_BDPLUS_SUPPORT\n", __FILE__, __LINE__));
    return (DR_FAILURE);
}
#endif

⌨️ 快捷键说明

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