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

📄 ig_parse.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        load the object definition segment
    */

    /* read the object id */
    CurObj->VersionNumber = VersionNumber;
    ObjStart+=3;

    /* get sequence flags, these won't be accurate for mulitPES segments */
    CurObj->SeqDesc.FirstInSequenceFlag = ((*ObjStart) & BIT7) >> 7;
    CurObj->SeqDesc.LastInSequenceFlag = ((*ObjStart) & BIT6) >> 6;
    ObjStart++;

    /* read the object data fragment */
    CurObj->ObjData.DataLength = (*ObjStart) << 16 | ((*(ObjStart+1)) << 8) | (*(ObjStart+2));
    CurObj->ObjData.Width = MAKE_WORD(ObjStart+3);  /* could add paranoia check here on do_update */
    CurObj->ObjData.Height = MAKE_WORD(ObjStart+5); /* could add paranoia check here on do_update */
    ObjStart+=7;

    /* how big is the image? */
    OutputSize = CurObj->ObjData.Width * CurObj->ObjData.Height;

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

#ifdef ALLOW_IG_PROFILING
        if (IGStats.Profiling == 1)
        {
            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), ("IGLoadObject(): Failed to Lock LUT8 Surface\n"));
            goto errout;
        }

        /* RLE decode into the surface */
        if (IG_STATUS_SUCCESS != IGRLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
            CurObj->pitch, CurObj->ObjData.Width, IGInfo.CoordsHalfWidth))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to RLE decode the image\n"));
            goto errout;
        }

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

            if (IGInfo.CoordsHalfWidth)
            {
                IGStats.TotalPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
            }
            else
            {
                IGStats.TotalPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
            }
        }
#endif
    }
    else
    {
        /* fill in the surface pointers */
        desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_DFBPALETTEHANDLE);
        desc.pixelformat = DSPF_LUT8;
        if (IGInfo.CoordsHalfWidth == 0)
        {
            desc.width = CurObj->ObjData.Width;
        }
        else
        {
            /* add one to account for odd width images */
            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 = IGPalettes[0].DFBPal;

        /* create palettized surface */
        if (IG_STATUS_SUCCESS != IGGraphicsCreateLUT8Surface(&desc, CurObj))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to Create LUT8 Surface\n"));
            return IG_STATUS_ERROR;
        }

#ifdef ALLOW_IG_PROFILING
        if (IGStats.Profiling == 1)
        {
            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), ("IGLoadObject(): Failed to Lock LUT8 Surface\n"));
            return IG_STATUS_ERROR;
        }

        /* RLE decode into the surface */
        if (IG_STATUS_SUCCESS != IGRLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
            CurObj->pitch, CurObj->ObjData.Width, IGInfo.CoordsHalfWidth))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to RLE decode the image\n"));
            return IG_STATUS_ERROR;
        }

        /* unlock the surface */
        if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed Unlock LUT8 surface\n"));
            return IG_STATUS_ERROR;
        }
#ifdef ALLOW_IG_PROFILING
        if (IGStats.Profiling == 1)
        {
            IGStats.TotalRLETicks += OS_GetTicks() - TickStart;

            if (IGInfo.CoordsHalfWidth)
            {
                IGStats.TotalPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
            }
            else
            {
                IGStats.TotalPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
            }
        }
#endif

        gIGDecodedObjectBuffUsed += OutputSize;
    }

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

    return IG_STATUS_SUCCESS;

errout:

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

    CurObj->InUse = 0;

    return IG_STATUS_ERROR;
}


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

            /* clear ODS memory */
            memset(&IGObjList[i], 0, sizeof(OBJECT_DEFINITION_SEGMENT));
        }
    }

    /* all of the decoded object buffer is free now */
    gIGDecodedObjectBuffUsed = 0;
}

/**
 * IGClearPalettes - clear all the palette memory to the Clear Color (0xFF)
 *
 * @return VOID
 */
void IGClearPalettes()
{
    for (int i=0; i<IG_MAX_PALETTES; i++)
    {
        /* set all palette colors to transparent */
        memset(IGPalettes[i].Colors, 0xFF, IG_MAX_PALETTE_COLORS * sizeof(DFBColor));
        IGPalettes[i].PaletteVersion = 0;
    }
}

/**
 * IGFlushParseQ - clear all messages from the parse Queue
 *
 * @return VOID
 */
IG_STATUS IGFlushParseQ()
{
    IG_PARSE_MSG *pMessage;

    while (1)
    {
        /* Get a stream message */
        pMessage = (IG_PARSE_MSG *)IGInfo.IGParseQ->Read(OS_NO_WAIT);
        if (pMessage)
        {
            IGInfo.IGParseQ->ReleaseMsg(pMessage);
            pMessage=NULL;
        }
        else
        {
            break;
        }
    }

    return IG_STATUS_SUCCESS;
}


/**
 * IGFlushRenderQ - clear all messages from the render Queue
 *
 * @return VOID
 */
IG_STATUS IGFlushRenderQ()
{
    IG_RENDER_MSG *pMessage;

    while (1)
    {
        /* Get a stream message */
        pMessage = (IG_RENDER_MSG *)IGInfo.IGRenderQ->Read(OS_NO_WAIT);
        if (pMessage)
        {
            /* free memory */
            if (pMessage->ICS)
            {
                IGFreeICS(pMessage->ICS);
                pMessage->ICS = NULL;
            }

            IGInfo.IGRenderQ->ReleaseMsg(pMessage);
            pMessage = NULL;
        }
        else
        {
            break;
        }
    }

    return IG_STATUS_SUCCESS;
}

/**
 * IGFlush - called during a IGStop(), clears all object lists and resets the parser
 *
 * @return VOID
 */
IG_STATUS IGFlush()
{
    /* flush the parseQ and RenderQ */
    IGFlushParseQ();
    IGFlushRenderQ();

    /* wait for the parser to be free */
    while (gIGParserWaiting == 0)
    {
        OS_SemGive(IGInfo.RenderWait.WaitSem);
        OS_SemGive(IGInfo.ParseWait.WaitSem);
        OS_TaskYield();
    }

    /* no composition or selection timeouts */
    IGInfo.CompositionTimeoutPTS = 0;
    IGInfo.SelectionTimeoutPTS = 0;

    /* take the ics lock to clear the renderer */
    OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);

    /* cancel all timers */
    OS_TimerStop(IGInfo.TimerAnimation);
    OS_TimerStop(IGInfo.TimerUserSelection);

    /* clear the IGInfo structure */
    if (IGInfo.ICS)
    {
        /* fire event */
        IGToPEICSInValid();
        IGFreeICS(IGInfo.ICS);
        IGInfo.ICS = NULL;
    }
    IGInfo.ActivePage = NULL;
    IGInfo.SelectedButton = NULL;

    /* clear out all the objects in our list */
    IGFreeObjects();

    /* clear our palettes */
    IGClearPalettes();

    /* reset the graphics plane */
    IGGraphicsClearBuffer(NULL, 0);
    OS_TimerSet(IGInfo.TimerFlip, 1);
    OS_TaskYield();

    OS_SemGive(IGInfo.ICSLock);

    return IG_STATUS_SUCCESS;
}

/**
 * IGWaitForDTS - wait for a DTS value to show up so we can decode a segment
 *
 * @return VOID
 */
IG_STATUS IGWaitForDTS(ULONG DTS)
{
    /* first check if the time has already passed that we want, if so just return */
    if (IGInfo.CurPTS < DTS)
    {
        if (IGInfo.SyncState == IG_DECODE_SYNC)
        {
            /* setup the ParseWait IG_WAIT_TIME_SEM to block and wait for the PTS we want */
            IGInfo.ParseWait.WaitPTS = DTS;

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

            IGInfo.ParseWait.WaitPTS = 0;
        }
    }

    return (IG_STATUS_SUCCESS);
}

⌨️ 快捷键说明

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