/// <summary> /// Called by vlc when the video format is needed. This method allocats the picture buffers for vlc and tells it to set the chroma to RV32 /// </summary> /// <param name="userdata">The user data that will be given to the <see cref="LockVideo"/> callback. It contains the pointer to the buffer</param> /// <param name="chroma">The chroma</param> /// <param name="width">The visible width</param> /// <param name="height">The visible height</param> /// <param name="pitches">The buffer width</param> /// <param name="lines">The buffer height</param> /// <returns>The number of buffers allocated</returns> private uint VideoFormat(out IntPtr userdata, IntPtr chroma, ref uint width, ref uint height, ref uint pitches, ref uint lines) { var pixelFormat = IsAlphaChannelEnabled ? PixelFormats.Bgra32 : PixelFormats.Bgr32; FourCCConverter.ToFourCC("RV32", chroma); pitches = this.GetAlignedDimension((uint)(width * pixelFormat.BitsPerPixel) / 8, 32); lines = this.GetAlignedDimension(height, 32); var size = pitches * lines; #if NET45 this.memoryMappedFile = MemoryMappedFile.CreateNew(null, size); var handle = this.memoryMappedFile.SafeMemoryMappedFileHandle.DangerousGetHandle(); #else this.memoryMappedFile = Win32Interop.CreateFileMapping(new IntPtr(-1), IntPtr.Zero, Win32Interop.PageAccess.ReadWrite, 0, (int)size, null); var handle = this.memoryMappedFile; #endif var args = new { width = width, height = height, pixelFormat = pixelFormat, pitches = pitches }; this.dispatcher.Invoke((Action)(() => { this.VideoSource = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(handle, (int)args.width, (int)args.height, args.pixelFormat, (int)args.pitches, 0); })); #if NET45 this.memoryMappedView = this.memoryMappedFile.CreateViewAccessor(); var viewHandle = this.memoryMappedView.SafeMemoryMappedViewHandle.DangerousGetHandle(); #else this.memoryMappedView = Win32Interop.MapViewOfFile(this.memoryMappedFile, Win32Interop.FileMapAccess.AllAccess, 0, 0, size); var viewHandle = this.memoryMappedView; #endif userdata = viewHandle; return(1); }
private uint VideoSetFormat(ref IntPtr opaque, ref uint chroma, ref uint width, ref uint height, ref uint pitches, ref uint lines) { var context = new VlcControlWpfRendererContext(width, height, PixelFormats.Bgr32); chroma = BitConverter.ToUInt32(new[] { (byte)'R', (byte)'V', (byte)'3', (byte)'2' }, 0); width = (uint)context.Width; height = (uint)context.Height; pitches = (uint)context.Stride; lines = (uint)context.Height; myBitmapSectionPointer = Win32Interop.CreateFileMapping(new IntPtr(-1), IntPtr.Zero, Win32Interop.PageAccess.ReadWrite, 0, context.Size, null); opaque = Win32Interop.MapViewOfFile(myBitmapSectionPointer, Win32Interop.FileMapAccess.AllAccess, 0, 0, (uint)context.Size); Dispatcher.Invoke((Action)(() => { myBitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(myBitmapSectionPointer, context.Width, context.Height, context.PixelFormat, context.Stride, 0); VideoSource = myBitmap; VideoBrush.ImageSource = myBitmap; })); return(1); }
/// <summary> /// Called by vlc when the video format is needed. This method allocats the picture buffers for vlc and tells it to set the chroma to RV32 /// </summary> /// <param name="userdata">The user data that will be given to the <see cref="LockVideo"/> callback. It contains the pointer to the buffer</param> /// <param name="chroma">The chroma</param> /// <param name="width">The visible width</param> /// <param name="height">The visible height</param> /// <param name="pitches">The buffer width</param> /// <param name="lines">The buffer height</param> /// <returns>The number of buffers allocated</returns> private uint VideoFormat(out IntPtr userdata, IntPtr chroma, ref uint width, ref uint height, ref uint pitches, ref uint lines) { var pixelFormat = IsAlphaChannelEnabled ? PixelFormats.Bgra32 : PixelFormats.Bgr32; FourCCConverter.ToFourCC("RV32", chroma); //Correct video width and height according to TrackInfo var md = MediaPlayer.GetMedia(); foreach (MediaTrack track in md.Tracks) { if (track.Type == MediaTrackTypes.Video) { var trackInfo = (VideoTrack)track.TrackInfo; if (trackInfo.Width > 0 && trackInfo.Height > 0) { width = trackInfo.Width; height = trackInfo.Height; if (trackInfo.SarDen != 0) { width = width * trackInfo.SarNum / trackInfo.SarDen; } } break; } } pitches = this.GetAlignedDimension((uint)(width * pixelFormat.BitsPerPixel) / 8, 32); lines = this.GetAlignedDimension(height, 32); var size = pitches * lines; #if NET45 this.memoryMappedFile = MemoryMappedFile.CreateNew(null, size); var handle = this.memoryMappedFile.SafeMemoryMappedFileHandle.DangerousGetHandle(); #else this.memoryMappedFile = Win32Interop.CreateFileMapping(new IntPtr(-1), IntPtr.Zero, Win32Interop.PageAccess.ReadWrite, 0, (int)size, null); var handle = this.memoryMappedFile; #endif var args = new { width = width, height = height, pixelFormat = pixelFormat, pitches = pitches }; this.dispatcher.Invoke((Action)(() => { this.VideoSource = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(handle, (int)args.width, (int)args.height, args.pixelFormat, (int)args.pitches, 0); })); #if NET45 this.memoryMappedView = this.memoryMappedFile.CreateViewAccessor(); var viewHandle = this.memoryMappedView.SafeMemoryMappedViewHandle.DangerousGetHandle(); #else this.memoryMappedView = Win32Interop.MapViewOfFile(this.memoryMappedFile, Win32Interop.FileMapAccess.AllAccess, 0, 0, size); var viewHandle = this.memoryMappedView; #endif userdata = viewHandle; return(1); }