Example #1
0
        // Token: 0x06000A59 RID: 2649 RVA: 0x0001E1A8 File Offset: 0x0001C3A8
        private IMFSample ReadFromSource()
        {
            int num = this.sourceProvider.Read(this.sourceBuffer, 0, this.sourceBuffer.Length);

            if (num == 0)
            {
                return(null);
            }
            IMFMediaBuffer imfmediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num);
            IntPtr         destination;
            int            num2;
            int            num3;

            imfmediaBuffer.Lock(out destination, out num2, out num3);
            Marshal.Copy(this.sourceBuffer, 0, destination, num);
            imfmediaBuffer.Unlock();
            imfmediaBuffer.SetCurrentLength(num);
            IMFSample imfsample = MediaFoundationApi.CreateSample();

            imfsample.AddBuffer(imfmediaBuffer);
            imfsample.SetSampleTime(this.inputPosition);
            long num4 = MediaFoundationTransform.BytesToNsPosition(num, this.sourceProvider.WaveFormat);

            imfsample.SetSampleDuration(num4);
            this.inputPosition += num4;
            Marshal.ReleaseComObject(imfmediaBuffer);
            return(imfsample);
        }
Example #2
0
        // Token: 0x06000945 RID: 2373 RVA: 0x0001B0A0 File Offset: 0x000192A0
        private long ConvertOneBuffer(IMFSinkWriter writer, int streamIndex, IWaveProvider inputProvider, long position, byte[] managedBuffer)
        {
            long           num            = 0L;
            IMFMediaBuffer imfmediaBuffer = MediaFoundationApi.CreateMemoryBuffer(managedBuffer.Length);
            int            count;

            imfmediaBuffer.GetMaxLength(out count);
            IMFSample imfsample = MediaFoundationApi.CreateSample();

            imfsample.AddBuffer(imfmediaBuffer);
            IntPtr destination;
            int    num2;

            imfmediaBuffer.Lock(out destination, out count, out num2);
            int num3 = inputProvider.Read(managedBuffer, 0, count);

            if (num3 > 0)
            {
                num = MediaFoundationEncoder.BytesToNsPosition(num3, inputProvider.WaveFormat);
                Marshal.Copy(managedBuffer, 0, destination, num3);
                imfmediaBuffer.SetCurrentLength(num3);
                imfmediaBuffer.Unlock();
                imfsample.SetSampleTime(position);
                imfsample.SetSampleDuration(num);
                writer.WriteSample(streamIndex, imfsample);
            }
            else
            {
                imfmediaBuffer.Unlock();
            }
            Marshal.ReleaseComObject(imfsample);
            Marshal.ReleaseComObject(imfmediaBuffer);
            return(num);
        }
Example #3
0
        /// <summary>
        /// Sets the duration of the sample.
        /// </summary>
        /// <param name="sample">A valid IMFSample instance.</param>
        /// <param name="sampleTime">Duration of the sample.</param>
        /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns>
        public static HResult SetSampleDuration(this IMFSample sample, TimeSpan sampleDuration)
        {
            if (sample == null)
            {
                throw new ArgumentNullException("sample");
            }

            return(sample.SetSampleDuration(sampleDuration.Ticks));
        }
Example #4
0
        private long ConvertOneBuffer(IMFSinkWriter writer, int streamIndex, IWaveProvider inputProvider, long position, byte[] managedBuffer, int seconds, ref bool flag)
        {
            long           durationConverted = 0;
            int            maxLength;
            IMFMediaBuffer buffer = MediaFoundationApi.CreateMemoryBuffer(managedBuffer.Length);

            buffer.GetMaxLength(out maxLength);

            IMFSample sample = MediaFoundationApi.CreateSample();

            sample.AddBuffer(buffer);

            IntPtr ptr;
            int    currentLength;

            buffer.Lock(out ptr, out maxLength, out currentLength);
            int oneLength = inputProvider.WaveFormat.AverageBytesPerSecond;
            int read      = 0;

            if (flag)
            {
                for (int i = 0; i < seconds; i++)
                {
                    read = inputProvider.Read(managedBuffer, 0, oneLength);
                }
                flag = false;
            }
            else
            {
                read = inputProvider.Read(managedBuffer, 0, oneLength);
            }

            if (read > 0)
            {
                durationConverted = BytesToNsPosition(read, inputProvider.WaveFormat);
                Marshal.Copy(managedBuffer, 0, ptr, read);
                buffer.SetCurrentLength(read);
                buffer.Unlock();
                sample.SetSampleTime(position);
                sample.SetSampleDuration(durationConverted);
                writer.WriteSample(streamIndex, sample);
                //writer.Flush(streamIndex);
            }
            else
            {
                buffer.Unlock();
            }

            Marshal.ReleaseComObject(sample);
            Marshal.ReleaseComObject(buffer);
            return(durationConverted);
        }
Example #5
0
        private void DuplicateSample(IMFSample pInSample, out IMFSample pOutSample)
        {
            MFError throwonhr;
            int     flags;
            long    lTime;

            throwonhr = MFExtern.MFCreateSample(out pOutSample);
            throwonhr = pInSample.CopyAllItems(pOutSample);

            HResult hr = pInSample.GetSampleDuration(out lTime);

            if (Succeeded(hr))
            {
                throwonhr = pOutSample.SetSampleDuration(lTime);
            }

            hr = pInSample.GetSampleTime(out lTime);
            if (Succeeded(hr))
            {
                throwonhr = pOutSample.SetSampleTime(lTime);
            }

            hr = pInSample.GetSampleFlags(out flags);
            if (Succeeded(hr))
            {
                throwonhr = pOutSample.SetSampleFlags(flags);
            }

            IMFMediaBuffer mb;

            throwonhr = MFExtern.MFCreateMemoryBuffer(m_imageHeightInPixels * m_imageWidthInPixels * 4, out mb);

            try
            {
                // Set the data size on the output buffer.
                throwonhr = mb.SetCurrentLength(m_cbImageSizeOutput);

                throwonhr = pOutSample.AddBuffer(mb);
            }
            finally
            {
                SafeRelease(mb);
            }
        }
Example #6
0
        private void SetSampleAttributes(StspSampleHeader sampleHeader, IMFSample sample)
        {
            ThrowIfError(sample.SetSampleTime(sampleHeader.ullTimestamp));
            ThrowIfError(sample.SetSampleDuration(sampleHeader.ullDuration));

            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_BottomFieldFirst, StspSampleFlags.StspSampleFlag_BottomFieldFirst);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_CleanPoint, StspSampleFlags.StspSampleFlag_CleanPoint);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_DerivedFromTopField, StspSampleFlags.StspSampleFlag_DerivedFromTopField);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_Discontinuity, StspSampleFlags.StspSampleFlag_Discontinuity);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_Interlaced, StspSampleFlags.StspSampleFlag_Interlaced);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_RepeatFirstField, StspSampleFlags.StspSampleFlag_RepeatFirstField);
            SET_SAMPLE_ATTRIBUTE(sampleHeader, sample, MFSampleExtension_SingleField, StspSampleFlags.StspSampleFlag_SingleField);

            /* show debug info...
             * int cbTotalLen;
             * sample.GetTotalLength(out cbTotalLen);
             * var isKeyFrame = Convert.ToBoolean(sampleHeader.dwFlags & (int)StspSampleFlags.StspSampleFlag_CleanPoint);
             * Debug.WriteLine($"{DateTime.Now.ToString()} Received sample {sampleHeader.ullTimestamp} Duration-{sampleHeader.ullDuration} Length-{cbTotalLen} " + (isKeyFrame ? "key frame" : ""));
             */
        }
Example #7
0
        /// <summary>Generates the "tail" of the audio effect.</summary>
        /// <param name="InputMessageNumber">Message number to use with OutputSample.</param>
        /// <remarks>
        /// Generates the "tail" of the audio effect. The tail is the portion
        /// of the delay effect that is heard after the input stream ends.
        ///
        /// To generate the tail, the client must drain the MFT by sending
        /// the MFT_MESSAGE_COMMAND_DRAIN message and then call ProcessOutput
        /// to get the tail samples.
        /// </remarks>
        private void ProcessEffectTail(int InputMessageNumber)
        {
            IMFMediaBuffer pOutputBuffer = null;

            MFError throwonhr;
            IntPtr  pbOutputData     = IntPtr.Zero; // Pointer to the memory in the output buffer.
            int     cbOutputLength   = 0;           // Size of the output buffer.
            int     cbBytesProcessed = 0;           // How much data we processed.

            IMFSample pOutSample = null;

            // Allocate an output buffer.
            throwonhr = MFExtern.MFCreateMemoryBuffer(m_cbTailSamples, out pOutputBuffer);

            try
            {
                throwonhr = MFExtern.MFCreateSample(out pOutSample);
                throwonhr = pOutSample.AddBuffer(pOutputBuffer);

                // Lock the output buffer.
                int cb;
                throwonhr = pOutputBuffer.Lock(out pbOutputData, out cbOutputLength, out cb);

                // Calculate how many audio samples we can process.
                cbBytesProcessed = Math.Min(m_cbTailSamples, cbOutputLength);

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

                // Fill the output buffer with silence, because we are also using it as the input buffer.
                FillBufferWithSilence(pbOutputData, cbBytesProcessed);

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

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

                if (m_rtTimestamp >= 0)
                {
                    long hnsDuration = (cbBytesProcessed / m_AvgBytesPerSec) * UNITS;

                    // Set the time stamp and duration on the output sample.
                    throwonhr = pOutSample.SetSampleTime(m_rtTimestamp);
                    throwonhr = pOutSample.SetSampleDuration(hnsDuration);
                }

                // Done.
                m_cbTailSamples = 0;

                OutputSample(pOutSample, InputMessageNumber);
            }
            catch
            {
                SafeRelease(pOutSample);
                throw;
            }
            finally
            {
                if (pbOutputData != IntPtr.Zero)
                {
                    pOutputBuffer.Unlock();
                }
                SafeRelease(pOutputBuffer);
            }
        }
Example #8
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 #9
0
 private void SetSampleAttributes(StspSampleHeader sampleHeader, IMFSample sample)
 {
     ThrowIfError(sample.SetSampleTime(sampleHeader.ullTimestamp));
     ThrowIfError(sample.SetSampleDuration(sampleHeader.ullDuration));
 }
Example #10
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);
        }