//----------------------------------------------------------------------------- // 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); }
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; }
// // 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); }
//------------------------------------------------------------------- // 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); }
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; }
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; }
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; }
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); }
public void SetPixelAspectRatio(MFRatio ratio) { Utils.MFSetAttribute2UINT32asUINT64(GetMediaType(), MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, ratio.Numerator, ratio.Denominator); }
// 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); }
// Gets the frames per second as a ratio. public void GetFrameRate(out MFRatio pRatio) { GetFrameRate(out pRatio.Numerator, out pRatio.Denominator); }
//------------------------------------------------------------------- // 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); }