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

📄 dr_prefetch.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2005 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file dr_prefetch.cpp
 *
 * Prefetch class for the DR
 *
 * $Id: dr_prefetch.cpp,v 1.116 2007/01/05 01:59:29 rbehe Exp $
 */

#include <stdlib.h>
#include "vdvd_types.h"

#include "loader_app.h"
#include "dr_types.h"
#include "dr_prefetch.h"

#ifdef DMALLOC
#include "dmalloc.h"
#endif

#define DR_TO_DISK 0

#if DR_TO_DISK
#include <fcntl.h>
int fdrout[4];
#include <stdio.h>
#include <unistd.h>
char drfilename[24] = "/mnt/hd/dr_stream";
#endif

#define DEBUG_DR_PREFETCH DBG_ERROR
#define DBG_ON(x) (DEBUG_DR_PREFETCH >= x)

OS_SEM_ID DRPrefetch::m_semDevice=0;


/**********************************************
 *
 * Implementations for DRPrefetch Base Class
 *
 **********************************************/


static ULONG PrefetchThreadCaller(PVOID pvParam)
{
    DR_ERROR status = DR_FAILURE;

    if (NULL != pvParam)
    {
        status = ( (DRPrefetch*)pvParam )->PrefetchThread();
    }

    OS_TaskExit();

    return (status);
}


/**
 * destroy - stops the prefetch task and deletes all allocated objects
 *
 * @retval none
 *
 * @remarks none.
 */
void DRPrefetch::destroy(void)
{

#if DR_TO_DISK
    if (fdrout[m_idnum] > 0)
    {
        close(fdrout[m_idnum]);
    }
#endif

    /* if the thread is running (which it should be), stop and kill and delete it */
    if (m_prefetchThreadID != 0)
    {
        /* Set the flag to kill it */
        m_fKill   = TRUE;

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

        QueueControl(DR_QUEUE_CMD_ENABLE);

        /* and wait for it to die */
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u:  Call OS_TaskJoin\n", __FILE__, __LINE__, m_idnum));
        OS_TaskJoin(m_prefetchThreadID);
        OS_TaskDelete(m_prefetchThreadID);
        m_prefetchThreadID = 0;
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u:  Call OS_TaskJoin ... Completed\n", __FILE__, __LINE__, m_idnum));
    }

    /* delete the play block semaphore */
    if (m_semPlayBlock != 0)
    {
        OS_SemDelete(m_semPlayBlock);
        m_semPlayBlock = 0;
    }

    /* delete the queueEnabled semaphore */
    if (m_semPlayQueueEnabled != 0)
    {
        OS_SemDelete(m_semPlayQueueEnabled);
        m_semPlayQueueEnabled = 0;
    }

    /* delete the device semaphore */
    if (m_semDevice != 0)
    {
        OS_SemDelete(m_semDevice);
        m_semDevice = 0;
    }

    /* delete our play queue and associated allocations */
    if (m_pPlayMessagePool)
    {
        OS_MemFree(m_pPlayMessagePool);
        m_pPlayMessagePool = NULL;
    }
    if (m_prefetchPlayQueue != NULL)
    {
        m_prefetchPlayQueue->Destroy();
        delete (m_prefetchPlayQueue);
        m_prefetchPlayQueue = NULL;
    }

    m_prefetchStream = NULL;
}




/**
 * Private function used to send a cStream packet to the PE.
 *
 * @param streamMessage          - The message.
 * @param pPayload               - A payload to attach to the message.
 *
 * @retval DR_ERROR
 *
 */
DR_ERROR DRPrefetch::drSendStream(DROUTPUTMESSAGE streamMessage, cPayload *pPayload)
{
    DROUTPUTMESSAGE *pStreamMessage = NULL;
    DR_ERROR        status          = DR_SUCCESS;


#if DR_TO_DISK
    if (pPayload != NULL)
    {
        write( fdrout[m_idnum], pPayload->get_rd_ptr(), pPayload->get_size());
    }
#endif

    /* Get a stream message */
    do
    {
        if (m_fAbort == TRUE)
        {
            status = DR_FAILURE;
            break;
        }
        pStreamMessage = (DROUTPUTMESSAGE *)m_prefetchStream->GetMsg(OS_WAIT_1S/4); /* TODO: figure out how to do with a WAIT_FOREVER */
    } while (pStreamMessage == NULL);

    if (DR_SUCCESS == status)
    {
        /* Fill it with data */

        *pStreamMessage = streamMessage;
        pStreamMessage->Encryption          = m_encryption_type;

        /* reference the payload */
        if (pPayload != NULL)
        {
            while (1)
            {
                pStreamMessage->payload = pPayload->REF_PAYLOAD;
                if (pStreamMessage->payload != NULL)
                {
                    break;
                }
                OS_TaskDelay(OS_WAIT_1S / 50);
            }
        }
        else
        {
            pStreamMessage->payload = NULL;
        }

        DBGPRINT(DBG_ON(DBG_VERBOSE), ("DR output stream %u fullstatus():  %u\n", m_idnum, m_prefetchStream->FullStatus()));

        /* Pass it along */
        if (m_prefetchStream->Write((PVOID)pStreamMessage, OS_WAIT_FOREVER) != OS_OK)
        {
            DbgPrint(("%s, %d, drSendStream FAILED\n", __FILE__, __LINE__));
            status = DR_FAILURE;
        }
    }

    if (DR_SUCCESS != status)
    {
        if (NULL != pStreamMessage)
        {
            if (pStreamMessage->payload != NULL)
            {
                delete (pStreamMessage->payload);
                pStreamMessage->payload = NULL;
            }
            m_prefetchStream->ReleaseMsg(pStreamMessage);
        }
    }

    return (status);
}






/**
 * Private function used to send a timing packet to the PE.
 *
 * @param bAppType          - The application type.
 * @param bTransCond        - The transition condition (from the previous to the current).
 * @param ulStartTime       - The start time.
 * @param ulStopTime        - The stop time.
 * @param pvContext         - The context (can be null if not applicable).
 *
 * @retval DR_ERROR
 */
DR_ERROR DRPrefetch::drSendTimingInfo(BYTE bAppType, BYTE bTransCond, ULONG ulStartTime, ULONG ulStopTime, PVOID pvContext)
{
    DROUTPUTMESSAGE     streamMessage;
    cPayload            *pStreamPayload    = NULL;
    INFOPAYLOAD         *infoPayload;

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


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

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

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

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

    /* set the data */
    infoPayload->time.bAppType    = bAppType;
    infoPayload->time.bTransCond  = bTransCond;
    infoPayload->time.ulStartTime = ulStartTime;
    infoPayload->time.ulStopTime  = ulStopTime;

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

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

    return(DR_SUCCESS);
}


/**
 * Configure - starts up the prefetch thread and allocates all member objects.
 *
 * @param prm_loader    - the loader.
 * @param prm_stream    - the the output stream.
 * @param prm_event     - the event handler.
 * @param prm_pContext  - the context of the event handler.
 *
 * @retval none
 *
 * @remarks none.
 */
DR_ERROR DRPrefetch::Configure (LOADER_HANDLE prm_loader, cStream* prm_stream, DR_EVENT prm_event, PVOID prm_pContext)
{
    if (m_loader != NULL)
    {
        DbgPrint(("DRPrefetch has already been Configured! Need to delete before reconfigure!\n"));
        return(DR_INVALID_STATE);
    }

    m_prefetchStream = prm_stream;
    m_loader         = prm_loader;
    m_event          = prm_event;
    m_pContext       = prm_pContext;

    m_fKill  = FALSE;
    m_fAbort = FALSE;

    /* Create and initialize the data proc message queue */
    m_prefetchPlayQueue = new cStream;
    m_pPlayMessagePool = OS_MemAlloc(sizeof(PLAYMSG) * DR_PLAYQUEUE_DEPTH);
    if ((m_prefetchPlayQueue == NULL) || (m_pPlayMessagePool == NULL))
    {
        DbgPrint(("DRCreate: Unable to create PlayQueue!\n"));
        goto errout;
    }
    else
    {
        m_prefetchPlayQueue->Initialize(m_pPlayMessagePool, DR_PLAYQUEUE_DEPTH, sizeof(PLAYMSG), "DR_DATAQUEUE");
    }

    m_semPlayBlock = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_EMPTY, "PlayBlock");
    if (m_semPlayBlock == 0)
    {
        DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
        goto errout;
    }

    m_semPlayQueueEnabled = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_EMPTY, "PlayQueueEnabled");
    if (m_semPlayQueueEnabled == 0)
    {
        DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
        goto errout;
    }

    if (m_semDevice == 0)
    {
        m_semDevice = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_FULL, "DeviceSemaphore");
    }
    if (m_semDevice == 0)
    {
        DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
        goto errout;
    }


    /* Create the DR data thread */
    m_prefetchThreadID = OS_TaskSpawnParam(
        "DR Prefetch Task",
        DR_DATATASK_PRIORITY,
        DR_PREFETCH_STACK_SIZE,
        PrefetchThreadCaller,
        this,
        NULL
        );

    if (m_prefetchThreadID == OS_FAILURE)
    {
        DbgPrint(("\nDRPrefetch: Unable to spawn DRPrefetch Task!\n"));
        goto errout;
    }

#if DR_TO_DISK
    DBGPRINT(DBG_ON(DBG_TRACE), ("\n\n***********************\n"));
    DBGPRINT(DBG_ON(DBG_TRACE), ("DR_TO_DISK IS TURNED ON\n"));
    DBGPRINT(DBG_ON(DBG_TRACE), ("***********************\n\n"));

⌨️ 快捷键说明

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