public Canvas(int width, int height, int keyHeight, int fps, string videoName, int crf = 13, uint lineColor = 0xFF000080, string ffArg = "") { Width = width; Height = height; keyh = keyHeight; this.fps = fps; string ffarg = string.Concat("ffmpeg -y -hide_banner -f rawvideo -pix_fmt rgba -s ", width, "x", height, " -r ", fps, " -i - -pix_fmt yuv420p -preset ultrafast -crf ", crf, " \"", videoName + "\" ", ffArg); ffpipe = CStream.OpenPipe(ffarg, "wb"); frame = (uint *)UnsafeMemory.Allocate((ulong)width * (ulong)height * 4); UnsafeMemory.Set(frame, 0, (ulong)width * (ulong)height * 4); data = (uint **)UnsafeMemory.Allocate((ulong)height * (ulong)sizeof(void *)); for (uint i = 0; i < height; ++i) { data[i] = frame + (height - 1 - i) * width; } for (int i = 0; i != 128; ++i) { keyx[i] = (i / 12 * 126 + genkeyx[i % 12]) * Width / 1350; } for (int i = 0; i != 127; ++i) { keyw[i] = (i % 12) switch { 1 or 3 or 6 or 8 or 10 => width * 9 / 1350, 4 or 11 => keyx[i + 1] - keyx[i], _ => keyx[i + 2] - keyx[i], } } ; keyw[127] = width - keyx[127]; linc = lineColor; for (int i = 0; i != 128; ++i) { keycolor[i] = (i % 12) switch { 1 or 3 or 6 or 8 or 10 => 0xFF000000, _ => 0xFFFFFFFF, } } ; keyColors = (uint *)UnsafeMemory.Allocate(512); fixed(uint *p = keycolor) UnsafeMemory.Copy(keyColors, p, 512); emptyFrame = (uint *)UnsafeMemory.Allocate((ulong)width * (ulong)height * 4); for (int i = 0; i < Height; ++i) { for (int j = 0; j < Width; ++j) { data[i][j] = 0xFF000000; } } UnsafeMemory.Copy(emptyFrame, frame, (ulong)width * (ulong)height * 4); //renderPush = Task.Run(() => //{ // while (!destoryed) // { // if (!FrameList.IsEmpty) // { // FrameList.TryDequeue(out IntPtr f); // void* currFrame = f.ToPointer(); // ffpipe.Write(currFrame, (ulong)Width * (ulong)Height, 4); // UnsafeMemory.Free(currFrame); // } // } //}); }