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

📄 textst_render.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2005-2006 Videon Central, Inc.                            **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file textst_render.cpp
 *
 * $Revision: 1.6 $ 
 *
 * API to the Text Subtitle renderer.
 * This is a private API that is intented to be used only by
 * modules internal to the TextST Module.
 *
 */

#include <string.h>
#include <directfb.h>
#include "vdvd_types.h"
#include "textst_render.h"
#include "textst_presctrl.h"
#include "textst_api.h"
#include "textst_types.h"
#include "osapi.h"
#include "dbgprint.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

/* Debug macros */
#define DBG_TEXTST_RENDER   DBG_ERROR
#define DBG_ON(x)           (DBG_TEXTST_RENDER >= x)

/**
 * TextST Decoder local handle
 */
typedef struct tagTEXTST_RENDER_HANDLE
{
    ULONG           ulTaskId;
    OS_MSG_Q_ID     MsgQID;
    BOOLEAN         fExitPending;
    BOOLEAN         fSuspendPending;
    OS_SEM_ID       semSuspend;
    OS_SEM_ID       semSynch;
    TEXTST_INFO     *hTextST;
} TEXTST_RENDER_HANDLE;

/**
 * Local variables
 */
static TEXTST_RENDER_HANDLE    *hTextSTRender = NULL;

/**
 * Local functions
 */
static TEXTST_STATUS    textstrenderDPSRender(TEXTST_INFO *hTextST, TEXTST_RENDER_INFO *pRenderInfo, TEXTST_BITMAP_OBJECT *pBmpObj);
static ULONG            TextSTRenderTask(PVOID pvParam);

/**
 * TextSTRenderCreate --  Create the TextST Renderer
 *
 * @param
 *      hTextST -- handle to textst data
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderCreate(TEXTST_INFO *hTextST)
{
    if (hTextSTRender != NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Already created!\n"));
        goto errout;
    }

    /* Create the local handle */
    hTextSTRender = (TEXTST_RENDER_HANDLE *)OS_MemAlloc(sizeof(TEXTST_RENDER_HANDLE) );
    if (hTextSTRender == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating local handle!\n"));
        goto errout;
    }

    /* Initialize TextST Render handle */
    memset(hTextSTRender, 0, sizeof(TEXTST_RENDER_HANDLE) );

    /* Keep handle to TextST Module data */
    hTextSTRender->hTextST = hTextST;

    /* Create semaphore used for suspending */
    hTextSTRender->semSuspend = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
    if (hTextSTRender->semSuspend == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating semaphore!\n"));
        goto errout;
    }

    /* Create semaphore used for synchronization */
    hTextSTRender->semSynch = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
    if (hTextSTRender->semSynch == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating semaphore!\n"));
        goto errout;
    }

    /* Create the TextST Render message queuee */
    hTextSTRender->MsgQID = OS_MsgQCreate( ( (TEXTST_DB_SIZE / sizeof(TEXTST_RENDER_INFO) ) + 1), sizeof(TEXTST_RENDER_INFO *), OS_MSG_Q_FIFO);
    if (hTextSTRender->MsgQID == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure creating msg queue!\n"));
        goto errout;
    }

    /* Create the TextST Render task */
    hTextSTRender->ulTaskId = OS_TaskSpawnParam("TextSTRenderTask", OS_TASK_HIGH_PRIORITY, 4096, TextSTRenderTask, (PVOID)hTextST, NULL);
    if (hTextSTRender->ulTaskId == (ULONG)OS_FAILURE)
    {
        hTextSTRender->ulTaskId = 0;
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderCreate: Failure spawning task!\n"));
        goto errout;
    }

    return (TEXTST_SUCCESS);

errout:

    if (hTextSTRender != NULL)
    {
        if (hTextSTRender->ulTaskId != 0)
        {
            TEXTST_RENDER_INFO *msg = NULL;

            /* Force task to exit */
            hTextSTRender->fExitPending = TRUE;
            OS_MsgQSend(hTextSTRender->MsgQID, (char *)&msg, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);

            /* Wait for task to exit then delete the task */
            OS_TaskJoin(hTextSTRender->ulTaskId);
            OS_TaskDelete(hTextSTRender->ulTaskId);
            hTextSTRender->ulTaskId = 0;
        }

        if (hTextSTRender->MsgQID != 0)
        {
            /* Delete the msg queue */
            OS_MsgQDelete(hTextSTRender->MsgQID);
            hTextSTRender->MsgQID = 0;
        }

        if (0 != hTextSTRender->semSynch)
        {
            /* Delete semaphore */
            OS_SemDelete(hTextSTRender->semSynch);
            hTextSTRender->semSynch = 0;
        }

        if (0 != hTextSTRender->semSuspend)
        {
            /* Delete semaphore */
            OS_SemDelete(hTextSTRender->semSuspend);
            hTextSTRender->semSuspend = 0;
        }

        /* Delete local handle */
        OS_MemFree(hTextSTRender);
        hTextSTRender = NULL;
    }

    return (TEXTST_FAILURE);
}

/**
 * TextSTRenderDelete --  Delete the TextST Renderer
 *
 * @param
 *      None
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderDelete(void)
{
    if (hTextSTRender != NULL)
    {
        if (hTextSTRender->ulTaskId != 0)
        {
            TEXTST_RENDER_INFO *msg = NULL;

            /* Force task to exit */
            hTextSTRender->fExitPending = TRUE;
            OS_MsgQSend(hTextSTRender->MsgQID, (char *)&msg, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);

            /* Wait for task to exit then delete the task */
            OS_TaskJoin(hTextSTRender->ulTaskId);
            OS_TaskDelete(hTextSTRender->ulTaskId);
            hTextSTRender->ulTaskId = 0;
        }

        if (hTextSTRender->MsgQID != 0)
        {
            /* Delete the msg queue */
            OS_MsgQDelete(hTextSTRender->MsgQID);
            hTextSTRender->MsgQID = 0;
        }

        if (0 != hTextSTRender->semSynch)
        {
            /* Delete semaphore */
            OS_SemDelete(hTextSTRender->semSynch);
            hTextSTRender->semSynch = 0;
        }

        if (0 != hTextSTRender->semSuspend)
        {
            /* Delete semaphore */
            OS_SemDelete(hTextSTRender->semSuspend);
            hTextSTRender->semSuspend = 0;
        }

        /* Delete local handle */
        OS_MemFree(hTextSTRender);
        hTextSTRender = NULL;

        return (TEXTST_SUCCESS);
    }
    else
    {
        return (TEXTST_FAILURE);
    }
}

/**
 * TextSTRenderAddDPS --  Add a DPS's rendering info the the TextST Renderer Queue.
 *
 * @param
 *      pRenderInfo -- Rendering information for the DPS
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderAddDPS(TEXTST_RENDER_INFO *pRenderInfo)
{
    DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderAddDPS: Enter\n"));

    if (hTextSTRender == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: TextST Renderer not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Check that message queue is created */
    if (hTextSTRender->MsgQID == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: Msg queue not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Send rendering info to the TextST Render task */
    if (OS_MsgQSend(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderAddDPS: Failure sending message!\n"));
        return (TEXTST_FAILURE);
    }

    return (TEXTST_SUCCESS);
}

/**
 * TextSTRenderFlush --  Flush the TextST Renderer queue.
 *
 * @param
 *      none
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderFlush(void)
{
    TEXTST_RENDER_INFO  *pRenderInfo    = NULL;
    BOOLEAN             fDone           = FALSE;

    DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderFlush: Enter\n"));

    if (hTextSTRender == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: TextST Presentation Controller not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Check that message queue is created */
    if (hTextSTRender->MsgQID == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: Msg queue not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Remove all messages from the queue */
    while (fDone != TRUE)
    {
        if (OS_MsgQRemove(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *) ) != OS_OK)
        {
            fDone = TRUE;
            break;
        }
        else
        {
            if (pRenderInfo != NULL)
            {
                /* Entering DB critical section */
                OS_SemTake(hTextSTRender->hTextST->semDB, OS_WAIT_FOREVER);

                /* Free memory from Composition Buffer */
                if (OS_MemPoolFree(hTextSTRender->hTextST->mempoolDB, pRenderInfo) != OS_OK)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderFlush: Failed to release from DCB!\n"));
                }

                /* Leaving DB Critical Section */
                OS_SemGive(hTextSTRender->hTextST->semDB);
            }
        }
    }

    return (TEXTST_SUCCESS);
}

/**
 * TextSTRenderSuspend --  Suspend the TextST Renderer
 *
 * @param
 *      none
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderSuspend(void)
{
    TEXTST_RENDER_INFO *pRenderInfo = NULL;

    DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderSuspend: Enter\n"));

    if (hTextSTRender == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderSuspend: TextST Presentation Controller not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Set flag to indicate a suspend is pending */
    hTextSTRender->fSuspendPending = TRUE;

    /* Send blank message in case render task is waiting for a message */
    OS_MsgQSend(hTextSTRender->MsgQID, (char *)&pRenderInfo, sizeof(TEXTST_RENDER_INFO *), OS_NO_WAIT, OS_MSG_PRI_NORMAL);

    /* Wait until render task is suspended */
    OS_SemTake(hTextSTRender->semSynch, OS_WAIT_FOREVER);

    /* Clear the suspend pending flag */
    hTextSTRender->fSuspendPending = FALSE;

    return (TEXTST_SUCCESS);
}

/**
 * TextSTRenderResume --  Resume the TextST Renderer
 *
 * @param
 *      none

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -