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
|