📄 textst_decoder.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_decoder.cpp
*
* $Revision: 1.7 $
*
* Text Subtitle decoder.
* This is a private module that is intented to be used only by
* modules internal to the TextST Module.
*
*/
#include <string.h>
#include "vdvd_types.h"
#include "textst_decoder.h"
#include "textst_api.h"
#include "textst_render.h"
#include "textst_presctrl.h"
#include "osapi.h"
#include "utility.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_TEXTST_DECODER DBG_ERROR
#define DBG_ON(x) (DBG_TEXTST_DECODER >= x)
/**
* TextST Decoder local handle
*/
typedef struct tagTEXTST_DECODER_HANDLE
{
ULONG ulTaskId;
BOOLEAN fExitPending;
BOOLEAN fStopPending;
OS_SEM_ID semWaitingStart;
OS_SEM_ID semSynch;
ULONG ulCurrentDPS;
} TEXTST_DECODER_HANDLE;
/**
* Local variables
*/
static TEXTST_DECODER_HANDLE *hTextSTDecoder = NULL;
/**
* Local functions
*/
static ULONG TextSTDecoderTask(PVOID pvParam);
static TEXTST_STATUS textstdecoderParseDPS(TEXTST_INFO *hTextST, ULONG ulDPSNumber, TEXTST_RENDER_INFO *pRenderInfo, TEXTST_COMPOSITION_INFO *pCompInfo);
static TEXTST_STATUS textstdecoderGetDPSOffset(TEXTST_INFO *hTextST, ULONG ulDPSNumber, ULONG *pByteOffset);
static TEXTST_STATUS textstdecoderIsDPSContinuous(TEXTST_INFO *hTextST, ULONG ulDPSNumber, UBYTE *pContFlag);
/**
* TextSTDecoderCreate -- Create the Text Subtitle Decoder.
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTDecoderCreate(TEXTST_INFO *hTextST)
{
if (hTextSTDecoder != NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderCreate: Already created!\n"));
goto errout;
}
/* Create the local handle */
hTextSTDecoder = (TEXTST_DECODER_HANDLE *)OS_MemAlloc(sizeof(TEXTST_DECODER_HANDLE) );
if (hTextSTDecoder == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderCreate: Failure creating local handle!\n"));
goto errout;
}
/* Initialize TextST decoder handle */
memset(hTextSTDecoder, 0, sizeof(TEXTST_DECODER_HANDLE) );
/* Create waiting semaphore */
hTextSTDecoder->semWaitingStart = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTDecoder->semWaitingStart == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderCreate: Failure creating waiting semaphore!\n"));
goto errout;
}
/* Create synhronization semaphore */
hTextSTDecoder->semSynch = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hTextSTDecoder->semSynch == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderCreate: Failure creating synch semaphore!\n"));
goto errout;
}
/* Create the TextST Decoder task */
hTextSTDecoder->ulTaskId = OS_TaskSpawnParam("TextSTDecoderTask", OS_TASK_HIGH_PRIORITY, 4096, TextSTDecoderTask, (PVOID)hTextST, NULL);
if (hTextSTDecoder->ulTaskId == (ULONG)OS_FAILURE)
{
hTextSTDecoder->ulTaskId = 0;
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderCreate: Failure spawning task!\n"));
goto errout;
}
return (TEXTST_SUCCESS);
errout:
if (hTextSTDecoder != NULL)
{
if (hTextSTDecoder->ulTaskId != 0)
{
/* Force task to exit */
hTextSTDecoder->fExitPending = TRUE;
hTextSTDecoder->fStopPending = TRUE;
OS_SemGive(hTextSTDecoder->semWaitingStart);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTDecoder->ulTaskId);
OS_TaskDelete(hTextSTDecoder->ulTaskId);
hTextSTDecoder->ulTaskId = 0;
}
if (0 != hTextSTDecoder->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTDecoder->semSynch);
hTextSTDecoder->semSynch = 0;
}
if (0 != hTextSTDecoder->semWaitingStart)
{
/* Delete semaphore */
OS_SemDelete(hTextSTDecoder->semWaitingStart);
hTextSTDecoder->semWaitingStart = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTDecoder);
hTextSTDecoder = NULL;
}
return (TEXTST_FAILURE);
}
/**
* TextSTDecoderDelete -- Delete the Text Subtitle Decoder.
*
* @param
* none
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTDecoderDelete(void)
{
if (hTextSTDecoder != NULL)
{
if (hTextSTDecoder->ulTaskId != 0)
{
/* Force task to exit */
hTextSTDecoder->fExitPending = TRUE;
hTextSTDecoder->fStopPending = TRUE;
OS_SemGive(hTextSTDecoder->semWaitingStart);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hTextSTDecoder->ulTaskId);
OS_TaskDelete(hTextSTDecoder->ulTaskId);
hTextSTDecoder->ulTaskId = 0;
}
if (0 != hTextSTDecoder->semSynch)
{
/* Delete semaphore */
OS_SemDelete(hTextSTDecoder->semSynch);
hTextSTDecoder->semSynch = 0;
}
if (0 != hTextSTDecoder->semWaitingStart)
{
/* Delete semaphore */
OS_SemDelete(hTextSTDecoder->semWaitingStart);
hTextSTDecoder->semWaitingStart = 0;
}
/* Delete local handle */
OS_MemFree(hTextSTDecoder);
hTextSTDecoder = NULL;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderDelete: Not created!\n"));
return (TEXTST_FAILURE);
}
return (TEXTST_SUCCESS);
}
/**
* TextSTDecoderStart -- Start the Text Subtitle Decoder.
*
* @param
* hTextST -- TextST Module handle
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTDecoderStart(ULONG ulDPSNumber)
{
if (hTextSTDecoder == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderStart: TextST Decoder not created!\n"));
return (TEXTST_FAILURE);
}
/* Set the current DPS */
hTextSTDecoder->ulCurrentDPS = ulDPSNumber;
/* Clear flags */
hTextSTDecoder->fExitPending = FALSE;
hTextSTDecoder->fStopPending = FALSE;
/* Signal that decoder should start */
OS_SemGive(hTextSTDecoder->semWaitingStart);
return (TEXTST_SUCCESS);
}
/**
* TextSTDecoderStop -- Stop the Text Subtitle Decoder.
*
* @param
* hTextST -- TextST Module handle
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTDecoderStop(void)
{
if (hTextSTDecoder == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderStop: TextST Decoder not created!\n"));
return (TEXTST_FAILURE);
}
/* Set stop flag */
hTextSTDecoder->fStopPending = TRUE;
/* Release decoder from waiting for a start */
OS_SemGive(hTextSTDecoder->semWaitingStart);
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTDecoderStop: wait for decoder to become stopped\n"));
/* Wait for the decoder to become stopped */
OS_SemTake(hTextSTDecoder->semSynch, OS_WAIT_FOREVER);
return (TEXTST_SUCCESS);
}
/**
* TextSTDecoderFlush -- Flush the Text Subtitle Decoder.
*
* @param
* hTextST -- TextST Module handle
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTDecoderFlush(void)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderFlush: stubbed\n"));
return (TEXTST_NOT_IMPLEMENTED);
}
//////////////////////////////////////////////////////////////////////////////////
// Private Functions
//
/**
* TextSTDecoderTask -- Task that runs during the life of the TextST Decoder. All
* TextST decoding occurs in the context of this task.
*/
static ULONG TextSTDecoderTask(PVOID pvParam)
{
TEXTST_INFO *hTextST = (TEXTST_INFO *)pvParam;
TEXTST_RENDER_INFO *pRenderInfo = NULL;
TEXTST_COMPOSITION_INFO *pCompInfo = NULL;
BOOLEAN fError = FALSE;
BOOLEAN fStartDPS;
while (hTextSTDecoder->fExitPending == FALSE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTDecoderTask: wait for start\n"));
/* Initialize start flag */
fStartDPS = TRUE;
/* Wait until decoder is started */
OS_SemTake(hTextSTDecoder->semWaitingStart, OS_WAIT_FOREVER);
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTDecoderTask: decoder started\n"));
while (hTextSTDecoder->fStopPending == FALSE)
{
if (pCompInfo == NULL)
{
/* Entering DCB critical section */
OS_SemTake(hTextST->semDCB, OS_WAIT_FOREVER);
/* Allocate a buffer from the Dialog Buffer to load rendering info */
pCompInfo = (TEXTST_COMPOSITION_INFO *)OS_MemPoolAlloc(hTextST->mempoolDCB, sizeof(TEXTST_COMPOSITION_INFO) );
if (pCompInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("TextSTDecoderTask: Dialog Composition Buffer full!\n"));
}
/* Leaving DCB Critical Section */
OS_SemGive(hTextST->semDCB);
}
if (pRenderInfo == NULL)
{
/* Entering DB critical section */
OS_SemTake(hTextST->semDB, OS_WAIT_FOREVER);
/* Allocate a buffer from the Dialog Buffer to load rendering info */
pRenderInfo = (TEXTST_RENDER_INFO *)OS_MemPoolAlloc(hTextST->mempoolDB, sizeof(TEXTST_RENDER_INFO) );
if (pRenderInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("TextSTDecoderTask: Dialog Buffer full!\n"));
}
/* Leaving DB Critical Section */
OS_SemGive(hTextST->semDB);
}
/*
* Don't parse DPS until neither DB nor DCB is full.
*/
if ( (pRenderInfo == NULL) || (pCompInfo == NULL) )
{
OS_TaskYield(); // avoid getting stuck in a tight loop
continue;
}
/* Parse a single DPS */
if (textstdecoderParseDPS(hTextST, hTextSTDecoder->ulCurrentDPS, pRenderInfo, pCompInfo) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderTask: Failed to parse DPS!\n"));
fError = TRUE;
}
else
{
/*
* If palette update flag is set for this DPS (AND this is NOT a starting DPS), then no rendering
* needs to occur so just pass the composition info along to the
* presentation controller. Otherwise, pass the rendering info to
* the textst renderer, as well as passing composition info to the
* presentation controller.
*/
if ( (pCompInfo->palette_update_flag == 0) || (fStartDPS == TRUE) )
{
/* Pass the rendering info to the TextST Renderer */
if (TextSTRenderAddDPS(pRenderInfo) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderTask: Failed to Add DPS to renderer queue\n"));
fError = TRUE;
}
}
else
{
/* Don't need rendering info, so can release it */
/* Entering DB critical section */
OS_SemTake(hTextST->semDB, OS_WAIT_FOREVER);
/* Free memory from Dialog Buffer */
if (OS_MemPoolFree(hTextST->mempoolDB, pRenderInfo) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderTask: Failed to release buffer!\n"));
}
/* Leaving DB Critical Section */
OS_SemGive(hTextST->semDB);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -