/// <returns> /// true:keep calling me /// false:this phase done /// </returns> bool Flush2(mfxFrameSurface1 **frame) { *frame = (mfxFrameSurface1 *)0; // mfxSyncPoint syncpD; mfxFrameSurface1 *pmfxOutSurface = (mfxFrameSurface1 *)0; // bool UseVPP = false; // if (UseVPP) return(false); #if false // // Stage 3: Retrieve the buffered VPP frames // //while (MFX_ERR_NONE <= sts) { int nIndex2 = GetFreeSurfaceIndex(pmfxSurfaces2, nSurfNumVPPOut); // Find free frame surface QuickSyncStatic.ThrowOnBadStatus((mfxStatus)nIndex2, "cannot find free surface"); // Process a frame asychronously (returns immediately) sts = mfxVPP->RunFrameVPPAsync(NULL, pmfxSurfaces2[nIndex2], NULL, &syncpV); if (MFX_ERR_MORE_DATA == sts) { return(sts); // continue; } MSDK_IGNORE_MFX_STS(sts, MFX_ERR_MORE_SURFACE); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); //MSDK_BREAK_ON_ERROR(sts); sts = session.SyncOperation(syncpV, 60000); // Synchronize. Wait until frame processing is ready MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); ++nFrame; if (bEnableOutput) { //sts = WriteRawFrame(pmfxSurfaces2[nIndex2], fSink); //MSDK_BREAK_ON_ERROR(sts); *frame = pmfxSurfaces2[nIndex2]; return(sts); //printf("Frame number: %d\r", nFrame); } //} // MFX_ERR_MORE_DATA indicates that all buffers has been fetched, exit in case of other errors //MSDK_IGNORE_MFX_STS(sts, MFX_ERR_MORE_DATA); //MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); #endif }
/// <summary> /// /// </summary> /// <param name="frame"></param> /// <returns> /// true:keep calling me /// false:this phase done /// </returns> bool Flush1(mfxFrameSurface1 **frame) { mfxStatus sts = 0; * frame = (mfxFrameSurface1 *)0; mfxSyncPoint syncpD, syncpV; mfxFrameSurface1 *pmfxOutSurface = (mfxFrameSurface1 *)0; int nIndex = 0; int nIndex2 = 0; // // Stage 2: Retrieve the buffered decoded frames // //while (MFX_ERR_NONE <= sts || MFX_ERR_MORE_SURFACE == sts) { if (mfxStatus.MFX_WRN_DEVICE_BUSY == sts) { Thread.Sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync } nIndex = GetFreeSurfaceIndex(pmfxSurfaces); // Find free frame surface QuickSyncStatic.ThrowOnBadStatus((mfxStatus)nIndex, "cannot find free surface"); // Decode a frame asychronously (returns immediately) fixed(mfxFrameSurface1 *p1 = &pmfxSurfaces[nIndex]) sts = UnsafeNativeMethods.MFXVideoDECODE_DecodeFrameAsync(session, null, p1, &pmfxOutSurface, &syncpD); // Ignore warnings if output is available, // if no output and no action required just repeat the DecodeFrameAsync call if (mfxStatus.MFX_ERR_NONE < sts && syncpD.sync_ptr != null) { sts = mfxStatus.MFX_ERR_NONE; } if (!enableVPP) { if (mfxStatus.MFX_ERR_NONE == sts) { sts = UnsafeNativeMethods.MFXVideoCORE_SyncOperation(session, syncpD, 60000); // Synchronize. Wait until decoded frame is ready *frame = pmfxOutSurface; } } if (sts == mfxStatus.MFX_ERR_MORE_SURFACE) // decoder needs to be called again, it is eating memory.SWmode { return(true); } if (sts == mfxStatus.MFX_ERR_MORE_DATA) { return(false); } if (sts < 0) { throw new QuickSyncException("Flush1 fail", sts); } if (enableVPP && sts == mfxStatus.MFX_ERR_NONE) { fixed(mfxFrameSurface1 *p1 = &pmfxSurfaces2[nIndex2]) { nIndex2 = GetFreeSurfaceIndex(pmfxSurfaces2); // Find free frame surface QuickSyncStatic.ThrowOnBadStatus((mfxStatus)nIndex2, "cannot find free surface"); for (;;) { // Process a frame asychronously (returns immediately) sts = UnsafeNativeMethods.MFXVideoVPP_RunFrameVPPAsync(session, pmfxOutSurface, p1, null, &syncpV); //if (sts == MFX_WRN_VIDEO_PARAM_CHANGED) // ; if (mfxStatus.MFX_ERR_NONE < sts && syncpV.sync_ptr == null) { // repeat the call if warning and no output if (mfxStatus.MFX_WRN_DEVICE_BUSY == sts) { Thread.Sleep(1); // wait if device is busy } } else if (mfxStatus.MFX_ERR_NONE < sts && syncpV.sync_ptr != null) { sts = mfxStatus.MFX_ERR_NONE; // ignore warnings if output is available break; } else { break; // not a warning } // VPP needs more data, let decoder decode another frame as input if (mfxStatus.MFX_ERR_MORE_DATA == sts) { //continue; return(false); } else if (mfxStatus.MFX_ERR_MORE_SURFACE == sts) { // Not relevant for the illustrated workload! Therefore not handled. // Relevant for cases when VPP produces more frames at output than consumes at input. E.g. framerate conversion 30 fps -> 60 fps //break; return(true); } else if (sts < 0) { throw new QuickSyncException("RunFrameVPPAsync fail", sts); } // MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); //MSDK_BREAK_ON_ERROR(sts); } if (mfxStatus.MFX_ERR_NONE == sts && syncpV.sync != IntPtr.Zero) { sts = UnsafeNativeMethods.MFXVideoCORE_SyncOperation(session, syncpV, 60000); // Synchronize. Wait until decoded frame is ready *frame = p1; } } } return(true); //} // MFX_ERR_MORE_DATA means that decoder is done with buffered frames, need to go to VPP buffering loop, exit in case of other errors //MSDK_IGNORE_MFX_STS(sts, MFX_ERR_MORE_DATA); //MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); }
/// <summary> /// Place a decoded frame in 'frame' if one is available. /// </summary> /// <param name="frame">Where to pyt frame.</param> /// <returns> /// true:keep calling me /// false:this phase done /// </returns> /// bool DecodeFrame(mfxFrameSurface1 **frame) { mfxStatus sts = 0; *frame = (mfxFrameSurface1 *)0; mfxSyncPoint syncpD; mfxSyncPoint syncpV; mfxFrameSurface1 *pmfxOutSurface = (mfxFrameSurface1 *)0; int nIndex = 0; int nIndex2 = 0; // // Stage 1: Main decoding loop // if (mfxStatus.MFX_ERR_NONE <= sts || mfxStatus.MFX_ERR_MORE_DATA == sts || mfxStatus.MFX_ERR_MORE_SURFACE == sts) { if (mfxStatus.MFX_WRN_DEVICE_BUSY == sts) { Thread.Sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync } //if (MFX_ERR_MORE_DATA == sts) { // sts = ReadBitStreamData(&config.mfxBS, fSource); // Read more data into input bit stream // MSDK_BREAK_ON_ERROR(sts); //} foo: if (mfxStatus.MFX_ERR_MORE_SURFACE == sts || mfxStatus.MFX_ERR_NONE == sts) { nIndex = GetFreeSurfaceIndex(pmfxSurfaces); // Find free frame surface QuickSyncStatic.ThrowOnBadStatus((mfxStatus)nIndex, "cannot find free surface"); } // Decode a frame asychronously (returns immediately) // - If input bitstream contains multiple frames DecodeFrameAsync will start decoding multiple frames, and remove them from bitstream // it might have been better to use marshal.XXX to pin this? fixed(mfxFrameSurface1 *p1 = &pmfxSurfaces[nIndex]) fixed(mfxBitstream * p2 = &bitstream) { sts = UnsafeNativeMethods.MFXVideoDECODE_DecodeFrameAsync(session, p2, p1, &pmfxOutSurface, &syncpD); if (!enableVPP && mfxStatus.MFX_ERR_NONE == sts && syncpD.sync != IntPtr.Zero) { sts = UnsafeNativeMethods.MFXVideoCORE_SyncOperation(session, syncpD, 60000); // Synchronize. Wait until decoded frame is ready *frame = pmfxOutSurface; } } // Decode a frame asychronously (returns immediately) //sts = mfxDEC->DecodeFrameAsync(&config.mfxBS, pmfxSurfaces[nIndex], &pmfxOutSurface, &syncpD); //if (sts == MFX_WRN_VIDEO_PARAM_CHANGED) // ; // I had a problem where I was getting a lot of these, I suspect // when you get this return code, and you sync anyway, it forces more of them // be sure to test this statement under vmware in software mode // it seems this uniquely happens there that it uses this to ask for more internal surfaces. if (sts == mfxStatus.MFX_ERR_MORE_SURFACE) { goto foo; } // Ignore warnings if output is available, // if no output and no action required just repeat the DecodeFrameAsync call if (mfxStatus.MFX_ERR_NONE < sts && syncpD.sync != IntPtr.Zero) { sts = mfxStatus.MFX_ERR_NONE; } } if (sts == mfxStatus.MFX_ERR_MORE_SURFACE) // decoder needs to be called again, it is eating memory.SWmode { return(true); } if (sts == mfxStatus.MFX_ERR_MORE_DATA) { return(false); } if (sts < 0) { throw new QuickSyncException("DecodeFrame fail", sts); } if (enableVPP && sts == mfxStatus.MFX_ERR_NONE) { fixed(mfxFrameSurface1 *p1 = &pmfxSurfaces2[nIndex2]) { nIndex2 = GetFreeSurfaceIndex(pmfxSurfaces2); // Find free frame surface QuickSyncStatic.ThrowOnBadStatus((mfxStatus)nIndex2, "cannot find free surface"); tryagain: // Process a frame asychronously (returns immediately) sts = UnsafeNativeMethods.MFXVideoVPP_RunFrameVPPAsync(session, pmfxOutSurface, p1, null, &syncpV); //if (sts == MFX_WRN_VIDEO_PARAM_CHANGED) // ; if (mfxStatus.MFX_ERR_NONE < sts && syncpV.sync_ptr == null) { // repeat the call if warning and no output if (mfxStatus.MFX_WRN_DEVICE_BUSY == sts) { Thread.Sleep(1); // wait if device is busy goto tryagain; } } else if (mfxStatus.MFX_ERR_NONE < sts && syncpV.sync_ptr != null) { sts = mfxStatus.MFX_ERR_NONE; // ignore warnings if output is available } else if (mfxStatus.MFX_ERR_MORE_DATA == sts) // VPP needs more data, let decoder decode another frame as input { //continue; return(false); } else if (mfxStatus.MFX_ERR_MORE_SURFACE == sts) { // Not relevant for the illustrated workload! Therefore not handled. // Relevant for cases when VPP produces more frames at output than consumes at input. E.g. framerate conversion 30 fps -> 60 fps //break; return(true); } else if (sts < 0) { throw new QuickSyncException("RunFrameVPPAsync fail", sts); } // MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); //MSDK_BREAK_ON_ERROR(sts); else if (mfxStatus.MFX_ERR_NONE == sts && syncpV.sync != IntPtr.Zero) { sts = UnsafeNativeMethods.MFXVideoCORE_SyncOperation(session, syncpV, 60000); // Synchronize. Wait until decoded frame is ready *frame = p1; return(true); } } } return(true); }
public static extern mfxStatus MFXVideoVPP_RunFrameVPPAsyncEx(mfxSession session, mfxFrameSurface1 *insurf, mfxFrameSurface1 *work, mfxFrameSurface1 **outsurf, mfxSyncPoint *syncp);
public static extern mfxStatus MFXVideoDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp);
public static extern mfxStatus NativeDecoder_Flush2(IntPtr handle, mfxFrameSurface1 **frame);