protected MFRect m_rcDestRect; // Destination rectangle. #endregion Fields #region Constructors public D3DPresentEngine() { m_iFrames = 0; m_hwnd = IntPtr.Zero; m_DeviceResetToken = 0; m_pD3D9 = null; m_pDevice = null; m_pDeviceManager = null; m_pSurfaceRepaint = null; m_rcDestRect = new MFRect(); m_DisplayMode = new D3DDISPLAYMODE(); InitializeD3D(); CreateD3DDevice(); }
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; }
protected void CalculateOutputRectangle(IMFMediaType pProposed, out MFRect prcOutput) { int srcWidth = 0, srcHeight = 0; MFRatio inputPAR; MFRatio outputPAR; MFRect rcOutput = new MFRect(); MFVideoArea displayArea; VideoTypeBuilder pmtProposed = null; // Helper object to read the media type. pmtProposed = new VideoTypeBuilder(pProposed); // Get the source's frame dimensions. pmtProposed.GetFrameDimensions(out srcWidth, out srcHeight); // Get the source's display area. pmtProposed.GetVideoDisplayArea(out displayArea); // 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 = CorrectAspectRatio(rcOutput, inputPAR, outputPAR); pmtProposed.Dispose(); }
public int SetVideoPosition(MFVideoNormalizedRect pnrcSource, MFRect prcDest) { // Make sure we *never* leave this entry point with an exception try { lock (this) { // Validate parameters. // One parameter can be NULL, but not both. if (pnrcSource == null && prcDest == null) { throw new COMException("EVRCustomPresenter::SetVideoPosition", E_Pointer); } // Validate the rectangles. if (pnrcSource != null) { // The source rectangle cannot be flipped. if ((pnrcSource.left > pnrcSource.right) || (pnrcSource.top > pnrcSource.bottom)) { throw new COMException("Bad source", E_InvalidArgument); } // The source rectangle has range (0..1) if ((pnrcSource.left < 0) || (pnrcSource.right > 1) || (pnrcSource.top < 0) || (pnrcSource.bottom > 1)) { throw new COMException("source has invalid values", E_InvalidArgument); } } if (prcDest != null) { // The destination rectangle cannot be flipped. if ((prcDest.left > prcDest.right) || (prcDest.top > prcDest.bottom)) { throw new COMException("bad destination", E_InvalidArgument); } } // Update the source rectangle. Source clipping is performed by the mixer. if (pnrcSource != null) { m_nrcSource.CopyFrom(pnrcSource); if (m_pMixer != null) { SetMixerSourceRect(m_pMixer, m_nrcSource); } } // Update the destination rectangle. if (prcDest != null) { MFRect rcOldDest = m_pD3DPresentEngine.GetDestinationRect(); // Check if the destination rectangle changed. if (!rcOldDest.Equals(prcDest)) { m_pD3DPresentEngine.SetDestinationRect(prcDest); // Set a new media type on the mixer. if (m_pMixer != null) { try { RenegotiateMediaType(); } catch (COMException e) { if (e.ErrorCode == MFError.MF_E_TRANSFORM_TYPE_NOT_SET) { // This error means that the mixer is not ready for the media type. // Not a failure case -- the EVR will notify us when we need to set // the type on the mixer. } else { throw; } } // The media type changed. Request a repaint of the current frame. m_bRepaint = true; ProcessOutput(); // Ignore errors, the mixer might not have a video frame. } } } } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
void TestSetVideoPosition() { MFVideoNormalizedRect r1 = new MFVideoNormalizedRect(); MFRect r2 = new MFRect(); r1.bottom = 1.0f; r1.right = 0.9f; r2.bottom = 234; r2.right = 345; int hr = m_vdc.SetVideoPosition(r1, r2); MFError.ThrowExceptionForHR(hr); MFVideoNormalizedRect r3 = new MFVideoNormalizedRect(); MFRect r4 = new MFRect(); hr = m_vdc.GetVideoPosition(r3, r4); MFError.ThrowExceptionForHR(hr); }
//----------------------------------------------------------------------------- // UpdateDestRect // // Updates the target rectangle by clipping it to the video window's client // area. // // Called whenever the application sets the video window or the destination // rectangle. //----------------------------------------------------------------------------- protected void UpdateDestRect() { if (m_hwnd != IntPtr.Zero) { MediaFoundation.Misc.MFRect rcView = new MFRect(); GetClientRect(m_hwnd, rcView); // Clip the destination rectangle to the window's client area. if (m_rcDestRect.right > rcView.right) { m_rcDestRect.right = rcView.right; } if (m_rcDestRect.bottom > rcView.bottom) { m_rcDestRect.bottom = rcView.bottom; } } }
private void menuItem14_Click(object sender, EventArgs e) { MFVideoAlphaBitmap alphaBmp = new MFVideoAlphaBitmap(); using (Bitmap alphaBitmap = new Bitmap("epsonproj.png")) { //alphaBitmap is a 32bit semitransparent Bitmap Graphics g = Graphics.FromImage(alphaBitmap); // get pointer to needed objects IntPtr hdc = g.GetHdc(); IntPtr memDC = CreateCompatibleDC(hdc); IntPtr hBitmap = alphaBitmap.GetHbitmap(); IntPtr hOld = SelectObject(memDC, hBitmap); alphaBmp.GetBitmapFromDC = true; alphaBmp.stru = memDC; alphaBmp.paras = new MFVideoAlphaBitmapParams(); alphaBmp.paras.dwFlags = MFVideoAlphaBitmapFlags.Alpha | MFVideoAlphaBitmapFlags.DestRect; // calculate destination rectangle MFVideoNormalizedRect mfNRect = new MFVideoNormalizedRect(); //NormalizedRect nRect = GetDestRectangle(width, height, subtitleLines); mfNRect.top = 0.5f;// nRect.top; mfNRect.left = 0.5f;// nRect.left; mfNRect.right = 1.0f;//nRect.right; mfNRect.bottom = 1.0f;// nRect.bottom; // used when viewing half side by side anaglyph video that is stretched to full width //if (FrameMode == Mars.FrameMode.HalfSideBySide) //{ // mfNRect.left /= 2; // mfNRect.right /= 2; //} alphaBmp.paras.nrcDest = mfNRect; // calculate source rectangle (full subtitle bitmap) MFRect rcSrc = new MFRect(); rcSrc.bottom = alphaBitmap.Height; rcSrc.right = alphaBitmap.Width; rcSrc.top = 0; rcSrc.left = 0; alphaBmp.paras.rcSrc = rcSrc; // apply 1-bit transparency //System.Drawing.Color colorKey = System.Drawing.Color.White; //alphaBmp.paras.clrSrcKey = ColorTranslator.ToWin32(colorKey); // 90% visible alphaBmp.paras.fAlpha = 0.5F; // set the bitmap to the evr mixer mixBmp.SetAlphaBitmap(alphaBmp); // cleanup SelectObject(memDC, hOld); DeleteDC(memDC); g.ReleaseHdc(); } }
/// <summary> /// Resize video /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public int ResizeVideo(short width, short height) { TRACE(string.Format("ResizeVideo: {0}x{1}", width, height)); int hr = S_Ok; if (m_pVideoDisplay != null) { try { MFRect rcDest = new MFRect(); MFVideoNormalizedRect nRect = new MFVideoNormalizedRect(); nRect.left = 0; nRect.right = 1; nRect.top = 0; nRect.bottom = 1; rcDest.left = 0; rcDest.top = 0; rcDest.right = width; rcDest.bottom = height; m_pVideoDisplay.SetVideoPosition(nRect, rcDest); } catch (Exception e) { hr = Marshal.GetHRForException(e); } } return hr; }
/// <summary> /// Copy the members from an MFRect into this object /// </summary> /// <param name="from">The rectangle from which to copy the values.</param> public void CopyFrom(MFRect from) { left = from.left; top = from.top; right = from.right; bottom = from.bottom; }
private void InitializeEVR(IBaseFilter pEVR, int dwStreams, out IMFVideoDisplayControl ppDisplay) { IMFVideoRenderer pRenderer; IMFVideoDisplayControl pDisplay; IEVRFilterConfig pConfig; IMFVideoPresenter pPresenter; // Before doing anything else, set any custom presenter or mixer. // Presenter? if (m_clsidPresenter != Guid.Empty) { Type type = Type.GetTypeFromCLSID(m_clsidPresenter); // An error here means that the custom presenter sample from // http://mfnet.sourceforge.net hasn't been installed or // registered. pPresenter = (IMFVideoPresenter)Activator.CreateInstance(type); try { pRenderer = (IMFVideoRenderer)pEVR; pRenderer.InitializeRenderer(null, pPresenter); } finally { //Marshal.ReleaseComObject(pPresenter); } } // Continue with the rest of the set-up. // Set the video window. object o; IMFGetService pGetService = null; pGetService = (IMFGetService)pEVR; pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out o); try { pDisplay = (IMFVideoDisplayControl)o; } catch { Marshal.ReleaseComObject(o); throw; } try { // Set the number of streams. pDisplay.SetVideoWindow(m_hwndVideo.Handle); if (dwStreams > 1) { pConfig = (IEVRFilterConfig)pEVR; pConfig.SetNumberOfStreams(dwStreams); } // Set the display position to the entire window. Rectangle r = m_hwndVideo.ClientRectangle; MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); pDisplay.SetVideoPosition(null, rc); // Return the IMFVideoDisplayControl pointer to the caller. ppDisplay = pDisplay; } finally { //Marshal.ReleaseComObject(pDisplay); } m_pMixer = null; }
private void SetAspectRatio(Size? ratio = null, bool setVideoWindow = true) { int screenWidth; int screenHeight; if (m_graph == null) return; if (_isInExclusiveMode) { var size = System.Windows.Forms.Screen.FromControl(_hiddenWindow.Form).Bounds; screenWidth = size.Width; screenHeight = size.Height; } else { var hiddenWindowContentSize = _hiddenWindow.ContentPixelSize; screenWidth = hiddenWindowContentSize.Width; screenHeight = hiddenWindowContentSize.Height; } // Set the display position to the entire window. if (_mPDisplay != null) { var rc = new MFRect(0, 0, screenWidth, screenHeight); _mPDisplay.SetVideoPosition(null, rc); } // Get Aspect Ratio int aspectX; int aspectY; if (ratio.HasValue) { aspectX = ratio.Value.Width; aspectY = ratio.Value.Height; } else { var basicVideo2 = (IBasicVideo2)m_graph; basicVideo2.GetPreferredAspectRatio(out aspectX, out aspectY); var sourceHeight = 0; var sourceWidth = 0; _basicVideo.GetVideoSize(out sourceWidth, out sourceHeight); if (aspectX == 0 || aspectY == 0 || sourceWidth > 0 || sourceHeight > 0) { aspectX = sourceWidth; aspectY = sourceHeight; } } // Adjust Video Size var iAdjustedHeight = 0; if (aspectX > 0 && aspectY > 0) { double adjustedHeight = aspectY * screenWidth; adjustedHeight /= aspectX; iAdjustedHeight = Convert.ToInt32(Math.Round(adjustedHeight)); } if (screenHeight > iAdjustedHeight && iAdjustedHeight > 0) { double totalMargin = (screenHeight - iAdjustedHeight); var topMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(0, topMargin, screenWidth, iAdjustedHeight); } else if (iAdjustedHeight > 0) { double adjustedWidth = aspectX * screenHeight; adjustedWidth /= aspectY; var iAdjustedWidth = Convert.ToInt32(Math.Round(adjustedWidth)); double totalMargin = (screenWidth - iAdjustedWidth); var leftMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(leftMargin, 0, iAdjustedWidth, screenHeight); } if (setVideoWindow) { _videoWindow.SetWindowPosition(0, 0, screenWidth, screenHeight); } }
public void Track(Point pt) { if (m_pMixer == null || m_pMapper == null) { throw new COMException("null mixer or mapper", MFError.MF_E_INVALIDREQUEST); } Rectangle r = m_hwndVideo.ClientRectangle; MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); // x, y: Mouse coordinates, normalized relative to the composition rectangle. float x = (float)pt.X / rc.right; float y = (float)pt.Y / rc.bottom; // Map the mouse coordinates to the reference stream. m_pMapper.MapOutputCoordinateToInputStream( x, y, // Output coordinates 0, // Output stream (the mixer only has one) 0, // Input stream (0 = ref stream) out x, out y // Receives the normalized input coordinates. ); // Offset by the original hit point. x -= m_ptHitTrack.X; y -= m_ptHitTrack.Y; float max_offset = 1.0f - m_fScale; // Maximum left and top positions for the substream. MFVideoNormalizedRect nrcDest = new MFVideoNormalizedRect(); if (x < 0) { nrcDest.left = 0; nrcDest.right = m_fScale; } else if (x > max_offset) { nrcDest.right = 1; nrcDest.left = max_offset; } else { nrcDest.left = x; nrcDest.right = x + m_fScale; } if (y < 0) { nrcDest.top = 0; nrcDest.bottom = m_fScale; } else if (y > max_offset) { nrcDest.bottom = 1; nrcDest.top = max_offset; } else { nrcDest.top = y; nrcDest.bottom = y + m_fScale; } // Set the new position. m_pMixer.SetStreamOutputRect(1, nrcDest); }
public bool HitTest(Point pt) { if (m_pMapper == null) { throw new COMException("null mapper", MFError.MF_E_INVALIDREQUEST); } int hr = 0; bool bHit = false; float x = -1, y = -1; // Normalize the coordinates (ie, calculate them as a percentage of // the video window's entire client area). Rectangle r = m_hwndVideo.ClientRectangle; MFRect rc = new MFRect(r.Left, r.Top, r.Right, r.Bottom); float x1 = (float)pt.X / rc.right; float y1 = (float)pt.Y / rc.bottom; // Map these coordinates into the coordinate space of the substream. m_pMapper.MapOutputCoordinateToInputStream( x1, y1, // Output coordinates 0, // Output stream (the mixer only has one) 1, // Input stream (1 = substream) out x, out y // Receives the normalized input coordinates. ); // If the mapped coordinates fall within [0-1], it's a hit. if (Succeeded(hr)) { bHit = ((x >= 0) && (x <= 1) && (y >= 0) && (y <= 1)); } if (bHit) { // Store the hit point. // We adjust the hit point by the substream scaling factor, so that the // hit point is now scaled to the reference stream. // Example: // - The hit point is (0.5,0.5), the center of the image. // - The scaling factor is 0.5, so the substream image is 50% the size // of the reference stream. // The adjusted hit point is (0.25,0.25) FROM the origin of the substream // rectangle but IN units of the reference stream. See DShowPlayer::Track // for where this is used. m_ptHitTrack = new PointF(x * m_fScale, y * m_fScale); } return bHit ? true : false; }
private void SetVideoPositions() { var hiddenWindowContentSize = _hiddenWindow.ContentPixelSize; var screenWidth = Convert.ToInt32(Math.Round(hiddenWindowContentSize.Width)); var screenHeight = Convert.ToInt32(Math.Round(hiddenWindowContentSize.Height)); _logger.Info("window content width: {0}, window height: {1}", screenWidth, screenHeight); // Set the display position to the entire window. var rc = new MFRect(0, 0, screenWidth, screenHeight); _mPDisplay.SetVideoPosition(null, rc); //_mPDisplay.SetFullscreen(true); // Get Aspect Ratio int aspectX; int aspectY; decimal heightAsPercentOfWidth = 0; var basicVideo2 = (IBasicVideo2)m_graph; basicVideo2.GetPreferredAspectRatio(out aspectX, out aspectY); var sourceHeight = 0; var sourceWidth = 0; _basicVideo.GetVideoSize(out sourceWidth, out sourceHeight); if (aspectX == 0 || aspectY == 0 || sourceWidth > 0 || sourceHeight > 0) { aspectX = sourceWidth; aspectY = sourceHeight; } if (aspectX > 0 && aspectY > 0) { heightAsPercentOfWidth = decimal.Divide(aspectY, aspectX); } // Adjust Video Size var iAdjustedHeight = 0; if (aspectX > 0 && aspectY > 0) { var adjustedHeight = Convert.ToDouble(heightAsPercentOfWidth * screenWidth); iAdjustedHeight = Convert.ToInt32(Math.Round(adjustedHeight)); } //SET MADVR WINDOW TO FULL SCREEN AND SET POSITION if (screenHeight >= iAdjustedHeight && iAdjustedHeight > 0) { double totalMargin = (screenHeight - iAdjustedHeight); var topMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(0, topMargin, screenWidth, iAdjustedHeight); } else if (screenHeight < iAdjustedHeight && iAdjustedHeight > 0) { var adjustedWidth = Convert.ToDouble(screenHeight / heightAsPercentOfWidth); var iAdjustedWidth = Convert.ToInt32(Math.Round(adjustedWidth)); if (iAdjustedWidth == 1919) iAdjustedWidth = 1920; double totalMargin = (screenWidth - iAdjustedWidth); var leftMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(leftMargin, 0, iAdjustedWidth, screenHeight); } _videoWindow.SetWindowPosition(0, 0, screenWidth, screenHeight); }
public int GetVideoPosition(MFVideoNormalizedRect pnrcSource, MFRect prcDest) { // Make sure we *never* leave this entry point with an exception try { lock (this) { if (pnrcSource == null || prcDest == null) { throw new COMException("EVRCustomPresenter::GetVideoPosition", E_Pointer); } pnrcSource.CopyFrom(m_nrcSource); prcDest.CopyFrom(m_pD3DPresentEngine.GetDestinationRect()); } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
//----------------------------------------------------------------------------- // SetDestinationRect // // Sets the region within the video window where the video is drawn. //----------------------------------------------------------------------------- public void SetDestinationRect(MFRect rcDest) { if (!m_rcDestRect.Equals(rcDest)) { lock (this) { m_rcDestRect.left = rcDest.left; m_rcDestRect.right = rcDest.right; m_rcDestRect.top = rcDest.top; m_rcDestRect.bottom = rcDest.bottom; UpdateDestRect(); } } }
private void SetAspectRatio(Size? ratio = null, bool setVideoWindow = true) { int screenWidth; int screenHeight; if (m_graph == null) return; if (_isInExclusiveMode) { var size = System.Windows.Forms.Screen.FromControl(_hostForm).Bounds; screenWidth = size.Width; screenHeight = size.Height; } else { var hiddenWindowContentSize = _hostForm.Bounds; screenWidth = hiddenWindowContentSize.Width; screenHeight = hiddenWindowContentSize.Height; } // Set the display position to the entire window. if (_mPDisplay != null) { MFRect dRect = new MFRect(0, 0, screenWidth, screenHeight); MFSize vSize = new MFSize(), vAR = new MFSize(); double m_ZoomX = 1, m_ZoomY = 1, m_PosX = 0.5, m_PosY = 0.5; MFVideoNormalizedRect sRect = new MFVideoNormalizedRect(); sRect.top = 0; sRect.left = 0; sRect.right = 1; sRect.bottom = 1; int hr = _mPDisplay.GetNativeVideoSize(vSize, vAR); if (hr > -1) { double dVideoAR = (double)vSize.Width / vSize.Height; double dWRWidth = screenWidth; double dWRHeight = screenHeight; double dVRWidth = dWRHeight * dVideoAR; double dVRHeight; _logger.Debug("Scale: {0} Video Width: {1} Video Height: {2} X-AR: {3} Y-AR: {4}", _iVideoScaling, vSize.Width, vSize.Height, vAR.cx, vAR.cy); switch (_iVideoScaling) { case VideoScalingScheme.HALF: dVRWidth = vSize.Width * 0.5; dVRHeight = vSize.Height * 0.5; break; case VideoScalingScheme.NORMAL: dVRWidth = vSize.Width; dVRHeight = vSize.Height; break; case VideoScalingScheme.DOUBLE: dVRWidth = vSize.Width * 2.0; dVRHeight = vSize.Height * 2.0; break; case VideoScalingScheme.STRETCH: dVRWidth = dWRWidth; dVRHeight = dWRHeight; break; default: //ASSERT(FALSE); // Fallback to "Touch Window From Inside" if settings were corrupted. case VideoScalingScheme.FROMINSIDE: case VideoScalingScheme.FROMOUTSIDE: if ((screenWidth < dVRWidth) != (_iVideoScaling == VideoScalingScheme.FROMOUTSIDE)) { dVRWidth = dWRWidth; dVRHeight = dVRWidth / dVideoAR; } else { dVRHeight = dWRHeight; } break; case VideoScalingScheme.ZOOM1: case VideoScalingScheme.ZOOM2: { double minw = dWRWidth < dVRWidth ? dWRWidth : dVRWidth; double maxw = dWRWidth > dVRWidth ? dWRWidth : dVRWidth; double scale = _iVideoScaling == VideoScalingScheme.ZOOM1 ? 1.0 / 3.0 : 2.0 / 3.0; dVRWidth = minw + (maxw - minw) * scale; dVRHeight = dVRWidth / dVideoAR; break; } } // Scale video frame double dScaledVRWidth = m_ZoomX * dVRWidth; double dScaledVRHeight = m_ZoomY * dVRHeight; // Position video frame // left and top parts are allowed to be negative dRect.left = (int)Math.Round(m_PosX * (dWRWidth * 3.0 - dScaledVRWidth) - dWRWidth); dRect.top = (int)Math.Round(m_PosY * (dWRHeight * 3.0 - dScaledVRHeight) - dWRHeight); // right and bottom parts are always at picture center or beyond, so never negative dRect.right = (int)Math.Round(dRect.left + dScaledVRWidth); dRect.bottom = (int)Math.Round(dRect.top + dScaledVRHeight); //apply overscan //dRect.top = dRect.top - (ps.OverscanHeight / 2); //dRect.left = dRect.left - (ps.OverscanWidth / 2); //dRect.right = dRect.right + (ps.OverscanWidth / 2);//this.Width; //dRect.bottom = dRect.bottom + (ps.OverscanHeight / 2);//this.Height; } _mPDisplay.SetVideoPosition(sRect, dRect); } // Get Aspect Ratio int aspectX; int aspectY; if (ratio.HasValue) { aspectX = ratio.Value.Width; aspectY = ratio.Value.Height; } else { var basicVideo2 = (IBasicVideo2)m_graph; basicVideo2.GetPreferredAspectRatio(out aspectX, out aspectY); var sourceHeight = 0; var sourceWidth = 0; _basicVideo.GetVideoSize(out sourceWidth, out sourceHeight); if (aspectX == 0 || aspectY == 0 || sourceWidth > 0 || sourceHeight > 0) { aspectX = sourceWidth; aspectY = sourceHeight; } } // Adjust Video Size var iAdjustedHeight = 0; if (aspectX > 0 && aspectY > 0) { double adjustedHeight = aspectY * screenWidth; adjustedHeight /= aspectX; iAdjustedHeight = Convert.ToInt32(Math.Round(adjustedHeight)); } if (screenHeight > iAdjustedHeight && iAdjustedHeight > 0) { double totalMargin = (screenHeight - iAdjustedHeight); var topMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(0, topMargin, screenWidth, iAdjustedHeight); } else if (iAdjustedHeight > 0) { double adjustedWidth = aspectX * screenHeight; adjustedWidth /= aspectY; var iAdjustedWidth = Convert.ToInt32(Math.Round(adjustedWidth)); double totalMargin = (screenWidth - iAdjustedWidth); var leftMargin = Convert.ToInt32(Math.Round(totalMargin / 2)); _basicVideo.SetDestinationPosition(leftMargin, 0, iAdjustedWidth, screenHeight); } if (setVideoWindow) { _videoWindow.SetWindowPosition(0, 0, screenWidth, screenHeight); } }
private void MoveVideoWindow() { int hr = 0; try { // Track the movement of the container window and resize as needed if (this.evrDisplay != null) { MFVideoNormalizedRect sRect = new MFVideoNormalizedRect(); sRect.top = 0; sRect.left = 0; sRect.right = 1; sRect.bottom = 1; MediaFoundation.Misc.MFRect dRect = new MediaFoundation.Misc.MFRect(); MFSize vSize = new MFSize(), vAR = new MFSize(); double m_ZoomX = 1, m_ZoomY = 1, m_PosX = 0.5, m_PosY = 0.5; //dRect.top = 0; //dRect.left = 0; //dRect.right = ClientRectangle.Width;//this.Width; //dRect.bottom = ClientRectangle.Height;//this.Height; //dRect.top = 0 - (ps.OverscanHeight / 2); //dRect.left = 0 - (ps.OverscanWidth / 2); //dRect.right = ClientRectangle.Width + (ps.OverscanWidth / 2);//this.Width; //dRect.bottom = ClientRectangle.Height + (ps.OverscanHeight / 2);//this.Height; hr = evrDisplay.GetNativeVideoSize(vSize, vAR); DsError.ThrowExceptionForHR(hr); double dVideoAR = (double)vSize.Width / vSize.Height; double dWRWidth = ClientRectangle.Width; double dWRHeight = ClientRectangle.Height; double dVRWidth = dWRHeight * dVideoAR; double dVRHeight; switch (iVideoScaling) { case dvstype.HALF: dVRWidth = vSize.Width * 0.5; dVRHeight = vSize.Height * 0.5; break; case dvstype.NORMAL: dVRWidth = vSize.Width; dVRHeight = vSize.Height; break; case dvstype.DOUBLE: dVRWidth = vSize.Width * 2.0; dVRHeight = vSize.Height * 2.0; break; case dvstype.STRETCH: dVRWidth = dWRWidth; dVRHeight = dWRHeight; break; default: //ASSERT(FALSE); // Fallback to "Touch Window From Inside" if settings were corrupted. case dvstype.FROMINSIDE: case dvstype.FROMOUTSIDE: if ((ClientRectangle.Width < dVRWidth) != (iVideoScaling == dvstype.FROMOUTSIDE)) { dVRWidth = dWRWidth; dVRHeight = dVRWidth / dVideoAR; } else { dVRHeight = dWRHeight; } break; case dvstype.ZOOM1: case dvstype.ZOOM2: { double minw = dWRWidth < dVRWidth ? dWRWidth : dVRWidth; double maxw = dWRWidth > dVRWidth ? dWRWidth : dVRWidth; double scale = iVideoScaling == dvstype.ZOOM1 ? 1.0 / 3.0 : 2.0 / 3.0; dVRWidth = minw + (maxw - minw) * scale; dVRHeight = dVRWidth / dVideoAR; break; } } // Scale video frame double dScaledVRWidth = m_ZoomX * dVRWidth; double dScaledVRHeight = m_ZoomY * dVRHeight; // Position video frame // left and top parts are allowed to be negative dRect.left = (int)Math.Round(m_PosX * (dWRWidth * 3.0 - dScaledVRWidth) - dWRWidth); dRect.top = (int)Math.Round(m_PosY * (dWRHeight * 3.0 - dScaledVRHeight) - dWRHeight); // right and bottom parts are always at picture center or beyond, so never negative dRect.right = (int)Math.Round(dRect.left + dScaledVRWidth); dRect.bottom = (int)Math.Round(dRect.top + dScaledVRHeight); //apply overscan dRect.top = dRect.top - (ps.OverscanHeight / 2); dRect.left = dRect.left - (ps.OverscanWidth / 2); dRect.right = dRect.right + (ps.OverscanWidth / 2);//this.Width; dRect.bottom = dRect.bottom + (ps.OverscanHeight / 2);//this.Height; this.evrDisplay.SetVideoPosition(sRect, dRect); Debug.Print("t: {0} l: {1} r:{2} b:{3}", dRect.top, dRect.left, dRect.right, dRect.bottom); } } catch (Exception ex) { FileLogger.Log("MoveVideoWindow Error: {0}", ex.Message); } }