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

📄 spu_app.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* vim:set ts=4 sw=4 et: */
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 spu_app.cpp
 *
 * Public API for the DVD Software Subpicture Decoder
 *
 * $Id: spu_app.cpp,v 1.31 2007/01/05 00:26:14 rbehe Exp $
 */
#include "vdvd_types.h"
#include "osapi.h"
#include "dbgprint.h"
#include "cStream.h"
#include "spu_types.h"
#include "spu_app.h"
#include "spu_render.h"
#include "spu_decoder.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

#define SPU_THREAD_PRIORITY       (OS_TASK_NORMAL_PRIORITY - 1)
#define SPU_THREAD_STACKSIZE      (8 * 1024)
#define SPU_THREAD_NAME           "spu_app"

/* private functions */
static ULONG SPDecoderProcessData(PVOID hSPDecoder);
static SPU_ERR spuHide(SPU_HANDLE hSPDecoder, BOOLEAN fEraceForcedSP);

/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUCreate(SPU_HANDLE *handle)
{
    SPU_DECODER *pSPDecoder = NULL;

    if (handle == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    /* allocate handle */
    pSPDecoder = (SPU_DECODER *)OS_MemAlloc( sizeof(SPU_DECODER));
    if (pSPDecoder == NULL)
    {
        return (SPU_ERR_OUTOFMEMORY);
    }

    /* set the memory to zero */
    memset(pSPDecoder, 0, sizeof(SPU_DECODER));

    /* allocate our SPU buffer */
    pSPDecoder->pbSpuBuffer = (BYTE*)OS_MemAlloc(400*1024);
    if (pSPDecoder->pbSpuBuffer == NULL)
    {
        goto errhandler;
    }

    /* initialize */
    pSPDecoder->ulState             = SPU_STATE_UNREALIZED;
    pSPDecoder->ulPTS               = 0;
    pSPDecoder->dcsq_timeout        = 0;
    pSPDecoder->fKillThread         = FALSE;
    pSPDecoder->pStreamDecode       = NULL;
    pSPDecoder->pSyncContext        = NULL;
    pSPDecoder->pSyncCallback       = NULL;
    pSPDecoder->fInserted           = SP_NOT_INSERTED;

    pSPDecoder->critical_section = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_FULL, "spusem");

    pSPDecoder->HLI.StartX   = 0xFFFF;
    pSPDecoder->HLI.EndX     = 0xFFFF;
    pSPDecoder->HLI.StartY   = 0xFFFF;
    pSPDecoder->HLI.EndY     = 0xFFFF;

    /* initialize the spu render */
    if (SPURenderHwInit() != SPU_SUCCESS)
    {
        DbgPrint(("SPUCreate: SPURenderHwInit() failed\n"));
        goto errhandler;
    }

    pSPDecoder->ulState = SPU_STATE_REALIZING;

    *handle = pSPDecoder;

    return (SPU_SUCCESS);

errhandler:

    if (pSPDecoder != NULL)
    {
        if (pSPDecoder->critical_section != 0)
        {
            OS_SemDelete(pSPDecoder->critical_section);
            pSPDecoder->critical_section = 0;
        }

        if (pSPDecoder->pbSpuBuffer != NULL)
        {
            OS_MemFree(pSPDecoder->pbSpuBuffer);
        }

        OS_MemFree(( PVOID )pSPDecoder );
        pSPDecoder = NULL;
    }

    *handle = NULL;

    return (SPU_FAILURE);
}

/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUDelete(SPU_HANDLE hSPDecoder)
{
    SPU_DECODER *pSPU = (SPU_DECODER *)hSPDecoder;

    if (pSPU == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (pSPU->pStreamDecode != NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("SPUDelete: MUST FIRST CALL SPUDetachInputStream()\n"));
        return (SPU_ERR_INVALID_STATE);
    }

    /* delete critical section */
    DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: delete critical section\n"));
    if (pSPU->critical_section != 0)
    {
        OS_SemDelete(pSPU->critical_section);
        pSPU->critical_section = 0;
    }

    /* delete spu buffer */
    DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: delete spu buffer\n"));
    if (pSPU->pbSpuBuffer != NULL)
    {
        OS_MemFree(pSPU->pbSpuBuffer);
    }

    /* free handle */
    DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: free handle\n"));
    OS_MemFree( pSPU );

    /* delete the spu render */
    DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: delete the spu render\n"));
    SPURenderHwUninit();

    return (SPU_SUCCESS);
}


/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUAttachInputStream(SPU_HANDLE hSPDecoder, cStream* pInStream)
{
    SPU_DECODER *pSPU = (SPU_DECODER *)hSPDecoder;

    if (pSPU == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (pInStream == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (pSPU->ulState > SPU_STATE_REALIZING)
    {
        return (SPU_ERR_INVALID_STATE);
    }

    if (pSPU->pStreamDecode != NULL)
    {
        return (SPU_FAILURE);
    }

    /* passed all the tests so accept the new input stream */
    pSPU->pStreamDecode = pInStream;

    /* spawn the decoder thread */
    pSPU->ulThreadID = OS_TaskSpawnParam(
        SPU_THREAD_NAME,
        SPU_THREAD_PRIORITY,
        SPU_THREAD_STACKSIZE,
        SPDecoderProcessData,
        pSPU,
        NULL );

    if (pSPU->ulThreadID == 0)
    {
        DbgPrint(("SPUCreate: OS_TaskSpawnParam() failed\n"));
        pSPU->pStreamDecode = NULL;
    }
    else
    {
        /* update our state */
        if (pSPU->pSyncCallback == NULL)
        {
            pSPU->ulState = SPU_STATE_REALIZING;
        }
        else
        {
            pSPU->ulState = SPU_STATE_REALIZED;
        }
    }

    return (SPU_SUCCESS);
}


/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUDetachInputStream(SPU_HANDLE hSPDecoder)
{
    SPU_DECODER       *pSPU       = (SPU_DECODER *)hSPDecoder;
    cSPUStreamMessage *pSPMessage = NULL;

    if (pSPU == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (pSPU->pStreamDecode != NULL)
    {
        /* delete the thread */
        DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: delete the thread\n"));
        pSPU->fKillThread = TRUE;
        pSPU->ulState     = SPU_STATE_FLUSHING;

        /* release wait states */
        DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: release wait states\n"));
        pSPMessage = (cSPUStreamMessage*)pSPU->pStreamDecode->GetMsg(OS_NO_WAIT);
        if (pSPMessage != NULL)
        {
            pSPMessage->payload = NULL;
            pSPU->pStreamDecode->Write((PVOID)pSPMessage);
        }

        /* Wait for thread to terminate */
        DBGPRINT(DBG_ON(DBG_TRACE), ("SPUDelete: Wait for thread to terminate\n"));
        OS_TaskJoin(pSPU->ulThreadID);
        OS_TaskDelete(pSPU->ulThreadID);

        /* set pointer to NULL */
        pSPU->pStreamDecode = NULL;

        /* update our state */
        pSPU->ulState = SPU_STATE_REALIZING;
    }

    return (SPU_SUCCESS);
}


/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUAttachSyncCallback(SPU_HANDLE hSPDecoder, SPU_SYNC_CALLBACK func, PVOID context)
{
    SPU_DECODER *pSPU = (SPU_DECODER *)hSPDecoder;

    if (pSPU == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (func == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (context == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }

    if (pSPU->ulState > SPU_STATE_REALIZING)
    {
        return (SPU_ERR_INVALID_STATE);
    }

    if (pSPU->pSyncCallback != NULL)
    {
        return (SPU_FAILURE);
    }

    /* passed all the tests so accept the new callback */
    pSPU->pSyncCallback = (PVOID)func;
    pSPU->pSyncContext  = context;

    /* update our state */
    if (pSPU->pStreamDecode == NULL)
    {
        pSPU->ulState = SPU_STATE_REALIZING;
    }
    else
    {
        pSPU->ulState = SPU_STATE_REALIZED;
    }

    return (SPU_SUCCESS);
}


/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUDetachSyncCallback(SPU_HANDLE hSPDecoder)
{
    SPU_DECODER *pSPU = (SPU_DECODER *)hSPDecoder;
    if (pSPU == NULL)
    {
        return (SPU_ERR_NULLPTR);
    }
    return (SPU_SUCCESS);
}


/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/
SPU_ERR SPUStart(SPU_HANDLE hSPDecoder)
{
    SPU_DECODER *pSPU = (SPU_DECODER *)hSPDecoder;

    /* verify handle */
    if (pSPU == NULL)
    {
        DbgPrint(("SPUStart: NULL HANDLE\n"));
        return (SPU_ERR_NULLPTR);

⌨️ 快捷键说明

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