/// <summary> /// (Abstract) Process the input buffers from a previous call to InternalProcessInput into the provided output buffers /// </summary> /// <param name="dwFlags">Flags controlling the operation</param> /// <param name="cOutputBufferCount">The number of buffers provided (one per output stream)</param> /// <param name="pOutputBuffers">The output buffer into which the data is processed</param> /// <param name="pdwStatus">Zero</param> /// <returns>S_FALSE if there is no output, S_OK for successful operation.</returns> /// <remarks> /// This method is called by the abstract class. It passes the output buffers to the implementor. /// Typically, this is when the actual work is done, processing the input buffers into the output /// buffers. /// </remarks> protected abstract int InternalProcessOutput(DMOProcessOutput dwFlags, int cOutputBufferCount, DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus);
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="dwFlags">Flags</param> /// <param name="cOutputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="pOutputBuffers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> override protected int InternalProcessOutput( DMOProcessOutput dwFlags, int cOutputBufferCount, [In, Out] DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus) { int hr = 0; bool bFoundOne = false; pdwStatus = 0; // No input buffers to process if (m_pBuffer != null) { int [] cbCurrent = new int[OutputPinCount]; // 0 int [] cbOutData = new int[OutputPinCount]; //int.MaxValue; IntPtr [] pbOutData = new IntPtr[OutputPinCount]; //IntPtr.Zero; int iProcess = m_cbInData; for (int x = 0; x < OutputPinCount; x++) { if (pOutputBuffers[x].pBuffer != null) { // Get a pointer to the output buffer hr = pOutputBuffers[x].pBuffer.GetBufferAndLength(out pbOutData[x], out cbCurrent[x]); if (hr >= 0) { pbOutData[x] = (IntPtr)(pbOutData[x].ToInt32() + cbCurrent[x]); hr = pOutputBuffers[x].pBuffer.GetMaxLength(out cbOutData[x]); if (hr >= 0) { iProcess = Math.Min(iProcess, (cbOutData[x] - cbCurrent[x]) * 2); bFoundOne = true; } } } else { pbOutData[x] = IntPtr.Zero; cbOutData[x] = int.MaxValue; cbCurrent[x] = 0; } if (hr < 0) { break; } } if (hr >= 0) { if (bFoundOne) { // Process from input to output according to the mode DoSplit( iProcess, m_InBuffer, pbOutData[0], pbOutData[1] ); } for (int x = 0; x < OutputPinCount; x++) { // Keep the flags & time info from the input pOutputBuffers[x].rtTimelength = m_TimeLength; pOutputBuffers[x].rtTimestamp = m_TimeStamp; if (pOutputBuffers[x].pBuffer != null) { pOutputBuffers[x].pBuffer.SetLength((iProcess / 2) + cbCurrent[x]); } if (m_cbInData == iProcess) { pOutputBuffers[x].dwStatus = m_Flags; } else { pOutputBuffers[x].dwStatus = m_Flags | DMOOutputDataBufferFlags.InComplete; } } // Did we process everything? if (m_cbInData == iProcess) { ReleaseInputBuffs(); } else { // Reset for next call, skipping processed data long l = (long)Math.Round(((double)iProcess / m_cbInData) * m_TimeLength); m_TimeStamp += l; m_TimeLength -= l; m_InBuffer = (IntPtr)(m_InBuffer.ToInt32() + iProcess); m_cbInData -= iProcess; } } } else { hr = S_FALSE; } return(hr); }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="flags">A <see cref="DMOProcessOutput"/> Flags</param> /// <param name="outputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="outputBufferPointers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput flags, int outputBufferCount, [In, Out] DMOOutputDataBuffer[] outputBufferPointers, out int pdwStatus) { // Check buffer IntPtr outputPointer; int outputByteCount; int currentByteCount; int hr = SOK; pdwStatus = 0; // No input buffers to process if (this.buffer != null) { if (outputBufferPointers[0].pBuffer != null) { // Get a pointer to the output buffer hr = outputBufferPointers[0].pBuffer.GetBufferAndLength(out outputPointer, out currentByteCount); if (hr >= 0) { hr = outputBufferPointers[0].pBuffer.GetMaxLength(out outputByteCount); if (hr >= 0) { // Make sure we have room if (outputByteCount >= currentByteCount + OutputType(0).sampleSize) { // Get the mode for the current timecode MPData gazeX = ParamCalcValueForTime(0, this.bufferTimeStamp); MPData gazeY = ParamCalcValueForTime(1, this.bufferTimeStamp); MPData mouseX = ParamCalcValueForTime(2, this.bufferTimeStamp); MPData mouseY = ParamCalcValueForTime(3, this.bufferTimeStamp); // Process from input to output according to the mode this.DoOverlay( (IntPtr)(outputPointer.ToInt32() + currentByteCount), this.bufferByteCount, this.bufferPointer, this.streamBBP, new Point(gazeX.vInt, gazeY.vInt), new Point(mouseX.vInt, mouseY.vInt)); // Keep the flags & time info from the input outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.bufferTimeLength; outputBufferPointers[0].rtTimestamp = this.bufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseInputBuffs(); // Say we've filled the buffer hr = outputBufferPointers[0].pBuffer.SetLength(outputByteCount); } else { hr = EINVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.bufferTimeLength; outputBufferPointers[0].rtTimestamp = this.bufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseInputBuffs(); } } else { hr = SFALSE; } return(hr); }
/// <summary> /// COM entry point for IMediaObject.ProcessOutput /// </summary> /// <remarks> /// There should be no need to modify or override this method. It will call the /// abstract and virtual methods to perform its work. /// </remarks> public int ProcessOutput( DMOProcessOutput dwFlags, int ulOutputBufferCount, DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus) { int hr; try { // Avoid multi-threaded access issues lock(this) { m_Log.Write("ProcessOutput\r\n"); pdwStatus = 0; // The number of buffers needs to exactly equal the number of streams if (ulOutputBufferCount == m_NumOutputs && ( (dwFlags & ~DMOProcessOutput.DiscardWhenNoBuffer) == 0)) { // If there are output streams, pOutputBuffers can't be null if (m_NumOutputs > 0 || pOutputBuffers != null) { hr = AllocateStreamingResources(); if (hr >= 0) { // Init the status flags to zero int dw; for (dw = 0; dw < m_NumOutputs; dw++) { pOutputBuffers[dw].dwStatus = DMOOutputDataBufferFlags.None; } // Fill the buffers hr = InternalProcessOutput( dwFlags, ulOutputBufferCount, pOutputBuffers, out pdwStatus); // remember the DMO's incomplete status for (dw = 0; dw < m_NumOutputs; dw++) { if ( (pOutputBuffers[dw].dwStatus & DMOOutputDataBufferFlags.InComplete) > 0) { m_OutputInfo[dw].fIncomplete = true; } else { m_OutputInfo[dw].fIncomplete = false; } } } } else { hr = E_POINTER; } } else { hr = E_INVALIDARG; } } } catch (Exception e) { // Generic handling of all exceptions. While .NET will turn exceptions into // HRESULTS "automatically", I prefer to have some place I can set a breakpoint. hr = CatFail(e); // Have to have this to make the compiler happy. pdwStatus = 0; } return hr; }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="flags">A <see cref="DMOProcessOutput"/> Flags</param> /// <param name="outputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="outputBufferPointers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput flags, int outputBufferCount, [In, Out] DMOOutputDataBuffer[] outputBufferPointers, out int pdwStatus) { // Check buffer IntPtr outputPointer; int outputByteCount; int currentByteCount; int hr = SOK; pdwStatus = 0; // Check for no input buffers to process for (int i = 0; i < InputPinCount; i++) { if (this.inputStreams[i].Buffer == null) { return SFALSE; } } if (outputBufferPointers[0].pBuffer != null) { // Get a pointer to the output buffer hr = outputBufferPointers[0].pBuffer.GetBufferAndLength(out outputPointer, out currentByteCount); if (hr >= 0) { hr = outputBufferPointers[0].pBuffer.GetMaxLength(out outputByteCount); if (hr >= 0) { // Make sure we have room if (outputByteCount >= currentByteCount + OutputType(0).sampleSize) { long timeStamp = this.inputStreams[0].BufferTimeStamp; MPData backgroundColor = ParamCalcValueForTime(0, timeStamp); // Get the mode for the current timecode for (int i = 0; i < InputPinCount; i++) { MPData streamLeft = ParamCalcValueForTime((i * 5) + 1, timeStamp); MPData streamTop = ParamCalcValueForTime((i * 5) + 2, timeStamp); MPData streamWidth = ParamCalcValueForTime((i * 5) + 3, timeStamp); MPData streamHeight = ParamCalcValueForTime((i * 5) + 4, timeStamp); MPData streamAlpha = ParamCalcValueForTime((i * 5) + 5, timeStamp); RectangleF streamPosition = new RectangleF( streamLeft.vFloat, streamTop.vFloat, streamWidth.vFloat, streamHeight.vFloat); this.inputStreams[i].Alpha = streamAlpha.vFloat; this.inputStreams[i].Position = streamPosition; } // Process from input to output according to the mode this.DoOverlay( (IntPtr)(outputPointer.ToInt32() + currentByteCount), outputByteCount, this.inputStreams, backgroundColor.vInt); // Keep the flags & time info from the input outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.inputStreams[0].BufferTimeLength; outputBufferPointers[0].rtTimestamp = timeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseAllInputBuffers(); // Say we've filled the buffer hr = outputBufferPointers[0].pBuffer.SetLength(outputByteCount); } else { hr = EINVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.inputStreams[0].BufferTimeLength; outputBufferPointers[0].rtTimestamp = this.inputStreams[0].BufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseAllInputBuffers(); } return hr; }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="flags">A <see cref="DMOProcessOutput"/> Flags</param> /// <param name="outputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="outputBufferPointers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput flags, int outputBufferCount, [In, Out] DMOOutputDataBuffer[] outputBufferPointers, out int pdwStatus) { // Check buffer IntPtr outputPointer; int outputByteCount; int currentByteCount; int hr = SOK; pdwStatus = 0; // Check for no input buffers to process for (int i = 0; i < InputPinCount; i++) { if (this.inputStreams[i].Buffer == null) { return(SFALSE); } } if (outputBufferPointers[0].pBuffer != null) { // Get a pointer to the output buffer hr = outputBufferPointers[0].pBuffer.GetBufferAndLength(out outputPointer, out currentByteCount); if (hr >= 0) { hr = outputBufferPointers[0].pBuffer.GetMaxLength(out outputByteCount); if (hr >= 0) { // Make sure we have room if (outputByteCount >= currentByteCount + OutputType(0).sampleSize) { long timeStamp = this.inputStreams[0].BufferTimeStamp; MPData backgroundColor = ParamCalcValueForTime(0, timeStamp); // Get the mode for the current timecode for (int i = 0; i < InputPinCount; i++) { MPData streamLeft = ParamCalcValueForTime((i * 5) + 1, timeStamp); MPData streamTop = ParamCalcValueForTime((i * 5) + 2, timeStamp); MPData streamWidth = ParamCalcValueForTime((i * 5) + 3, timeStamp); MPData streamHeight = ParamCalcValueForTime((i * 5) + 4, timeStamp); MPData streamAlpha = ParamCalcValueForTime((i * 5) + 5, timeStamp); RectangleF streamPosition = new RectangleF( streamLeft.vFloat, streamTop.vFloat, streamWidth.vFloat, streamHeight.vFloat); this.inputStreams[i].Alpha = streamAlpha.vFloat; this.inputStreams[i].Position = streamPosition; } // Process from input to output according to the mode this.DoOverlay( (IntPtr)(outputPointer.ToInt32() + currentByteCount), outputByteCount, this.inputStreams, backgroundColor.vInt); // Keep the flags & time info from the input outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.inputStreams[0].BufferTimeLength; outputBufferPointers[0].rtTimestamp = timeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseAllInputBuffers(); // Say we've filled the buffer hr = outputBufferPointers[0].pBuffer.SetLength(outputByteCount); } else { hr = EINVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.inputStreams[0].BufferTimeLength; outputBufferPointers[0].rtTimestamp = this.inputStreams[0].BufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseAllInputBuffers(); } return(hr); }
int ProcessOutput( DMOProcessOutput dwFlags, int cOutputBufferCount, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus );
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="dwFlags">Flags</param> /// <param name="cOutputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="pOutputBuffers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput dwFlags, int cOutputBufferCount, [In, Out] DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus) { int hr = 0; bool bFoundOne = false; pdwStatus = 0; // No input buffers to process if (m_pBuffer != null) { int [] cbCurrent = new int[OutputPinCount]; // 0 int [] cbOutData = new int[OutputPinCount]; //int.MaxValue; IntPtr [] pbOutData = new IntPtr[OutputPinCount]; //IntPtr.Zero; int iProcess = m_cbInData; for (int x=0; x < OutputPinCount; x++) { if (pOutputBuffers[x].pBuffer != null) { // Get a pointer to the output buffer hr = pOutputBuffers[x].pBuffer.GetBufferAndLength(out pbOutData[x], out cbCurrent[x]); if (hr >= 0) { pbOutData[x] = (IntPtr)(pbOutData[x].ToInt32() + cbCurrent[x]); hr = pOutputBuffers[x].pBuffer.GetMaxLength(out cbOutData[x]); if (hr >= 0) { iProcess = Math.Min(iProcess, (cbOutData[x] - cbCurrent[x]) * 2); bFoundOne = true; } } } else { pbOutData[x] = IntPtr.Zero; cbOutData[x] = int.MaxValue; cbCurrent[x] = 0; } if (hr < 0) { break; } } if (hr >= 0) { if (bFoundOne) { // Process from input to output according to the mode DoSplit( iProcess, m_InBuffer, pbOutData[0], pbOutData[1] ); } for (int x=0; x < OutputPinCount; x++) { // Keep the flags & time info from the input pOutputBuffers[x].rtTimelength = m_TimeLength; pOutputBuffers[x].rtTimestamp = m_TimeStamp; if (pOutputBuffers[x].pBuffer != null) { pOutputBuffers[x].pBuffer.SetLength((iProcess / 2) + cbCurrent[x]); } if (m_cbInData == iProcess) { pOutputBuffers[x].dwStatus = m_Flags; } else { pOutputBuffers[x].dwStatus = m_Flags | DMOOutputDataBufferFlags.InComplete; } } // Did we process everything? if (m_cbInData == iProcess) { ReleaseInputBuffs(); } else { // Reset for next call, skipping processed data long l = (long)Math.Round(((double)iProcess / m_cbInData) * m_TimeLength); m_TimeStamp += l; m_TimeLength -= l; m_InBuffer = (IntPtr)(m_InBuffer.ToInt32() + iProcess); m_cbInData -= iProcess; } } } else { hr = S_FALSE; } return hr; }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="dwFlags">Flags</param> /// <param name="cOutputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="pOutputBuffers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput dwFlags, int cOutputBufferCount, [In, Out] DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus) { // Check buffer IntPtr pbOutData; int cbOutData; int cbCurrent; int hr = S_OK; pdwStatus = 0; // No input buffers to process if (m_pBuffer != null) { if (pOutputBuffers[0].pBuffer != null) { // Get a pointer to the output buffer hr = pOutputBuffers[0].pBuffer.GetBufferAndLength(out pbOutData, out cbCurrent); if (hr >= 0) { hr = pOutputBuffers[0].pBuffer.GetMaxLength(out cbOutData); if (hr >= 0) { // Make sure we have room if (cbOutData >= cbCurrent + OutputType(0).sampleSize) { // Get the mode for the current timecode MPData m = ParamCalcValueForTime(0, m_TimeStamp); // Process from input to output according to the mode DoFlip((IntPtr)(pbOutData.ToInt32() + cbCurrent), m_cbInData, m_InBuffer, m_BPP, (FlipMode)m.vInt); // Keep the flags & time info from the input pOutputBuffers[0].dwStatus = m_Flags; pOutputBuffers[0].rtTimelength = m_TimeLength; pOutputBuffers[0].rtTimestamp = m_TimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. ReleaseInputBuffs(); // Say we've filled the buffer hr = pOutputBuffers[0].pBuffer.SetLength(cbOutData); } else { hr = E_INVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. pOutputBuffers[0].dwStatus = m_Flags; pOutputBuffers[0].rtTimelength = m_TimeLength; pOutputBuffers[0].rtTimestamp = m_TimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. ReleaseInputBuffs(); } } else { hr = S_FALSE; } return hr; }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="flags">A <see cref="DMOProcessOutput"/> Flags</param> /// <param name="outputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="outputBufferPointers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessOutput( DMOProcessOutput flags, int outputBufferCount, [In, Out] DMOOutputDataBuffer[] outputBufferPointers, out int pdwStatus) { // Check buffer IntPtr outputPointer; int outputByteCount; int currentByteCount; int hr = SOK; pdwStatus = 0; // No input buffers to process if (this.buffer != null) { if (outputBufferPointers[0].pBuffer != null) { // Get a pointer to the output buffer hr = outputBufferPointers[0].pBuffer.GetBufferAndLength(out outputPointer, out currentByteCount); if (hr >= 0) { hr = outputBufferPointers[0].pBuffer.GetMaxLength(out outputByteCount); if (hr >= 0) { // Make sure we have room if (outputByteCount >= currentByteCount + OutputType(0).sampleSize) { // Get the mode for the current timecode MPData gazeX = ParamCalcValueForTime(0, this.bufferTimeStamp); MPData gazeY = ParamCalcValueForTime(1, this.bufferTimeStamp); MPData mouseX = ParamCalcValueForTime(2, this.bufferTimeStamp); MPData mouseY = ParamCalcValueForTime(3, this.bufferTimeStamp); // Process from input to output according to the mode this.DoOverlay( (IntPtr)(outputPointer.ToInt32() + currentByteCount), this.bufferByteCount, this.bufferPointer, this.streamBBP, new Point(gazeX.vInt, gazeY.vInt), new Point(mouseX.vInt, mouseY.vInt)); // Keep the flags & time info from the input outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.bufferTimeLength; outputBufferPointers[0].rtTimestamp = this.bufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseInputBuffs(); // Say we've filled the buffer hr = outputBufferPointers[0].pBuffer.SetLength(outputByteCount); } else { hr = EINVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. outputBufferPointers[0].dwStatus = this.bufferFlags; outputBufferPointers[0].rtTimelength = this.bufferTimeLength; outputBufferPointers[0].rtTimestamp = this.bufferTimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. this.ReleaseInputBuffs(); } } else { hr = SFALSE; } return hr; }
/// <summary> /// Given output buffers, process the input buffers into the output buffers. /// </summary> /// <param name="dwFlags">Flags</param> /// <param name="cOutputBufferCount">Number of buffers (will be one per output stream)</param> /// <param name="pOutputBuffers">The buffers</param> /// <param name="pdwStatus">Reserved: 0</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> override protected int InternalProcessOutput( DMOProcessOutput dwFlags, int cOutputBufferCount, [In, Out] DMOOutputDataBuffer [] pOutputBuffers, out int pdwStatus) { // Check buffer IntPtr pbOutData; int cbOutData; int cbCurrent; int hr = S_OK; pdwStatus = 0; // No input buffers to process if (m_pBuffer != null) { if (pOutputBuffers[0].pBuffer != null) { // Get a pointer to the output buffer hr = pOutputBuffers[0].pBuffer.GetBufferAndLength(out pbOutData, out cbCurrent); if (hr >= 0) { hr = pOutputBuffers[0].pBuffer.GetMaxLength(out cbOutData); if (hr >= 0) { // Make sure we have room if (cbOutData >= cbCurrent + OutputType(0).sampleSize) { // Get the mode for the current timecode MPData m = ParamCalcValueForTime(0, m_TimeStamp); // Process from input to output according to the mode DoFlip((IntPtr)(pbOutData.ToInt32() + cbCurrent), m_cbInData, m_InBuffer, m_BPP, (FlipMode)m.vInt); // Keep the flags & time info from the input pOutputBuffers[0].dwStatus = m_Flags; pOutputBuffers[0].rtTimelength = m_TimeLength; pOutputBuffers[0].rtTimestamp = m_TimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. ReleaseInputBuffs(); // Say we've filled the buffer hr = pOutputBuffers[0].pBuffer.SetLength(cbOutData); } else { hr = E_INVALIDARG; } } } } else { // No output buffer provided. Happens in the DMO Wrapper if one of // the output pins is not connected. pOutputBuffers[0].dwStatus = m_Flags; pOutputBuffers[0].rtTimelength = m_TimeLength; pOutputBuffers[0].rtTimestamp = m_TimeStamp; // Release the buffer. Since we are always processing one buffer at // a time, we always release on completion. If our input might be // more than one buffer, we would only release the input when it had // be complete processed. ReleaseInputBuffs(); } } else { hr = S_FALSE; } return(hr); }