public unsafe void EncodeImagesToH264() { var frameFiles = Directory.GetFiles(".", "frame.*.jpeg").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++; } } } } }
public unsafe void DecodeAllFramesToImages(AVHWDeviceType HWDevice, string videoPath, string keyFramePath) { // 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 var url = videoPath; // 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; var filePath = keyFramePath; using (var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat)) { var frameNumber = 0; while (vsd.TryDecodeNextFrame(out var frame, out bool isKeyFrame)) { Console.WriteLine($"is key frame : {isKeyFrame}"); if (isKeyFrame) { //Console.WriteLine($"frame.pts: { frame.pkt_pts * ffmpeg.av_d2q(1,ffmpeg.AV_TIME_BASE).den}"); Console.WriteLine($"frame.pkt_pts: {frame.pkt_duration }"); Console.WriteLine($"frame.pkt_pts: {frame.pkt_pts }"); Console.WriteLine($"frame.pkt_pts: {frame.best_effort_timestamp}"); 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($"{filePath}frame-{frameNumber:D1}.jpeg", ImageFormat.Jpeg); Console.WriteLine($"frame: {frameNumber}"); frameNumber++; } } } } }