📄 dr_app.cpp
字号:
}
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 + -