public void SetFrameRate(MFRatio fps) { // Convert to a duration. int 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; }
protected MFRect CorrectAspectRatio(MFRect src, MFRatio srcPAR, MFRatio destPAR) { // Start with a rectangle the same size as src, but offset to the origin (0,0). MFRect rc = new MFRect(0, 0, src.right - src.left, src.bottom - src.top); // If the source and destination have the same PAR, there is nothing to do. // Otherwise, adjust the image size, in two steps: // 1. Transform from source PAR to 1:1 // 2. Transform from 1:1 to destination PAR. if ((srcPAR.Numerator != destPAR.Numerator) || (srcPAR.Denominator != destPAR.Denominator)) { // Correct for the source's PAR. if (srcPAR.Numerator > srcPAR.Denominator) { // The source has "wide" pixels, so stretch the width. rc.right = Utils.MulDiv(rc.right, srcPAR.Numerator, srcPAR.Denominator); } else if (srcPAR.Numerator > srcPAR.Denominator) { // The source has "tall" pixels, so stretch the height. rc.bottom = Utils.MulDiv(rc.bottom, srcPAR.Denominator, srcPAR.Numerator); } // else: PAR is 1:1, which is a no-op. // Next, correct for the target's PAR. This is the inverse operation of the previous. if (destPAR.Numerator > destPAR.Denominator) { // The destination has "tall" pixels, so stretch the width. rc.bottom = Utils.MulDiv(rc.bottom, destPAR.Denominator, destPAR.Numerator); } else if (destPAR.Numerator > destPAR.Denominator) { // The destination has "fat" pixels, so stretch the height. rc.right = Utils.MulDiv(rc.right, destPAR.Numerator, destPAR.Denominator); } // else: PAR is 1:1, which is a no-op. } return rc; }
// 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); }
public void SetPixelAspectRatio(MFRatio ratio) { Utils.MFSetAttribute2UINT32asUINT64(GetMediaType(), MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, ratio.Numerator, ratio.Denominator); }
// Defaults to 1:1 (square pixels) // // 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() { 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; }
// Gets the frames per second as a ratio. public void GetFrameRate(out MFRatio pRatio) { GetFrameRate(out pRatio.Numerator, out pRatio.Denominator); }
//----------------------------------------------------------------------------- // 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 = MulDiv(rc.Right, srcPAR.Numerator, srcPAR.Denominator); } else if (srcPAR.Numerator < srcPAR.Denominator) { // The source has "tall" pixels, so stretch the height. rcNewHeight = 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; }
//------------------------------------------------------------------- // SetVideoType // // Set the video format. //------------------------------------------------------------------- public int SetVideoType(IMFMediaType pType) { int hr = 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 = 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 = 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; m_bmpconvertFn = null; } return hr; }
//------------------------------------------------------------------- // 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; }