示例#1
0
        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);
        }