private static unsafe void DecodeAllFramesToImages(AVHWDeviceType HWDevice) { // decode all frames from url, please not it might local resorce, e.g. string url = "../../sample_mpeg4.mp4"; var url = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"; // be advised this file holds 1440 frames using (var vsd = new VideoStreamDecoder(url, HWDevice)) { Console.WriteLine($"codec name: {vsd.CodecName}"); var info = vsd.GetContextInfo(); info.ToList().ForEach(x => Console.WriteLine($"{x.Key} = {x.Value}")); var sourceSize = vsd.FrameSize; var sourcePixelFormat = HWDevice == AVHWDeviceType.AV_HWDEVICE_TYPE_NONE ? vsd.PixelFormat : GetHWPixelFormat(HWDevice); var destinationSize = sourceSize; var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGR24; using (var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat)) { var frameNumber = 0; while (vsd.TryDecodeNextFrame(out var frame)) { var convertedFrame = vfc.Convert(frame); using (var bitmap = new Bitmap(convertedFrame.width, convertedFrame.height, convertedFrame.linesize[0], PixelFormat.Format24bppRgb, (IntPtr)convertedFrame.data[0])) bitmap.Save($"frame.{frameNumber:D8}.jpg", ImageFormat.Jpeg); Console.WriteLine($"frame: {frameNumber}"); frameNumber++; } } } }
private static unsafe void DecodeAllFramesToImages(string url) { using (var vsd = new VideoStreamDecoder(url)) { Console.WriteLine($"codec name: {vsd.CodecName}"); var info = vsd.GetContextInfo(); info.ToList().ForEach(x => Console.WriteLine($"{x.Key} = {x.Value}")); var sourceSize = vsd.FrameSize; var sourcePixelFormat = vsd.PixelFormat; var destinationSize = sourceSize; var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGR24; using (var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat)) { var frameNumber = 0; while (vsd.TryDecodeNextFrame(out var frame)) { var convertedFrame = vfc.Convert(frame); var length = convertedFrame.width * convertedFrame.height * 3; var data = ToDataArray(convertedFrame.data[0], length); using (var image = Image.Load(data)) image.Save($"frame.{frameNumber:D8}.jpg"); //using (var bitmap = new Bitmap(convertedFrame.width, convertedFrame.height, convertedFrame.linesize[0], PixelFormat.Format24bppRgb, (IntPtr)convertedFrame.data[0])) // bitmap.Save($"frame.{frameNumber:D8}.jpg", ImageFormat.Jpeg); Console.WriteLine($"frame: {frameNumber}"); frameNumber++; } } } }
private static unsafe void EncodeImagesToH264() { var frameFiles = Directory.GetFiles(".", "frame.*.jpg").OrderBy(x => x).ToArray(); var fistFrameImage = Image.FromFile(frameFiles.First()); var outputFileName = "out.h264"; var fps = 25; var sourceSize = fistFrameImage.Size; var sourcePixelFormat = AVPixelFormat.AV_PIX_FMT_BGR24; var destinationSize = sourceSize; var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_YUV420P; using (var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat)) { using (var fs = File.Open(outputFileName, FileMode.Create)) // be advise only ffmpeg based player (like ffplay or vlc) can play this file, for the others you need to go through muxing { using (var vse = new H264VideoStreamEncoder(fs, fps, destinationSize)) { var frameNumber = 0; foreach (var frameFile in frameFiles) { byte[] bitmapData; using (var frameImage = Image.FromFile(frameFile)) using (var frameBitmap = frameImage is Bitmap bitmap ? bitmap : new Bitmap(frameImage)) { bitmapData = GetBitmapData(frameBitmap); } fixed(byte *pBitmapData = bitmapData) { var data = new byte_ptrArray8 { [0] = pBitmapData }; var linesize = new int_array8 { [0] = bitmapData.Length / sourceSize.Height }; var frame = new AVFrame { data = data, linesize = linesize, height = sourceSize.Height }; var convertedFrame = vfc.Convert(frame); convertedFrame.pts = frameNumber * fps; vse.Encode(convertedFrame); } Console.WriteLine($"frame: {frameNumber}"); frameNumber++; } } } } }
private static unsafe void DecodeAllFramesToImages(string url) { using (var vsd = TryGetDecoder(url)) { if (vsd == null || vsd.CodecName == "ansi") { return; } Console.WriteLine($"codec name: {vsd.CodecName}"); vsd.OutputDictionary(); var sourceSize = vsd.FrameSize; var sourcePixelFormat = vsd.PixelFormat; var destinationSize = sourceSize; var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGRA; using (var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat)) { var frameNumber = 1; while (vsd.TryDecodeNextFrame(out var frame) /*&& frameNumber < 10*/) { if (frame.metadata != null) { VideoStreamDecoder.OutputDictionary(frame.metadata, "frame " + frameNumber); } var total = Interlocked.Increment(ref counter); var filename = $"fr.{total}.{frameNumber:D8}.jpg"; if (total % 1000 == 0) { Console.WriteLine("{0:n1}k frames; {1:n0} bytes", total / 1000.0, GC.GetTotalMemory(true)); vfc.Convert(in frame, out var convertedFrame); var buffer = (IntPtr)convertedFrame.data[0]; var stride = convertedFrame.linesize[0]; using (var bitmap = new Bitmap(width: convertedFrame.width, height: convertedFrame.height, stride: stride, format: PixelFormat.Format32bppArgb, scan0: buffer)) bitmap.Save(filename, ImageFormat.Jpeg); Console.WriteLine($"{url}{filename} R{frame.repeat_pict}x {frame.pict_type} bet:{frame.best_effort_timestamp} {vsd.GetTime(frame.best_effort_timestamp)} dts:{frame.pkt_dts} pts:{frame.pts} pktpts:{frame.pkt_pts}"); } //vfc.Convert(in frame, out var convertedFrame); //var buffer = (IntPtr)convertedFrame.data[0]; //var stride = convertedFrame.linesize[0]; //using (var bitmap = new Bitmap(width: convertedFrame.width, height: convertedFrame.height, stride: stride, format: PixelFormat.Format32bppArgb, scan0: buffer)) // bitmap.Save(filename, ImageFormat.Jpeg); //var source = BitmapSource.Create(convertedFrame.width, convertedFrame.height, 96, 96, PixelFormats.Bgra32, null, buffer, stride * convertedFrame.height, stride); //var bf = BitmapFrame.Create(source); //var encoder = new JpegBitmapEncoder() { QualityLevel = 50 }; //encoder.Frames.Add(bf); //using (var stream = File.Create(filename)) //{ // encoder.Save(stream); //} //Console.WriteLine($"{url}{filename} R{frame.repeat_pict}x {frame.pict_type} bet:{frame.best_effort_timestamp} {vsd.GetTime(frame.best_effort_timestamp)} dts:{frame.pkt_dts} pts:{frame.pts} pktpts:{frame.pkt_pts}"); frameNumber++; } } } }