📄 spu_app.cpp
字号:
/* 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 + -