Пример #1
0
        //-----------------------------------------------------------------------------
        // CorrectAspectRatio
        //
        // Converts a rectangle from the source's pixel aspect ratio (PAR) to 1:1 PAR.
        // Returns the corrected rectangle.
        //
        // For example, a 720 x 486 rect with a PAR of 9:10, when converted to 1x1 PAR,
        // is stretched to 720 x 540.
        //-----------------------------------------------------------------------------
        private static Rectangle CorrectAspectRatio(Rectangle src, MFRatio srcPAR)
        {
            // Start with a rectangle the same size as src, but offset to the origin (0,0).
            Rectangle rc          = new Rectangle(0, 0, src.Right - src.Left, src.Bottom - src.Top);
            int       rcNewWidth  = rc.Right;
            int       rcNewHeight = rc.Bottom;

            if ((srcPAR.Numerator != 1) || (srcPAR.Denominator != 1))
            {
                // Correct for the source's PAR.

                if (srcPAR.Numerator > srcPAR.Denominator)
                {
                    // The source has "wide" pixels, so stretch the width.
                    rcNewWidth = Kernal32.MulDiv(rc.Right, srcPAR.Numerator, srcPAR.Denominator);
                }
                else if (srcPAR.Numerator < srcPAR.Denominator)
                {
                    // The source has "tall" pixels, so stretch the height.
                    rcNewHeight = Kernal32.MulDiv(rc.Bottom, srcPAR.Denominator, srcPAR.Numerator);
                }
                // else: PAR is 1:1, which is a no-op.
            }

            rc = new Rectangle(0, 0, rcNewWidth, rcNewHeight);
            return(rc);
        }
Пример #2
0
        public void SetFrameRate(MFRatio fps)
        {
            // Convert to a duration.
            HResult hr = MFExtern.MFFrameRateToAverageTimePerFrame(fps.Numerator, fps.Denominator, out m_PerFrameInterval);

            MFError.ThrowExceptionForHR(hr);

            // Calculate 1/4th of this value, because we use it frequently.
            m_PerFrame_1_4th = m_PerFrameInterval / 4;
        }
Пример #3
0
        //
        // The following versions return reasonable defaults if the relevant attribute is not present (zero/FALSE).
        // This is useful for making quick comparisons betweeen media types.
        //

        public MFRatio GetPixelAspectRatio() // Defaults to 1:1 (square pixels)
        {
            MFRatio PAR = new MFRatio();

            try
            {
                Utils.MFGetAttribute2UINT32asUINT64(GetMediaType(), MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, out PAR.Numerator, out PAR.Denominator);
            }
            catch
            {
                PAR.Numerator   = 1;
                PAR.Denominator = 1;
            }
            return(PAR);
        }
Пример #4
0
        //-------------------------------------------------------------------
        // SetVideoType
        //
        // Set the video format.
        //-------------------------------------------------------------------
        public HResult InitializeSetVideoSize(int width, int height, MFRatio ratio)
        {
            HResult hr = HResult.S_OK;

            // Choose a conversion function.
            // (This also validates the format type.)
            hr = SetConversionFunction(MFMediaType.YUY2);
            if (Failed(hr))
            {
                goto done;
            }

            // Get some video attributes.
            m_width   = width;
            m_height  = height;
            m_PixelAR = ratio;

            FourCC f = new FourCC(MFMediaType.YUY2);

            m_format = (Format)f.ToInt32();
            // Get the image stride.
            hr = MFExtern.MFGetStrideForBitmapInfoHeader(f.ToInt32(), width, out m_lDefaultStride);

            // Create Direct3D swap chains.
            hr = CreateSwapChains();
            if (Failed(hr))
            {
                goto done;
            }

            // Update the destination rectangle for the correct
            // aspect ratio.
            UpdateDestinationRect();

done:
            if (Failed(hr))
            {
                m_format    = Format.Unknown;
                m_convertFn = null;
            }

            return(hr);
        }
Пример #5
0
        protected HRESULT CalculateOutputRectangle(IMFMediaType pProposedType, out DsRect prcOutput)
        {
            prcOutput = null;
            HRESULT hr = S_OK;
            int srcWidth = 0, srcHeight = 0;

            MFRatio inputPAR = new MFRatio(0, 0);
            MFRatio outputPAR = new MFRatio(0, 0);
            DsRect rcOutput = new DsRect(0, 0, 0, 0);

            MFVideoArea displayArea;

            MFHelper.VideoTypeBuilder pmtProposed = null;

            // Helper object to read the media type.
            hr = MFHelper.MediaTypeBuilder.Create(pProposedType, out pmtProposed);
            if (hr.Failed) return hr;

            // Get the source's frame dimensions.
            hr = pmtProposed.GetFrameDimensions(out srcWidth, out srcHeight);
            if (hr.Failed) return hr;

            // Get the source's display area.
            hr = pmtProposed.GetVideoDisplayArea(out displayArea);
            if (hr.Failed) return hr;

            // Calculate the x,y offsets of the display area.
            int offsetX = (int)displayArea.OffsetX.GetOffset();
            int offsetY = (int)displayArea.OffsetY.GetOffset();

            // Use the display area if valid. Otherwise, use the entire frame.
            if (displayArea.Area.Width != 0 &&
                displayArea.Area.Height != 0 &&
                offsetX + displayArea.Area.Width <= (srcWidth) &&
                offsetY + displayArea.Area.Height <= (srcHeight))
            {
                rcOutput.left = offsetX;
                rcOutput.right = offsetX + displayArea.Area.Width;
                rcOutput.top = offsetY;
                rcOutput.bottom = offsetY + displayArea.Area.Height;
            }
            else
            {
                rcOutput.left = 0;
                rcOutput.top = 0;
                rcOutput.right = srcWidth;
                rcOutput.bottom = srcHeight;
            }

            // rcOutput is now either a sub-rectangle of the video frame, or the entire frame.

            // If the pixel aspect ratio of the proposed media type is different from the monitor's,
            // letterbox the video. We stretch the image rather than shrink it.

            inputPAR = pmtProposed.GetPixelAspectRatio();    // Defaults to 1:1

            outputPAR.Denominator = outputPAR.Numerator = 1; // This is an assumption of the sample.

            // Adjust to get the correct picture aspect ratio.
            prcOutput = MFHelper.CorrectAspectRatio(rcOutput, inputPAR, outputPAR);

            return NOERROR;
        }
Пример #6
0
            public void SetFrameRate(MFRatio fps)
            {
                long AvgTimePerFrame = 0;

                // Convert to a duration.
                MFFrameRateToAverageTimePerFrame(fps.Numerator, fps.Denominator, out AvgTimePerFrame);

                m_PerFrameInterval = AvgTimePerFrame;

                // Calculate 1/4th of this value, because we use it frequently.
                m_PerFrame_1_4th = m_PerFrameInterval / 4;
            }
Пример #7
0
        protected HRESULT SetMediaType(IMFMediaType pMediaType)
        {
            // Note: pMediaType can be NULL (to clear the type)

            // Clearing the media type is allowed in any state (including shutdown).
            if (pMediaType == null)
            {
                m_pMediaType = null;
                ReleaseResources();
                return S_OK;
            }

            HRESULT hr = S_OK;
            MFRatio fps = new MFRatio(0, 0);

            // Cannot set the media type after shutdown.
            hr = CheckShutdown();

            if (hr.Succeeded)
            {
                // Check if the new type is actually different.
                // Note: This function safely handles NULL input parameters.
                if (MFHelper.AreMediaTypesEqual(m_pMediaType, pMediaType))
                {
                    return S_OK; // Nothing more to do.
                }

                // We're really changing the type. First get rid of the old type.
                m_pMediaType = null;
                ReleaseResources();

                // Initialize the presenter engine with the new media type.
                // The presenter engine allocates the samples.

                hr = CreateVideoSamples(pMediaType);

                if (hr.Succeeded)
                {
                    // Set the frame rate on the scheduler.
                    if (SUCCEEDED(MFHelper.GetFrameRate(pMediaType, out fps)) && (fps.Numerator != 0) && (fps.Denominator != 0))
                    {
                        m_scheduler.SetFrameRate(fps);
                    }
                    else
                    {
                        // NOTE: The mixer's proposed type might not have a frame rate, in which case
                        // we'll use an arbitary default. (Although it's unlikely the video source
                        // does not have a frame rate.)
                        m_scheduler.SetFrameRate(g_DefaultFrameRate);
                    }

                    // Store the media type.
                    ASSERT(pMediaType != NULL);
                    m_pMediaType = pMediaType;
                }
            }

            if (hr.Failed)
            {
                ReleaseResources();
            }
            return hr;
        }
Пример #8
0
        public HResult SetVideoType(IMFMediaType pType)
        {
            HResult hr = HResult.S_OK;
            Guid    subtype;
            MFRatio PAR = new MFRatio();

            // Find the video subtype.
            hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype);
            if (Failed(hr))
            {
                goto done;
            }

            // Choose a conversion function.
            // (This also validates the format type.)

            hr = SetConversionFunction(subtype);
            if (Failed(hr))
            {
                goto done;
            }

            //
            // Get some video attributes.
            //

            // Get the frame size.
            hr = MFExtern.MFGetAttributeSize(pType, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_width, out m_height);
            if (Failed(hr))
            {
                goto done;
            }

            // Get the image stride.
            hr = GetDefaultStride(pType, out m_lDefaultStride);
            if (Failed(hr))
            {
                goto done;
            }

            // Get the pixel aspect ratio. Default: Assume square pixels (1:1)
            hr = MFExtern.MFGetAttributeRatio(pType, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, out PAR.Numerator, out PAR.Denominator);

            if (Succeeded(hr))
            {
                m_PixelAR = PAR;
            }
            else
            {
                m_PixelAR.Numerator = m_PixelAR.Denominator = 1;
            }

            FourCC f = new FourCC(subtype);

            m_format = (Format)f.ToInt32();

            // Create Direct3D swap chains.

            hr = CreateSwapChains();
            if (Failed(hr))
            {
                goto done;
            }

            // Update the destination rectangle for the correct
            // aspect ratio.

            UpdateDestinationRect();

done:
            if (Failed(hr))
            {
                m_format    = Format.Unknown;
                m_convertFn = null;
            }

            return(hr);
        }
Пример #9
0
 public void SetPixelAspectRatio(MFRatio ratio)
 {
     Utils.MFSetAttribute2UINT32asUINT64(GetMediaType(), MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, ratio.Numerator, ratio.Denominator);
 }
Пример #10
0
 // Sets the number of frames per second, as a ratio.
 public void SetFrameRate(MFRatio ratio)
 {
     Utils.MFSetAttribute2UINT32asUINT64(GetMediaType(), MFAttributesClsid.MF_MT_FRAME_RATE, ratio.Numerator, ratio.Denominator);
 }
Пример #11
0
 // Gets the frames per second as a ratio.
 public void GetFrameRate(out MFRatio pRatio)
 {
     GetFrameRate(out pRatio.Numerator, out pRatio.Denominator);
 }
Пример #12
0
        //-------------------------------------------------------------------
        // SetVideoType
        //
        // Set the video snapFormat.
        //-------------------------------------------------------------------
        public int SetVideoType(IMFMediaType pType)
        {
            Guid subtype;
            var  PAR = new MFRatio();

            // Find the video subtype.
            var hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype);

            try
            {
                if (Failed(hr))
                {
                    throw new Exception();
                }

                // Choose a conversion function.
                // (This also validates the snapFormat type.)

                hr = SetConversionFunction(subtype);
                if (Failed(hr))
                {
                    throw new Exception();
                }

                //
                // Get some video attributes.
                //

                // Get the frame size.
                hr = CProcess.MfGetAttributeSize(pType, out width, out height);
                if (Failed(hr))
                {
                    throw new Exception();
                }

                // Get the image stride.
                hr = GetDefaultStride(pType, out lDefaultStride);
                if (Failed(hr))
                {
                    throw new Exception();
                }

                // Get the pixel aspect ratio. Default: Assume square pixels (1:1)
                hr = CProcess.MfGetAttributeRatio(pType, out PAR.Numerator, out PAR.Denominator);

                if (Succeeded(hr))
                {
                    pixelAR = PAR;
                }
                else
                {
                    pixelAR.Numerator = pixelAR.Denominator = 1;
                }

                var f = new FourCC(subtype);
                format = (Format)f.ToInt32();

                // Create Direct3D swap chains.

                hr = CreateSwapChains();
                if (Failed(hr))
                {
                    throw new Exception();
                }

                // Update the destination rectangle for the correct
                // aspect ratio.

                UpdateDestinationRect();
            }
            finally
            {
                if (Failed(hr))
                {
                    format      = Format.Unknown;
                    m_convertFn = null;
                }
            }
            return(hr);
        }