Esempio n. 1
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 = OpenSebJ.eRender.device.GetObjectByValue(DxMagicNumber);
                IntPtr hMonitor        = OpenSebJ.eRender.getMonitor();

                hr = vmrSurfaceAllocatorNotify.SetD3DDevice(unmanagedDevice, hMonitor);
                DsError.ThrowExceptionForHR(hr);

                if (OpenSebJ.eRender.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(
                            OpenSebJ.eRender.device,
                            lpAllocInfo.dwWidth,
                            lpAllocInfo.dwHeight,
                            1,
                            Usage.RenderTarget,
                            OpenSebJ.eRender.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);

                //System.Windows.Forms.MessageBox.Show(device.ToString());

                //VideoRender.eRender.createDevice(device);

                return(0);
            }
            catch (DirectXException e)
            {
                return(e.ErrorCode);
            }
            catch
            {
                return(E_FAIL);
            }
        }
Esempio n. 2
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;
            }
        }
Esempio n. 3
0
        public int InitializeDevice(IntPtr dwUserID, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers)
        {
            _surfaces = new Surface[lpNumBuffers];
            for (int s = 0; s < lpNumBuffers; s++)
            {
                _surfaces[s] = Surface.CreateRenderTarget(_d3Device, lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, Format.X8R8G8B8,
                    MultisampleType.None, 0, true);
            }

            return 0;
        }
Esempio n. 4
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;
            }
        }
Esempio n. 5
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));

              // The allocator sometime call this method with invalid pool value (4 for me). Don't ask me why!
              // If the pool is invalid, return an error now to avoid an exception later in the code.
              if ((lpAllocInfo.Pool < 0) || (lpAllocInfo.Pool > 3))
            return D3DERR_INVALIDCALL;

              // 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 (!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.
              return D3DERR_INVALIDCALL;
            }
              }

              try
              {
            IntPtr unmanagedDevice = device.GetObjectByValue(DxMagicNumber);
            IntPtr hMonitor = Manager.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.DeviceCaps.TextureCaps.SupportsPower2)
            {
              // 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 = device.CreateOffscreenPlainSurface(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, (Format)lpAllocInfo.Format, (Pool)lpAllocInfo.Pool);

              // And get it unmanaged pointer
              unmanagedSurface = videoSurface.GetObjectByValue(DxMagicNumber);

              // 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.GetObjectByValue(DxMagicNumber);

              // 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
            return e.ErrorCode;
              }
              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)
        {
            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;
            }
        }
Esempio n. 7
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);

                    //SlimDX.Direct3D9.Device dev = Device.FromPointer(Marshal.GetIUnknownForObject(m_device));
                    IntPtr sharedHandle;
                    //Surface s = Surface.CreateRenderTarget(dev, 
                    //                                       lpAllocInfo.dwWidth, 
                    //                                       lpAllocInfo.dwHeight,
                    //                                       Format.X8B8G8R8, 
                    //                                       MultisampleType.None, 
                    //                                       0, 
                    //                                       false,
                    //                                       out sharedHandle);
                    IntPtr videoSurface;
                    //

                    hr = m_device.CreateRenderTarget(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight, D3DFORMAT.D3DFMT_A8R8G8B8, D3DMULTISAMPLE_TYPE.D3DMULTISAMPLE_NONE, 0, false, out videoSurface, out sharedHandle);

                    //hr = m_device.CreateTexture(lpAllocInfo.dwWidth,
                    //                            lpAllocInfo.dwHeight,
                    //                            1,
                    //                            1,
                    //                            D3DFORMAT.D3DFMT_A8B8G8R8,
                    //                            0,
                    //                            out videoSurface,
                    //                            out sharedHandle);

                    DxSurfaces[0] = videoSurface;
                    //DxSurfaces[0] = s.ComPointer;
                    InvokeNewSurfaceEvent(DxSurfaces[0], sharedHandle, new Size(lpAllocInfo.dwWidth, lpAllocInfo.dwHeight));
                }

                return hr;
            }
            catch
            {
                return E_FAIL;
            }
        }