/// <summary> /// Accept the input buffers to be processed. You'll want to read /// the MSDN docs on this one. One point worth noting is that DMO /// doesn't require that one complete block be passed at a time. /// Picture a case where raw data is being read from a file, and your /// DMO is the first to process it. The chunk of data you receive /// might represent one image, 5 images, half an image, etc. Likewise, /// your input could contain both video and audio that you are splitting /// into two output streams. /// That helps explain some of the parameters you see here and in /// InternalProcessOutput. /// Note that while DMO doesn't insist on it, for this sample, we /// specifically request that only complete buffers be provided. /// </summary> /// <param name="inputStreamIndex">Stream Index</param> /// <param name="mediaBuffer">Interface that holds the input data</param> /// <param name="flags">Flags to control input processing</param> /// <param name="timestamp">Timestamp of the sample</param> /// <param name="timelength">Duration of the sample</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessInput( int inputStreamIndex, [In] IMediaBuffer mediaBuffer, DMOInputDataBuffer flags, long timestamp, long timelength) { // Check state - if we already have a buffer, we shouldn't be getting another Debug.Assert(this.inputStreams[inputStreamIndex].Buffer == null, "We already have a buffer, we shouldn't be getting another"); IntPtr bufferPointer; int bufferByteCount; int hr = mediaBuffer.GetBufferAndLength(out bufferPointer, out bufferByteCount); this.inputStreams[inputStreamIndex].BufferPointer = bufferPointer; this.inputStreams[inputStreamIndex].BufferByteCount = bufferByteCount; if (hr >= 0) { // Ignore zero length buffers if (this.inputStreams[inputStreamIndex].BufferByteCount > 0) { this.inputStreams[inputStreamIndex].Buffer = mediaBuffer; // Cast the input flags to become output flags this.bufferFlags = (DMOOutputDataBufferFlags)flags; // If there is a time, store it if (0 == (flags & DMOInputDataBuffer.Time)) { this.inputStreams[inputStreamIndex].BufferTimeStamp = MaxTime; } else { this.inputStreams[inputStreamIndex].BufferTimeStamp = timestamp; } // If there is a TimeLength, store it if (0 == (flags & DMOInputDataBuffer.TimeLength)) { this.inputStreams[inputStreamIndex].BufferTimeLength = -1; } else { this.inputStreams[inputStreamIndex].BufferTimeLength = timelength; } hr = SOK; } else { this.ReleaseInputBuffs(inputStreamIndex); hr = SFALSE; } } return(hr); }
/// <summary> /// Accept the input buffers to be processed. You'll want to read /// the MSDN docs on this one. One point worth noting is that DMO /// doesn't require that one complete block be passed at a time. /// Picture a case where raw data is being read from a file, and your /// DMO is the first to process it. The chunk of data you receive /// might represent one image, 5 images, half an image, etc. Likewise, /// your input could contain both video and audio that you are splitting /// into two output streams. /// That helps explain some of the parameters you see here and in /// InternalProcessOutput. /// Note that while DMO doesn't insist on it, for this sample, we /// specifically request that only complete buffers be provided. /// </summary> /// <param name="dwInputStreamIndex">Stream Index</param> /// <param name="pBuffer">Interface that holds the input data</param> /// <param name="dwFlags">Flags to control input processing</param> /// <param name="rtTimestamp">Timestamp of the sample</param> /// <param name="rtTimelength">Duration of the sample</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> override protected int InternalProcessInput( int dwInputStreamIndex, [In] IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength) { // Check state - if we already have a buffer, we shouldn't be getting another Debug.Assert(m_pBuffer == null); int cbData; int hr = pBuffer.GetBufferAndLength(out m_InBuffer, out m_cbInData); if (hr >= 0) { // Ignore zero length buffers if (m_cbInData > 0) { m_pBuffer = pBuffer; // Cast the input flags to become output flags m_Flags = (DMOOutputDataBufferFlags)dwFlags; // If there is a time, store it if (0 == (dwFlags & DMOInputDataBuffer.Time)) { m_TimeStamp = MAX_TIME; } else { m_TimeStamp = rtTimestamp; } // If there is a TimeLength, store it if (0 == (dwFlags & DMOInputDataBuffer.TimeLength)) { m_TimeLength = -1; } else { m_TimeLength = rtTimelength; } hr = S_OK; } else { ReleaseInputBuffs(); hr = S_FALSE; } } return(hr); }
/// <summary> /// (Abstract) Accept input buffers to be processed /// </summary> /// <param name="dwInputStreamIndex">Input stream number</param> /// <param name="pBuffer">Input buffer to process</param> /// <param name="dwFlags">Processing flags</param> /// <param name="rtTimestamp">Timestamp of sample(s)</param> /// <param name="rtTimelength">Length of sample(s)</param> /// <returns>S_OK if the operation completes successfully, S_FALSE if there /// is no input to process.</returns> /// <remarks> /// This method is called by the abstract class. It passes the actual data to be process to the /// implementor. Commonly, the implementor stores these values, waiting for the call to /// InternalProcessOutput (which contains the buffers into which the results are to be stored), at /// which point they are released. /// </remarks> protected abstract int InternalProcessInput(int dwInputStreamIndex, IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength);
/// <summary> /// COM entry point for IMediaObject.ProcessInput /// </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 ProcessInput( int ulStreamIndex, IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength ) { int hr; try { // Avoid multi-threaded access issues lock(this) { m_Log.Write(string.Format("ProcessInput ({0}, {1}, {2}, {3})\r\n", ulStreamIndex, dwFlags, rtTimestamp, rtTimelength)); if (pBuffer != null) { // Validate the stream number if (ulStreamIndex < m_NumInputs && ulStreamIndex >= 0) { // Validate flags if ( (dwFlags & ~(DMOInputDataBuffer.SyncPoint | DMOInputDataBuffer.Time | DMOInputDataBuffer.TimeLength)) == 0) { // Make sure all streams have media types set and resources are allocated hr = AllocateStreamingResources(); if (hr >= 0) { // If we aren't accepting input, forget it if (InternalAcceptingInput(ulStreamIndex) == S_OK) { m_fFlushed = false; hr = InternalProcessInput( ulStreamIndex, pBuffer, dwFlags, rtTimestamp, rtTimelength); } else { hr = DMOResults.E_NotAccepting; } } } else { hr = E_INVALIDARG; } } else { hr = DMOResults.E_InvalidStreamIndex; } } else { hr = E_POINTER; } } } 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); } return hr; }
/// <summary> /// Accept the input buffers to be processed. You'll want to read /// the MSDN docs on this one. One point worth noting is that DMO /// doesn't require that one complete block be passed at a time. /// Picture a case where raw data is being read from a file, and your /// DMO is the first to process it. The chunk of data you receive /// might represent one image, 5 images, half an image, etc. Likewise, /// your input could contain both video and audio that you are splitting /// into two output streams. /// That helps explain some of the parameters you see here and in /// InternalProcessOutput. /// Note that while DMO doesn't insist on it, for this sample, we /// specifically request that only complete buffers be provided. /// </summary> /// <param name="inputStreamIndex">Stream Index</param> /// <param name="mediaBuffer">Interface that holds the input data</param> /// <param name="flags">Flags to control input processing</param> /// <param name="timestamp">Timestamp of the sample</param> /// <param name="timelength">Duration of the sample</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessInput( int inputStreamIndex, [In] IMediaBuffer mediaBuffer, DMOInputDataBuffer flags, long timestamp, long timelength) { // Check state - if we already have a buffer, we shouldn't be getting another Debug.Assert(this.inputStreams[inputStreamIndex].Buffer == null, "We already have a buffer, we shouldn't be getting another"); IntPtr bufferPointer; int bufferByteCount; int hr = mediaBuffer.GetBufferAndLength(out bufferPointer, out bufferByteCount); this.inputStreams[inputStreamIndex].BufferPointer = bufferPointer; this.inputStreams[inputStreamIndex].BufferByteCount = bufferByteCount; if (hr >= 0) { // Ignore zero length buffers if (this.inputStreams[inputStreamIndex].BufferByteCount > 0) { this.inputStreams[inputStreamIndex].Buffer = mediaBuffer; // Cast the input flags to become output flags this.bufferFlags = (DMOOutputDataBufferFlags)flags; // If there is a time, store it if (0 == (flags & DMOInputDataBuffer.Time)) { this.inputStreams[inputStreamIndex].BufferTimeStamp = MaxTime; } else { this.inputStreams[inputStreamIndex].BufferTimeStamp = timestamp; } // If there is a TimeLength, store it if (0 == (flags & DMOInputDataBuffer.TimeLength)) { this.inputStreams[inputStreamIndex].BufferTimeLength = -1; } else { this.inputStreams[inputStreamIndex].BufferTimeLength = timelength; } hr = SOK; } else { this.ReleaseInputBuffs(inputStreamIndex); hr = SFALSE; } } return hr; }
/// <summary> /// Accept the input buffers to be processed. You'll want to read /// the MSDN docs on this one. One point worth noting is that DMO /// doesn't require that one complete block be passed at a time. /// Picture a case where raw data is being read from a file, and your /// DMO is the first to process it. The chunk of data you receive /// might represent one image, 5 images, half an image, etc. Likewise, /// your input could contain both video and audio that you are splitting /// into two output streams. /// That helps explain some of the parameters you see here and in /// InternalProcessOutput. /// Note that while DMO doesn't insist on it, for this sample, we /// specifically request that only complete buffers be provided. /// </summary> /// <param name="dwInputStreamIndex">Stream Index</param> /// <param name="pBuffer">Interface that holds the input data</param> /// <param name="dwFlags">Flags to control input processing</param> /// <param name="rtTimestamp">Timestamp of the sample</param> /// <param name="rtTimelength">Duration of the sample</param> /// <returns>S_FALSE if there is no output, S_OK otherwise</returns> protected override int InternalProcessInput( int dwInputStreamIndex, [In] IMediaBuffer pBuffer, DMOInputDataBuffer dwFlags, long rtTimestamp, long rtTimelength) { // Check state - if we already have a buffer, we shouldn't be getting another Debug.Assert(m_pBuffer == null); int cbData; int hr = pBuffer.GetBufferAndLength(out m_InBuffer, out m_cbInData); if (hr >= 0) { // Ignore zero length buffers if (m_cbInData > 0) { m_pBuffer = pBuffer; // Cast the input flags to become output flags m_Flags = (DMOOutputDataBufferFlags)dwFlags; // If there is a time, store it if (0 == (dwFlags & DMOInputDataBuffer.Time)) { m_TimeStamp = MAX_TIME; } else { m_TimeStamp = rtTimestamp; } // If there is a TimeLength, store it if (0 == (dwFlags & DMOInputDataBuffer.TimeLength)) { m_TimeLength = -1; } else { m_TimeLength = rtTimelength; } hr = S_OK; } else { ReleaseInputBuffs(); hr = S_FALSE; } } return hr; }
/// <summary> /// (Abstract) Accept input buffers to be processed /// </summary> /// <param name="inputStreamIndex">Input stream number</param> /// <param name="bufferVal">Input buffer to process</param> /// <param name="flags">Processing flags</param> /// <param name="timestamp">Timestamp of sample(s)</param> /// <param name="timelength">Length of sample(s)</param> /// <returns>S_OK if the operation completes successfully, S_FALSE if there /// is no input to process.</returns> /// <remarks> /// This method is called by the abstract class. It passes the actual data to be process to the /// implementor. Commonly, the implementor stores these values, waiting for the call to /// InternalProcessOutput (which contains the buffers into which the results are to be stored), at /// which point they are released. /// </remarks> protected abstract int InternalProcessInput(int inputStreamIndex, IMediaBuffer bufferVal, DMOInputDataBuffer flags, long timestamp, long timelength);
/// <summary> /// COM entry point for IMediaObject.ProcessInput /// </summary> /// <param name="streamIndex">Zero-based index of an input stream on the DMO.</param> /// <param name="bufferVal">Pointer to the buffer's IMediaBuffer interface.</param> /// <param name="flags">Bitwise combination of zero or /// more flags from the DMO_INPUT_DATA_BUFFER_FLAGS enumeration.</param> /// <param name="timestamp">Time stamp that /// specifies the start time of the data in the buffer. /// If the buffer has a valid time stamp, set the DMO_INPUT_DATA_BUFFERF_TIME /// flag in the flags parameter. Otherwise, the DMO ignores this value.</param> /// <param name="timelength">Reference time specifying the duration /// of the data in the buffer. If this value is valid, set /// the DMO_INPUT_DATA_BUFFERF_TIMELENGTH flag in the flags /// parameter. Otherwise, the DMO ignores this value.</param> /// <returns>A HRESULT value.</returns> /// <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 ProcessInput( int streamIndex, IMediaBuffer bufferVal, DMOInputDataBuffer flags, long timestamp, long timelength) { int hr; try { // Avoid multi-threaded access issues lock (this) { if (bufferVal != null) { // Validate the stream number if (streamIndex < this.numInputs && streamIndex >= 0) { // Validate flags if ((flags & ~(DMOInputDataBuffer.SyncPoint | DMOInputDataBuffer.Time | DMOInputDataBuffer.TimeLength)) == 0) { // Make sure all streams have media types set and resources are allocated hr = this.AllocateStreamingResources(); if (hr >= 0) { // If we aren't accepting input, forget it if (this.InternalAcceptingInput(streamIndex) == SOK) { this.flushed = false; hr = this.InternalProcessInput( streamIndex, bufferVal, flags, timestamp, timelength); } else { hr = DMOResults.E_NotAccepting; } } } else { hr = EINVALIDARG; } } else { hr = DMOResults.E_InvalidStreamIndex; } } else { hr = EPOINTER; } } } 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 = this.CatFail(e); } return hr; }