Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <summary>
        /// The constructor.  The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoSplit() : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            m_Log.Write("Constructor\r\n");

            // Initialize the data members
            m_TimeStamp  = 0;
            m_TimeLength = 0;
            m_cbInData   = 0;
            m_Flags      = 0;
            m_InBuffer   = IntPtr.Zero;
            m_pBuffer    = null;
        }
Beispiel #4
0
        /// <summary>
        /// Release all info for the most recent input buffer
        /// </summary>
        private void ReleaseInputBuffs()
        {
            if (m_pBuffer != null)
            {
                Marshal.ReleaseComObject(m_pBuffer);
                m_pBuffer = null;
            }
            m_InBuffer = IntPtr.Zero;
            m_cbInData = 0;
            m_Flags    = 0;

            // I specifically DON'T release the TimeStamp so we can keep track of where we are
        }
Beispiel #5
0
        /// <summary>
        /// The constructor.  The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoSplit()
            : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            m_Log.Write("Constructor\r\n");

            // Initialize the data members
            m_TimeStamp = 0;
            m_TimeLength = 0;
            m_cbInData = 0;
            m_Flags = 0;
            m_InBuffer = IntPtr.Zero;
            m_pBuffer = null;
        }
Beispiel #6
0
        /// <summary>
        /// Release all info for the most recent input buffer
        /// </summary>
        private void ReleaseInputBuffs()
        {
            if (this.buffer != null)
            {
                Marshal.ReleaseComObject(this.buffer);
                this.buffer = null;
            }

            this.bufferPointer   = IntPtr.Zero;
            this.bufferByteCount = 0;
            this.bufferFlags     = 0;

            // I specifically DON'T release the TimeStamp so we can keep track of where we are
        }
Beispiel #7
0
        /// <summary>
        /// The constructor.  The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoFlip()
            : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            m_Log.Write("Constructor\r\n");

            // Initialize the data members
            m_Width = 0;
            m_Height = 0;
            m_Stride = 0;
            m_BPP = 0;
            m_TimeStamp = 0;
            m_TimeLength = 0;
            m_cbInData = 0;
            m_Flags = 0;
            m_InBuffer = IntPtr.Zero;
            m_pBuffer = null;

            // Start describing the parameters this DMO supports.  Building this
            // structure (painful as it is) will allow the base class to automatically
            // support IMediaParamInfo & IMediaParams, which allow clients to find
            // out what parameters you support, and to set them.

            // Our parameter has a minimum value of zero, and a max of
            // FlipMode.LAST, and a default of DEFAULTMODE;  See the MSDN
            // docs for MP_PARAMINFO for a description of the other parameters
            ParamInfo p = new ParamInfo();

            p.mopCaps = MPCaps.Jump;
            p.mpdMinValue.vInt = 0;
            p.mpdMaxValue.vInt = (int)FlipMode.LAST;
            p.mpdNeutralValue.vInt = (int)DEFAULTMODE;
            p.mpType = MPType.ENUM;
            p.szLabel = "";
            p.szUnitText = "FlipMode";

            // Parameter #0, using the struct, and a format string (described in MSDN
            // under IMediaParamInfo::GetParamText).  Note that when marshaling strings,
            // .NET will add another \0
            ParamDefine(0, p, "FlipMode\0\0None\0FlipY\0FlipX\0FlipY|FlipX\0");
        }
Beispiel #8
0
        /// <summary>
        /// The constructor.  The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoFlip() : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            m_Log.Write("Constructor\r\n");

            // Initialize the data members
            m_Width      = 0;
            m_Height     = 0;
            m_Stride     = 0;
            m_BPP        = 0;
            m_TimeStamp  = 0;
            m_TimeLength = 0;
            m_cbInData   = 0;
            m_Flags      = 0;
            m_InBuffer   = IntPtr.Zero;
            m_pBuffer    = null;

            // Start describing the parameters this DMO supports.  Building this
            // structure (painful as it is) will allow the base class to automatically
            // support IMediaParamInfo & IMediaParams, which allow clients to find
            // out what parameters you support, and to set them.

            // Our parameter has a minimum value of zero, and a max of
            // FlipMode.LAST, and a default of DEFAULTMODE;  See the MSDN
            // docs for MP_PARAMINFO for a description of the other parameters
            ParamInfo p = new ParamInfo();

            p.mopCaps              = MPCaps.Jump;
            p.mpdMinValue.vInt     = 0;
            p.mpdMaxValue.vInt     = (int)FlipMode.LAST;
            p.mpdNeutralValue.vInt = (int)DEFAULTMODE;
            p.mpType     = MPType.ENUM;
            p.szLabel    = "";
            p.szUnitText = "FlipMode";

            // Parameter #0, using the struct, and a format string (described in MSDN
            // under IMediaParamInfo::GetParamText).  Note that when marshaling strings,
            // .NET will add another \0
            ParamDefine(0, p, "FlipMode\0\0None\0FlipY\0FlipX\0FlipY|FlipX\0");
        }
Beispiel #9
0
        ///////////////////////////////////////////////////////////////////////////////
        // Construction and Initializing methods                                     //
        ///////////////////////////////////////////////////////////////////////////////
        #region CONSTRUCTION

        /// <summary>
        /// Initializes a new instance of the DmoOverlay class.
        /// The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoOverlay()
            : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            // Initialize the data members
            this.streamWidth      = 0;
            this.streamHeight     = 0;
            this.streamStride     = 0;
            this.streamBBP        = 0;
            this.bufferTimeStamp  = 0;
            this.bufferTimeLength = 0;
            this.bufferByteCount  = 0;
            this.bufferFlags      = 0;
            this.bufferPointer    = IntPtr.Zero;
            this.buffer           = null;

            // Start describing the parameters this DMO supports.  Building this
            // structure (painful as it is) will allow the base class to automatically
            // support IMediaParamInfo & IMediaParams, which allow clients to find
            // out what parameters you support, and to set them.

            // See the MSDN
            // docs for MP_PARAMINFO for a description of the other parameters
            ParamInfo gazeX = new ParamInfo();

            gazeX.mopCaps              = MPCaps.Jump;
            gazeX.mpdMinValue.vInt     = 0;
            gazeX.mpdMaxValue.vInt     = 2000;
            gazeX.mpdNeutralValue.vInt = 1;
            gazeX.mpType     = MPType.INT;
            gazeX.szLabel    = "GazeX";
            gazeX.szUnitText = "Pixel";

            ParamInfo gazeY = new ParamInfo();

            gazeY.mopCaps              = MPCaps.Jump;
            gazeY.mpdMinValue.vInt     = 0;
            gazeY.mpdMaxValue.vInt     = 2000;
            gazeY.mpdNeutralValue.vInt = 1;
            gazeY.mpType     = MPType.INT;
            gazeY.szLabel    = "GazeY";
            gazeY.szUnitText = "Pixel";

            ParamInfo mouseX = new ParamInfo();

            mouseX.mopCaps              = MPCaps.Jump;
            mouseX.mpdMinValue.vInt     = 0;
            mouseX.mpdMaxValue.vInt     = 2000;
            mouseX.mpdNeutralValue.vInt = 1;
            mouseX.mpType     = MPType.INT;
            mouseX.szLabel    = "MouseX";
            mouseX.szUnitText = "Pixel";

            ParamInfo mouseY = new ParamInfo();

            mouseY.mopCaps              = MPCaps.Jump;
            mouseY.mpdMinValue.vInt     = 0;
            mouseY.mpdMaxValue.vInt     = 2000;
            mouseY.mpdNeutralValue.vInt = 1;
            mouseY.mpType     = MPType.INT;
            mouseY.szLabel    = "MouseY";
            mouseY.szUnitText = "Pixel";

            // Parameter #0, using the struct, and a format string (described in MSDN
            // under IMediaParamInfo::GetParamText).  Note that when marshaling strings,
            // .NET will add another \0
            ParamDefine(0, gazeX, "GazeX\0Pixel\0");
            ParamDefine(1, gazeY, "GazeY\0Pixel\0");
            ParamDefine(2, mouseX, "MouseX\0Pixel\0");
            ParamDefine(3, mouseY, "MouseY\0Pixel\0");

            // Initialize the buffers for the gaze and mouse cursor overlay bitmaps.
            Bitmap    circleBitmap = (Bitmap)Properties.Resources.Circle;
            Rectangle circleRect   = new Rectangle(0, 0, circleBitmap.Width, circleBitmap.Height);

            this.gazeCursorSize = circleRect.Size;
            this.gazeCursorData = circleBitmap.LockBits(circleRect, ImageLockMode.ReadOnly, circleBitmap.PixelFormat);

            // Get the address of the first line.
            IntPtr gazeCursorScan0Pointer = this.gazeCursorData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int gazeCursorBytes = this.gazeCursorData.Stride * this.gazeCursorData.Height;

            this.gazeCursorArgbValues = new byte[gazeCursorBytes];

            // Copy the RGB values into the array.
            Marshal.Copy(gazeCursorScan0Pointer, this.gazeCursorArgbValues, 0, gazeCursorBytes);

            Bitmap    arrowBitmap = Properties.Resources.Arrow;
            Rectangle cursorRect  = new Rectangle(0, 0, arrowBitmap.Width, arrowBitmap.Height);

            this.mouseCursorSize = cursorRect.Size;
            this.mouseCursorData = arrowBitmap.LockBits(cursorRect, ImageLockMode.ReadOnly, arrowBitmap.PixelFormat);

            // Get the address of the first line.
            IntPtr mouseCursorScan0Pointer = this.mouseCursorData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int mouseCursorBytes = this.mouseCursorData.Stride * this.mouseCursorData.Height;

            this.mouseCursorArgbValues = new byte[mouseCursorBytes];

            // Copy the RGB values into the array.
            Marshal.Copy(mouseCursorScan0Pointer, this.mouseCursorArgbValues, 0, mouseCursorBytes);
        }
Beispiel #10
0
        ///////////////////////////////////////////////////////////////////////////////
        // Construction and Initializing methods                                     //
        ///////////////////////////////////////////////////////////////////////////////
        #region CONSTRUCTION

        /// <summary>
        /// Initializes a new instance of the DmoMixer class.
        /// The parameters to the base class
        /// describe the number of input and output streams, which
        /// DirectShow calls Pins, followed by the number of parameters
        /// this class supports (can be zero), and the timeformat of those
        /// parameters (should include ParamClass.TimeFormatFlags.Reference
        /// if NumParameters > 0).
        /// </summary>
        public DmoMixer()
            : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
        {
            // Initialize the data members
            this.bufferFlags  = 0;
            this.inputStreams = new VideoStream[InputPinCount];

            for (int i = 0; i < InputPinCount; i++)
            {
                this.inputStreams[i] = new VideoStream();
            }

            this.outputStream = new VideoStream();

            // Start describing the parameters this DMO supports.  Building this
            // structure (painful as it is) will allow the base class to automatically
            // support IMediaParamInfo & IMediaParams, which allow clients to find
            // out what parameters you support, and to set them.

            // See the MSDN
            // docs for MP_PARAMINFO for a description of the other parameters
            ParamInfo backgroundColor = new ParamInfo();

            backgroundColor.mopCaps              = MPCaps.Jump;
            backgroundColor.mpdMinValue.vInt     = int.MinValue;
            backgroundColor.mpdMaxValue.vInt     = int.MaxValue;
            backgroundColor.mpdNeutralValue.vInt = 0;
            backgroundColor.mpType     = MPType.INT;
            backgroundColor.szLabel    = "BackgroundColor";
            backgroundColor.szUnitText = "Color";

            ParamDefine(0, backgroundColor, "BackgroundColor\0Color\0");

            for (int i = 0; i < InputPinCount; i++)
            {
                ParamInfo streamLeft = new ParamInfo();
                streamLeft.mopCaps                = MPCaps.Jump;
                streamLeft.mpdMinValue.vFloat     = 0;
                streamLeft.mpdMaxValue.vFloat     = 1;
                streamLeft.mpdNeutralValue.vFloat = 0;
                streamLeft.mpType     = MPType.FLOAT;
                streamLeft.szLabel    = "Stream" + i.ToString() + "Left";
                streamLeft.szUnitText = "Position";

                ParamInfo streamTop = new ParamInfo();
                streamTop.mopCaps                = MPCaps.Jump;
                streamTop.mpdMinValue.vFloat     = 0;
                streamTop.mpdMaxValue.vFloat     = 1;
                streamTop.mpdNeutralValue.vFloat = 0;
                streamTop.mpType     = MPType.FLOAT;
                streamTop.szLabel    = "Stream" + i.ToString() + "Top";
                streamTop.szUnitText = "Position";

                ParamInfo streamWidth = new ParamInfo();
                streamWidth.mopCaps                = MPCaps.Jump;
                streamWidth.mpdMinValue.vFloat     = 0;
                streamWidth.mpdMaxValue.vFloat     = 1;
                streamWidth.mpdNeutralValue.vFloat = 1;
                streamWidth.mpType     = MPType.FLOAT;
                streamWidth.szLabel    = "Stream" + i.ToString() + "Width";
                streamWidth.szUnitText = "Position";

                ParamInfo streamHeight = new ParamInfo();
                streamHeight.mopCaps                = MPCaps.Jump;
                streamHeight.mpdMinValue.vFloat     = 0;
                streamHeight.mpdMaxValue.vFloat     = 1;
                streamHeight.mpdNeutralValue.vFloat = 1;
                streamHeight.mpType     = MPType.FLOAT;
                streamHeight.szLabel    = "Stream" + i.ToString() + "Height";
                streamHeight.szUnitText = "Position";

                ParamInfo streamAlpha = new ParamInfo();
                streamAlpha.mopCaps                = MPCaps.Jump;
                streamAlpha.mpdMinValue.vFloat     = 0;
                streamAlpha.mpdMaxValue.vFloat     = 1;
                streamAlpha.mpdNeutralValue.vFloat = 1;
                streamAlpha.mpType     = MPType.FLOAT;
                streamAlpha.szLabel    = "Stream" + i.ToString() + "Alpha";
                streamAlpha.szUnitText = "Alpha";

                ParamDefine((i * 5) + 1, streamLeft, "Stream" + i.ToString() + "Left\0Position\0");
                ParamDefine((i * 5) + 2, streamTop, "Stream" + i.ToString() + "Top\0Position\0");
                ParamDefine((i * 5) + 3, streamWidth, "Stream" + i.ToString() + "Width\0Position\0");
                ParamDefine((i * 5) + 4, streamHeight, "Stream" + i.ToString() + "Height\0Position\0");
                ParamDefine((i * 5) + 5, streamAlpha, "Stream" + i.ToString() + "Alpha\0Alpha\0");
            }
        }
Beispiel #11
0
    /// <summary>
    /// Release all info for the given input buffer
    /// </summary>
    /// <param name="inputStreamIndex">Index of the input stream to be released.</param>
    private void ReleaseInputBuffs(int inputStreamIndex)
    {
      if (this.inputStreams[inputStreamIndex].Buffer != null)
      {
        Marshal.ReleaseComObject(this.inputStreams[inputStreamIndex].Buffer);
        this.inputStreams[inputStreamIndex].Buffer = null;
      }

      this.inputStreams[inputStreamIndex].BufferPointer = IntPtr.Zero;
      this.inputStreams[inputStreamIndex].BufferByteCount = 0;
      this.bufferFlags = 0;

      // I specifically DON'T release the TimeStamp so we can keep track of where we are
    }
Beispiel #12
0
    /// <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;
    }
Beispiel #13
0
    ///////////////////////////////////////////////////////////////////////////////
    // Construction and Initializing methods                                     //
    ///////////////////////////////////////////////////////////////////////////////
    #region CONSTRUCTION

    /// <summary>
    /// Initializes a new instance of the DmoMixer class.  
    /// The parameters to the base class
    /// describe the number of input and output streams, which
    /// DirectShow calls Pins, followed by the number of parameters
    /// this class supports (can be zero), and the timeformat of those
    /// parameters (should include ParamClass.TimeFormatFlags.Reference
    /// if NumParameters > 0).
    /// </summary>
    public DmoMixer()
      : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
    {
      // Initialize the data members
      this.bufferFlags = 0;
      this.inputStreams = new VideoStream[InputPinCount];

      for (int i = 0; i < InputPinCount; i++)
      {
        this.inputStreams[i] = new VideoStream();
      }

      this.outputStream = new VideoStream();

      // Start describing the parameters this DMO supports.  Building this
      // structure (painful as it is) will allow the base class to automatically
      // support IMediaParamInfo & IMediaParams, which allow clients to find
      // out what parameters you support, and to set them.

      // See the MSDN
      // docs for MP_PARAMINFO for a description of the other parameters
      ParamInfo backgroundColor = new ParamInfo();
      backgroundColor.mopCaps = MPCaps.Jump;
      backgroundColor.mpdMinValue.vInt = int.MinValue;
      backgroundColor.mpdMaxValue.vInt = int.MaxValue;
      backgroundColor.mpdNeutralValue.vInt = 0;
      backgroundColor.mpType = MPType.INT;
      backgroundColor.szLabel = "BackgroundColor";
      backgroundColor.szUnitText = "Color";

      ParamDefine(0, backgroundColor, "BackgroundColor\0Color\0");

      for (int i = 0; i < InputPinCount; i++)
      {
        ParamInfo streamLeft = new ParamInfo();
        streamLeft.mopCaps = MPCaps.Jump;
        streamLeft.mpdMinValue.vFloat = 0;
        streamLeft.mpdMaxValue.vFloat = 1;
        streamLeft.mpdNeutralValue.vFloat = 0;
        streamLeft.mpType = MPType.FLOAT;
        streamLeft.szLabel = "Stream" + i.ToString() + "Left";
        streamLeft.szUnitText = "Position";

        ParamInfo streamTop = new ParamInfo();
        streamTop.mopCaps = MPCaps.Jump;
        streamTop.mpdMinValue.vFloat = 0;
        streamTop.mpdMaxValue.vFloat = 1;
        streamTop.mpdNeutralValue.vFloat = 0;
        streamTop.mpType = MPType.FLOAT;
        streamTop.szLabel = "Stream" + i.ToString() + "Top";
        streamTop.szUnitText = "Position";

        ParamInfo streamWidth = new ParamInfo();
        streamWidth.mopCaps = MPCaps.Jump;
        streamWidth.mpdMinValue.vFloat = 0;
        streamWidth.mpdMaxValue.vFloat = 1;
        streamWidth.mpdNeutralValue.vFloat = 1;
        streamWidth.mpType = MPType.FLOAT;
        streamWidth.szLabel = "Stream" + i.ToString() + "Width";
        streamWidth.szUnitText = "Position";

        ParamInfo streamHeight = new ParamInfo();
        streamHeight.mopCaps = MPCaps.Jump;
        streamHeight.mpdMinValue.vFloat = 0;
        streamHeight.mpdMaxValue.vFloat = 1;
        streamHeight.mpdNeutralValue.vFloat = 1;
        streamHeight.mpType = MPType.FLOAT;
        streamHeight.szLabel = "Stream" + i.ToString() + "Height";
        streamHeight.szUnitText = "Position";

        ParamInfo streamAlpha = new ParamInfo();
        streamAlpha.mopCaps = MPCaps.Jump;
        streamAlpha.mpdMinValue.vFloat = 0;
        streamAlpha.mpdMaxValue.vFloat = 1;
        streamAlpha.mpdNeutralValue.vFloat = 1;
        streamAlpha.mpType = MPType.FLOAT;
        streamAlpha.szLabel = "Stream" + i.ToString() + "Alpha";
        streamAlpha.szUnitText = "Alpha";

        ParamDefine((i * 5) + 1, streamLeft, "Stream" + i.ToString() + "Left\0Position\0");
        ParamDefine((i * 5) + 2, streamTop, "Stream" + i.ToString() + "Top\0Position\0");
        ParamDefine((i * 5) + 3, streamWidth, "Stream" + i.ToString() + "Width\0Position\0");
        ParamDefine((i * 5) + 4, streamHeight, "Stream" + i.ToString() + "Height\0Position\0");
        ParamDefine((i * 5) + 5, streamAlpha, "Stream" + i.ToString() + "Alpha\0Alpha\0");
      }
    }
Beispiel #14
0
        /// <summary>
        /// Release all info for the most recent input buffer
        /// </summary>
        private void ReleaseInputBuffs()
        {
            if (m_pBuffer != null)
            {
                Marshal.ReleaseComObject(m_pBuffer);
                m_pBuffer = null;
            }
            m_InBuffer = IntPtr.Zero;
            m_cbInData = 0;
            m_Flags = 0;

            // I specifically DON'T release the TimeStamp so we can keep track of where we are
        }
Beispiel #15
0
        /// <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;
        }
Beispiel #16
0
    ///////////////////////////////////////////////////////////////////////////////
    // Construction and Initializing methods                                     //
    ///////////////////////////////////////////////////////////////////////////////
    #region CONSTRUCTION

    /// <summary>
    /// Initializes a new instance of the DmoOverlay class.  
    /// The parameters to the base class
    /// describe the number of input and output streams, which
    /// DirectShow calls Pins, followed by the number of parameters
    /// this class supports (can be zero), and the timeformat of those
    /// parameters (should include ParamClass.TimeFormatFlags.Reference
    /// if NumParameters > 0).
    /// </summary>
    public DmoOverlay()
      : base(InputPinCount, OutputPinCount, NumParams, TimeFormatFlags.Reference)
    {
      // Initialize the data members
      this.streamWidth = 0;
      this.streamHeight = 0;
      this.streamStride = 0;
      this.streamBBP = 0;
      this.bufferTimeStamp = 0;
      this.bufferTimeLength = 0;
      this.bufferByteCount = 0;
      this.bufferFlags = 0;
      this.bufferPointer = IntPtr.Zero;
      this.buffer = null;

      // Start describing the parameters this DMO supports.  Building this
      // structure (painful as it is) will allow the base class to automatically
      // support IMediaParamInfo & IMediaParams, which allow clients to find
      // out what parameters you support, and to set them.

      // See the MSDN
      // docs for MP_PARAMINFO for a description of the other parameters
      ParamInfo gazeX = new ParamInfo();
      gazeX.mopCaps = MPCaps.Jump;
      gazeX.mpdMinValue.vInt = 0;
      gazeX.mpdMaxValue.vInt = 2000;
      gazeX.mpdNeutralValue.vInt = 1;
      gazeX.mpType = MPType.INT;
      gazeX.szLabel = "GazeX";
      gazeX.szUnitText = "Pixel";

      ParamInfo gazeY = new ParamInfo();
      gazeY.mopCaps = MPCaps.Jump;
      gazeY.mpdMinValue.vInt = 0;
      gazeY.mpdMaxValue.vInt = 2000;
      gazeY.mpdNeutralValue.vInt = 1;
      gazeY.mpType = MPType.INT;
      gazeY.szLabel = "GazeY";
      gazeY.szUnitText = "Pixel";

      ParamInfo mouseX = new ParamInfo();
      mouseX.mopCaps = MPCaps.Jump;
      mouseX.mpdMinValue.vInt = 0;
      mouseX.mpdMaxValue.vInt = 2000;
      mouseX.mpdNeutralValue.vInt = 1;
      mouseX.mpType = MPType.INT;
      mouseX.szLabel = "MouseX";
      mouseX.szUnitText = "Pixel";

      ParamInfo mouseY = new ParamInfo();
      mouseY.mopCaps = MPCaps.Jump;
      mouseY.mpdMinValue.vInt = 0;
      mouseY.mpdMaxValue.vInt = 2000;
      mouseY.mpdNeutralValue.vInt = 1;
      mouseY.mpType = MPType.INT;
      mouseY.szLabel = "MouseY";
      mouseY.szUnitText = "Pixel";

      // Parameter #0, using the struct, and a format string (described in MSDN
      // under IMediaParamInfo::GetParamText).  Note that when marshaling strings,
      // .NET will add another \0
      ParamDefine(0, gazeX, "GazeX\0Pixel\0");
      ParamDefine(1, gazeY, "GazeY\0Pixel\0");
      ParamDefine(2, mouseX, "MouseX\0Pixel\0");
      ParamDefine(3, mouseY, "MouseY\0Pixel\0");

      // Initialize the buffers for the gaze and mouse cursor overlay bitmaps.
      Bitmap circleBitmap = (Bitmap)Properties.Resources.Circle;
      Rectangle circleRect = new Rectangle(0, 0, circleBitmap.Width, circleBitmap.Height);
      this.gazeCursorSize = circleRect.Size;
      this.gazeCursorData = circleBitmap.LockBits(circleRect, ImageLockMode.ReadOnly, circleBitmap.PixelFormat);

      // Get the address of the first line.
      IntPtr gazeCursorScan0Pointer = this.gazeCursorData.Scan0;

      // Declare an array to hold the bytes of the bitmap.
      int gazeCursorBytes = this.gazeCursorData.Stride * this.gazeCursorData.Height;
      this.gazeCursorArgbValues = new byte[gazeCursorBytes];

      // Copy the RGB values into the array.
      Marshal.Copy(gazeCursorScan0Pointer, this.gazeCursorArgbValues, 0, gazeCursorBytes);

      Bitmap arrowBitmap = Properties.Resources.Arrow;
      Rectangle cursorRect = new Rectangle(0, 0, arrowBitmap.Width, arrowBitmap.Height);
      this.mouseCursorSize = cursorRect.Size;
      this.mouseCursorData = arrowBitmap.LockBits(cursorRect, ImageLockMode.ReadOnly, arrowBitmap.PixelFormat);

      // Get the address of the first line.
      IntPtr mouseCursorScan0Pointer = this.mouseCursorData.Scan0;

      // Declare an array to hold the bytes of the bitmap.
      int mouseCursorBytes = this.mouseCursorData.Stride * this.mouseCursorData.Height;
      this.mouseCursorArgbValues = new byte[mouseCursorBytes];

      // Copy the RGB values into the array.
      Marshal.Copy(mouseCursorScan0Pointer, this.mouseCursorArgbValues, 0, mouseCursorBytes);
    }