📄 textst_render.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2005-2006 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 textst_render.cpp
*
* $Revision: 1.6 $
*
* API to the Text Subtitle renderer.
* This is a private API that is intented to be used only by
* modules internal to the TextST Module.
*
*/
#include <string.h>
#include <directfb.h>
#include "vdvd_types.h"
#include "textst_render.h"
#include "textst_presctrl.h"
#include "textst_api.h"
#include "textst_types.h"
#include "osapi.h"
#include "dbgprint.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_TEXTST_RENDER DBG_ERROR
#define DBG_ON(x) (DBG_TEXTST_RENDER >= x)
/**
* TextST Decoder local handle
*/
typedef struct tagTEXTST_RENDER_HANDLE
{
ULONG ulTaskId;
OS_MSG_Q_ID MsgQID;
BOOLEAN fExitPending;
BOOLEAN fSuspendPending;
OS_SEM_ID semSuspend;
OS_SEM_ID semSynch;
TEXTST_INFO *hTextST;
} TEXTST_RENDER_HANDLE;
/**
* Local variables
*/
static TEXTST_RENDER_HANDLE *hTextSTRender = NULL;
/**
* Local functions
*/
static TEXTST_STATUS textstrenderDPSRender(TEXTST_INFO *hTextST, TEXTST_RENDER_INFO *pRenderInfo, TEXTST_BITMAP_OBJECT *pBmpObj);
static ULONG TextSTRenderTask(PVOID pvParam);
/**
* TextSTRenderCreate -- Create the TextST Renderer
*
* @param
* hTextST -- handle to textst data
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTRenderCreate(TEXTST_INFO *hTextST)
{
if (hTextSTRender != NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Already created!\n"));
goto errout;
}
/* Create the local handle */
hTextSTRender = (TEXTST_RENDER_HANDLE *)OS_MemAlloc(sizeof(TEXTST_RENDER_HANDLE) );
if (hTextSTRender == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating local handle!\n"));
goto errout;
}
/* Initialize TextST Render handle */
memset(hTextSTRender, 0, sizeof(TEXTST_RENDER_HANDLE) );
/* Keep handle to TextST Module data */
hTextSTRender->hTextST = hTextST;
/* Create semaphore used for suspending */
hTextSTRender->semSuspend = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTRender->semSuspend == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating semaphore!\n"));
goto errout;
}
/* Create semaphore used for synchronization */
hTextSTRender->semSynch = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTRender->semSynch == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating semaphore!\n"));
goto errout;
}
/* Create the TextST Render message queuee */
hTextSTRender->MsgQID = OS_MsgQCreate( ( (TEXTST_DB_SIZE / sizeof(TEXTST_RENDER_INFO) ) + 1), sizeof(TEXTST_RENDER_INFO *), OS_MSG_Q_FIFO);
if (hTextSTRender->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating msg queue!\n"));
goto errout;
}
/* Create the TextST Render task */
hTextSTRender->ulTaskId = OS_TaskSpawnParam("TextSTRenderTask", OS_TASK_HIGH_PRIORITY, 4096, TextSTRenderTask, (PVOID)hTextST, NULL);
if (hTextSTRender->ulTaskId == (ULONG)OS_FAILURE)
{
hTextSTRender->ulTaskId = 0;
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure spawning task!\n"));
goto errout;
}
return (TEXTST_SUCCESS);
errout:
if (hTextSTRender != NULL)
{
if (hTextSTRender->ulTaskId != 0)
{
TEXTST_RENDER_INFO *msg = NULL;
/* Force task to exit */
hTextSTRender->fExitPending = TRUE;
OS_MsgQSend(hTextSTRender->MsgQID, (char *)&msg, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTRender->ulTaskId);
OS_TaskDelete(hTextSTRender->ulTaskId);
hTextSTRender->ulTaskId = 0;
}
if (hTextSTRender->MsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTRender->MsgQID);
hTextSTRender->MsgQID = 0;
}
if (0 != hTextSTRender->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTRender->semSynch);
hTextSTRender->semSynch = 0;
}
if (0 != hTextSTRender->semSuspend)
{
/* Delete semaphore */
OS_SemDelete(hTextSTRender->semSuspend);
hTextSTRender->semSuspend = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTRender);
hTextSTRender = NULL;
}
return (TEXTST_FAILURE);
}
/**
* TextSTRenderDelete -- Delete the TextST Renderer
*
* @param
* None
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTRenderDelete(void)
{
if (hTextSTRender != NULL)
{
if (hTextSTRender->ulTaskId != 0)
{
TEXTST_RENDER_INFO *msg = NULL;
/* Force task to exit */
hTextSTRender->fExitPending = TRUE;
OS_MsgQSend(hTextSTRender->MsgQID, (char *)&msg, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTRender->ulTaskId);
OS_TaskDelete(hTextSTRender->ulTaskId);
hTextSTRender->ulTaskId = 0;
}
if (hTextSTRender->MsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTRender->MsgQID);
hTextSTRender->MsgQID = 0;
}
if (0 != hTextSTRender->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTRender->semSynch);
hTextSTRender->semSynch = 0;
}
if (0 != hTextSTRender->semSuspend)
{
/* Delete semaphore */
OS_SemDelete(hTextSTRender->semSuspend);
hTextSTRender->semSuspend = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTRender);
hTextSTRender = NULL;
return (TEXTST_SUCCESS);
}
else
{
return (TEXTST_FAILURE);
}
}
/**
* TextSTRenderAddDPS -- Add a DPS's rendering info the the TextST Renderer Queue.
*
* @param
* pRenderInfo -- Rendering information for the DPS
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTRenderAddDPS(TEXTST_RENDER_INFO *pRenderInfo)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderAddDPS: Enter\n"));
if (hTextSTRender == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: TextST Renderer not created!\n"));
return (TEXTST_FAILURE);
}
/* Check that message queue is created */
if (hTextSTRender->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: Msg queue not created!\n"));
return (TEXTST_FAILURE);
}
/* Send rendering info to the TextST Render task */
if (OS_MsgQSend(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: Failure sending message!\n"));
return (TEXTST_FAILURE);
}
return (TEXTST_SUCCESS);
}
/**
* TextSTRenderFlush -- Flush the TextST Renderer queue.
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTRenderFlush(void)
{
TEXTST_RENDER_INFO *pRenderInfo = NULL;
BOOLEAN fDone = FALSE;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderFlush: Enter\n"));
if (hTextSTRender == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: TextST Presentation Controller not created!\n"));
return (TEXTST_FAILURE);
}
/* Check that message queue is created */
if (hTextSTRender->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: Msg queue not created!\n"));
return (TEXTST_FAILURE);
}
/* Remove all messages from the queue */
while (fDone != TRUE)
{
if (OS_MsgQRemove(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *) ) != OS_OK)
{
fDone = TRUE;
break;
}
else
{
if (pRenderInfo != NULL)
{
/* Entering DB critical section */
OS_SemTake(hTextSTRender->hTextST->semDB, OS_WAIT_FOREVER);
/* Free memory from Composition Buffer */
if (OS_MemPoolFree(hTextSTRender->hTextST->mempoolDB, pRenderInfo) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: Failed to release from DCB!\n"));
}
/* Leaving DB Critical Section */
OS_SemGive(hTextSTRender->hTextST->semDB);
}
}
}
return (TEXTST_SUCCESS);
}
/**
* TextSTRenderSuspend -- Suspend the TextST Renderer
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTRenderSuspend(void)
{
TEXTST_RENDER_INFO *pRenderInfo = NULL;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderSuspend: Enter\n"));
if (hTextSTRender == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderSuspend: TextST Presentation Controller not created!\n"));
return (TEXTST_FAILURE);
}
/* Set flag to indicate a suspend is pending */
hTextSTRender->fSuspendPending = TRUE;
/* Send blank message in case render task is waiting for a message */
OS_MsgQSend(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait until render task is suspended */
OS_SemTake(hTextSTRender->semSynch, OS_WAIT_FOREVER);
/* Clear the suspend pending flag */
hTextSTRender->fSuspendPending = FALSE;
return (TEXTST_SUCCESS);
}
/**
* TextSTRenderResume -- Resume the TextST Renderer
*
* @param
* none
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -