DirectDraw播放中BLT failed与Lock失败问题

DirectDraw播放中BLT failed与Lock失败问题

编者:李国帅

qq:9611153 微信lgs9611153

时间:2009-10-13 03:07下午

背景原因:

这是一个曾经遇到的播放问题,并不会造成严重问题。发生在win32的年代,一个曾经的记忆。

 

所需资源:

VC,DirectDraw

问题描述:

在其它的机器上出现了以下错误,奇怪的现象

(1)频繁出现BLT failed

 

BLT failed ddrval=-2147467259. dstRect(745,763;1005,983) //FFFFFFFF 0x80004005l //FFFFFFFF80004005

2009/09/01 07:16:51       BLT failed ddrval=-2147467259. dstRect(761,97;1013,322)

blt 出现E_FAIL错误,很经常。已经进行了锁定。

 

没有图像可能与pullid(播放流标记)得到的数据有关系?播放过程中出现间接中断并继续,说明不是因为pullid发生了改变。

blt贴图失败,能不能不进行提示,使用try把错误扔掉。

         贴图失败不会导致程序出错,出错的原因是其他的问题。

看是不是越界  一般blt失败就是越界Blt到不该Blt的地方了,曾经有过copymemory错误,但是只要锁定成功就不会了。

 

(2)出现lock失败

 

Lock又出现失败的情况了,在一台新机器上,没有安装显卡。

播放器后备缓冲在锁定缓冲区的时候出现了无数的lock失败,不是显卡问题。

CUtil::Instance()->DbgFilePrintf(L"TSPlayer",_T("LockBuffer Backsurface Lock Failed. ddrval=%d."),ddrval);

2009/10/14 14:53:44       TSPlayer: LockBuffer Backsurface Lock Failed. ddrval=-2005532222.//FFFFFFFF887601C2

 

这个问题不会导致程序出现异常错误。

unsigned char* CDisplayHandle::LockBuffer(LPDIRECTDRAWSURFACE7 lpddsBack)

{

    ATLASSERT (lpddsBack != NULL);

    if(lpddsBack == NULL) return NULL;

 

    //DDLOCK_SURFACEMEMORYPTR

    HRESULT ddrval;

    DDSURFACEDESC2 ddsd;

    ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));

    ddsd.dwSize = sizeof(DDSURFACEDESC2);

    //ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);

    //ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;

    //ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;

    //ddsd.dwHeight = Height;

    //ddsd.dwWidth = Width;

    //ddsd.dwFlags |= DDSD_PIXELFORMAT;

    //ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;

    //ddsd.ddpfPixelFormat.dwFourCC = SubType.Data1;

 

    ddrval = lpddsBack->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WRITEONLY/* | DDLOCK_WAIT*/, NULL);

    if (FAILED(ddrval))//if (ddrval != DD_OK)

    {

        if (ddrval == DDERR_INVALIDPARAMS)

        {

            ddrval = lpddsBack->Lock(NULL, &ddsd, /*DDLOCK_WAIT |*/ DDLOCK_WRITEONLY, NULL);

        }

        if (ddrval == DDERR_SURFACELOST)

        {

            lpddsBack->Restore(); //已经Restore但还是无法锁定。

            ddrval = lpddsBack->Lock(NULL, &ddsd, /*DDLOCK_WAIT |*/ DDLOCK_WRITEONLY, NULL);

        }

    }

    //ATLASSERT(SUCCEEDED(ddrval));

    if (FAILED(ddrval))//if (ddrval != DD_OK)

    {

        CUtil::Instance()->DbgFilePrintf(L"TSClient",_T("TSPlayer: LockBuffer Backsurface Lock Failed. ddrval=0x%X."),ddrval);

        return NULL;

    }

    unsigned char* pBuffer = NULL;

    pBuffer = (unsigned char*)ddsd.lpSurface;

    ATLASSERT(pBuffer != NULL);

    if(pBuffer == NULL)lpddsBack->Unlock(NULL);

 

    return pBuffer;

}

 

 

 

可能的原因:

 

在后期处理程序的时候也出现,原因是cpu和内存使用量过大,导致计算错误。

程序在运行过程中,突然出现BLT failed,程序开始响应缓慢,出现问题。

2010/01/27 22:39:39       **Player:  BLT failed ddrval=0X80004005. dstRect(218,234;426,371)

2010/01/27 22:39:39       **Player:  BLT failed ddrval=0X80004005. dstRect(428,512;637,649)

2010/01/27 22:39:39       **Player:  BLT failed ddrval=0X80004005. dstRect(218,96;426,232)

2010/01/27 22:39:39       **Player:  BLT failed ddrval=0X80004005. dstRect(428,234;637,371)

2010/01/29 09:16:04       *** fail for (BYTE*)malloc(262144) failed.

 

 

参考

 

/* * Display hardware is capable of bltting to or from system memory */

#define   DDERR_GENERIC       E_FAIL

#define   E_FAIL        _HRESULT_TYPEDEF_(0x80004005L)

#define   DDERR_NOZBUFFERHW   MAKE_DDHRESULT(340)

#define   MAKE_DDHRESULT(code) MAKE_HRESULT(1,_FACDD,code)

#define MAKE_HRESULT(sev,fac,code) \

  ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )

#define MAKE_SCODE(sev,fac,code) \

  ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )

 

#define _FACDD  0x876

#define MAKE_DDHRESULT( code )  MAKE_HRESULT( 1, _FACDD, code )

/*DDERR_SURFACEBUSY Access to this surface is being refused because the surface is already locked by another thread. */

/*DDERR_SURFACELOST Access to this surface is being refused because the surface is gone.

 * The DIRECTDRAWSURFACE object representing this surface should have Restore called on it. */

 

#define DDERR_SURFACEBUSY   MAKE_DDHRESULT( 430 ) = ((1<<31) | (0x876)<<16 | 430 ) = 0x887601ae

#define DDERR_SURFACELOST   MAKE_DDHRESULT( 450 ) = 0x887601C2

 

 

猜你喜欢

转载自blog.csdn.net/lgs790709/article/details/86674439