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);
        }
Beispiel #2
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);
            }
        }
Beispiel #3
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);
        }
Beispiel #4
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);
            }
        }