//todo: put the process work to background thread to speed up. public HResult ProcessSample(IMFSample videoSample) { HResult hr = HResult.S_OK; MFTOutputStatusFlags mftOutFlags; MFTOutputStreamInfo StreamInfo; if (videoSample == null) { return(hr); } pDecoderTransform.ProcessInput(0, videoSample, 0); pDecoderTransform.GetOutputStatus(out mftOutFlags); pDecoderTransform.GetOutputStreamInfo(0, out StreamInfo); while (true) { IMFMediaBuffer resultBuffer; //reset the cache buffer. MFExtern.MFCreateMemoryBuffer(StreamInfo.cbSize, out resultBuffer); _mftOutSample.RemoveAllBuffers(); _mftOutSample.AddBuffer(resultBuffer); ProcessOutputStatus outputStatus; var mftProcessOutput = pDecoderTransform.ProcessOutput(0, 1, _mftOutBufferContainer, out outputStatus); if (mftProcessOutput == HResult.MF_E_TRANSFORM_NEED_MORE_INPUT) { //continue provice input data. break; } else if (_mftOutBufferContainer[0].dwStatus == MFTOutputDataBufferFlags.Incomplete) { //todo: the decoded data include more than one samples,we need to receive all data items. } else { IMFMediaBuffer buffer; _mftOutSample.ConvertToContiguousBuffer(out buffer); invokeDecodeComplete(buffer, StreamInfo.cbSize); } } return(hr); }
private int ReadFromTransform() { MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1]; IMFSample iMFSample = MediaFoundationApi.CreateSample(); IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(this.outputBuffer.Length); iMFSample.AddBuffer(iMFMediaBuffer); iMFSample.SetSampleTime(this.outputPosition); array[0].pSample = iMFSample; _MFT_PROCESS_OUTPUT_STATUS mFT_PROCESS_OUTPUT_STATUS; int num = this.transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out mFT_PROCESS_OUTPUT_STATUS); if (num == -1072861838) { Marshal.ReleaseComObject(iMFMediaBuffer); Marshal.ReleaseComObject(iMFSample); return(0); } if (num != 0) { Marshal.ThrowExceptionForHR(num); } IMFMediaBuffer iMFMediaBuffer2; array[0].pSample.ConvertToContiguousBuffer(out iMFMediaBuffer2); IntPtr source; int num2; int num3; iMFMediaBuffer2.Lock(out source, out num2, out num3); this.outputBuffer = BufferHelpers.Ensure(this.outputBuffer, num3); Marshal.Copy(source, this.outputBuffer, 0, num3); this.outputBufferOffset = 0; this.outputBufferCount = num3; iMFMediaBuffer2.Unlock(); this.outputPosition += MediaFoundationTransform.BytesToNsPosition(this.outputBufferCount, this.WaveFormat); Marshal.ReleaseComObject(iMFMediaBuffer); iMFSample.RemoveAllBuffers(); Marshal.ReleaseComObject(iMFSample); Marshal.ReleaseComObject(iMFMediaBuffer2); return(num3); }