📄 textst_decoder.cpp
字号:
if (fError == FALSE)
{
/* If this is a starting DPS, then set the flag in the composition info */
if (fStartDPS == TRUE)
{
fStartDPS = FALSE;
pCompInfo->fFirstDPS = TRUE;
}
else
{
pCompInfo->fFirstDPS = FALSE;
}
/* Pass the composition info to the TextST Presentation Controller */
if (TextSTPresCtrlAddDPS(pCompInfo) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderTask: Failed to Add DPS to presentation queue\n"));
fError = TRUE;
}
}
}
if (fError == TRUE)
{
/* 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);
/* Entering DCB critical section */
OS_SemTake(hTextST->semDCB, OS_WAIT_FOREVER);
/* Free memory from Composition Buffer */
if (OS_MemPoolFree(hTextST->mempoolDCB, pCompInfo) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTDecoderTask: Failed to release buffer!\n"));
}
/* Leaving DCB Critical Section */
OS_SemGive(hTextST->semDCB);
}
/* Reset error flag */
fError = FALSE;
/* Reset pointers */
pRenderInfo = NULL;
pCompInfo = NULL;
/* Increment to the next DPS */
hTextSTDecoder->ulCurrentDPS++;
/* If all DPS's have been decoded, then stop decoding */
if (hTextSTDecoder->ulCurrentDPS == hTextST->usNumberOfDPS)
{
break;
}
}
/* Signal that decoder is stopped */
OS_SemGive(hTextSTDecoder->semSynch);
DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTDecoderTask: decoder stopped\n"));
}
/* exit task */
OS_TaskExit();
return (0);
}
/**
* textstdecoderParseDPS -- Parse a DPS (Dialog Presentation Segment).
*
* @param
* hTextST -- textst info handle
* ulDPSNumber -- Number of DPS to parse
* pRenderInfo -- pointer to struct to load rendering information into
* pCompInfo -- pointer to struct to load composition information into
*
* @retval
* TEXTST_STATUS
*/
static TEXTST_STATUS textstdecoderParseDPS(TEXTST_INFO *hTextST, ULONG ulDPSNumber, TEXTST_RENDER_INFO *pRenderInfo, TEXTST_COMPOSITION_INFO *pCompInfo)
{
ULONG ulByteOffset;
ULONG ulProcessedLength;
UBYTE ubDataType;
UBYTE ubDataLength;
ULONG ulTextStringOffset;
ULONG ulInlineStyleOffset;
ULONG ulNumberOfInlineStyles;
/* Make sure pointers are valid */
if ( (hTextST == NULL) || (pRenderInfo == NULL) || (pCompInfo == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderParseDPS: Null pointer!\n"));
return (TEXTST_NULL_PTR);
}
/* Check that Subtitle Preload Buffer is valid */
if (hTextST->bSPB == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderParseDPS: Invalid SPB!\n"));
return (TEXTST_FAILURE);
}
/* Set DPS numbers */
pRenderInfo->dps_number = ulDPSNumber;
pCompInfo->dps_number = ulDPSNumber;
/* Get the offset for this dps */
if (textstdecoderGetDPSOffset(hTextST, ulDPSNumber, &ulByteOffset) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderParseDPS: Failed to get dps offset!\n"));
return (TEXTST_FAILURE);
}
/* Jump over pes header */
ulByteOffset += 6;
/* Make sure we are on a DPS */
if (hTextST->bSPB[ulByteOffset] != 0x82)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderParseDPS: Invalid DPS, dps #%d!\n", ulDPSNumber));
return (TEXTST_FAILURE);
}
/* Skip over segment descriptor */
ulByteOffset += 3;
/* Set Start PTS value */
pCompInfo->presentation_start_time = (uint64)MAKE_DWORD(&hTextST->bSPB[ulByteOffset + 1]);
pCompInfo->presentation_start_time |= (uint64)(hTextST->bSPB[ulByteOffset] & 0x01) << 32;
/* Adjust byte offset */
ulByteOffset += 5;
/* Set End PTS value */
pCompInfo->presentation_end_time = (uint64)MAKE_DWORD(&hTextST->bSPB[ulByteOffset + 1]);
pCompInfo->presentation_end_time |= (uint64)(hTextST->bSPB[ulByteOffset] & 0x01) << 32;
/* Adjust byte offset */
ulByteOffset += 5;
/* Set palette update flag value */
pCompInfo->palette_update_flag = hTextST->bSPB[ulByteOffset] >> 7;
/* Adjust byte offset */
ulByteOffset++;
if (pCompInfo->palette_update_flag == 1)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("textstdecoderParseDPS: DPS #%d, palette update flag is set\n", ulDPSNumber));
/* Set palette length */
pCompInfo->palette.length = MAKE_WORD(&hTextST->bSPB[ulByteOffset]);
/* Set pointer to palette entries */
pCompInfo->palette.palette_entry = (TEXTST_PALETTE_ENTRY *)&hTextST->bSPB[ulByteOffset + 2];
/* Adjust byte offset */
ulByteOffset += pCompInfo->palette.length + 2;
}
/* Set number of regions */
pRenderInfo->number_of_regions = hTextST->bSPB[ulByteOffset];
/* Adjust byte offset */
ulByteOffset++;
/* Set continuous presentation flag value */
/* NOTE: this flag indicates a continuous presentation between this DPS and the NEXT DPS */
if (textstdecoderIsDPSContinuous(hTextST, (ulDPSNumber + 1), &pCompInfo->continuous_present_flag) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderParseDPS: failed to get continuous flag!\n"));
pCompInfo->continuous_present_flag = 0;
}
for (int i = 0; i < pRenderInfo->number_of_regions; i++)
{
/* Set forced-on flag value */
pCompInfo->forced_on_flag[i] = (hTextST->bSPB[ulByteOffset] >> 6) & 0x01;
/* Set region style id from DSS */
pRenderInfo->region_style_id_ref[i] = hTextST->bSPB[ulByteOffset + 1];
pCompInfo->region_style_id_ref[i] = hTextST->bSPB[ulByteOffset + 1];
/* Adjust byte offset */
ulByteOffset += 2;
/* Set region subtitle length */
pRenderInfo->region_subtitle[i].region_subtitle_length = MAKE_WORD(&hTextST->bSPB[ulByteOffset]);
/* Adjust byte offset */
ulByteOffset += 2;
/* initialize the inline style position values */
memset(pRenderInfo->region_subtitle[i].inline_style_position, 0xff, TEXTST_MAX_CHARS_PER_DPS_REGION);
/* set initial counter values */
ulProcessedLength = 0;
ulTextStringOffset = 0;
ulInlineStyleOffset = 0;
ulNumberOfInlineStyles = 0;
while (ulProcessedLength < pRenderInfo->region_subtitle[i].region_subtitle_length)
{
/* Skip over escape code */
ulByteOffset++;
/* Set data type */
ubDataType = hTextST->bSPB[ulByteOffset++];
/* Set data length */
ubDataLength = hTextST->bSPB[ulByteOffset++];
if (ubDataType == 0x01)
{
for (int j = 0; j < ubDataLength; j++)
{
/* Read text string */
pRenderInfo->region_subtitle[i].text_string[j + ulTextStringOffset] = hTextST->bSPB[ulByteOffset++];
}
/* Adjust string offset */
ulTextStringOffset += ubDataLength;
}
else if ( ( (ubDataType >= 0x02) && (ubDataType <= 0x05) ) || (ubDataType == 0x0A) || (ubDataType == 0x0B) )
{
/* set the inline style data type */
pRenderInfo->region_subtitle[i].inline_style_type[ulNumberOfInlineStyles] = ubDataType;
/* set the inline style position */
pRenderInfo->region_subtitle[i].inline_style_position[ulNumberOfInlineStyles] = (uint8)(ulTextStringOffset);
for (int j = 0; j < ubDataLength; j++)
{
/* Read inline style values */
pRenderInfo->region_subtitle[i].inline_style_values[j + ulInlineStyleOffset] = hTextST->bSPB[ulByteOffset++];
}
/* Adjust inline style offset */
ulInlineStyleOffset += ubDataLength;
/* increment number of inline styles */
ulNumberOfInlineStyles++;
}
/* Adjust processed length */
ulProcessedLength += ubDataLength + 3;
}
/* Set data length */
pRenderInfo->region_subtitle[i].data_length = (UBYTE)ulTextStringOffset;
}
return (TEXTST_SUCCESS);
}
/**
* textstdecoderGetDPSOffset -- Get offset in the SPB of the specified DPS.
*
* @param
* hTextST -- textst info handle
* ulDPSNumber -- Number of DPS to parse
* pByteOffset -- pointer that gets set to byte offset of dps (0xffffffff = not found)
*
* @retval
* TEXTST_STATUS
*/
static TEXTST_STATUS textstdecoderGetDPSOffset(TEXTST_INFO *hTextST, ULONG ulDPSNumber, ULONG *pByteOffset)
{
ULONG ulDPSIndex = 0;
ULONG ulByteOffset = 0;
USHORT usNumDPS;
if ( (hTextST == NULL) || (pByteOffset == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderGetDPSOffset: NULL pointer!\n"));
return (TEXTST_NULL_PTR);
}
ulByteOffset = 0;
/* Jump over DSS and pes header and number of DPS field */
ulByteOffset = hTextST->pDSS->segment_descriptor.segment_length + 9;
/* set number of dps's */
usNumDPS = MAKE_WORD(&hTextST->bSPB[ulByteOffset]);
/* adjst offset */
ulByteOffset += 2;
if (ulDPSNumber < usNumDPS)
{
/* Find specified DPS within the subtitle preloaded buffer */
while (ulDPSIndex != ulDPSNumber)
{
/* Jump over pes header */
ulByteOffset += 6;
/* Make sure we are on a DPS */
if (hTextST->bSPB[ulByteOffset++] != 0x82)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderGetDPSOffset: Invalid DPS, dps #%d!\n", ulDPSNumber));
return (TEXTST_FAILURE);
}
/* Adjust offset into the SPB */
ulByteOffset += (MAKE_WORD(&hTextST->bSPB[ulByteOffset]) + 2);
/* Increment Index */
ulDPSIndex++;
}
*pByteOffset = ulByteOffset;
}
else
{
*pByteOffset = 0xffffffff;
}
return (TEXTST_SUCCESS);
}
/**
* textstdecoderIsDPSContinuous -- Get continuous presentation for the specified dps.
*
* @param
* hTextST -- textst info handle
* ulDPSNumber -- Number of DPS to parse
* pContFlag -- pointer that gets set to continuous presentation flag (1=continuous presentation)
*
* @retval
* TEXTST_STATUS
*/
static TEXTST_STATUS textstdecoderIsDPSContinuous(TEXTST_INFO *hTextST, ULONG ulDPSNumber, UBYTE *pContFlag)
{
UBYTE ubContinuousFlag = 0;
ULONG ulByteOffset;
if ( (hTextST == NULL) || (pContFlag == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderIsDPSContinuous: NULL pointer!\n"));
return (TEXTST_NULL_PTR);
}
/* Get the offset for this dps */
if (textstdecoderGetDPSOffset(hTextST, ulDPSNumber, &ulByteOffset) != TEXTST_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("textstdecoderIsDPSContinuous: Failed to get dps offset!\n"));
return (TEXTST_FAILURE);
}
if (ulByteOffset == 0xffffffff)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("textstdecoderIsDPSContinuous: dps not found!\n"));
}
else
{
UBYTE ubNumRegions;
/* adjust byte offset */
ulByteOffset += 19;
/* check if there is a palette definition in this dps */
if ( (hTextST->bSPB[ulByteOffset++] >> 7) == 1)
{
/* Adjust byte offset */
ulByteOffset += MAKE_WORD(&hTextST->bSPB[ulByteOffset]) + 2;
}
/* Set number of regions */
ubNumRegions = hTextST->bSPB[ulByteOffset];
/* Adjust byte offset */
ulByteOffset++;
for (int i = 0; i < ubNumRegions; i++)
{
ubContinuousFlag |= (hTextST->bSPB[ulByteOffset] >> 7);
/* adjust byte offset */
ulByteOffset += MAKE_WORD(&hTextST->bSPB[ulByteOffset + 2]) + 4;
}
}
/* set return flag */
*pContFlag = ubContinuousFlag;
return (TEXTST_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -