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

📄 dr_app.cpp

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

    if (status == DR_SUCCESS)
    {
        play.bdrom.connectCond   = pParams->connection;
        play.bdrom.strmType      = pParams->streamType;
        play.bdrom.ulFilenum     = GET_INT_FROM_ASCII5(pParams->filename);
        play.bdrom.playFlag      = PLAYFLAG_NORMAL;
        play.bdrom.ulInTime      = pParams->in_point;
        play.bdrom.ulOutTime     = pParams->out_point;
        play.bdrom.ubRefToSTC    = pParams->ref_to_STC_id;
        play.bdrom.fReverse      = pParams->fDirection;
        play.bdrom.bDiscrete     = pParams->bDiscrete;
        play.bdrom.playItem_id   = pParams->playItem_id;
        play.bdrom.playList_id   = pParams->playList_id;
        play.bdrom.title_num     = pParams->title_num;
        play.bdrom.pvContext     = pvContext;

        /* remove the previously queued play request if one exists. It will be replaced by a new request */
        dr->prefetch[pParams->streamType]->QueueControl(DR_QUEUE_CMD_CLEAR);

        /* return from play command immediately - we're just dropping it in the queue */
        fBlockonPlay = FALSE;

        /* Add the new request to the play queue */
        dr->prefetch[pParams->streamType]->Play(play, fBlockonPlay);
    }

errout:
    /* If the command failed, signal the command error event */
    if (DR_SUCCESS != status)
    {
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_COMMAND_ERROR, (PVOID)DR_PLAY_BDROM);
        }
    }

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);
}


/**
 * Requests the DR to read the HDDVD_std sectors from the loader.
 *
 * @param handle    - Operating system handle for the DR object.
 * @param pParams   - pointer to a structure of parameters.
 * @param pvContext - pointer to a context that is returned with all status events.
 *
 * @retval DR_ERROR
 */
DR_ERROR DRPlayHDDVD_STD(DR_HANDLE handle, DR_PARAMS_DVD *pParams, PVOID pvContext)
{
    // @todo (JCA - 2007/01/05) See if there is a way to merge this function with DRPlayDVD.

    DRHANDLE     *dr = (DRHANDLE*)handle;
    DR_ERROR     status = DR_SUCCESS;
    PLAYCMD      play;
    BOOLEAN      fBlockonPlay = FALSE;

    /* validate our input */
    if (NULL == handle)
    {
        DBGPRINT(DEBUG_DR_APP, ("%s: NULL DR_HANDLE\n", __FUNCTION__));
        return (DR_FAILURE);
    }
    if (pParams->playtype == DR_TYPE_MSF)
    {
        return (DR_INVALID_PARAM);
    }

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);

    /* check state */
    if ( (dr->State & DR_STATE_PLAY_FIELD) == 0 )
    {
        status = DR_INVALID_STATE;
        goto errout;
    }

    /* check that prefetch object exists */
    if (dr->prefetch[DR_STREAM_MAIN] == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: DR Play: specified prefetch doesn't exist\n", __FUNCTION__));
        status = DR_INVALID_PARAM;
        goto errout;
    }

#ifdef DRM_SUPPORT
    if (AES_ECB == dr->EncryptionType)
    {
        /*
         * TODO: grab the title key for aacs decryption
         */
        DbgPrint(("%s:%d - NO DRM SUPPORT\n", __FILE__, __LINE__));

        /* DRM NOT SUPPORTED
         * This will eject the disc */
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_ERROR, (PVOID)DR_AACS_FAILURE);
        }
        goto errout;
    }
#endif

    if (status == DR_SUCCESS)
    {
        play.dvd.queueType     = pParams->queue;
        play.dvd.playType      = pParams->playtype;
        play.dvd.ulStart       = pParams->startLBN;
        play.dvd.ulEnd         = pParams->endLBN;
        play.dvd.ulBegin       = pParams->beginLBN;
        play.dvd.fIsVobuStill  = pParams->fIsVobuStill;
        play.dvd.fIsLastCell   = pParams->fIsLastCell;
        play.dvd.pvContext     = pvContext;

        if ( (play.dvd.queueType == DR_QUEUE_ABORT) || (play.dvd.queueType == DR_QUEUE_NONSEAMLESS) )
        {
            /* stop the current play - we're restarting */
            dr->prefetch[DR_STREAM_MAIN]->Stop(FALSE);
            /* don't return from the play command until the play command has been received by the prefetch thread */
            fBlockonPlay = TRUE;
        }
        else if (play.dvd.queueType == DR_QUEUE_SEAMLESS)
        {
            /* remove the previously queued play request if one exists. It will be replaced by a new request */
            dr->prefetch[DR_STREAM_MAIN]->QueueControl(DR_QUEUE_CMD_CLEAR);
            /* return from play command immediately - we're just dropping it in the queue */
            fBlockonPlay = FALSE;
        }

        /* Add the new request to the play queue */
        dr->prefetch[DR_STREAM_MAIN]->Play(play, fBlockonPlay);
    }

errout:
    /* If the command failed, signal the command error event */
    if (DR_SUCCESS != status)
    {
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_COMMAND_ERROR, (PVOID)DR_PLAY_HDDVD_STD);
        }
    }

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRPlayHDDVD_STD() */

/**
 * Requests the DR to read the HDDVD_std sectors from the loader.
 *
 * @param handle        - Operating system handle for the DR object.
 * @param streamType    - Which stream to play file on.
 * @param connection    - What is the connection condition.
 * @param strURI        - Which file to play.
 * @param boIn          - Start point of playback.
 * @param boOut         - End point of playback.
 * @param fReverse      - are we going in forward or reverse.
 * @param bDiscrete     - are we reading in discrete chunks (I-frame FF) or continuously.
 * @param pvContext     - pointer to a context that is returned with all status events.
 *
 * @retval DR_ERROR
 */
DR_ERROR DRPlayHDDVD_ADV(DR_HANDLE handle, DR_PARAMS_HDDVD *pParams, PVOID pvContext)
{
    DRHANDLE     *dr = (DRHANDLE*)handle;
    DR_ERROR     status = DR_SUCCESS;
    PLAYCMD      play;
    BOOLEAN      fBlockonPlay = FALSE;


    /* validate our input */
    if (NULL == handle)
    {
        DBGPRINT(DEBUG_DR_APP, ("%s:%u - NULL DR_HANDLE\n", __FILE__, __LINE__));
        return (DR_FAILURE);
    }

    if ( pParams->strURI == NULL )
    {
        DBGPRINT(DEBUG_DR_APP, ("%s:%u - NULL FILENAME\n", __FILE__, __LINE__));
        return (DR_INVALID_PARAM);
    }

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);

    DBGPRINT(DBG_ON(DBG_TRACE), ("%s\n", __FUNCTION__));

    /* check state */
    if ( (dr->State & DR_STATE_PLAY_FIELD) == 0 )
    {
        status = DR_INVALID_STATE;
        DBGPRINT(DEBUG_DR_APP, ("%s:%u - INVALID STATE\n", __FILE__, __LINE__));
        goto errout;
    }

    /* check that prefetch object exists */
    if (dr->prefetch[pParams->streamType] == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: DR Play: specified prefetch doesn't exist\n", __FUNCTION__));
        status = DR_INVALID_PARAM;
        goto errout;
    }

#ifdef DRM_SUPPORT
    if (AES_ECB == dr->EncryptionType)
    {
        /*
         * TODO: grab the title key for aacs decryption
         */
        DbgPrint(("%s:%d - NO DRM SUPPORT\n", __FILE__, __LINE__));

        /* DRM NOT SUPPORTED
         * This will eject the disc */
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_ERROR, (PVOID)DR_AACS_FAILURE);
        }
        goto errout;
    }
#endif

    if (status == DR_SUCCESS)
    {
        memset(play.hddvd_adv.strURI, 0, HDDVD_URI_MAX_SIZE);
        if (strlen(pParams->strURI) > HDDVD_URI_MAX_SIZE)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): INVALID URI LENGTH (%d)!\n", __FUNCTION__, strlen(pParams->strURI)));
            memcpy(play.hddvd_adv.strURI, pParams->strURI, HDDVD_URI_MAX_SIZE);
        }
        else
        {
            memcpy(play.hddvd_adv.strURI, pParams->strURI, strlen(pParams->strURI));
        }

        play.hddvd_adv.boIn           = pParams->boIn;
        play.hddvd_adv.boOut          = pParams->boOut;
        play.hddvd_adv.time45k_In     = pParams->tIn;
        play.hddvd_adv.time45k_Out    = pParams->tOut;
        play.hddvd_adv.connectCond    = pParams->connection;
        play.hddvd_adv.strmType       = pParams->streamType;
        play.hddvd_adv.skip_evobu     = pParams->skip_evobu;
        play.hddvd_adv.read_until_ref = pParams->read_until_ref;
        play.hddvd_adv.pvContext      = pvContext;

        /* remove the previously queued play request if one exists. It will be replaced by a new request */
        dr->prefetch[pParams->streamType]->QueueControl(DR_QUEUE_CMD_CLEAR);

        /* return from play command immediately - we're just dropping it in the queue */
        fBlockonPlay = FALSE;

        /* Add the new request to the play queue */
        dr->prefetch[pParams->streamType]->Play(play, fBlockonPlay);
    }

errout:
    /* If the command failed, signal the command error event */
    if (DR_SUCCESS != status)
    {
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_COMMAND_ERROR, (PVOID)DR_PLAY_HDDVD_ADV);
        }
    }

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRPlayHDDVD_ADV() */




/**
 * Sets the desired angle to playback. This command is only valid for seamless
 * angle modes. For non-seamless angles a new DRPlayDVD() command is required.
 *
 * @param handle                - Operating system handle for the DR object.
 * @param angle                 - Angle to playback. Must be an integer between 1 and 9.
 * @param ulStartAngleCellAddr  - Start of Cell Address.
 * @param ulEndAngleCellAddr    - End of Cell Address.
 *
 * @retval DR_ERROR
 */
DR_ERROR DRSetDVDAngle(DR_HANDLE handle, ULONG ulAngle, ULONG ulStartAngleCellAddr, ULONG ulEndAngleCellAddr)
{
    DRHANDLE    *dr             = (DRHANDLE*)handle;
    DR_ERROR    status          = DR_SUCCESS;

    /* validate */
    if (NULL == handle)
    {
        DBGPRINT(DEBUG_DR_APP, ("DRSetDVDAngle: NULL DR_HANDLE\n"));
        return (DR_FAILURE);
    }

    /* angle must be integer between 1 and 9 */
    if ( (ulAngle == DR_NO_AGL_C) || (ulAngle >= DR_AGL_C_INVALID) )
    {
        DBGPRINT(DEBUG_DR_APP, ("DRSetDVDAngle: Invalid angle number\n"));
        return (DR_FAILURE);
    }

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);


    DBGPRINT(DBG_ON(DBG_TRACE), ("%s\n", __FUNCTION__));

    /* check state */
    if ( ((dr->State & DR_STATE_PLAY_FIELD) == 0)                   ||
         ( ((dr->State & DR_STATE_DISC_FIELD) != DR_STATE_DVD )       &&
           ((dr->State & DR_STATE_DISC_FIELD) != DR_STATE_HDDVD_STD ) &&
           ((dr->State & DR_STATE_DISC_FIELD) != DR_STATE_HDDVD_ADV )  )  )
    {
        status = DR_INVALID_STATE;
        goto errout;
    }

    /* it's all good, send the angle change */
    if (status == DR_SUCCESS)
    {
        if (dr->prefetch[DR_STREAM_MAIN] != NULL)
        {
            ANGLECMD angle;
            angle.ulAngle               = ulAngle;
            angle.ulStartAngleCellAddr  = ulStartAngleCellAddr;
            angle.ulEndAngleCellAddr    = ulEndAngleCellAddr;

            status = dr->prefetch[DR_STREAM_MAIN]->AngleChange(&angle);
        }
    }

errout:

    /* If the command failed, signal the command error event */
    if (DR_SUCCESS != status)
    {
        if (dr->eventCallback != NULL)
        {
            dr->eventCallback(dr->eventContext, DR_EVENT_COMMAND_ERROR, (PVOID)DR_SET_DVD_ANGLE);
        }
    }

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRSetDVDAngle() */




/**
 * Set playback rate.
 *
 * @param handle - Operating system handle for the DR object.
 * @param skip_vobu - Number of VOBu to skip during playback.
 * @param read_until_ref - Playback up to the reference for a VOBu.
 *
 * @retval DR_ERROR
 */
DR_ERROR DRSetDVDSpeed(DR_HANDLE handle, ULONG skip_vobu, ULONG read_until_ref)
{
    DRHANDLE *dr             = (DRHANDLE*)handle;
    DR_ERROR status          = DR_SUCCESS;


    /* validate */
    if (NULL == handle)
    {
        DBGPRINT(DEBUG_DR_APP, ("DRSetDVDSpeed: NULL DR_HANDLE\n"));
        return (DR_FAILURE);
    }
    if (skip_vobu > DR_BWDI_VIDEO)
    {
        DBGPRINT(DEBUG_DR_APP, ("DRSetDVDSpeed: INVALID skip_vobu request\n"));
        return (DR_FAILURE);
    }
    if (read_until_ref > DR_UNTIL_3RDREF_EA)
    {
        DBGPRINT(DEBUG_DR_APP, ("DRSetDVDSpeed: INVALID read_until_ref request\n"));
        return (DR_FAILURE);
    }

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);


    DBGPRINT(DBG_ON(DBG_TRACE), ("%s\n", __FUNCTION__));

     /* check state */
     if ( ( (dr->State & DR_STATE_PLAY_FIELD) == 0)                   ||
          ( ((dr->State & DR_STATE_DISC_FIELD) != DR_STATE_DVD)      &&
            ((dr->State & DR_STATE_DISC_FIELD) != DR_STATE_HDDVD_STD )  )  )
     {
         status = DR_INVALID_STATE;
     }

     /* it's all good, send the speed change */
     if (status == DR_SUCCESS)
     {
         for(int i=0; i<BDROM_NUM_MAX_PREFETCH; i++)                   /* probably should only do this for the main - but others have to keep up */
         {                                                             /* do they call new "play" commands or does DR keep track? */
             if (dr->prefetch[i] != NULL)
             {
                 SPEEDCMD speed;
                 speed.skip_vobu        = skip_vobu;
                 speed.read_until_ref   = read_until_ref;

                 dr->prefetch[i]->SetSpeed(&speed);
             }
         }
     }

    /* If the command failed, signal the command error event */

⌨️ 快捷键说明

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