示例#1
0
static IDirectDrawSurface* GetBlitSurface()
{
  IDirectDrawSurface* blitSurface;

  if(PrimarySurfaceVersion < 4)
  {
    IDirectDrawSurface *surf = (IDirectDrawSurface *) PrimarySurface;

    DDSURFACEDESC ddsd;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    if(FAILED(surf->GetSurfaceDesc(&ddsd)))
      printLog("video: can't get surface desc\n");
    else
    {
      ddsd.dwWidth = captureWidth;
      ddsd.dwHeight = captureHeight;

      ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
      ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
      IDirectDraw *dd = (IDirectDraw *) PrimaryDDraw;
      if(FAILED(dd->CreateSurface(&ddsd,&blitSurface,0)))
        printLog("video: could not create blit target\n");
    }
  }
  else
  {
    IDirectDrawSurface4 *srf4 = (IDirectDrawSurface4 *) PrimarySurface;

    DDSURFACEDESC2 ddsd;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    if(FAILED(srf4->GetSurfaceDesc(&ddsd)))
      printLog("video: can't get surface desc\n");
    else
    {
      ddsd.dwWidth = captureWidth;
      ddsd.dwHeight = captureHeight;

      ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
      ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
      ddsd.ddsCaps.dwCaps2 = 0;
      IDirectDraw4 *dd = (IDirectDraw4 *) PrimaryDDraw;
      if(FAILED(dd->CreateSurface(&ddsd,(IDirectDrawSurface4 **) &blitSurface,0)))
        printLog("video: could not create blit target\n");
    }
  }

  return blitSurface;
}
示例#2
0
  bool SetFormatFromSurface(IUnknown *surfPtr)
  {
    IDirectDrawSurface *surf = (IDirectDrawSurface *) surfPtr;

    DDPIXELFORMAT fmt;
    ZeroMemory(&fmt,sizeof(fmt));
    fmt.dwSize = sizeof(fmt);

    if(FAILED(surf->GetPixelFormat(&fmt)))
    {
      printLog("video: can't get pixel format\n");
      return false;
    }

    SetFormat(&fmt);
    if(IsPaletted())
      UpdatePalette();

    return true;
  }
示例#3
0
static void PrimarySurfaceCreated(IUnknown *ddraw,IUnknown *srfp,int ver)
{
  PrimaryDDraw = ddraw;
  PrimarySurface = srfp;
  PrimarySurfaceVersion = ver;

  if(PrimarySurfaceVersion < 4)
  {
    IDirectDrawSurface *surf = (IDirectDrawSurface *) PrimarySurface;

    DDSURFACEDESC ddsd;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    if(FAILED(surf->GetSurfaceDesc(&ddsd)))
      printLog("video: can't get surface desc\n");
    else
    {
      if(captureWidth != ddsd.dwWidth || captureHeight != ddsd.dwHeight)
        setCaptureResolution(ddsd.dwWidth,ddsd.dwHeight);
    }
  }
  else
  {
    IDirectDrawSurface4 *srf4 = (IDirectDrawSurface4 *) PrimarySurface;

    DDSURFACEDESC2 ddsd;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    if(FAILED(srf4->GetSurfaceDesc(&ddsd)))
      printLog("video: can't get surface desc\n");
    else
    {
      if(captureWidth != ddsd.dwWidth || captureHeight != ddsd.dwHeight)
        setCaptureResolution(ddsd.dwWidth,ddsd.dwHeight);
    }
  }

  graphicsInitTiming();
}
示例#4
0
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();
}
示例#5
0
////////////////////////////////////////////////////////////////////////////
//
// @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;
}
void update_screen() {
    IDirectDrawSurface *dst;
    RECT dstRect;
    RECT srcRect;
    HRESULT hr;
    POINT pt;

    // NTS: dx_bitmap.is_valid() is not a valid test because base==canvas==NULL unless surface is locked
    if (ddsurfaceBMP == NULL) return;

    // NTS: We must provide a source rect, else Windows XP in 24bpp mode will conveniently choose to render the
    //      right half (where extra padding+junk exist) rather than from the left side. Provide a source rect
    //      to make it 100% clear which part of the surface we want blitted to screen.
    pt.x = pt.y = 0;
    ClientToScreen(hwndMain,&pt);
    GetClientRect(hwndMain,&dstRect);
    OffsetRect(&dstRect,pt.x,pt.y);
    srcRect.top = srcRect.left = 0;
    srcRect.right = dx_bitmap.width;
    srcRect.bottom = dx_bitmap.height;

    if (ddsurfaceGDI != NULL)
        dst = ddsurfaceGDI;
    else if (ddsurfacePrimary != NULL)
        dst = ddsurfacePrimary;
    else
        dst = NULL;

    if (dst != NULL)
        hr = dst->Blt(&dstRect,ddsurfaceBMP,&srcRect,0,NULL);
    else
        hr = DD_OK;

    if (hr == DDERR_SURFACELOST) {
        fprintf(stderr,"Whoops, the primary surface was lost.\n");
        if ((hr=dst->Restore()) != DD_OK) {
            fprintf(stderr,"Unable to restore surface hr=0x%08lx.\n",hr);
            unlock_bitmap();
            free_bitmap();
            free_dx_primary_surface();
            init_dx_primary_surface();

            RECT rct;
            GetClientRect(hwndMain,&rct);

            if (!init_bitmap(rct.right,rct.bottom))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                        (unsigned int)rct.right,(unsigned int)rct.bottom);

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
        }
    }
    else if (hr != DD_OK) {
        fprintf(stderr,"DirectX blit failed, HR=0x%08lx\n",hr);
    }
}
示例#7
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;
  }