📄 textst_api.cpp
字号:
/* create buffers for all fonts and read font data into the buffers */
ulByteOffset = 1;
for (int i = 0; i < TextSTInfo->ubNumberOfFonts; i++)
{
/* set font filename */
snprintf(font_filename, 64, "/mnt/cdrom/BDMV/AUXDATA/%.5s.otf", &bFontList[ulByteOffset]);
/* Get stats from font file */
if (stat(font_filename, &stat_buf) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTLoadFonts() -- Error getting file stats!\n"));
goto errout;
}
/* set the font file size */
TextSTInfo->font_info[i].uiBufferSize = stat_buf.st_size;
/* allocate buffer to load font data into */
TextSTInfo->font_info[i].pvFontBuffer = OS_MemAlloc(TextSTInfo->font_info[i].uiBufferSize);
if (TextSTInfo->font_info[i].pvFontBuffer == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTLoadFonts: Failed to allocate font buffer!\n"));
goto errout;
}
/* open the font file for reading */
otf_file = fopen(font_filename, "r");
if (otf_file == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTLoadFonts: Failed to open otf file!\n"));
goto errout;
}
/* read font data into the font buffer */
if (TextSTInfo->font_info[i].uiBufferSize != fread(TextSTInfo->font_info[i].pvFontBuffer, 1, TextSTInfo->font_info[i].uiBufferSize, otf_file))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTLoadFonts: Failed to read font file!\n"));
goto errout;
}
/* close the font file */
fclose(otf_file);
otf_file = NULL;
/* Adjust byte offset */
ulByteOffset += 5;
}
return (TEXTST_SUCCESS);
errout:
if (otf_file != NULL)
{
fclose(otf_file);
otf_file = NULL;
}
TextSTUnloadFonts(handle);
return (TEXTST_FAILURE);
}
/**
* TextSTUnloadFonts -- If the Text Subtitle module is in the stopped state, clear
* the Font Preloading Buffer.
*
* @param
* handle -- textst handle
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTUnloadFonts(TEXTST_HANDLE handle)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUnloadFonts: TextST Module not initialized!\n"));
return (TEXTST_NOT_INITIALIZED);
}
if (TextSTInfo->tState != TEXTST_STATE_STOPPED)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUnloadFonts: Must be in stop state!\n"));
return (TEXTST_INVALID_STATE);
}
/* free all allocated font buffers */
for (int i = 0; i < TextSTInfo->ubNumberOfFonts; i++)
{
if (TextSTInfo->font_info[i].pvFontBuffer != NULL)
{
/* free the font buffer */
OS_MemFree(TextSTInfo->font_info[i].pvFontBuffer);
TextSTInfo->font_info[i].pvFontBuffer = NULL;
}
}
return (TEXTST_SUCCESS);
}
/**
* TextSTStyleChange -- If the Text Subtitle module is in the running state, change the
* user selected text style.
*
* @param
* handle -- textst handle
* ulStyleID -- style id in the Dialog Style Segment (1 - 25)
*
* @retval
* TEXTST_STATUS
*/
TEXTST_STATUS TextSTStyleChange(TEXTST_HANDLE handle, ULONG ulStyleID)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTStyleChange: ENTER\n"));
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: TextST Module not initialized!\n"));
return (TEXTST_NOT_INITIALIZED);
}
/* check that dss has been loaded */
if ( (TextSTInfo->fDSSLoaded != TRUE) || (TextSTInfo->pDSS == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: DSS has not been loaded!\n"));
return (TEXTST_FAILURE);
}
/* check for valid user style id */
if ( (ulStyleID > TextSTInfo->pDSS->number_of_user_styles) || (ulStyleID < 1) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Invalid user style ID!\n"));
return (TEXTST_FAILURE);
}
/* set user style id */
TextSTInfo->ubUserStyleID = (UBYTE)(ulStyleID - 1);
/*
* If texst is running, need to restart decoder from current dps so new user style
* settings will be rendered. If start is pending, then decoder has not actually
* started, so we don't need to restart it.
*/
if ( (TextSTInfo->tState == TEXTST_STATE_RUNNING) && (TextSTInfo->fStartPending == FALSE) )
{
ULONG ulStartDPS;
/* Erase the textst display */
if (TextSTPresCtrlErase() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to erase dps!\n"));
return (TEXTST_FAILURE);
}
/* Suspend the TextST Presentation Controller */
if (TextSTPresCtrlSuspend() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to suspend Presentation controller!\n"));
return (TEXTST_FAILURE);
}
/* Suspend the TextST Renderer */
if (TextSTRenderSuspend() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to suspend Renderer!\n"));
return (TEXTST_FAILURE);
}
/* Stop the TextST Decoder */
if (TextSTDecoderStop() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to stop TextST Decoder!\n"));
return (TEXTST_FAILURE);
}
/* Flush the TextST Renderer */
if (TextSTRenderFlush() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to flush TextST Render!\n"));
return (TEXTST_FAILURE);
}
/* Flush the TextST Presentation Controller's Composition Queue */
if (TextSTPresCtrlFlushCompQ() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to flush TextST Presentation Controller's Composition Queue!\n"));
return (TEXTST_FAILURE);
}
/* Flush the TextST Presentation Controller's Bitmap Queue */
if (TextSTPresCtrlFlushBmpQ() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to flush TextST Presentation Controller's Bitmap Queue!\n"));
return (TEXTST_FAILURE);
}
/* Resume the TextST Renderer */
if (TextSTRenderResume() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to resume Renderer!\n"));
return (TEXTST_FAILURE);
}
/* Resume the TextST Presentation Controller */
if (TextSTPresCtrlResume() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to resume TextST Presentation controller!\n"));
return (TEXTST_FAILURE);
}
/* Calculate which DPS to start decoding at, based on PTS */
ulStartDPS = textstGetNextDPS(TextSTInfo, TextSTInfo->ulCurPTS);
/*
* Check that there are remaining dps's in the title.
*/
if (ulStartDPS == 0xffffffff)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTStyleChange: no more dps's!\n"));
}
else
{
/* Start the TextST Decoder */
if (TextSTDecoderStart(ulStartDPS) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTStyleChange: Failed to start TextST Decoder!\n"));
return (TEXTST_FAILURE);
}
}
}
return (TEXTST_SUCCESS);
}
/**
* TextSTSetTimeBase - Set the textst system time base.
*
* @param handle -- textst handle
* @param ulTimeBase -- system time base (this is the sync start time of textst)
*
* @return TEXTST_STATUS
*/
TEXTST_STATUS TextSTSetTimeBase(TEXTST_HANDLE handle, ULONG ulTimeBase)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTSetTimeBase: time base = 0x%08x\n", ulTimeBase));
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTSetTimeBase: TextST Module not initialized!\n"));
return (TEXTST_NOT_INITIALIZED);
}
/* set system time base */
TextSTInfo->SysTimeBase = ulTimeBase;
return (TEXTST_SUCCESS);
}
/**
* TextSTUpdateTimeStamp - Notify the TextST Module of an update to the current timestamp.
*
* @param handle -- textst handle
* @param ULONG PTS - The current Presentation Time Stamp
* @param ULONG SCR - The current System Clock Reference
*
* @return TEXTST_STATUS
*/
TEXTST_STATUS TextSTUpdateTimeStamp(TEXTST_HANDLE handle, TIME45k time45k_currTime)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
TEXTST_STATUS status = TEXTST_SUCCESS;
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("TextSTUpdateTimeStamp: time45k_currTime = 0x%lx\n", time45k_currTime));
#endif
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUpdateTimeStamp: TextST Module not initialized!\n"));
return (TEXTST_NOT_INITIALIZED);
}
if ( (TextSTInfo->tState == TEXTST_STATE_RUNNING) && (time45k_currTime != 0xffffffff) )
{
/*
* Set the current count. The counter starts from the initial counter time,
* which is the start pts of the first dps.
*/
TextSTInfo->ulCurPTS = TextSTInfo->InitalCounterTime + (time45k_currTime * 2);
/*
* If there is a start pending, then start the textst decoder at the
* appropriate dps.
*/
if (TextSTInfo->fStartPending == TRUE)
{
ULONG ulStartDPS;
/* Clear start pending flag */
TextSTInfo->fStartPending = FALSE;
/* Calculate which DPS to start decoding at, based on PTS */
ulStartDPS = textstGetNextDPS(TextSTInfo, TextSTInfo->ulCurPTS);
if (ulStartDPS == 0xffffffff)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTUpdateTimeStamp: no more dps's!\n"));
}
else
{
/* Start the TextST Decoder */
if (TextSTDecoderStart(ulStartDPS) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUpdateTimeStamp: Failed to start TextST Decoder!\n"));
status = TEXTST_FAILURE;
}
}
}
/*
* If DPS is being presented and the current PTS has reached the end PTS of the
* current DPS, then erase the DPS.
*/
if ( (TextSTInfo->ulWaitEndPTS != 0xffffffff) &&
(TextSTInfo->ulCurPTS >= (TextSTInfo->SysTimeBase + TextSTInfo->ulWaitEndPTS) ) )
{
TextSTInfo->ulWaitEndPTS = 0xffffffff;
if (TextSTPresCtrlErase() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUpdateTimeStamp: TextSTPresCtrlClearDPS() FAILED!\n"));
status = TEXTST_FAILURE;
}
}
/*
* If DPS is waiting to be presented and the current PTS has reached the PTS of the
* waiting DPS, then present the DPS.
*/
if ( (TextSTInfo->ulWaitStartPTS != 0xffffffff) &&
(TextSTInfo->ulCurPTS >= (TextSTInfo->SysTimeBase + TextSTInfo->ulWaitStartPTS) ) )
{
if (TextSTPresCtrlPresentNextDPS() != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTUpdateTimeStamp: TextSTPresCtrlPresentNextDPS() FAILED!\n"));
status = TEXTST_FAILURE;
}
}
}
return (status);
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -