/// <summary>To be documented.</summary>
        public readonly unsafe int GetFrontBufferData(IDirect3DSurface9 *pDestSurface)
        {
            var @this = (IDirect3DSwapChain9 *)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
            int ret   = default;

            ret = ((delegate * unmanaged[Cdecl] < IDirect3DSwapChain9 *, IDirect3DSurface9 *, int >)LpVtbl[4])(@this, pDestSurface);
            return(ret);
        }
        /// <summary>To be documented.</summary>
        public readonly unsafe int GetSurfaceLevel(uint Level, ref IDirect3DSurface9 *ppSurfaceLevel)
        {
            var @this = (IDirect3DTexture9 *)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
            int ret   = default;

            fixed(IDirect3DSurface9 **ppSurfaceLevelPtr = &ppSurfaceLevel)
            {
                ret = ((delegate * unmanaged[Cdecl] < IDirect3DTexture9 *, uint, IDirect3DSurface9 **, int >)LpVtbl[18])(@this, Level, ppSurfaceLevelPtr);
            }

            return(ret);
        }
Beispiel #3
0
 public unsafe Surface(IDirect3DSurface9 *lp, object device) : base((IntPtr)lp)
 {
     throw new NotImplementedException();
 }
Beispiel #4
0
 public unsafe Surface(IDirect3DSurface9 *pInterop) : base((IntPtr)null)
 {
     throw new NotImplementedException();
 }
Beispiel #5
0
 public unsafe void UpdateUnmanagedPointer(IDirect3DSurface9 *pInterface)
 {
     throw new NotImplementedException();
 }
        /// <summary>To be documented.</summary>
        public readonly unsafe int GetCubeMapSurface(CubemapFaces FaceType, uint Level, ref IDirect3DSurface9 *ppCubeMapSurface)
        {
            var @this = (IDirect3DCubeTexture9 *)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
            int ret   = default;

            fixed(IDirect3DSurface9 **ppCubeMapSurfacePtr = &ppCubeMapSurface)
            {
                ret = ((delegate * unmanaged[Cdecl] < IDirect3DCubeTexture9 *, CubemapFaces, uint, IDirect3DSurface9 **, int >)LpVtbl[18])(@this, FaceType, Level, ppCubeMapSurfacePtr);
            }

            return(ret);
        }
        public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers)
        {
            lock (this)
            {
                log.InfoFormat("DirectShowCodec[{0}]: {1}x{2} : {3} / {4} / {5} / {6} / 0x{7:x}", ID,
                               lpAllocInfo.dwWidth, lpAllocInfo.dwHeight,
                               FourCCToStr(lpAllocInfo.Format),
                               adapterInfo.CurrentDisplayMode.Format,
                               lpAllocInfo.MinBuffers,
                               (Pool)lpAllocInfo.Pool,
                               lpAllocInfo.dwFlags);

                Axiom.Media.PixelFormat texFormat = D3DHelper.ConvertEnum(adapterInfo.CurrentDisplayMode.Format);
                Format format = (Format)lpAllocInfo.Format;

                // if format is YUV ? (note : 0x30303030 = "    ")
                if (lpAllocInfo.Format > 0x30303030)
                {
                    // NV12 textures appear not to play correctly; when using them with an
                    // offscreen surface, they only show the first frame or so.  Doing this
                    // should cause it to renegotiate to RGB.
                    //
                    // New and improved: YV12 seems to have the same problem.
                    if (
                        (lpAllocInfo.Format == StrToFourCC("NV12")) ||
                        (lpAllocInfo.Format == StrToFourCC("YV12"))
                        )
                    {
                        // XXXMLM - this may cause us to pop an external window
                        log.WarnFormat("DirectShowCodec[{0}]: Rejecting {1} format", ID, FourCCToStr(lpAllocInfo.Format));
                        return D3DERR_INVALIDCALL;
                    }

                    // Check if the hardware support format conversion from this YUV format to the RGB desktop format
                    if (!D3D.Manager.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.
                        log.WarnFormat("DirectShowCodec[{0}]: Cannot convert between formats", ID);
                        return D3DERR_INVALIDCALL;
                    }
                }
                try
                {
                    IDirect3DDevice9* unmanagedDevice = device.UnmanagedComPointer;
                    IntPtr hMonitor = D3D.Manager.GetAdapterMonitor(adapterInfo.Adapter);

                    // Give our Direct3D device to the VMR9 filter
                    try
                    {
                        IVMRSurfaceAllocatorNotify9 notify9 = vmrSurfaceAllocatorNotify;
                        vmrSurfaceAllocatorNotify.SetD3DDevice((IntPtr)unmanagedDevice, hMonitor);
                    }
                    catch (InvalidCastException e)
                    {
                        // It turns out that if this function is called from the
                        // decoder thread, the hr return value of the SetD3DDevice
                        // call will be E_INVALIDCAST.  However, if we've already
                        // notified the allocator notify interface of the device,
                        // the rest of this function will happen correctly.  So
                        // only throw the exception if we haven't notified the
                        // device yet.
                        if ((IntPtr)unmanagedDevice != notifiedDevice)
                        {
                            throw e;
                        }
                    }
                    notifiedDevice = (IntPtr)unmanagedDevice;

                    videoSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight);
                    videoRectangle = new Rectangle(Point.Empty, videoSize);

                    // Always do power of two sized textures
                    lpAllocInfo.dwWidth = Manager.NextPowerOfTwo(lpAllocInfo.dwWidth);
                    lpAllocInfo.dwHeight = Manager.NextPowerOfTwo(lpAllocInfo.dwHeight);

                    textureSize = new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight);

                    // Just in case
                    DeleteSurfaces();

                    // if format is YUV ?
                    if (lpAllocInfo.Format > 0x30303030)
                    {
                        log.InfoFormat("DirectShowCodec[{0}]: Creating offscreen surface ({1}x{2})",
                                       ID, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight);

                        // An offscreen surface must be created
                        lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface;

                        // Create it
                        try
                        {
                            // ATI and nVidia both fail this call when created with YUV, so ask for
                            // an RGB texture first if we can get away with it.
                            if ((lpAllocInfo.dwFlags & VMR9SurfaceAllocationFlags.RGBDynamicSwitch) != 0)
                            {
                                videoSurface = device.CreateOffscreenPlainSurface(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight,
                                    adapterInfo.CurrentDisplayMode.Format, (Pool)lpAllocInfo.Pool);
                            }
                            else
                            {
                                videoSurface = device.CreateOffscreenPlainSurface(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight,
                                    (Format)lpAllocInfo.Format, (Pool)lpAllocInfo.Pool);
                            }
                        }
                        catch
                        {
                            log.WarnFormat("Failed to create {0} surface", (Format)lpAllocInfo.Format);
                            return D3DERR_INVALIDCALL;
                        }
                        // And get it unmanaged pointer
                        unmanagedSurface = videoSurface.UnmanagedComPointer;

                        axiomTexture = TextureManager.Instance.GetByName(textureName);
                        if (axiomTexture != null)
                        {
                            log.InfoFormat("DirectShowCodec[{0}]: Removing old texture \"{1}\"",
                                ID, textureName);
                            axiomTexture.Unload();

                            axiomTexture.TextureType = TextureType.TwoD;
                            axiomTexture.Width = lpAllocInfo.dwWidth;
                            axiomTexture.Height = lpAllocInfo.dwHeight;
                            axiomTexture.NumMipMaps = 0;
                            axiomTexture.Format = texFormat;
                            axiomTexture.Usage = TextureUsage.RenderTarget;
                            axiomTexture.CreateInternalResources();
                        }
                        else
                        {
                            axiomTexture = TextureManager.Instance.CreateManual(
                                textureName,
                                TextureType.TwoD,
                                lpAllocInfo.dwWidth, lpAllocInfo.dwHeight,
                                0, // no mip maps
                                texFormat, // from the display
                                TextureUsage.RenderTarget);
                        }
                        if (axiomTexture is D3DTexture)
                        {
                            D3DTexture d3t = (D3DTexture)axiomTexture;
                            if (d3t.DXTexture is D3D.Texture)
                            {
                                privateTexture = (D3D.Texture)d3t.DXTexture;
                            }
                            else
                            {
                                throw new Exception("D3D texture could not get DX texture");
                            }
                        }
                        else
                        {
                            throw new Exception("D3D Texture failed to create");
                        }

                        // Get the MipMap surface 0 for the copy (see PresentImage)
                        privateSurface = privateTexture.GetSurfaceLevel(0);
                        device.ColorFill(privateSurface, new Rectangle(0, 0, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight), Color.Black);

                        // This code path need a surface copy
                        needCopy = true;
                    }
                    else
                    {
                        log.InfoFormat("DirectShowCodec[{0}]: Creating texture surface ({1}x{2})",
                                       ID, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight);

                        // in RGB pixel format
                        //lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface;

                        //Surface s = device.CreateRenderTarget();

                        axiomTexture = TextureManager.Instance.GetByName(textureName);
                        if (axiomTexture != null)
                        {
                            log.InfoFormat("DirectShowCodec[{0}]: Removing old texture \"{1}\"",
                                ID, textureName);
                            axiomTexture.Unload();

                            axiomTexture.TextureType = TextureType.TwoD;
                            axiomTexture.Width = lpAllocInfo.dwWidth;
                            axiomTexture.Height = lpAllocInfo.dwHeight;
                            axiomTexture.NumMipMaps = 0;
                            axiomTexture.Format = texFormat;
                            axiomTexture.Usage = TextureUsage.RenderTarget;
                            axiomTexture.CreateInternalResources();
                        }
                        else
                        {
                            axiomTexture = TextureManager.Instance.CreateManual(
                                textureName,
                                TextureType.TwoD,
                                lpAllocInfo.dwWidth, lpAllocInfo.dwHeight,
                                0, // no mip maps
                                texFormat, // from the display
                                TextureUsage.RenderTarget);
                        }
                        if (axiomTexture is D3DTexture)
                        {
                            D3DTexture d3t = (D3DTexture)axiomTexture;
                            if (d3t.DXTexture is D3D.Texture)
                            {
                                privateTexture = (D3D.Texture)d3t.DXTexture;
                            }
                        }
                        else
                        {
                            throw new Exception("D3D Texture failed to create");
                        }

                        // And get the MipMap surface 0 for the VMR9 filter
                        privateSurface = privateTexture.GetSurfaceLevel(0);
                        unmanagedSurface = privateSurface.UnmanagedComPointer;
                        device.ColorFill(privateSurface, new Rectangle(0, 0, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight), Color.Black);

                        // 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 (DirectXException e)
                {
                    // A Direct3D error can occure : Notify it to the VMR9 filter
                    LogUtil.ExceptionLog.ErrorFormat("Caught DirectX Exception: {0}", e.ToString());
                    return e.ErrorCode;
                }
                catch (Exception e)
                {
                    // Or else, notify a more general error
                    LogUtil.ExceptionLog.ErrorFormat("Caught Exception: {0}", e.ToString());
                    return E_FAIL;
                }

                // This allocation is a success
                return 0;
            }
        }
        /// <summary>To be documented.</summary>
        public readonly unsafe int GetBackBuffer(uint iBackBuffer, BackbufferType Type, ref IDirect3DSurface9 *ppBackBuffer)
        {
            var @this = (IDirect3DSwapChain9 *)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
            int ret   = default;

            fixed(IDirect3DSurface9 **ppBackBufferPtr = &ppBackBuffer)
            {
                ret = ((delegate * unmanaged[Cdecl] < IDirect3DSwapChain9 *, uint, BackbufferType, IDirect3DSurface9 **, int >)LpVtbl[5])(@this, iBackBuffer, Type, ppBackBufferPtr);
            }

            return(ret);
        }