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

📄 pg_parse.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    /* if this is an update then we already malloc'd the space */
    if (1 == DoUpdate)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("PG Doing object update\n"));

        if (NULL == PGObjList[ObjectID].SurfaceLUT8)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("ERROR: PGLoadObject, there is no surface to update\n"));
            goto errout;
        }

#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            TickStart = OS_GetTicks();
        }
#endif

        /* lock the dfb surface buffer for the object and RLE decode into it */
        if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to Lock LUT8 Surface\n"));
            goto errout;
        }

        /* RLE decode into the surface */
        status = RLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
                           CurObj->pitch, CurObj->ObjData.Width, PGInfo.CoordsHalfWidth);
        if (status != PG_STATUS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to RLE decode the image\n"));
#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                PGStats.PGTotalRLEFailures++;
            }
#endif
            goto errout;
        }

        /* unlock the surface */
        if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed Unlock LUT8 surface\n"));
            goto errout;
        }

#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            PGStats.PGTotalRLETicks += OS_GetTicks() - TickStart;

            if (PGInfo.CoordsHalfWidth)
            {
                PGStats.PGPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
            }
            else
            {
                PGStats.PGPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
            }
        }
#endif
    }
    else
    {
        DFBSurfaceDescription desc;
        desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_DFBPALETTEHANDLE);
        desc.pixelformat = DSPF_LUT8;
        if (PGInfo.CoordsHalfWidth == 0)
        {
            desc.width = CurObj->ObjData.Width;
        }
        else
        {
            desc.width = (CurObj->ObjData.Width+1)/2;
        }
        desc.height = CurObj->ObjData.Height;
        desc.caps = (DFBSurfaceCapabilities)(DSCAPS_VIDEOONLY | DSCAPS_PREMULTIPLIED);
        /* Any palette will do as it will not be used */
        desc.dfbpalette = PGPalettes[0].DFBPal;

        /* create palettized surface */
        if (PG_STATUS_SUCCESS != PGGraphicsCreateLUT8Surface(&desc, CurObj))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject: Failed to create surface for PG image\n"));
            goto errout;
        }

#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            TickStart = OS_GetTicks();
        }
#endif

        /* lock the dfb surface buffer for the object and RLE decode into it */
        if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to Lock LUT8 Surface\n"));
            goto errout;
        }

        /* RLE decode into the surface */
        status = RLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
                           CurObj->pitch, CurObj->ObjData.Width, PGInfo.CoordsHalfWidth);
        if (status != PG_STATUS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to RLE decode the image\n"));
#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                PGStats.PGTotalRLEFailures++;
            }
#endif
            goto errout;
        }

        /* unlock the surface */
        if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed Unlock LUT8 surface\n"));
            goto errout;
        }
#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            PGStats.PGTotalRLETicks += OS_GetTicks() - TickStart;

            if (PGInfo.CoordsHalfWidth)
            {
                PGStats.PGPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
            }
            else
            {
                PGStats.PGPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
            }
        }
#endif
    }

    /* we are using this slot */
    CurObj->InUse = 1;

    return PG_STATUS_SUCCESS;

errout:

    if (CurObj->SurfaceLUT8)
    {
        CurObj->SurfaceLUT8->Release(CurObj->SurfaceLUT8);
        CurObj->SurfaceLUT8 = NULL;
    }

    CurObj->InUse = 0;

    return PG_STATUS_ERROR;
}

/**
 * PGLoadWindows - Load a window defintion segment
 *
 * @return VOID
 */
PG_STATUS PGLoadWindows(BYTE *DataStart, ULONG DataLength)
{
    BYTE WindowID;
    BYTE NumWindows;

    /* quit set? */
    if (PGInfo.CurrentState != PG_STATE_RUNNING)
    {
        return PG_STATUS_SUCCESS;
    }

    NumWindows = *DataStart;
    DataStart++;

    if (NumWindows > MAX_WINDOWS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("Num Windows too high, %d\n", NumWindows));
        return PG_STATUS_ERROR;
    }

    /* load the windows */
    for (int i=0; i<NumWindows; i++)
    {
        WindowID = *DataStart;

        if (WindowID != i)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("Window ID not in order, invalid window\n"));
            return PG_STATUS_ERROR;
        }

        if (WindowID > MAX_WINDOWS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("Window ID value too large, ignoring window\n"));
            return PG_STATUS_ERROR;
        }

        PGWindows[i].X = MAKE_WORD(DataStart+1);
        PGWindows[i].Y = MAKE_WORD(DataStart+3);
        PGWindows[i].Width = MAKE_WORD(DataStart+5);
        PGWindows[i].Height = MAKE_WORD(DataStart+7);
        DataStart+=SIZE_WINDOW;
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGFreeObjects - free all the object in PGObjList (and the memory they hold)
 *
 * @return VOID
 */
void PGFreeObjects()
{
    for (int i=0; i<PG_MAX_ODS; i++)
    {
        if (PGObjList[i].InUse)
        {
            /* also free the DirectFBSurface */
            if (PGObjList[i].SurfaceLUT8)
            {
                PGObjList[i].SurfaceLUT8->Release(PGObjList[i].SurfaceLUT8);
                PGObjList[i].SurfaceLUT8 = NULL;
            }

            memset(&PGObjList[i], 0, sizeof(OBJECT_DEFINITION_SEGMENT));
        }
    }
}

/**
 * PGClearPalettes - clear all palettes
 *
 * @return VOID
 */
void PGClearPalettes()
{
    for (int i = 0; i < PG_MAX_PALETTES; i++)
    {
        /* set all palette colors to transparent */
        memset(PGPalettes[i].Colors, 0, PG_MAX_PALETTE_COLORS * sizeof(DFBColor));
        PGPalettes[i].PaletteVersion = 0;
    }
}

/**
 * PGFlushParseQ - clear all messages from the parse Queue
 *
 * @return VOID
 */
PG_STATUS PGFlushParseQ()
{
    PG_PARSE_MSG *pMessage = NULL;

    while (1)
    {
        /* Get a stream message */
        pMessage = (PG_PARSE_MSG *)PGInfo.PGParseQ->Read(OS_NO_WAIT);
        if (pMessage)
        {
            PGInfo.PGParseQ->ReleaseMsg(pMessage);
        }
        else
        {
            break;
        }
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGFlush - called during a PGStop(), clears all object lists and resets the parser
 *
 * @return VOID
 */
PG_STATUS PGFlush()
{
    BYTE fClearBuffer = 0;

    /* flush the parser Q */
    PGFlushParseQ();

    /* wait for DecodeData to finish and go back to blocking */
    while (gPGParserWaiting == 0)
    {
        OS_SemGive(PGInfo.ParseWait.WaitSem);
        OS_SemGive(PGInfo.RenderWait.WaitSem);
        OS_TaskYield();
    }

    /* clear screen */
    PGGraphicsClearBuffer(&fClearBuffer, 0);

    if (0 != fClearBuffer)
    {
        OS_TimerSet(PGInfo.PGFlipTimer, 1);
        OS_TaskYield();
    }

    /* delete objects and palettes */
    PGFreeObjects();
    PGClearPalettes();

    /* we are reset, make sure any PCS's are cleared,
    note the parser is already reset here so these won't be in use */
    if (NULL != PGInfo.RenderPCS)
    {
        ReleasePCS(PGInfo.RenderPCS);
        PGInfo.RenderPCS = NULL;
    }

    if (NULL != PGInfo.ParserPCS)
    {
        ReleasePCS(PGInfo.ParserPCS);
        PGInfo.ParserPCS = NULL;
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGWaitForDTS - wait for a PTS to show up
 *
 * @return VOID
 */
PG_STATUS PGWaitForDTS(ULONG DTS)
{
    /* first check if the time has already passed that we want, if so just return */
    if (PGInfo.CurPTS < DTS)
    {
        /* setup the ParseWait PG_WAIT_TIME_SEM to block and wait for the PTS we want */
        PGInfo.ParseWait.WaitTime.WaitPTS = DTS;
        PGInfo.ParseWait.WaitTime.Enabled = 1;

        /* now block wait for the time to show, we awake via UpdateTimeStamp() semgive */
        OS_SemTake(PGInfo.ParseWait.WaitSem, OS_WAIT_FOREVER);

        /* clear flags */
        PGInfo.ParseWait.WaitTime.WaitPTS = 0;
        PGInfo.ParseWait.WaitTime.Enabled = 0;
    }

    return PG_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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