static void ImplementFlip(IUnknown *surf,int version) { IDirectDrawSurface *back = 0; videoNeedEncoder(); if(params.CaptureVideo) { if(version < 4) { DDSCAPS caps; ZeroMemory(&caps,sizeof(caps)); caps.dwCaps = DDSCAPS_BACKBUFFER; ((IDirectDrawSurface *) surf)->GetAttachedSurface(&caps,&back); } else { DDSCAPS2 caps; ZeroMemory(&caps,sizeof(caps)); caps.dwCaps = DDSCAPS_BACKBUFFER; ((IDirectDrawSurface4 *) surf)->GetAttachedSurface(&caps,(IDirectDrawSurface4 **) &back); } if(back) { VideoCaptureDataLock lock; if(Blitter.BlitSurfaceToCapture(back,version)) encoder->WriteFrame(captureData); back->Release(); } } nextFrame(); }
//////////////////////////////////////////////////////////////////////////// // // @mfunc | CVisRefCntMemBlock | ~CVisRefCntMemBlock | // // Destructor called when this object is destroyed. If this // object allocated memory in its constructor, that memory // will be freed when the destructor is called. The destructor // is virtual so that other classes can be derived from this // class. // //////////////////////////////////////////////////////////////////////////// CVisRefCntMemBlock::~CVisRefCntMemBlock(void) { #ifdef _DEBUG if (m_pbData != 0) { // Decrement the count of blocks of this type. if ((m_evismemblock != evismemblockAllocFileMapping) && (m_evismemblock != evismemblockAllocGlobalAlloc) #ifdef VIS_MEMBLOCK_USE_IMALLOC && (m_evismemblock != evismemblockAllocIMalloc) #endif // VIS_MEMBLOCK_USE_IMALLOC && (m_evismemblock != evismemblockAllocNewDouble)) { -- s_cBlockExternal; s_cbExternalTotal -= m_cbData; } else { assert((m_evismemblock > 0) && (m_evismemblock <= cMemBlockAllocators)); -- s_cBlockAlloc[m_evismemblock]; s_cbAllocTotal[m_evismemblock] -= m_cbData; } // Ref count may not be zero if delete is used to destroy this // object. s_cAddRefTotal -= m_cRef; // Remove this memory block to the globals list of all memory blocks // currently in use. HANDLE hMutex = CreateMutex(0, FALSE, "CVisRefCntMemBlockDebugMutex"); assert(hMutex != 0); VisWaitForSingleObject(hMutex, INFINITE); CVisRefCntMemBlock *pRefCntMemBlockPrev = 0; CVisRefCntMemBlock *pRefCntMemBlock = s_pRefCntMemBlockFirst; while ((pRefCntMemBlock != this) && (pRefCntMemBlock != 0)) { pRefCntMemBlockPrev = pRefCntMemBlock; pRefCntMemBlock = pRefCntMemBlock->m_pRefCntMemBlockNext; } if (pRefCntMemBlock != 0) { if (pRefCntMemBlockPrev == 0) { s_pRefCntMemBlockFirst = m_pRefCntMemBlockNext; m_pRefCntMemBlockNext = 0; } else { pRefCntMemBlockPrev->m_pRefCntMemBlockNext = m_pRefCntMemBlockNext; m_pRefCntMemBlockNext = 0; } } ReleaseMutex(hMutex); CloseHandle(hMutex); } #endif // _DEBUG if (m_evismemblock == evismemblockAllocFileMapping) { // Free memory allocated using CreateFileMapping. assert(m_pbData != 0); UnmapViewOfFile(m_pbData); CloseHandle(m_hFileMapping); m_hFileMapping = 0; } else if (m_evismemblock == evismemblockAllocNewDouble) { // Free memory allocated using operator new. delete [] (double *) m_pbData; } else if (m_evismemblock == evismemblockAllocGlobalAlloc) { // Free memory allocated using GlobalAlloc. GlobalFree(m_pbData); } #ifdef VIS_MEMBLOCK_USE_IMALLOC else if (m_evismemblock == evismemblockAllocIMalloc) { // Allocate memory using the OLE task allocator. CoTaskMemFree(m_pbData); } #endif // VIS_MEMBLOCK_USE_IMALLOC else if (m_evismemblock == evismemblockAllocDirectDrawSurface) { // Release memory allocated using DirectDrawSurface assert(m_pvUser != 0); IDirectDrawSurface* pDDS = (IDirectDrawSurface *)m_pvUser; pDDS->Release(); } else if (m_pfnCallback != 0) { m_pfnCallback(m_pbData, m_pvUser); } m_pbData = 0; }
bool BlitSurfaceToCapture(IDirectDrawSurface *surf,int version) { IDirectDrawSurface* blitSurface = GetBlitSurface(); if(!blitSurface || !SetFormatFromSurface(surf)) return false; // blit backbuffer to our readback surface RECT rc; rc.left = 0; rc.top = 0; rc.right = captureWidth; rc.bottom = captureHeight; if(FAILED(blitSurface->Blt(&rc,surf,&rc,DDBLT_WAIT,0))) { printLog("video: blit failed\n"); return false; } LPBYTE surface; DWORD pitch; if(version < 4) { DDSURFACEDESC ddsd; ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); if(FAILED(blitSurface->Lock(0,&ddsd,DDLOCK_WAIT,0))) { printLog("video: can't lock surface\n"); return false; } surface = (LPBYTE) ddsd.lpSurface; pitch = ddsd.lPitch; } else { IDirectDrawSurface4 *srf4 = (IDirectDrawSurface4 *) blitSurface; DDSURFACEDESC2 ddsd; ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); if(FAILED(srf4->Lock(0,&ddsd,DDLOCK_WAIT,0))) { printLog("video: can't lock surface\n"); return false; } surface = (LPBYTE) ddsd.lpSurface; pitch = ddsd.lPitch; } // blit individual lines for(int y=0;y<captureHeight;y++) { unsigned char *src = surface + (captureHeight-1-y) * pitch; unsigned char *dst = captureData + y * captureWidth * 3; BlitOneLine(src,dst,captureWidth); } blitSurface->Unlock(surface); blitSurface->Release(); return true; }