Example #1
0
        override protected void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber)
        {
            MFError throwonhr;

            IMFMediaBuffer pInput;

            // Set the Discontinuity flag on the sample that's going to OutputSample.
            HandleDiscontinuity(Discontinuity, pInputSample);

            // Get the data buffer from the input sample.  If the sample has
            // multiple buffers, you might be able to get (slightly) better
            // performance processing each buffer in turn rather than forcing
            // a new, full-sized buffer to get created.
            throwonhr = pInputSample.ConvertToContiguousBuffer(out pInput);

            try
            {
                // Process it.
                DoWork(pInput);

                // Send the modified input sample to the output sample queue.
                OutputSample(pInputSample, InputMessageNumber);

                m_FrameCount++;
            }
            finally
            {
                // If (somewhere) there is .Net code that is holding on to an instance of
                // the same buffer as pInput, this will yank the RCW out from underneath
                // it, probably causing it to crash.  But if we don't release it, our memory
                // usage explodes.
                SafeRelease(pInput);
            }
        }
Example #2
0
        public static byte[] GetDataFromMediaSample(IMFSample sample)
        {
            IMFMediaBuffer pMediaBuffer = null;
            IntPtr         pBuffer;
            int            maxLen = 0, curLen = 0;

            //HResult hr = sample.LockStore();
            HResult hr = sample.ConvertToContiguousBuffer(out pMediaBuffer);

            MFError.ThrowExceptionForHR(hr);
            try
            {
                hr = pMediaBuffer.Lock(out pBuffer, out maxLen, out curLen);
                MFError.ThrowExceptionForHR(hr);

                try
                {
                    byte[] data = new byte[curLen];
                    Marshal.Copy(pBuffer, data, 0, curLen);
                    return(data);
                }
                finally
                {
                    hr = pMediaBuffer.Unlock();
                }
            }
            finally
            {
                //hr = sample.UnlockStore();
                COMBase.SafeRelease(pMediaBuffer);
            }
        }
Example #3
0
        override protected void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber)
        {
            MFError throwonhr;

            // Set the Discontinuity flag on the sample that's going to OutputSample.
            HandleDiscontinuity(Discontinuity, pInputSample);

            int cb;
            int cbBytesProcessed = 0;   // How much data we processed.

            int    cbInputLength;
            IntPtr pbInputData = IntPtr.Zero;

            IMFMediaBuffer pInputBuffer;

            // Convert to a single contiguous buffer.
            // NOTE: This does not cause a copy unless there are multiple buffers
            throwonhr = pInputSample.ConvertToContiguousBuffer(out pInputBuffer);

            try
            {
                // Lock the input buffer.
                throwonhr = pInputBuffer.Lock(out pbInputData, out cb, out cbInputLength);

                // Round to the next lowest multiple of nBlockAlign.
                cbBytesProcessed = cbInputLength - (cbInputLength % m_Alignment);

                // Process the data.
                ProcessAudio(pbInputData, pbInputData, cbBytesProcessed / m_Alignment);

                // Set the data length on the output buffer.
                throwonhr = pInputBuffer.SetCurrentLength(cbBytesProcessed);

                long hnsTime = 0;

                // Ignore failure if the input sample does not have a time stamp. This is
                // not an error condition. The client may not care about time stamps, and
                // we don't need them.
                if (Succeeded(pInputSample.GetSampleTime(out hnsTime)))
                {
                    long hnsDuration = (cbBytesProcessed / m_AvgBytesPerSec) * UNITS;
                    m_rtTimestamp = hnsTime + hnsDuration;
                }
                else
                {
                    m_rtTimestamp = -1;
                }

                OutputSample(pInputSample, InputMessageNumber);
            }
            finally
            {
                if (pbInputData != IntPtr.Zero)
                {
                    pInputBuffer.Unlock();
                }

                SafeRelease(pInputBuffer);
            }
        }
Example #4
0
        override protected void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber)
        {
            MFError throwonhr;

            IMFMediaBuffer pInput;

            // While we accept types that *might* be interlaced, if we actually receive
            // an interlaced sample, reject it.
            if (m_MightBeInterlaced)
            {
                int ix;

                // Returns a bool: true = interlaced, false = progressive
                throwonhr = pInputSample.GetUINT32(MFAttributesClsid.MFSampleExtension_Interlaced, out ix);

                if (ix != 0)
                {
                    SafeRelease(pInputSample);
                    return;
                }
            }

            // Set the Discontinuity flag on the sample that's going to OutputSample.
            HandleDiscontinuity(Discontinuity, pInputSample);

            int  i     = MFExtern.MFGetAttributeUINT32(Attributes, ClsidRotate, 0);
            bool IsOdd = (i & 1) == 1;

            // Does the specified rotation give a different orientation than
            // the old one?
            if (IsOdd != m_WasOdd)
            {
                // Yes, change the output type.
                OutputSample(null, InputMessageNumber);
                m_WasOdd = IsOdd;
            }

            // Get the data buffer from the input sample.  If the sample has
            // multiple buffers, you might be able to get (slightly) better
            // performance processing each buffer in turn rather than forcing
            // a new, full-sized buffer to get created.
            throwonhr = pInputSample.ConvertToContiguousBuffer(out pInput);

            try
            {
                // Process it.
                DoWork(pInput, (RotateFlipType)i);

                // Send the modified input sample to the output sample queue.
                OutputSample(pInputSample, InputMessageNumber);
            }
            finally
            {
                // If (somewhere) there is .Net code that is holding on to an instance of
                // the same buffer as pInput, this will yank the RCW out from underneath
                // it, probably causing it to crash.  But if we don't release it, our memory
                // usage explodes.
                SafeRelease(pInput);
            }
        }
Example #5
0
        //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);
        }
Example #6
0
        protected override void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber)
        {
            MFError throwonhr;

            // While we accept types that *might* be interlaced, if we actually receive
            // an interlaced sample, reject it.
            if (m_MightBeInterlaced)
            {
                int ix;

                // Returns a bool: true = interlaced, false = progressive
                HResult hr = pInputSample.GetUINT32(MFAttributesClsid.MFSampleExtension_Interlaced, out ix);

                // Can be S_False.
                if (hr != HResult.S_OK || ix != 0)
                {
                    throw new COMException("Interlaced", (int)HResult.E_FAIL);
                }
            }

            IMFMediaBuffer pInput     = null;
            IMFMediaBuffer pOutput    = null;
            IMFSample      pOutSample = null;

            // Get the data buffer from the input sample.  If the sample has
            // multiple buffers, you might be able to get (slightly) better
            // performance processing each buffer in turn rather than forcing
            // a new, full-sized buffer to get created.
            throwonhr = pInputSample.ConvertToContiguousBuffer(out pInput);

            try
            {
                // Make a duplicate of the input sample
                DuplicateSample(pInputSample, out pOutSample);

                // Set the Discontinuity flag on the sample that's going to OutputSample.
                HandleDiscontinuity(Discontinuity, pOutSample);

                throwonhr = pOutSample.ConvertToContiguousBuffer(out pOutput);

                // Process it.
                DoWork(pInput, pOutput);

                // Send the new output sample to the output sample queue.
                OutputSample(pOutSample, InputMessageNumber);
            }
            catch
            {
                SafeRelease(pOutSample);
                throw;
            }
            finally
            {
                // If (somewhere) there is .Net code that is holding on to an instance of
                // the same buffer as pInput, this will yank the RCW out from underneath
                // it, probably causing it to crash.  But if we don't release it, our memory
                // usage explodes.
                SafeRelease(pInput);

                SafeRelease(pOutput);
                SafeRelease(pInputSample);
            }
        }
Example #7
0
        override protected HResult OnProcessOutput(ref MFTOutputDataBuffer pOutputSamples)
        {
            HResult hr = HResult.S_OK;
            MFError throwonhr;

            // Since we don't specify MFTOutputStreamInfoFlags.ProvidesSamples, this can't be null.
            if (pOutputSamples.pSample != IntPtr.Zero)
            {
                long hnsDuration;
                long hnsTime;

                IMFMediaBuffer pInput     = null;
                IMFMediaBuffer pOutput    = null;
                IMFSample      pOutSample = null;

                try
                {
                    // Get the data buffer from the input sample.  If the sample has
                    // multiple buffers, you might be able to get (slightly) better
                    // performance processing each buffer in turn rather than forcing
                    // a new, full-sized buffer to get created.
                    throwonhr = InputSample.ConvertToContiguousBuffer(out pInput);

                    // Turn pointer to interface
                    pOutSample = Marshal.GetUniqueObjectForIUnknown(pOutputSamples.pSample) as IMFSample;

                    // Get the output buffer.
                    throwonhr = pOutSample.ConvertToContiguousBuffer(out pOutput);

                    OnProcessOutput(pInput, pOutput);

                    // Set status flags.
                    pOutputSamples.dwStatus = MFTOutputDataBufferFlags.None;

                    // Copy the duration and time stamp from the input sample,
                    // if present.

                    hr = InputSample.GetSampleDuration(out hnsDuration);
                    if (Succeeded(hr))
                    {
                        throwonhr = pOutSample.SetSampleDuration(hnsDuration);
                    }

                    hr = InputSample.GetSampleTime(out hnsTime);
                    if (Succeeded(hr))
                    {
                        throwonhr = pOutSample.SetSampleTime(hnsTime);
                    }
                }
                finally
                {
                    SafeRelease(pInput);
                    SafeRelease(pOutput);
                    SafeRelease(pOutSample);

                    // Release the current input sample so we can get another one.
                    InputSample = null;
                }
            }
            else
            {
                return(HResult.E_INVALIDARG);
            }

            return(HResult.S_OK);
        }
Example #8
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// This is the routine that performs the transform. Assumes InputSample is set.
        ///
        /// An override of the abstract version in TantaMFTBase_Sync.
        /// </summary>
        /// <param name="outputSampleDataStruct">The structure to populate with output data.</param>
        /// <returns>S_Ok unless error.</returns>
        /// <history>
        ///    01 Nov 18  Cynic - Ported In
        /// </history>
        protected override HResult OnProcessOutput(ref MFTOutputDataBuffer outputSampleDataStruct)
        {
            long           hnsDuration;
            long           hnsTime;
            HResult        hr = HResult.S_OK;
            IMFMediaBuffer inputMediaBuffer  = null;
            IMFMediaBuffer outputMediaBuffer = null;
            IMFSample      outputSample      = null;

            // Since we don't specify MFTOutputStreamInfoFlags.ProvidesSamples, this can't be null.
            // we expect the caller to have allocated the memory for this
            if (outputSampleDataStruct.pSample == IntPtr.Zero)
            {
                return(HResult.E_INVALIDARG);
            }

            try
            {
                // Get the data buffer from the input sample. If the sample contains more than one buffer,
                // this method copies the data from the original buffers into a new buffer, and replaces
                // the original buffer list with the new buffer. The new buffer is returned in the inputMediaBuffer parameter.
                // If the sample contains a single buffer, this method returns a pointer to the original buffer.
                // In typical use, most samples do not contain multiple buffers.
                hr = InputSample.ConvertToContiguousBuffer(out inputMediaBuffer);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("OnProcessOutput call to InputSample.ConvertToContiguousBuffer failed. Err=" + hr.ToString());
                }

                // Turn pointer into an interface. The GetUniqueObjectForIUnknown method ensures that we
                // receive a unique Runtime Callable Wrapper, because it does not match an IUnknown pointer
                // to an existing object. Use this method when you have to create a unique RCW that is not
                // impacted by other code that calls the ReleaseComObject method.
                outputSample = Marshal.GetUniqueObjectForIUnknown(outputSampleDataStruct.pSample) as IMFSample;
                if (outputSample == null)
                {
                    throw new Exception("OnProcessOutput call to GetUniqueObjectForIUnknown failed. outputSample ==  null");
                }

                // Now get the output buffer. A media sample contains zero or more buffers. Each buffer manages a block of
                // memory, and is represented by the IMFMediaBuffer interface. A sample can have multiple buffers.
                // The buffers are kept in an ordered list and accessed by index value. This call gets us a single
                // pointer to a single contigous buffer which is much more useful.
                hr = outputSample.ConvertToContiguousBuffer(out outputMediaBuffer);
                if (hr != HResult.S_OK)
                {
                    throw new Exception("OnProcessOutput call to InputSample.ConvertToContiguousBuffer failed. Err=" + hr.ToString());
                }

                // now that we have an input and output buffer, do the work to convert them to grayscale.
                // Writing into outputMediaBuffer will write to the approprate location in the outputSample
                // since we took care to Marshal it that way
                ConvertMediaBufferToGrayscale(inputMediaBuffer, outputMediaBuffer);

                // Set status flags.
                outputSampleDataStruct.dwStatus = MFTOutputDataBufferFlags.None;

                // Copy the duration from the input sample, if present. The
                // Media Session needs these in order to keep everything sync'ed
                hr = InputSample.GetSampleDuration(out hnsDuration);
                if (hr == HResult.S_OK)
                {
                    hr = outputSample.SetSampleDuration(hnsDuration);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("OnProcessOutput call to OutSample.SetSampleDuration failed. Err=" + hr.ToString());
                    }
                }

                // Copy the time stamp from the input sample, if present.
                hr = InputSample.GetSampleTime(out hnsTime);
                if (hr == HResult.S_OK)
                {
                    hr = outputSample.SetSampleTime(hnsTime);
                    if (hr != HResult.S_OK)
                    {
                        throw new Exception("OnProcessOutput call to OutSample.SetSampleTime failed. Err=" + hr.ToString());
                    }
                }
            }
            finally
            {
                // clean up
                SafeRelease(inputMediaBuffer);
                SafeRelease(outputMediaBuffer);
                SafeRelease(outputSample);

                // Release the current input sample so we can get another one.
                // the act of setting it to null releases it because the property
                // is coded that way
                InputSample = null;
            }

            return(HResult.S_OK);
        }