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

📄 textst_api.cpp

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