/// <summary> /// See constructor for documentation. /// </summary> protected void Construct(Action function, int nativeTaskGroupId = 0, int taskDataSize = 0) { Function = function; var ptr = Marshal.GetFunctionPointerForDelegate(Function); NativeTask = SonicRiders.Functions.Functions.SetTask.GetWrapper()((void *)ptr, (uint)nativeTaskGroupId, taskDataSize); }
/// <summary> /// Tries to get the current Task executed by the game. /// You should call this in a function that handles a specific task. /// </summary> /// <param name="task">The executed task.</param> public static bool TryGetCurrentTask(out Task *task) { if (*CurrentTask != (void *)0x0) { task = (Task *)(*CurrentTask); return(true); } task = (Task *)0x0; return(false); }
static int GetFreeTaskIndex(Task *pTaskPool, int n) { Trace.Assert(pTaskPool != null); for (int i = 0; i < n; i++) { if (pTaskPool[i].syncp.sync == IntPtr.Zero) { return(i); } } return((int)mfxStatus.MFX_ERR_NOT_FOUND); }
public static unsafe Thread CreateTask(uint xLoc, bool isRunning) { Native.ClearInterrupt(); uint *stack; Task *task = (Task *)(Heap.AllocateMem((uint)sizeof(Task))); task->Stack = Heap.AllocateMem(0x1000) + 0x1000;//Put pointer at end stack = (uint *)task->Stack; // Expand down stack // processor data *--stack = 0x202; // EFLAGS *--stack = 0x08; // CS *--stack = xLoc; // EIP // pusha *--stack = 0; // EDI *--stack = 0; // ESI *--stack = 0; // EBP *--stack = 0; // ESP *--stack = 0; // EBX *--stack = 0; // EDX *--stack = 0; // ECX *--stack = 0; // EAX // data segments *--stack = 0x10; // DS *--stack = 0x10; // ES *--stack = 0x10; // FS *--stack = 0x10; // GS task->Stack = (uint)stack; task->Address = (uint *)xLoc; task->state = (byte)(isRunning ? State.Alive : State.None); mTasks[Counter++] = *task; if (isRunning) { RunningTasks.Enqueue(Counter - 1); } Native.SetInterrupt(); return(new Thread(Counter - 1)); }
/// <summary>Initializes a new instance of the <see cref="LowLevelTranscoderCSharp"/> class.</summary> /// <param name="config">The configuration.</param> /// <param name="impl">The implementation.</param> /// <param name="forceSystemMemory">if set to <c>true</c> [force system memory].</param> public LowLevelTranscoderCSharp(TranscoderConfiguration config, mfxIMPL impl = mfxIMPL.MFX_IMPL_AUTO, bool forceSystemMemory = false) { mfxStatus sts; mfxVideoParam mfxDecParams = config.decParams; mfxVideoParam mfxVPPParams = config.vppParams; mfxVideoParam mfxEncParams = config.encParams; session = new mfxSession(); var ver = new mfxVersion() { Major = 1, Minor = 3 }; fixed(mfxSession *s = &session) sts = UnsafeNativeMethods.MFXInit(impl, &ver, s); QuickSyncStatic.ThrowOnBadStatus(sts, "MFXInit"); //deviceSetup = new DeviceSetup(session, forceSystemMemory); // mfxVideoParam mfxDecParams = new mfxVideoParam(); // mfxDecParams.mfx.CodecId = CodecId.MFX_CODEC_AVC; int bufsize = (int)1e6; mfxBS = (mfxBitstream *)MyAllocHGlobalAndZero(sizeof(mfxBitstream)); mfxBS->Data = MyAllocHGlobalAndZero(bufsize); mfxBS->DataLength = (uint)0; mfxBS->MaxLength = (uint)bufsize; mfxBS->DataOffset = 0; int outwidth = mfxDecParams.mfx.FrameInfo.CropW; int outheight = mfxDecParams.mfx.FrameInfo.CropH; // Query number of required surfaces for VPP //mfxFrameAllocRequest[] VPPRequest = new mfxFrameAllocRequest[2]; // [0] - in, [1] - out TwoMfxFrameAllocRequest VPPRequest; sts = UnsafeNativeMethods.MFXVideoVPP_QueryIOSurf(session, &mfxVPPParams, (mfxFrameAllocRequest *)&VPPRequest); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoVPP_QueryIOSurf), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, "vpp.queryiosurf"); // Query number required surfaces for dec mfxFrameAllocRequest DecRequest; sts = UnsafeNativeMethods.MFXVideoDECODE_QueryIOSurf(session, &mfxDecParams, &DecRequest); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoDECODE_QueryIOSurf), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, nameof(UnsafeNativeMethods.MFXVideoDECODE_QueryIOSurf)); // Query number of required surfaces for enc mfxFrameAllocRequest EncRequest = new mfxFrameAllocRequest(); sts = UnsafeNativeMethods.MFXVideoENCODE_QueryIOSurf(session, &mfxEncParams, &EncRequest); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoENCODE_QueryIOSurf), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, nameof(UnsafeNativeMethods.MFXVideoENCODE_QueryIOSurf)); // Determine the required number of surfaces for decoder output (VPP input) and for VPP output (encoder input) nSurfNumDecVPP = DecRequest.NumFrameSuggested + VPPRequest.In.NumFrameSuggested + mfxVPPParams.AsyncDepth; nSurfNumVPPEnc = EncRequest.NumFrameSuggested + VPPRequest.Out.NumFrameSuggested + mfxVPPParams.AsyncDepth; { Trace.Assert((mfxEncParams.IOPattern & IOPattern.MFX_IOPATTERN_IN_SYSTEM_MEMORY) != 0); Trace.Assert((mfxDecParams.IOPattern & IOPattern.MFX_IOPATTERN_OUT_SYSTEM_MEMORY) != 0); UInt16 width = (UInt16)QuickSyncStatic.ALIGN32(DecRequest.Info.Width); UInt16 height = (UInt16)QuickSyncStatic.ALIGN32(DecRequest.Info.Height); int bitsPerPixel = 12; int surfaceSize = width * height * bitsPerPixel / 8; var decVppSurfaceBuffers = Marshal.AllocHGlobal(surfaceSize * nSurfNumDecVPP); var vppEncSurfaceBuffers = Marshal.AllocHGlobal(surfaceSize * nSurfNumVPPEnc); pSurfaces = (mfxFrameSurface1 *)MyAllocHGlobalAndZero(sizeof(mfxFrameSurface1) * nSurfNumDecVPP); pSurfaces2 = (mfxFrameSurface1 *)MyAllocHGlobalAndZero(sizeof(mfxFrameSurface1) * nSurfNumVPPEnc); for (int i = 0; i < nSurfNumDecVPP; i++) { pSurfaces[i] = new mfxFrameSurface1(); pSurfaces[i].Info = DecRequest.Info; pSurfaces[i].Data.Y_ptr = (byte *)decVppSurfaceBuffers + i * surfaceSize; pSurfaces[i].Data.U_ptr = pSurfaces[i].Data.Y_ptr + width * height; pSurfaces[i].Data.V_ptr = pSurfaces[i].Data.U_ptr + 1; pSurfaces[i].Data.Pitch = width; } for (int i = 0; i < nSurfNumVPPEnc; i++) { pSurfaces2[i] = new mfxFrameSurface1(); pSurfaces2[i].Info = EncRequest.Info; pSurfaces2[i].Data.Y_ptr = (byte *)vppEncSurfaceBuffers + i * surfaceSize; pSurfaces2[i].Data.U_ptr = pSurfaces2[i].Data.Y_ptr + width * height; pSurfaces2[i].Data.V_ptr = pSurfaces2[i].Data.U_ptr + 1; pSurfaces2[i].Data.Pitch = width; } } sts = UnsafeNativeMethods.MFXVideoDECODE_Init(session, &mfxDecParams); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoDECODE_Init), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, "decode.init"); sts = UnsafeNativeMethods.MFXVideoENCODE_Init(session, &mfxEncParams); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoENCODE_Init), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, "encode.init"); sts = UnsafeNativeMethods.MFXVideoVPP_Init(session, &mfxVPPParams); if (sts == mfxStatus.MFX_WRN_PARTIAL_ACCELERATION) { warnings.Add(nameof(UnsafeNativeMethods.MFXVideoVPP_Init), sts); sts = 0; } QuickSyncStatic.ThrowOnBadStatus(sts, "vpp.init"); //mfxExtVPPDoNotUse zz; //zz.Header.BufferId = BufferId.MFX_EXTBUFF_VPP_DONOTUSE; //zz.Header.BufferSz = (uint)sizeof(mfxExtVPPDoUse); //mfxExtBuffer** pExtParamsVPPx = stackalloc mfxExtBuffer*[1]; //pExtParamsVPPx[0] = (mfxExtBuffer*)&zz; //var t1 = stackalloc uint[100]; //zz.AlgList = t1; //zz.NumAlg = 100; //mfxVideoParam par; //par.ExtParam = pExtParamsVPPx; //par.NumExtParam = 1; //sts = UnsafeNativeMethods.MFXVideoVPP_GetVideoParam(session, &par); //Trace.Assert(sts == mfxStatus.MFX_ERR_NONE); //Console.WriteLine(zz.NumAlg); //for (int i = 0; i < 10; i++) //{ // Console.WriteLine((BufferId)t1[i]); //} mfxVideoParam par; // Retrieve video parameters selected by encoder. // - BufferSizeInKB parameter is required to set bit stream buffer size par = new mfxVideoParam(); sts = UnsafeNativeMethods.MFXVideoENCODE_GetVideoParam(session, &par); QuickSyncStatic.ThrowOnBadStatus(sts, "enc.getvideoparams"); // Create task pool to improve asynchronous performance (greater GPU utilization) taskPoolSize = mfxEncParams.AsyncDepth; // number of tasks that can be submitted, before synchronizing is required // Task* pTasks = stackalloc Task[taskPoolSize]; pTasks = (Task *)MyAllocHGlobalAndZero(sizeof(Task) * taskPoolSize); // GCHandle gch3 = GCHandle.Alloc(pTasks, GCHandleType.Pinned); for (int i = 0; i < taskPoolSize; i++) { // Prepare Media SDK bit stream buffer pTasks[i].mfxBS.MaxLength = (uint)(par.mfx.BufferSizeInKB * 1000); pTasks[i].mfxBS.Data = MyAllocHGlobalAndZero((int)pTasks[i].mfxBS.MaxLength); Trace.Assert(pTasks[i].mfxBS.Data != IntPtr.Zero); } // GCHandle gch3 = GCHandle.Alloc(pTasks, GCHandleType.Pinned); }