/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Constructor, The '1' indicates there should only be 1 processing thread.
        ///    While you *can* set this higher, Grayscaling doesn't really
        ///    benefit from it.  See the TypeConverter for an MFT that does.
        /// </summary>
        /// <history>
        ///    01 Nov 18  Cynic - Ported In
        /// </history>
        public MFTTantaGrayscale_Async() : base(1)
        {
            DebugMessage("MFTTantaGrayscale_Async Constructor");

            TransformImageFunction = null;

            // build our list of guids of the Media Subtypes
            // we are prepared to accept
            m_MediaSubtypes = new Guid[] { FOURCC_NV12.ToMediaSubtype(), FOURCC_YUY2.ToMediaSubtype(), FOURCC_UYVY.ToMediaSubtype() };
        }
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        ///  Called when the input type gets set. We record the basic image
        ///  size and format information here.
        ///
        ///  Expects the InputType variable to have been set. This will have been
        ///  done in the base class immediately before this routine gets called
        ///
        ///  An override of the virtual stub in TantaMFTBase_Async.
        /// </summary>
        /// <history>
        ///    01 Nov 18  Cynic - Ported In
        /// </history>
        override protected void OnSetInputType()
        {
            MFError throwonhr;

            m_imageWidthInPixels  = 0;
            m_imageHeightInPixels = 0;
            m_videoFOURCC         = new FourCC(0);
            m_cbImageSize         = 0;
            m_lStrideIfContiguous = 0;

            TransformImageFunction = null;

            IMFMediaType pmt = InputType;

            // type can be null to clear
            if (pmt != null)
            {
                Guid subtype;

                throwonhr = pmt.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype);

                throwonhr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels);

                m_videoFOURCC = new FourCC(subtype);

                if (m_videoFOURCC == FOURCC_YUY2)
                {
                    TransformImageFunction = Update_YUY2;
                    m_lStrideIfContiguous  = m_imageWidthInPixels * 2;
                }
                else if (m_videoFOURCC == FOURCC_UYVY)
                {
                    TransformImageFunction = Update_UYVY;
                    m_lStrideIfContiguous  = m_imageWidthInPixels * 2;
                }
                else if (m_videoFOURCC == FOURCC_NV12)
                {
                    TransformImageFunction = Update_NV12;
                    m_lStrideIfContiguous  = m_imageWidthInPixels;
                }
                else
                {
                    throw new COMException("Unrecognized type", (int)HResult.E_UNEXPECTED);
                }

                // Calculate the image size (not including padding)
                int lImageSize;
                if (Succeeded(pmt.GetUINT32(MFAttributesClsid.MF_MT_SAMPLE_SIZE, out lImageSize)))
                {
                    m_cbImageSize = lImageSize;
                }
                else
                {
                    m_cbImageSize = GetImageSize(m_videoFOURCC, m_imageWidthInPixels, m_imageHeightInPixels);
                }

                int lStrideIfContiguous;
                if (Succeeded(pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStrideIfContiguous)))
                {
                    m_lStrideIfContiguous = lStrideIfContiguous;
                }

                // If the output type isn't set yet, we can pre-populate it,
                // since output must always exactly equal input.  This can
                // save a (tiny) bit of time in negotiating types.

                OnSetOutputType();
            }
            else
            {
                // Since the input must be set before the output, nulling the
                // input must also clear the output.  Note that nulling the
                // input is only valid if we are not actively streaming.

                OutputType = null;
            }
        }
Exemple #3
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        ///  Called when the input type gets set. We record the basic image
        ///  size and format information here.
        ///
        ///  Expects the InputType variable to have been set. This will have been
        ///  done in the base class immediately before this routine gets called
        ///
        ///  An override of the virtual stub in TantaMFTBase_Sync.
        /// </summary>
        /// <history>
        ///    01 Nov 18  Cynic - Ported In
        /// </history>
        override protected void OnSetInputType()
        {
            int     lImageSize;
            int     lStrideIfContiguous;
            Guid    subtype;
            HResult hr;

            // init some things
            m_imageWidthInPixels   = 0;
            m_imageHeightInPixels  = 0;
            m_videoFOURCC          = new FourCC(0);
            m_cbImageSize          = 0;
            m_lStrideIfContiguous  = 0;
            TransformImageFunction = null;

            // get this now, the type can be null to clear
            IMFMediaType pmt = InputType;

            if (pmt == null)
            {
                // Since the input must be set before the output, nulling the
                // input must also clear the output.  Note that nulling the
                // input is only valid if we are not actively streaming.
                OutputType = null;
                return;
            }

            // get the subtype GUID
            hr = pmt.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype);
            if (hr != HResult.S_OK)
            {
                throw new Exception("OnSetInputType call to get the subtype guid failed. Err=" + hr.ToString());
            }

            // get the image width and height in pixels. These will become
            // very important later when the time comes to convert to grey scale
            // Note that changing the size of the image on the screen, by resizing
            // the EVR control does not change this image size. The EVR will
            // remove various rows and columns as necssary for display purposes
            hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels);
            if (hr != HResult.S_OK)
            {
                throw new Exception("OnSetInputType call to get the image size failed failed. Err=" + hr.ToString());
            }

            // create a working FourCC subtype from the Guid. This only works because we can always
            // figure out the FOURCC code from the subtype Guid - it is the first four hex digits in
            // reverse order
            m_videoFOURCC = new FourCC(subtype);

            // switch based on the supported formats and set our transform function
            // and other format specific based info
            if (m_videoFOURCC == FOURCC_YUY2)
            {
                TransformImageFunction = TransformImageOfTypeYUY2;
                m_lStrideIfContiguous  = m_imageWidthInPixels * 2;
            }
            else if (m_videoFOURCC == FOURCC_UYVY)
            {
                TransformImageFunction = TransformImageOfTypeUYVY;
                m_lStrideIfContiguous  = m_imageWidthInPixels * 2;
            }
            else if (m_videoFOURCC == FOURCC_NV12)
            {
                TransformImageFunction = TransformImageOfTypeNV12;
                m_lStrideIfContiguous  = m_imageWidthInPixels;
            }
            else
            {
                throw new Exception("OnSetInputType Unrecognized type. Type =" + m_videoFOURCC.ToString());
            }

            // Calculate the image size (not including padding)
            hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_SAMPLE_SIZE, out lImageSize);
            if (hr == HResult.S_OK)
            {
                // we have an attribute with the image size use that
                m_cbImageSize = lImageSize;
            }
            else
            {
                // we calculate the image size from the format
                m_cbImageSize = GetImageSize(m_videoFOURCC, m_imageWidthInPixels, m_imageHeightInPixels);
            }

            // get the default stride. The stride is the number of bytes from one row of pixels in memory
            // to the next row of pixels in memory. If padding bytes are present, the stride is wider
            // than the width of the image. We will need this if the frames come in IMFMediaBuffers,
            // if the frames come in IMF2DBuffers we can get the stride directly from the buffer
            hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStrideIfContiguous);
            if (hr != HResult.S_OK)
            {
                throw new Exception("OnSetInputType call to MFAttributesClsid.MF_MT_DEFAULT_STRIDE failed. Err=" + hr.ToString());
            }

            // we have an attribute with the default stride
            m_lStrideIfContiguous = lStrideIfContiguous;

            // If the output type isn't set yet, we can pre-populate it,
            // since output must always exactly equal input.  This can
            // save a (tiny) bit of time in negotiating types.

            OnSetOutputType();
        }