Exemplo n.º 1
0
        /// <summary>
        /// Finds the bounds and crops accordingly immediately
        /// </summary>
        private void SingleCrop()
        {
            bool updateCrop = false;

            if (LastSwitchedAspectRatio < 0.1f)
            {
                LastDetectionResult = false;
                return;
            }

            if (GUIGraphicsContext.RenderBlackImage)
            {
                LastDetectionResult = false;
                return;
            }

            Bitmap frame = grabber.GetCurrentImage();

            if (frame == null || frame.Height == 0 || frame.Width == 0)
            {
                LastDetectionResult = false;
                return;
            }

            Rectangle bounds = new Rectangle();

            if (!analyzer.FindBounds(frame, ref bounds))
            {
                LastDetectionResult = false;
                frame.Dispose();
                frame = null;
                return;
            }

            double Hsym = 1.0;
            double Vsym = 1.0;

            if (bounds.Left > 20 || ((frame.Width - bounds.Right) > 20 && bounds.Left > 0))
            {
                Hsym = (double)(frame.Width - bounds.Right) / (double)bounds.Left;
            }
            if (bounds.Top > 20 || ((frame.Height - bounds.Bottom) > 20 && bounds.Top > 0))
            {
                Vsym = (double)(frame.Height - bounds.Bottom) / (double)bounds.Top;
            }

            if (currentSettings.verboseLog)
            {
                Log.Debug("ViewModeSwitcher: SingleCrop(), Detected BB -> left: {0}, right: {1}, top: {2}, bottom: {3}, Hsym: {4}, Vsym: {5}", bounds.Left, (frame.Width - bounds.Right), bounds.Top, (frame.Height - bounds.Bottom), Hsym, Vsym);
            }

            //Check for symmetry of black bars - asymmetric bars are probably a false detection
            if ((Hsym > SymLimHigh) || (Hsym < SymLimLow) || (Vsym > SymLimHigh) || (Vsym < SymLimLow))
            {
                if (currentSettings.verboseLog)
                {
                    Log.Debug("ViewModeSwitcher: SingleCrop(), Symmetry check failed");
                }
                if (NoMatchCropCount < 3)
                {
                    NoMatchCropCount++;
                    LastDetectionResult = false;
                }
                frame.Dispose();
                frame = null;
                return;
            }

            //Use the smallest black bar size
            double cropH = (double)(Math.Min(frame.Width - bounds.Right, bounds.Left));
            double cropV = (double)(Math.Min(frame.Height - bounds.Bottom, bounds.Top));

            //Check for a close match (within 1% of width/height) to the previous crop values
            if ((((Math.Abs(cropV - LastRawCropV)) / (double)frame.Height) > 0.01) ||
                (((Math.Abs(cropH - LastRawCropH)) / (double)frame.Width) > 0.01))
            {
                LastRawCropH = cropH;
                LastRawCropV = cropV;
                if (NoMatchCropCount < 3)
                {
                    NoMatchCropCount++;
                    LastDetectionResult = false;
                }
                if (currentSettings.verboseLog)
                {
                    Log.Debug("ViewModeSwitcher: SingleCrop(), No match with last crop : " + NoMatchCropCount);
                }
                frame.Dispose();
                frame = null;
                return;
            }

            LastRawCropH = cropH;
            LastRawCropV = cropV;

            //Work out actual picture aspect ratio
            double newasp = ((double)frame.Width - cropH * 2) / ((double)frame.Height - cropV * 2);

            bool checkPBv = false;

            if (LastAnamorphFactor > 0.0)
            {
                //Correction for anamorphic video i.e. when pixel aspect ratio != video aspect ratio.
                newasp *= LastAnamorphFactor;

                //Check for letterbox/pillarbox video
                if (LastSwitchedAspectRatio > 1.68 && LastSwitchedAspectRatio < 1.87)
                {
                    if ((cropV / (double)frame.Height < 0.02) && newasp > 1.2 && newasp < 1.46)
                    {
                        checkPBv = true;
                    }
                    else if ((cropH / (double)frame.Width < 0.02) && newasp > 2.1 && newasp < 2.57)
                    {
                        checkPBv = true;
                    }
                }
                else if (LastSwitchedAspectRatio > 1.25 && LastSwitchedAspectRatio < 1.41)
                {
                    if ((cropH / (double)frame.Width < 0.02) && newasp > 1.47 && newasp < 1.95)
                    {
                        checkPBv = true;
                    }
                    else if ((cropH / (double)frame.Width < 0.02) && newasp > 2.1 && newasp < 2.57)
                    {
                        checkPBv = true;
                    }
                }

                //After this correction, cropH value is in 'real' video pixels, not source pixels
                cropH *= LastAnamorphFactor;
            }

            if (newasp < 1.1 || newasp > 2.7) // faulty crop
            {
                if (NoMatchCropCount < 3)
                {
                    NoMatchCropCount++;
                    LastDetectionResult = false;
                }
                frame.Dispose();
                frame = null;
                return;
            }

            NoMatchCropCount = 0;

            if (currentSettings.verboseLog)
            {
                Log.Debug("ViewModeSwitcher: SingleCrop(), Video AR: {0}, Cropped AR: {1}", LastSwitchedAspectRatio, newasp);
            }

            //Check for 'Pillar Boxed' 4:3 inside 16:9 video, and 'Letter Boxed' 16:9 inside 4:3 video
            if (CheckRulesPBLB(-newasp, frame.Width, frame.Height, checkPBv))
            {
                if (LastSwitchedGeometry != Geometry.Type.NonLinearStretch)
                {
                    //NonLinearStretch needs full side bar cropping, other modes don't
                    cropH = overScan;
                    cropV = overScan / LastSwitchedAspectRatio;
                }
                else
                {
                    //Add overscan to NonLinearStretch
                    cropH += overScan;
                    cropV += overScan / LastSwitchedAspectRatio;
                }

                if (!isPBorLB) //Only update on first detection
                {
                    updateCrop = true;
                }
                isPBorLB = true;
            }
            else //Normal video cropping
            {
                //Use overscan cropping if larger than detected black bars
                cropH = Math.Max(cropH, overScan);
                cropV = Math.Max(cropV, overScan / LastSwitchedAspectRatio);

                if (isPBorLB)
                {
                    if (currentSettings.verboseLog)
                    {
                        Log.Debug("ViewModeSwitcher: SingleCrop(), PillarBox -> Normal");
                    }
                    //Force CheckAspectRatios() update
                    updatePending           = false;
                    isPBorLB                = false;
                    LastSwitchedAspectRatio = 0.0;
                    frame.Dispose();
                    frame = null;
                    return;
                }
                isPBorLB = false;
            }

            if (currentSettings.verboseLog)
            {
                Log.Debug("ViewModeSwitcher: SingleCrop(), Real cropH: {0}, cropV: {1}", cropH, cropV);
            }

            if ((Math.Abs(cropH - fCropH) > 5) || (Math.Abs(cropV - fCropV) > 3))
            {
                fCropH     = cropH;
                fCropV     = cropV;
                updateCrop = true;
            }

            if (updateCrop)
            {
                updatePending = true;
            }

            frame.Dispose();
            frame = null;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Finds the bounds and crops accordingly immediately
        /// </summary>
        private void SingleCrop()
        {
            if (GUIGraphicsContext.RenderBlackImage)
            {
                LastDetectionResult = false;
                return;
            }

            Bitmap frame = grabber.GetCurrentImage();

            if (frame == null || frame.Height == 0 || frame.Width == 0)
            {
                LastDetectionResult = false;
                return;
            }

            Rectangle bounds = new Rectangle();

            if (!analyzer.FindBounds(frame, ref bounds))
            {
                LastDetectionResult = false;
                return;
            }

            int cropH = Math.Min(GUIGraphicsContext.VideoSize.Width - bounds.Right, bounds.Left);

            if (cropH < overScan)
            {
                cropH = overScan;
            }

            int cropV = Math.Min(GUIGraphicsContext.VideoSize.Height - bounds.Bottom, bounds.Top);

            if (cropV < overScan / LastSwitchedAspectRatio)
            {
                cropV = (int)(overScan / LastSwitchedAspectRatio);
            }

            if (cropV > cropH / LastSwitchedAspectRatio)
            {
                cropV = (int)(cropH / LastSwitchedAspectRatio);
            }

            float newasp = (float)(frame.Width - cropH * 2) / (float)(frame.Height - cropV * 2);

            if (newasp < 1) // faulty crop
            {
                cropH = overScan;
                cropV = (int)(overScan / LastSwitchedAspectRatio);
            }

            if (cropH != cropSettings.Left || cropV != cropSettings.Top)
            {
                cropSettings.Top    = cropV; //bounds.Top;
                cropSettings.Bottom = cropV; // GUIGraphicsContext.VideoSize.Height - (bounds.Bottom + 1);
                cropSettings.Left   = cropH; // bounds.Left;
                cropSettings.Right  = cropH; // GUIGraphicsContext.VideoSize.Width - (bounds.Right + 1);
                SetCropMode();
            }
            if (newasp >= 1)
            {
                float asp = (float)(frame.Width) / (float)(frame.Height);
                //Log.Debug("asp: {0}, newasp: {1}", asp, newasp);
                if (Math.Abs(asp - newasp) > 0.2 && LastSwitchedAspectRatio > 1.5)
                {
                    SetAspectRatio("4:3 inside 16:9", Geometry.Type.NonLinearStretch);
                }
            }

            frame.Dispose();
            frame = null;
        }