📄 textst_api.cpp
字号:
* TextSTGetNumberOfUserStyles - Get the number of TextST user styles available.
*
* @param handle -- textst handle
*
* @return Number of user styles
*/
UBYTE TextSTGetNumberOfUserStyles(TEXTST_HANDLE handle)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
UBYTE ubNumUserStyles = 0;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTGetNumberOfUserStyles: ENTER\n"));
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTGetNumberOfUserStyles: TextST Module not initialized!\n"));
}
else
{
if ( (TextSTInfo->fDSSLoaded == TRUE) && (TextSTInfo->pDSS != NULL) )
{
/* set number of user styles */
ubNumUserStyles = TextSTInfo->pDSS->number_of_user_styles;
}
}
return (ubNumUserStyles);
}
/**
* TextSTGetCurrentUserStyle - Get the currently selected TextST user style number.
*
* @param handle -- textst handle
*
* @return User style number (1 - 25); If no user styles, then return 0
*/
UBYTE TextSTGetCurrentUserStyle(TEXTST_HANDLE handle)
{
TEXTST_INFO *TextSTInfo = (TEXTST_INFO *)handle;
UBYTE ubUserStyle = 0;
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTGetCurrentUserStyle: ENTER\n"));
if (TextSTInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTGetCurrentUserStyle: TextST Module not initialized!\n"));
}
else
{
if ( (TextSTInfo->fDSSLoaded == TRUE) && (TextSTInfo->pDSS != NULL) )
{
/* set user style number */
ubUserStyle = (TextSTInfo->pDSS->number_of_user_styles > 0) ? (TextSTInfo->ubUserStyleID + 1) : 0;
}
}
return (ubUserStyle);
}
/////////////////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS
//
/**
* textstLoadDSS -- Load the dialog style segment.
*
* @param
* TextSTInfo -- handle to textst module data
*
* @retval
* TEXTST_STATUS
*/
static TEXTST_STATUS textstLoadDSS(TEXTST_INFO *TextSTInfo)
{
ULONG ulSPBOffset = 0;
DbgAssert(TextSTInfo != NULL);
/* Allocate a buffer from the DCB to load DSS */
TextSTInfo->pDSS = (TEXTST_DSS *)OS_MemPoolAlloc(TextSTInfo->mempoolDCB, sizeof(TEXTST_DSS) );
if (TextSTInfo->pDSS == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstLoadDSS: Failed to allocate buffer for DSS!\n"));
goto errout;
}
/* Ignore pes header */
ulSPBOffset += 6;
/* Set segment descriptor */
TextSTInfo->pDSS->segment_descriptor.segment_type = TextST_SPB[ulSPBOffset];
TextSTInfo->pDSS->segment_descriptor.segment_length = MAKE_WORD(&TextST_SPB[ulSPBOffset+1]);
ulSPBOffset += 3;
/* Set player style flag */
TextSTInfo->pDSS->player_style_flag = TextST_SPB[ulSPBOffset] >> 7;
ulSPBOffset += 2;
/* Set number of region styles and number of user styles */
TextSTInfo->pDSS->number_of_region_styles = TextST_SPB[ulSPBOffset];
TextSTInfo->pDSS->number_of_user_styles = TextST_SPB[ulSPBOffset+1];
ulSPBOffset += 2;
/* Allocate a buffer from DCB for DSS region styles */
TextSTInfo->pDSS->region_style = (TEXTST_DSS_REGION_STYLE *)OS_MemPoolAlloc(TextSTInfo->mempoolDCB,
(sizeof(TEXTST_DSS_REGION_STYLE) * TextSTInfo->pDSS->number_of_region_styles) );
if (TextSTInfo->pDSS->region_style == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstLoadDSS: Failed to allocate buffer for DSS region styles!\n"));
goto errout;
}
/* Set region styles and user control styles */
for (uint8 i = 0; i < TextSTInfo->pDSS->number_of_region_styles; i++)
{
/* Set region style id */
TextSTInfo->pDSS->region_style[i].region_style_id = TextST_SPB[ulSPBOffset];
ulSPBOffset++;
/* Set region info for the region style */
TextSTInfo->pDSS->region_style[i].region_info.region_horizontal_position = MAKE_WORD(&TextST_SPB[ulSPBOffset]);
TextSTInfo->pDSS->region_style[i].region_info.region_vertical_position = MAKE_WORD(&TextST_SPB[ulSPBOffset + 2]);
TextSTInfo->pDSS->region_style[i].region_info.region_width = MAKE_WORD(&TextST_SPB[ulSPBOffset + 4]);
TextSTInfo->pDSS->region_style[i].region_info.region_height = MAKE_WORD(&TextST_SPB[ulSPBOffset + 6]);
TextSTInfo->pDSS->region_style[i].region_info.region_bg_palette_entry_id_ref = TextST_SPB[ulSPBOffset + 8];
ulSPBOffset += 10;
/* Set text box info for the region style */
TextSTInfo->pDSS->region_style[i].text_box_horizontal_position = MAKE_WORD(&TextST_SPB[ulSPBOffset]);
TextSTInfo->pDSS->region_style[i].text_box_vertical_position = MAKE_WORD(&TextST_SPB[ulSPBOffset + 2]);
TextSTInfo->pDSS->region_style[i].text_box_width = MAKE_WORD(&TextST_SPB[ulSPBOffset + 4]);
TextSTInfo->pDSS->region_style[i].text_box_height = MAKE_WORD(&TextST_SPB[ulSPBOffset + 6]);
ulSPBOffset += 8;
/* Set additional text info for the region style */
TextSTInfo->pDSS->region_style[i].text_flow = TextST_SPB[ulSPBOffset];
TextSTInfo->pDSS->region_style[i].text_horizontal_alignment = TextST_SPB[ulSPBOffset + 1];
TextSTInfo->pDSS->region_style[i].text_vertical_alignment = TextST_SPB[ulSPBOffset + 2];
TextSTInfo->pDSS->region_style[i].line_space = TextST_SPB[ulSPBOffset + 3];
ulSPBOffset += 4;
/* Set font style info for the region style */
TextSTInfo->pDSS->region_style[i].font_id_ref = TextST_SPB[ulSPBOffset];
TextSTInfo->pDSS->region_style[i].font_style = TextST_SPB[ulSPBOffset + 1];
TextSTInfo->pDSS->region_style[i].font_size = TextST_SPB[ulSPBOffset + 2];
TextSTInfo->pDSS->region_style[i].font_palette_entry_id_ref = TextST_SPB[ulSPBOffset + 3];
TextSTInfo->pDSS->region_style[i].font_outline_palette_entry_id_ref = TextST_SPB[ulSPBOffset + 4];
TextSTInfo->pDSS->region_style[i].font_outline_thickness = TextST_SPB[ulSPBOffset + 5];
#if USING_OLDER_VERSION
ulSPBOffset += 4;
#else
ulSPBOffset += 6;
#endif
/* Allocate a buffer from DCB for DSS region styles */
TextSTInfo->pDSS->region_style[i].user_control_style = (TEXTST_DSS_USER_CONTROL_STYLE *)OS_MemPoolAlloc(TextSTInfo->mempoolDCB,
(sizeof(TEXTST_DSS_USER_CONTROL_STYLE) * TextSTInfo->pDSS->number_of_user_styles) );
if (TextSTInfo->pDSS->region_style[i].user_control_style == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstLoadDSS: Failed to allocate buffer for DSS user styles!\n"));
goto errout;
}
/* Set user control styles in region style id = i */
for (uint8 j = 0; j < TextSTInfo->pDSS->number_of_user_styles; j++)
{
/* Set user style id */
TextSTInfo->pDSS->region_style[i].user_control_style[j].user_style_id = TextST_SPB[ulSPBOffset];
ulSPBOffset++;
/* Set region info for the user control style */
TextSTInfo->pDSS->region_style[i].user_control_style[j].region_horizontal_position_diretion = TextST_SPB[ulSPBOffset] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].region_horizontal_position_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset]) & 0x7fff;
TextSTInfo->pDSS->region_style[i].user_control_style[j].region_vertical_position_direction = TextST_SPB[ulSPBOffset + 2] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].region_vertical_position_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset + 2]) & 0x7fff;
ulSPBOffset += 4;
/* Set font info for the user control style */
TextSTInfo->pDSS->region_style[i].user_control_style[j].font_size_inc_dec = TextST_SPB[ulSPBOffset] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].font_size_delta = TextST_SPB[ulSPBOffset] & 0x7f;
ulSPBOffset++;
/* Set text box info for the user control style */
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_horizontal_position_direction = TextST_SPB[ulSPBOffset] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_horizontal_position_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset]) & 0x7fff;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_vertical_position_direction = TextST_SPB[ulSPBOffset + 2] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_vertical_position_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset + 2]) & 0x7fff;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_width_inc_dec = TextST_SPB[ulSPBOffset + 4] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_width_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset + 4]) & 0x7fff;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_height_inc_dec = TextST_SPB[ulSPBOffset + 6] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].text_box_height_delta = MAKE_WORD(&TextST_SPB[ulSPBOffset + 6]) & 0x7fff;
ulSPBOffset += 8;
/* Set line space info for the user control style */
TextSTInfo->pDSS->region_style[i].user_control_style[j].line_space_inc_dec = TextST_SPB[ulSPBOffset] >> 7;
TextSTInfo->pDSS->region_style[i].user_control_style[j].line_space_delta = TextST_SPB[ulSPBOffset] & 0x7f;
ulSPBOffset++;
}
}
/* Set palette length */
TextSTInfo->pDSS->palette.length = MAKE_WORD(&TextST_SPB[ulSPBOffset]);
ulSPBOffset += 2;
/* Set pointer to palette entries */
TextSTInfo->pDSS->palette.palette_entry = (TEXTST_PALETTE_ENTRY *)&TextST_SPB[ulSPBOffset];
return (TEXTST_SUCCESS);
errout:
textstClearDSS(TextSTInfo);
return (TEXTST_FAILURE);
}
/**
* textstClearDSS -- Clear the dialog style segment.
*
* @param
* TextSTInfo -- handle to textst module data
*
* @retval
* none
*/
static void textstClearDSS(TEXTST_INFO *TextSTInfo)
{
DbgAssert(TextSTInfo != NULL);
/* Free allocated buffers */
if (TextSTInfo->pDSS != NULL)
{
if (TextSTInfo->pDSS->region_style != NULL)
{
for (uint8 i = 0; i < TextSTInfo->pDSS->number_of_region_styles; i++)
{
if (TextSTInfo->pDSS->region_style[i].user_control_style != NULL)
{
OS_MemPoolFree(TextSTInfo->mempoolDCB, TextSTInfo->pDSS->region_style[i].user_control_style);
}
}
OS_MemPoolFree(TextSTInfo->mempoolDCB, TextSTInfo->pDSS->region_style);
}
OS_MemPoolFree(TextSTInfo->mempoolDCB, TextSTInfo->pDSS);
}
}
/**
* textstGetNextDPS -- Get the next dps number after the specified time value.
*
* @param
* TextSTInfo -- textst module handle
* ulPTS -- pts to search for in dps's
*
* @retval
* TEXTST_STATUS
*/
static ULONG textstGetNextDPS(TEXTST_INFO *TextSTInfo, ULONG ulPTS)
{
ULONG ulDPSNumber = 0;
uint64 dps_pts = 0;
ULONG ulByteOffset = 0;
ULONG usDPSLength;
if (TextSTInfo != NULL)
{
/* skip over first pes packet with dss */
ulByteOffset += MAKE_WORD(&TextST_SPB[4]) + 6;
while (ulDPSNumber < TextSTInfo->usNumberOfDPS)
{
/* skip pes header */
ulByteOffset += 6;
/* Make sure we are on a DPS */
if (TextST_SPB[ulByteOffset] != 0x82)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstGetNextDPS: Invalid DPS, dps #%d!\n", ulDPSNumber));
ulDPSNumber = 0xffffffff;
break;
}
/* set dps length */
usDPSLength = MAKE_WORD(&TextST_SPB[ulByteOffset + 1]);
dps_pts = (uint64)MAKE_DWORD(&TextST_SPB[ulByteOffset + 9]);
dps_pts |= (uint64)(TextST_SPB[ulByteOffset + 8] & 0x01) << 32;
if (ulPTS < (TextSTInfo->SysTimeBase + dps_pts) )
{
/* found dps */
break;
}
/* adjust byte offset */
ulByteOffset += usDPSLength + 3;
/* increment dps number */
ulDPSNumber++;
}
if (ulDPSNumber >= TextSTInfo->usNumberOfDPS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstGetNextDPS: could not find dps!\n"));
ulDPSNumber = 0xffffffff;
}
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstGetNextDPS: NULL ptr!\n"));
ulDPSNumber = 0xffffffff;
}
return (ulDPSNumber);
}
/**
* textstGetInitialCounter -- Get the initial counter time, which is the start pts of
* the first dps.
*
* @param
* TextSTInfo -- textst module handle
* ulInitalCounter -- variable that gets set to the inital counter time, which
* is the start pts of the first dps
*
* @retval
* TEXTST_STATUS
*/
static TEXTST_STATUS textstGetInitialCounter(TEXTST_INFO *TextSTInfo, ULONG &ulInitalCounter)
{
ULONG ulByteOffset = 0;
if (TextSTInfo == NULL)
{
return (TEXTST_NULL_PTR);
}
/* skip over first pes packet with dss */
ulByteOffset += MAKE_WORD(&TextST_SPB[4]) + 6;
/* skip pes header */
ulByteOffset += 6;
/* Make sure we are on a DPS */
if (TextST_SPB[ulByteOffset] != 0x82)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstGetInitialCounter: Invalid DPS!\n"));
return (TEXTST_FAILURE);
}
/* Set initial counter to the dps's start pts */
ulInitalCounter = (ULONG) ((uint64)MAKE_DWORD(&TextST_SPB[ulByteOffset + 4]));
ulInitalCounter |= (ULONG) ((uint64)(TextST_SPB[ulByteOffset + 3] & 0x01) << 32);
return (TEXTST_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -