⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textst_decoder.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                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 + -