/// <summary> /// Load an alternate image into the scene for the given texture name. /// Future movies that play should look for this texture and unload it /// if it exists. /// </summary> /// <param name="name"> /// The name of the texture to replace. /// </param> /// <param name="file"> /// The name of the file in the Textures directory to display. /// </param> /// <returns> /// True if the texture was created, false if it wasn't. /// </returns> public static bool ShowAltImage(string name, string file) { Axiom.Core.Texture texture = TextureManager.Instance.GetByName(name); if (texture != null) { if (texture.IsLoaded) { texture.Unload(); } TextureManager.Instance.Remove(name); } try { Axiom.Media.Image img = Axiom.Media.Image.FromFile(file); if (img != null) { texture = TextureManager.Instance.LoadImage(name, img); return(texture != null); } } catch (Exception e) { LogUtil.ExceptionLog.ErrorFormat("Exception: {0}", e); return(false); } return(false); }
public static bool HideAltImage(string name) { Axiom.Core.Texture texture = TextureManager.Instance.GetByName(name); if (texture != null) { if (texture.IsLoaded) { texture.Unload(); } TextureManager.Instance.Remove(name); return(true); } return(false); }
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; } }