public int InitializeDevice(System.IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) { int hr = 0; int width = 1; int height = 1; Debug.Assert(dwUserID == cookie, "IVMRSurfaceAllocatorEx9.InitializeDevice"); InitializeDeviceCount++; dstRect = new DsRect(0, 0, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight); try { if (device.DeviceCaps.TextureCaps.SupportsPower2) { while (width < lpAllocInfo.dwWidth) { width = width << 1; } while (height < lpAllocInfo.dwHeight) { height = height << 1; } lpAllocInfo.dwWidth = width; lpAllocInfo.dwHeight = height; } lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; unmanagedSurfaces = new IntPtr[lpNumBuffers]; hr = surfaceAllocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, unmanagedSurfaces); DsError.ThrowExceptionForHR(hr); // Assume this call works (ie Hardware new enough to create a TextureSurface : dx7 video board or better) // This test also doesn't support YUV surfaces creation } //catch (DirectXException dxe) //{ // return dxe.ErrorCode; //} catch (COMException e) { return(e.ErrorCode); } return(0); }
/// <summary> /// The InitializeDevice method is called by the Video Mixing Renderer 9 (VMR-9) /// when it needs the allocator-presenter to allocate surfaces. /// </summary> /// <param name="userId"> /// Application-defined identifier. This value is the same value that the application /// passed to the IVMRSurfaceAllocatorNotify9.AdviseSurfaceAllocator method in the /// dwUserID parameter. /// </param> /// <param name="lpAllocInfo"> /// Pointer to a VMR9AllocationInfo structure that contains a description of the surfaces to create. /// </param> /// <param name="lpNumBuffers"> /// On input, specifies the number of surfaces to create. When the method returns, /// this parameter contains the number of buffers that were actually allocated. /// </param> /// <returns>Returns an HRESULT code</returns> public int InitializeDevice(IntPtr userId, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) { if (m_allocatorNotify == null) { return(E_FAIL); } try { int hr; lock (m_staticLock) { /* These two pointers are passed to the the helper * to create our D3D surfaces */ var pDevice = GetComPointer(m_device); var pMonitor = GetAdapterMonitor(0); /* Setup our D3D Device with our renderer */ hr = m_allocatorNotify.SetD3DDevice(pDevice, pMonitor); DsError.ThrowExceptionForHR(hr); /* This is only used if the AllocateSurfaceHelper is used */ lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; /* Make sure our old surfaces are free'd */ FreeSurfaces(); /* This is an IntPtr array of pointers to D3D surfaces */ DxSurfaces = new IntPtr[lpNumBuffers]; /* This is where the magic happens, surfaces are allocated */ hr = m_allocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, DxSurfaces); if (hr < 0) { FreeSurfaces(); if (lpAllocInfo.Format > 0) { hr = m_device.CreateTexture(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, 1, 1, D3DFORMAT.D3DFMT_X8R8G8B8, 0, out m_privateTexture, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); hr = m_privateTexture.GetSurfaceLevel(0, out m_privateSurface); DsError.ThrowExceptionForHR(hr); } lpAllocInfo.dwFlags &= ~VMR9SurfaceAllocationFlags.TextureSurface; lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; DxSurfaces = new IntPtr[lpNumBuffers]; hr = m_allocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, DxSurfaces); if (hr < 0) { FreeSurfaces(); return(hr); } } } /* Nofity to our listeners we have new surfaces */ InvokeNewSurfaceEvent(m_privateSurface != null ? GetComPointer(m_privateSurface) : DxSurfaces[0]); return(hr); } catch { return(E_FAIL); } }
public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) { int hr = 0; Debug.WriteLine(string.Format("{0}x{1} : {2} / {3} / 0x{4:x}", lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, FourCCToStr(lpAllocInfo.Format), lpAllocInfo.Pool, lpAllocInfo.dwFlags)); // if format is YUV ? (note : 0x30303030 = " ") if (lpAllocInfo.Format > 0x30303030) { // Check if the hardware support format conversion from this YUV format to the RGB desktop format if (!D3D.CheckDeviceFormatConversion(creationParameters.AdapterOrdinal, creationParameters.DeviceType, (Format)lpAllocInfo.Format, adapterInfo.CurrentDisplayMode.Format)) { // If not, refuse this format! // The VMR9 will propose other formats supported by the downstream filter output pin. return(D3DERR_INVALIDCALL); } } try { IntPtr unmanagedDevice = device.ComPointer; IntPtr hMonitor = D3D.GetAdapterMonitor(adapterInfo.Adapter); // Give our Direct3D device to the VMR9 filter hr = vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); DsError.ThrowExceptionForHR(hr); videoSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight); int width = 1; int height = 1; // If hardware require textures to power of two sized if ((device.Capabilities.TextureCaps & TextureCaps.Pow2) == TextureCaps.Pow2) { // Compute the ideal size while (width < lpAllocInfo.dwWidth) { width = width << 1; } while (height < lpAllocInfo.dwHeight) { height = height << 1; } // notify this change to the VMR9 filter lpAllocInfo.dwWidth = width; lpAllocInfo.dwHeight = height; } textureSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight); // Just in case DeleteSurfaces(); // if format is YUV ? if (lpAllocInfo.Format > 0x30303030) { // An offscreen surface must be created lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; // Create it videoSurface = Surface.CreateOffscreenPlain(device, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, (Format)lpAllocInfo.Format, (Pool)lpAllocInfo.Pool); // And get it unmanaged pointer unmanagedSurface = videoSurface.ComPointer; // Then create a private texture for the client application privateTexture = new Texture( device, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, 1, Usage.RenderTarget, adapterInfo.CurrentDisplayMode.Format, Pool.Default ); // Get the MipMap surface 0 for the copy (see PresentImage) privateSurface = privateTexture.GetSurfaceLevel(0); // This code path need a surface copy needCopy = true; } else { // in RGB pixel format lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; // Simply create a texture privateTexture = new Texture( device, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, 1, Usage.RenderTarget, adapterInfo.CurrentDisplayMode.Format, Pool.Default ); // And get the MipMap surface 0 for the VMR9 filter privateSurface = privateTexture.GetSurfaceLevel(0); unmanagedSurface = privateSurface.ComPointer; // This code path don't need a surface copy. // The client appllication use the same texture the VMR9 filter use. needCopy = false; } // This allocator only support 1 buffer. // Notify the VMR9 filter lpNumBuffers = 1; } catch (SlimDXException e) { // A Direct3D error can occure : Notify it to the VMR9 filter return(e.ResultCode.Code); } catch { // Or else, notify a more general error return(E_FAIL); } // This allocation is a success return(0); }
public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) { int width = 1; int height = 1; float fTU = 1.0f; float fTV = 1.0f; if (vmrSurfaceAllocatorNotify == null) { return(E_FAIL); } int hr = 0; try { IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber); IntPtr hMonitor = Manager.GetAdapterMonitor(adapterInfo.Adapter); hr = vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor); DsError.ThrowExceptionForHR(hr); if (device.DeviceCaps.TextureCaps.SupportsPower2) { while (width < lpAllocInfo.dwWidth) { width = width << 1; } while (height < lpAllocInfo.dwHeight) { height = height << 1; } fTU = (float)(lpAllocInfo.dwWidth) / (float)(width); fTV = (float)(lpAllocInfo.dwHeight) / (float)(height); scene.SetSrcRect(fTU, fTV); lpAllocInfo.dwWidth = width; lpAllocInfo.dwHeight = height; } // NOTE: // we need to make sure that we create textures because // surfaces can not be textured onto a primitive. lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; DeleteSurfaces(); unmanagedSurfaces = new IntPtr[lpNumBuffers]; hr = vmrSurfaceAllocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, unmanagedSurfaces); // If we couldn't create a texture surface and // the format is not an alpha format, // then we probably cannot create a texture. // So what we need to do is create a private texture // and copy the decoded images onto it. if (hr < 0) { DeleteSurfaces(); FourCC fcc = new FourCC("0000"); // is surface YUV ? if (lpAllocInfo.Format > fcc.ToInt32()) { // create the private texture privateTexture = new Texture( device, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, 1, Usage.RenderTarget, adapterInfo.CurrentDisplayMode.Format, Pool.Default ); privateSurface = privateTexture.GetSurfaceLevel(0); } lpAllocInfo.dwFlags &= ~VMR9SurfaceAllocationFlags.TextureSurface; lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; unmanagedSurfaces = new IntPtr[lpNumBuffers]; hr = vmrSurfaceAllocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, unmanagedSurfaces); if (hr < 0) { return(hr); } } else { surfaces = new Hashtable(unmanagedSurfaces.Length); textures = new Hashtable(unmanagedSurfaces.Length); for (int i = 0; i < lpNumBuffers; i++) { Surface surf = new Surface(unmanagedSurfaces[i]); Texture text = (Texture)surf.GetContainer(new Guid("85C31227-3DE5-4f00-9B3A-F11AC38C18B5")); surfaces.Add(unmanagedSurfaces[i], surf); textures.Add(unmanagedSurfaces[i], text); } } return(scene.Init(device)); } catch (DirectXException e) { return(e.ErrorCode); } catch { return(E_FAIL); } }