threaded video decoding
							parent
							
								
									0f9511f0f6
								
							
						
					
					
						commit
						1954665c93
					
				|  | @ -10,19 +10,18 @@ namespace MoonWorks.Video | |||
| 
 | ||||
| 		public int Width => width; | ||||
| 		public int Height => height; | ||||
| 		public double FramesPerSecond => 28.97; | ||||
| 		public double FramesPerSecond { get; set; } | ||||
| 		public Dav1dfile.PixelLayout PixelLayout => pixelLayout; | ||||
| 		public int UVWidth { get; } | ||||
| 		public int UVHeight { get; } | ||||
| 
 | ||||
| 		private int width; | ||||
| 		private int height; | ||||
| 		private double fps; | ||||
| 		private Dav1dfile.PixelLayout pixelLayout; | ||||
| 
 | ||||
| 		bool IsDisposed; | ||||
| 
 | ||||
| 		public VideoAV1(string filename) | ||||
| 		public VideoAV1(string filename, double framesPerSecond) | ||||
| 		{ | ||||
| 			if (!File.Exists(filename)) | ||||
| 			{ | ||||
|  | @ -55,6 +54,8 @@ namespace MoonWorks.Video | |||
| 			{ | ||||
| 				throw new NotSupportedException("Unrecognized YUV format!"); | ||||
| 			} | ||||
| 
 | ||||
| 			FramesPerSecond = framesPerSecond; | ||||
| 		} | ||||
| 
 | ||||
| 		protected virtual void Dispose(bool disposing) | ||||
|  |  | |||
|  | @ -21,17 +21,26 @@ namespace MoonWorks.Video | |||
| 		private Texture vTexture = null; | ||||
| 		private Sampler LinearSampler; | ||||
| 
 | ||||
| 		private object readLock = new object(); | ||||
| 		private bool frameDataUpdated; | ||||
| 
 | ||||
| 		private IntPtr yDataHandle; | ||||
| 		private IntPtr uDataHandle; | ||||
| 		private IntPtr vDataHandle; | ||||
| 		private uint yDataLength; | ||||
| 		private uint uvDataLength; | ||||
| 		private uint yStride; | ||||
| 		private uint uvStride; | ||||
| 
 | ||||
| 		private int currentFrame; | ||||
| 
 | ||||
| 		private Stopwatch timer; | ||||
| 		private double lastTimestamp; | ||||
| 		private double timeElapsed; | ||||
| 
 | ||||
| 		private Stopwatch profilingTimer = new Stopwatch(); | ||||
| 
 | ||||
| 		private bool disposed; | ||||
| 
 | ||||
| 		public VideoPlayer(GraphicsDevice graphicsDevice, AudioDevice audioDevice) | ||||
| 		public VideoPlayer(GraphicsDevice graphicsDevice) | ||||
| 		{ | ||||
| 			GraphicsDevice = graphicsDevice; | ||||
| 			if (GraphicsDevice.VideoPipeline == null) | ||||
|  | @ -154,11 +163,6 @@ namespace MoonWorks.Video | |||
| 			Video = null; | ||||
| 		} | ||||
| 
 | ||||
| 		public void Update() | ||||
| 		{ | ||||
| 			if (Video == null) { return; } | ||||
| 		} | ||||
| 
 | ||||
| 		public void Render() | ||||
| 		{ | ||||
| 			if (Video == null || State == VideoState.Stopped) | ||||
|  | @ -172,27 +176,13 @@ namespace MoonWorks.Video | |||
| 			int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond))); | ||||
| 			if (thisFrame > currentFrame) | ||||
| 			{ | ||||
| 				profilingTimer.Restart(); | ||||
| 				int readResult = Dav1dfile.df_readvideo( | ||||
| 					Video.Handle, | ||||
| 					thisFrame - currentFrame, | ||||
| 					out var yData, | ||||
| 					out var uData, | ||||
| 					out var vData, | ||||
| 					out var yDataLength, | ||||
| 					out var uvDataLength, | ||||
| 					out var yStride, | ||||
| 					out var uvStride | ||||
| 				); | ||||
| 				profilingTimer.Stop(); | ||||
| 				System.Console.WriteLine($"Frame decoded in: {profilingTimer.Elapsed.TotalMilliseconds}"); | ||||
| 
 | ||||
| 				if (readResult == 1 || currentFrame == -1) | ||||
| 				if (frameDataUpdated) | ||||
| 				{ | ||||
| 					UpdateRenderTexture(yData, uData, vData, yDataLength, uvDataLength, yStride, uvStride); | ||||
| 					UpdateRenderTexture(); | ||||
| 				} | ||||
| 
 | ||||
| 				currentFrame = thisFrame; | ||||
| 				System.Threading.Tasks.Task.Run(ReadNextFrame); | ||||
| 			} | ||||
| 
 | ||||
| 			bool ended = Dav1dfile.df_eos(Video.Handle) == 1; | ||||
|  | @ -217,39 +207,42 @@ namespace MoonWorks.Video | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private void UpdateRenderTexture(IntPtr yData, IntPtr uData, IntPtr vData, uint yDataLength, uint uvDataLength, uint yStride, uint uvStride) | ||||
| 		private void UpdateRenderTexture() | ||||
| 		{ | ||||
| 			var commandBuffer = GraphicsDevice.AcquireCommandBuffer(); | ||||
| 			lock (readLock) | ||||
| 			{ | ||||
| 				var commandBuffer = GraphicsDevice.AcquireCommandBuffer(); | ||||
| 
 | ||||
| 			commandBuffer.SetTextureDataYUV( | ||||
| 				yTexture, | ||||
| 				uTexture, | ||||
| 				vTexture, | ||||
| 				yData, | ||||
| 				uData, | ||||
| 				vData, | ||||
| 				yDataLength, | ||||
| 				uvDataLength, | ||||
| 				yStride, | ||||
| 				uvStride | ||||
| 			); | ||||
| 				commandBuffer.SetTextureDataYUV( | ||||
| 					yTexture, | ||||
| 					uTexture, | ||||
| 					vTexture, | ||||
| 					yDataHandle, | ||||
| 					uDataHandle, | ||||
| 					vDataHandle, | ||||
| 					yDataLength, | ||||
| 					uvDataLength, | ||||
| 					yStride, | ||||
| 					uvStride | ||||
| 				); | ||||
| 
 | ||||
| 			commandBuffer.BeginRenderPass( | ||||
| 				new ColorAttachmentInfo(RenderTexture, Color.Black) | ||||
| 			); | ||||
| 				commandBuffer.BeginRenderPass( | ||||
| 					new ColorAttachmentInfo(RenderTexture, Color.Black) | ||||
| 				); | ||||
| 
 | ||||
| 			commandBuffer.BindGraphicsPipeline(GraphicsDevice.VideoPipeline); | ||||
| 			commandBuffer.BindFragmentSamplers( | ||||
| 				new TextureSamplerBinding(yTexture, LinearSampler), | ||||
| 				new TextureSamplerBinding(uTexture, LinearSampler), | ||||
| 				new TextureSamplerBinding(vTexture, LinearSampler) | ||||
| 			); | ||||
| 				commandBuffer.BindGraphicsPipeline(GraphicsDevice.VideoPipeline); | ||||
| 				commandBuffer.BindFragmentSamplers( | ||||
| 					new TextureSamplerBinding(yTexture, LinearSampler), | ||||
| 					new TextureSamplerBinding(uTexture, LinearSampler), | ||||
| 					new TextureSamplerBinding(vTexture, LinearSampler) | ||||
| 				); | ||||
| 
 | ||||
| 			commandBuffer.DrawPrimitives(0, 1, 0, 0); | ||||
| 				commandBuffer.DrawPrimitives(0, 1, 0, 0); | ||||
| 
 | ||||
| 			commandBuffer.EndRenderPass(); | ||||
| 				commandBuffer.EndRenderPass(); | ||||
| 
 | ||||
| 			GraphicsDevice.Submit(commandBuffer); | ||||
| 				GraphicsDevice.Submit(commandBuffer); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private static Texture CreateRenderTexture(GraphicsDevice graphicsDevice, int width, int height) | ||||
|  | @ -276,20 +269,30 @@ namespace MoonWorks.Video | |||
| 
 | ||||
| 		private void InitializeDav1dStream() | ||||
| 		{ | ||||
| 			// Grab the first video frame ASAP. | ||||
| 			Dav1dfile.df_readvideo( | ||||
| 				Video.Handle, | ||||
| 				1, | ||||
| 				out var _, | ||||
| 				out var _, | ||||
| 				out var _, | ||||
| 				out var _, | ||||
| 				out var _, | ||||
| 				out var _, | ||||
| 				out var _); | ||||
| 			System.Threading.Tasks.Task.Run(ReadNextFrame); | ||||
| 			currentFrame = -1; | ||||
| 		} | ||||
| 
 | ||||
| 		private void ReadNextFrame() | ||||
| 		{ | ||||
| 			lock (readLock) | ||||
| 			{ | ||||
| 				if (Dav1dfile.df_readvideo( | ||||
| 					Video.Handle, | ||||
| 					1, | ||||
| 					out yDataHandle, | ||||
| 					out uDataHandle, | ||||
| 					out vDataHandle, | ||||
| 					out yDataLength, | ||||
| 					out uvDataLength, | ||||
| 					out yStride, | ||||
| 					out uvStride) == 1 | ||||
| 				) { | ||||
| 					frameDataUpdated = true; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		protected virtual void Dispose(bool disposing) | ||||
| 		{ | ||||
| 			if (!disposed) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue