📄 textst_presctrl.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_presctrl.cpp
*
* $Revision: 1.6 $
*
* API to the Text Subtitle Presentation Controller.
* 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_presctrl.h"
#include "textst_api.h"
#include "textst_types.h"
#include "osapi.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_TEXTST_PRESCTRL DBG_ERROR
#define DBG_ON(x) (DBG_TEXTST_PRESCTRL >= x)
extern IDirectFB *pDfb;
/**
* TextST Presentation Controller local handle
*/
typedef struct tagTEXTST_PRESCTRL_HANDLE
{
ULONG ulTaskId;
OS_MSG_Q_ID CompMsgQID;
OS_MSG_Q_ID BmpMsgQID;
BOOLEAN fExitPending;
BOOLEAN fSuspendPending;
OS_SEM_ID semSuspend;
OS_SEM_ID semSynch;
OS_SEM_ID semPresentation;
TEXTST_INFO *hTextST;
} TEXTST_PRESCTRL_HANDLE;
/**
* Local variables
*/
static TEXTST_PRESCTRL_HANDLE *hTextSTPresCtrl = NULL;
/**
* Local functions
*/
TEXTST_STATUS textstpresctrlDisplayDPS(TEXTST_BITMAP_OBJECT *pBmpObj, TEXTST_COMPOSITION_INFO *pCompInfo);
TEXTST_STATUS textstpresctrlReleaseBitmapObj(TEXTST_BITMAP_OBJECT *pBmpObj);
TEXTST_STATUS textstpresctrlReleaseCompInfo(TEXTST_COMPOSITION_INFO *pCompInfo);
ULONG textstpresctrlMakeARGBfromYCrCb601(BYTE y, BYTE cr, BYTE cb, BYTE t);
ULONG textstpresctrlMakeARGBfromYCrCb709(BYTE y, BYTE cr, BYTE cb, BYTE t);
static ULONG TextSTPresCtrlTask(PVOID pvParam);
/**
* TextSTPresCtrlCreate -- Create the TextST Presentation Controller
*
* @param
* hTextST -- handle to textst data
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTPresCtrlCreate(TEXTST_INFO *hTextST)
{
if (hTextSTPresCtrl != NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Already created!\n"));
goto errout;
}
/* Create the local handle */
hTextSTPresCtrl = (TEXTST_PRESCTRL_HANDLE *)OS_MemAlloc(sizeof(TEXTST_PRESCTRL_HANDLE) );
if (hTextSTPresCtrl == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating local handle!\n"));
goto errout;
}
/* Initialize TextST Presentation Controller handle */
memset(hTextSTPresCtrl, 0, sizeof(TEXTST_PRESCTRL_HANDLE) );
/* Keep handle to TextST Module data */
hTextSTPresCtrl->hTextST = hTextST;
/* Create semaphore used for suspending */
hTextSTPresCtrl->semSuspend = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTPresCtrl->semSuspend == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating semaphore!\n"));
goto errout;
}
/* Create semaphore used for synchronization */
hTextSTPresCtrl->semSynch = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTPresCtrl->semSynch == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating semaphore!\n"));
goto errout;
}
/* Create semaphore used for presentation timing */
hTextSTPresCtrl->semPresentation = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTPresCtrl->semPresentation == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating semaphore!\n"));
goto errout;
}
/* Create the TextST Presentation Controller composition message queue */
hTextSTPresCtrl->CompMsgQID = OS_MsgQCreate( ( (TEXTST_DCB_SIZE / sizeof(TEXTST_COMPOSITION_INFO) ) + 1), sizeof(TEXTST_COMPOSITION_INFO *), OS_MSG_Q_FIFO);
if (hTextSTPresCtrl->CompMsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating comp msg queue!\n"));
goto errout;
}
/* Create the TextST Presentation Controller bitmap message queue */
hTextSTPresCtrl->BmpMsgQID = OS_MsgQCreate( (TEXTST_BOB_DEPTH + 1), sizeof(TEXTST_BITMAP_OBJECT), OS_MSG_Q_FIFO);
if (hTextSTPresCtrl->BmpMsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure creating bmp msg queue!\n"));
goto errout;
}
/* Create the TextST Presentation Controller task */
hTextSTPresCtrl->ulTaskId = OS_TaskSpawnParam("TextSTPresCtrlTask", OS_TASK_HIGH_PRIORITY, 4096, TextSTPresCtrlTask, (PVOID)hTextST, NULL);
if (hTextSTPresCtrl->ulTaskId == (ULONG)OS_FAILURE)
{
hTextSTPresCtrl->ulTaskId = 0;
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlCreate: Failure spawning task!\n"));
goto errout;
}
return (TEXTST_SUCCESS);
errout:
if (hTextSTPresCtrl != NULL)
{
if (hTextSTPresCtrl->ulTaskId != 0)
{
TEXTST_COMPOSITION_INFO *pCompInfo = NULL;
/* Force task to exit */
hTextSTPresCtrl->fExitPending = TRUE;
OS_MsgQSend(hTextSTPresCtrl->CompMsgQID, (char *)&pCompInfo, sizeof(TEXTST_COMPOSITION_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTPresCtrl->ulTaskId);
OS_TaskDelete(hTextSTPresCtrl->ulTaskId);
hTextSTPresCtrl->ulTaskId = 0;
}
if (hTextSTPresCtrl->BmpMsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTPresCtrl->BmpMsgQID);
hTextSTPresCtrl->BmpMsgQID = 0;
}
if (hTextSTPresCtrl->CompMsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTPresCtrl->CompMsgQID);
hTextSTPresCtrl->CompMsgQID = 0;
}
if (0 != hTextSTPresCtrl->semPresentation)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semPresentation);
hTextSTPresCtrl->semPresentation = 0;
}
if (0 != hTextSTPresCtrl->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semSynch);
hTextSTPresCtrl->semSynch = 0;
}
if (0 != hTextSTPresCtrl->semSuspend)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semSuspend);
hTextSTPresCtrl->semSuspend = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTPresCtrl);
hTextSTPresCtrl = NULL;
}
return (TEXTST_FAILURE);
}
/**
* TextSTPresCtrlDelete -- Delete the TextST Presentation Controller
*
* @param
* None
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTPresCtrlDelete(void)
{
if (hTextSTPresCtrl != NULL)
{
if (hTextSTPresCtrl->ulTaskId != 0)
{
TEXTST_COMPOSITION_INFO *pCompInfo = NULL;
/* Force task to exit */
hTextSTPresCtrl->fExitPending = TRUE;
OS_MsgQSend(hTextSTPresCtrl->CompMsgQID, (char *)&pCompInfo, sizeof(TEXTST_COMPOSITION_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTPresCtrl->ulTaskId);
OS_TaskDelete(hTextSTPresCtrl->ulTaskId);
hTextSTPresCtrl->ulTaskId = 0;
}
if (hTextSTPresCtrl->BmpMsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTPresCtrl->BmpMsgQID);
hTextSTPresCtrl->BmpMsgQID = 0;
}
if (hTextSTPresCtrl->CompMsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hTextSTPresCtrl->CompMsgQID);
hTextSTPresCtrl->CompMsgQID = 0;
}
if (0 != hTextSTPresCtrl->semPresentation)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semPresentation);
hTextSTPresCtrl->semPresentation = 0;
}
if (0 != hTextSTPresCtrl->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semSynch);
hTextSTPresCtrl->semSynch = 0;
}
if (0 != hTextSTPresCtrl->semSuspend)
{
/* Delete semaphore */
OS_SemDelete(hTextSTPresCtrl->semSuspend);
hTextSTPresCtrl->semSuspend = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTPresCtrl);
hTextSTPresCtrl = NULL;
return (TEXTST_SUCCESS);
}
else
{
return (TEXTST_FAILURE);
}
}
/**
* TextSTPresCtrlAddDPS -- Add a DPS's composition info the the TextST Presentation
* Controller Composition Queue.
*
* @param
* pCompInfo -- Composition information for the DPS
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTPresCtrlAddDPS(TEXTST_COMPOSITION_INFO *pCompInfo)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTPresCtrlAddDPS: Enter\n"));
if (hTextSTPresCtrl == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlAddDPS: TextST Presentation Controller not created!\n"));
return (TEXTST_FAILURE);
}
/* Check that message queue is created */
if (hTextSTPresCtrl->CompMsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlAddDPS: Msg queue not created!\n"));
return (TEXTST_FAILURE);
}
/* Send rendering info to the TextST Render task */
if (OS_MsgQSend(hTextSTPresCtrl->CompMsgQID, (char *)&pCompInfo, sizeof(TEXTST_COMPOSITION_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlAddDPS: Failure sending message!\n"));
return (TEXTST_FAILURE);
}
return (TEXTST_SUCCESS);
}
/**
* TextSTPresCtrlPresentNextDPS -- Present the currently waiting DPS.
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTPresCtrlPresentNextDPS(void)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTPresCtrlPresentNextDPS: Enter\n"));
if (hTextSTPresCtrl == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlPresentNextDPS: TextST Presentation Controller not created!\n"));
return (TEXTST_FAILURE);
}
/* set wait start pts to invalid */
hTextSTPresCtrl->hTextST->ulWaitStartPTS = 0xffffffff;
/* Release Presentation Control thread from waiting for PTS */
OS_SemGive(hTextSTPresCtrl->semPresentation);
return (TEXTST_SUCCESS);
}
/**
* TextSTPresCtrlErase -- Erase the textst display.
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTPresCtrlErase(void)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTPresCtrlErase: Enter\n"));
if (hTextSTPresCtrl == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlErase: TextST Presentation Controller not created!\n"));
return (TEXTST_FAILURE);
}
/* Set drawing color to clear */
if (hTextSTPresCtrl->hTextST->DFBInfo.PrimarySurface->SetColorIndex(hTextSTPresCtrl->hTextST->DFBInfo.PrimarySurface, 0Xff) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlErase: Failed to set color index!\n"));
return (TEXTST_FAILURE);
}
/*
* Clear the primary surface
*/
if (hTextSTPresCtrl->hTextST->DFBInfo.PrimarySurface->FillRectangle(hTextSTPresCtrl->hTextST->DFBInfo.PrimarySurface,
0, 0, hTextSTPresCtrl->hTextST->DFBInfo.ScreenWidth, hTextSTPresCtrl->hTextST->DFBInfo.ScreenHeight) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTPresCtrlErase: Failed to clear surface!\n"));
return (TEXTST_FAILURE);
}
/* Flip primary surface */
TextSTPresCtrlFlip();
return (TEXTST_SUCCESS);
}
/**
* TextSTPresCtrlLoadPalette -- Load a directfb palette with textst palette definition.
*
* @param
* pal -- textst palette definition to update directfb palette with
* dfb_palette -- directfb palette to load
*
* @retval
* TEXTST_STATUS
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -