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

📄 dr_app.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
        DBGPRINT(DEBUG_DR_APP, ("%s: NULL STREAM_HANDLE\n", __FUNCTION__));
        return(DR_INVALID_PARAM);
    }

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);


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

    ubStreamIndex = (UBYTE)streamType;

    /* must have at least one attach stream available */
    if ( ( (dr->State & DR_STATE_ATTACH_STREAM_FIELD) == 0 ) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: attach stream: Invalid State\n", __FUNCTION__));
        status = DR_INVALID_STATE;
        goto errout;
    }
    /*  if this is the first stream attached         and it's not the main stream    it's not allowed */
    if ( ( (dr->State & DR_STATE_PLAY_FIELD) == 0 ) && (ubStreamIndex != DR_STREAM_MAIN) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: attach stream: Invalid Parameter\n", __FUNCTION__));
        status = DR_INVALID_PARAM;
        goto errout;
    }
    /* check that this stream is not already attached */
    if (dr->prefetch[ubStreamIndex] != NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: attach stream: already attached\n", __FUNCTION__));
        status = DR_ALREADY_ATTACHED;
        goto errout;
    }

    /* it's all good, create a new prefetch object of the correct type */
    if (status == DR_SUCCESS)
    {
        dr->prefetch[ubStreamIndex] = drNewPrefetchForState((dr->State));
        if (dr->prefetch[ubStreamIndex] == NULL)
        {
            status = DR_FAILURE;
            DbgPrint(("Error with drNewPrefetchForState\n"));
            goto errout;
        }

        /* configure and initialize the new prefetch object and update the state */
        dr->prefetch[ubStreamIndex]->Configure(dr->tLoaderDev, (cStream *)stream_handle, drEventPasser, dr);
        // @todo: should check the return value, and handle a failure correctly

        dr->prefetch[ubStreamIndex]->setEncryptionType(dr->EncryptionType);

        dr->State = (DR_STATE)(dr->State + DR_STATE_PLAY);
        dr->State = (DR_STATE)(dr->State - DR_STATE_ATTACH_STREAM);
        DBGPRINT(DBG_ON(DBG_TRACE), ("dr->State: %x\n", dr->State));
    }

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

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRAttachStream() */




/**
 * Detaches a stream from the DR object.
 *
 * @param handle        - Operating system handle for the DR object.
 * @param streamType    - The DR stream to detach.
 */
DR_ERROR DRDetachStream(DR_HANDLE handle, DR_STREAM streamType)
{
    DRHANDLE     *dr             = (DRHANDLE*)handle;
    DR_ERROR     status          = DR_SUCCESS;
    UBYTE        ubStreamIndex;

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

    OS_SemTake(dr->semDRMutex, OS_WAIT_FOREVER);

    ubStreamIndex = (UBYTE)streamType;

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


    /* must have at least one stream already attached in order to detach */
    if ( ( dr->State & DR_STATE_PLAY_FIELD) == 0)
    {
        status = DR_INVALID_STATE;
        goto errout;
    }

    /*  if this is the main stream         and there are other streams still attached    it's not allowed */
    if ( (streamType == DR_STREAM_MAIN) &&  ( (dr->State & DR_STATE_PLAY_FIELD) != 0x0100 ) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: detach stream: Invalid Parameter\n", __FUNCTION__));
        status = DR_INVALID_PARAM;
        goto errout;
    }

    /* if this stream is not attached, can't detach it */
    if (dr->prefetch[ubStreamIndex] == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: dettach stream: nothing attached to detach\n", __FUNCTION__));
        status = DR_INVALID_PARAM;
        goto errout;
    }

    /* it's all good - detach the stream and delete the prefetch object and update the state */
    if (status == DR_SUCCESS)
    {
        delete(dr->prefetch[ubStreamIndex]);

        dr->prefetch[ubStreamIndex] = NULL;

        dr->State = (DR_STATE)(dr->State - DR_STATE_PLAY);
        dr->State = (DR_STATE)(dr->State + DR_STATE_ATTACH_STREAM);
        DBGPRINT(DBG_ON(DBG_TRACE), ("dr->State: %x\n", dr->State));
    }

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

    OS_SemGive(dr->semDRMutex);

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




/**
 * Requests the DR to read the CD sectors from the loader.
 *
 * @param handle     - Operating system handle for the DR object.
 * @param playtype   - Describes how to read the sectors from the loader.
 * @param queue      - Describes how to handle the command queue.
 * @param start      - Starting LBN or MSF address.
 * @param end        - Ending LBN or MSF address.
 * @param sectortype - The Type of CD sector reads (different for VCD, CDDA, etc).
 *
 * @retval DR_ERROR
 */
DR_ERROR DRPlayCD(DR_HANDLE handle, DR_PLAY_TYPE playtype, DR_QUEUE_TYPE queue, ULONG start, ULONG end, DR_CD_SECTOR_TYPE sectortype, SHORT sSpeed)
{
    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 (playtype == DR_TYPE_VOB)
    {
        return (DR_INVALID_PARAM);
    }
    if (queue == DR_QUEUE_NONSEAMLESS)
    {
        return (DR_INVALID_PARAM);
    }
    if ( (sectortype != DR_CD_SECTOR_CDDA) && (sSpeed != 1) )
    {
       return (DR_INVALID_PARAM);
    }
    if (sSpeed == 0)
    {
        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;
        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;
    }

    if (status == DR_SUCCESS)
    {
        play.cd.queueType     = queue;
        play.cd.playType      = playtype;
        play.cd.ulStart       = start;
        play.cd.ulEnd         = end;
        play.cd.sectorType    = sectortype;
        play.cd.sSpeed        = sSpeed;

        if (play.cd.queueType == DR_QUEUE_ABORT)
        {
            /* 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.cd.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_CD);
        }
    }

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRPlayCD() */






/**
 * Requests the DR to read the DVD sectors from the loader.
 *
 * @param handle   - Operating system handle for the DR object.
 * @param playtype - Describes how to read the sectors from the loader.
 * @param queue    - Describes how to handle the command queue.
 * @param startLBN - Starting LBN.
 * @param endLBN   - Ending LBN.
 * @param beginLBN - First DVD VOBu to start a DVD Cell playback.
 *
 * @retval DR_ERROR
 */
DR_ERROR DRPlayDVD(DR_HANDLE handle, DR_PARAMS_DVD *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: 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);

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

    /* 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;
    }

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

    OS_SemGive(dr->semDRMutex);

    /* Return status */
    return (status);

} /* end DRPlayDVD() */




/**
 * DRPlayBDROM - Play the file specified on the stream specified from the inpoint to the outpoint
 *
 * @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 filename      - Which file to play - must be a 5-character ascii code of only numbers.
 * @param in_point      - Start point of playback.
 * @param out_point     - End point of playback.
 * @param playItem_id   - Current Play item Id.
 * @param playList_id   - Current Play list Id.
 * @param ref_to_STC_id - refers to STC sequence of the playitem (used to find location of in and out points).
 * @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 DRPlayBDROM(DR_HANDLE handle, DR_PARAMS_BDROM *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: NULL DR_HANDLE\n", __FUNCTION__));
        return (DR_FAILURE);
    }

    if ( pParams->filename == NULL )
    {
        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;
        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;

⌨️ 快捷键说明

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