Exemplo n.º 1
0
        private void RunAnalyzeVideo()
        {
            Log.Info("Auto3D: Start Video Analysis");

            FrameGrabber fg = FrameGrabber.GetInstance();

            int maxAnalyzeSteps = 20;
            int treshold        = 5;

            VideoFormat[] vf = new VideoFormat[maxAnalyzeSteps + 1];

            int iStep = 0;

            while (_run && _bPlaying)
            {
                // wait 200 ms

                for (int i = 0; i < 10; i++)
                {
                    if (!_bPlaying) // if playing is stopped while we wait then return
                    {
                        return;
                    }

                    Thread.Sleep(20);
                }

                System.Drawing.Bitmap image = fg.GetCurrentImage();

                if (image != null)
                {
                    Bitmap fastCompareImage = new Bitmap(96, 96);

                    // set the resolutions the same to avoid cropping due to resolution differences
                    fastCompareImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

                    //use a graphics object to draw the resized image into the bitmap
                    using (Graphics graphics = Graphics.FromImage(fastCompareImage))
                    {
                        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bicubic;
                        graphics.DrawImage(image, 0, 0, fastCompareImage.Width, fastCompareImage.Height);
                    }

                    // Lock the bitmap's bits.
                    Rectangle rect = new Rectangle(0, 0, fastCompareImage.Width, fastCompareImage.Height);
                    System.Drawing.Imaging.BitmapData bmpData = fastCompareImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                    double similarity = 0;

                    vf[iStep] = VideoFormat.Fmt2D; // assume normal format

                    if (bCheckSideBySide)
                    {
                        similarity = Auto3DAnalyzer.CheckFor3DFormat(bmpData, bmpData.Width / 2, bmpData.Height, true);
                    }

                    if (similarity == -1) // not bright enough for analysis
                    {
                        continue;
                    }

                    if (similarity > 0.925)
                    {
                        vf[iStep] = VideoFormat.Fmt3DSBS;
                    }
                    else
                    {
                        if (bCheckTopAndBottom)
                        {
                            similarity = Auto3DAnalyzer.CheckFor3DFormat(bmpData, bmpData.Width, bmpData.Height / 2, false);
                        }

                        if (similarity == -1) // not bright enough for analysis -> continue
                        {
                            continue;
                        }

                        if (similarity > 0.925)
                        {
                            vf[iStep] = VideoFormat.Fmt3DTAB;
                        }
                    }

                    fastCompareImage.UnlockBits(bmpData);

                    Log.Debug("Similarity: " + similarity + " - " + vf[iStep].ToString());
                }

                if (iStep > 3)
                {
                    // check if we can make a decision

                    int countNormal       = 0;
                    int countSideBySide3D = 0;
                    int countTopBottom3D  = 0;

                    for (int i = 0; i <= iStep; i++)
                    {
                        switch (vf[i])
                        {
                        case VideoFormat.Fmt2D:

                            countNormal++;
                            break;

                        case VideoFormat.Fmt3DSBS:

                            countSideBySide3D++;
                            break;

                        case VideoFormat.Fmt3DTAB:

                            countTopBottom3D++;
                            break;
                        }
                    }

                    Log.Debug("Results(" + iStep + ") - Normal=" + countNormal + " - SBS3D=" + countSideBySide3D + " - TB3D=" + countTopBottom3D);

                    if ((countSideBySide3D >= (countNormal + treshold)) || (countTopBottom3D >= (countNormal + treshold)) || (countSideBySide3D >= countNormal && iStep == maxAnalyzeSteps) || (countTopBottom3D >= countNormal && iStep == maxAnalyzeSteps))
                    {
                        VideoFormat videoFormat = countTopBottom3D > countSideBySide3D ? VideoFormat.Fmt3DTAB : VideoFormat.Fmt3DSBS;

                        if ((videoFormat == VideoFormat.Fmt3DSBS) || (videoFormat == VideoFormat.Fmt3DTAB))
                        {
                            if (videoFormat == VideoFormat.Fmt3DTAB)
                            {
                                Log.Info("Auto3D: Video Analysis Finished: Switch TV to TAB 3D");
                            }
                            else
                            {
                                Log.Info("Auto3D: Video Analysis Finished: Switch TV to SBS 3D");
                            }

                            if (bConvert3DTo2D)
                            {
                                switch (videoFormat)
                                {
                                case VideoFormat.Fmt3DSBS:

                                    GUIGraphicsContext.Render3DMode = GUIGraphicsContext.eRender3DMode.SideBySideTo2D;
                                    break;

                                case VideoFormat.Fmt3DTAB:

                                    GUIGraphicsContext.Render3DMode = GUIGraphicsContext.eRender3DMode.TopAndBottomTo2D;
                                    break;
                                }

                                _currentMode = videoFormat;
                            }
                            else
                            {
                                if (_activeDevice.SwitchFormat(_currentMode, videoFormat))
                                {
                                    switch (videoFormat)
                                    {
                                    case VideoFormat.Fmt3DSBS:

                                        GUIGraphicsContext.Render3DMode = GUIGraphicsContext.eRender3DMode.SideBySide;
                                        break;

                                    case VideoFormat.Fmt3DTAB:

                                        GUIGraphicsContext.Render3DMode = GUIGraphicsContext.eRender3DMode.TopAndBottom;
                                        break;
                                    }

                                    _currentMode = videoFormat;
                                }
                            }

                            UpdateSubtitleRenderFormat();
                        }
                        else
                        {
                            ManualSelect3DFormat(videoFormat);
                            UpdateSubtitleRenderFormat();
                        }

                        return; // exit thread
                    }
                    else
                    if ((_currentMode == VideoFormat.Fmt2D) && ((countNormal > countSideBySide3D + treshold) || (countNormal > countTopBottom3D + treshold)))
                    {
                        // current format is normal and video is normal too, we do not need to switch
                        Log.Info("Auto3D: Format is 2D. No switch necessary");
                        return; // exit thread
                    }
                    else
                    if (_currentMode != VideoFormat.Fmt2D)
                    {
                        // current format 3d and video is 2d, so we must switch back to normal
                        RunSwitchBack();
                        return; // exit thread
                    }
                    else
                    if (iStep > maxAnalyzeSteps)
                    {
                        // we could not make a decision within the maximum allowed steps
                        Log.Info("Auto3D: Video Analysis failed!");
                        return; // exit thread
                    }
                }

                iStep++;
            }
        }