Jump to content

AForge - De vez em quando a aplicação deixa de responder ou não fecha.


BrunoFerreira

Recommended Posts

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;


namespace VirtualFPVRemoteControl
{
    public partial class MainForm : Form
    {
    
    //Global Var

        String[] serialLog = new String[300];
        SerialLogDisplay sld_form;
        int motorPower = 0;

        FilterInfoCollection filterInfoCollection;
        VideoCaptureDevice videoCaptureDevice;

        //Form Method

        public MainForm()
        {
            InitializeComponent();
        }




    //Generated Methods

        private void btnCCamera_Click(object sender, EventArgs e)
        {
            if(cmbCameraS.SelectedIndex > 0) {
                disconnectVideoStream(false);
                videoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[cmbCameraS.SelectedIndex-1].MonikerString);
                videoCaptureDevice.NewFrame += new NewFrameEventHandler(VideoCaptureDevice_NewFrame);
                videoCaptureDevice.Start();

                Add_Log("Camera \"" + filterInfoCollection[cmbCameraS.SelectedIndex-1].Name+ "\" Connected!");
            }
            else
            {
                disconnectVideoStream(true);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Camera System
            cmbCameraS.Items.Add("None");
            filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            foreach (FilterInfo filterInfo in filterInfoCollection)
            {
                cmbCameraS.Items.Add(filterInfo.Name);
            }
            cmbCameraS.SelectedIndex = 0;
            videoCaptureDevice = new VideoCaptureDevice();

            //Log
            shortLog.Parent = cameraDisplay;
            shortLog.BackColor = Color.Transparent;
            shortLog.Text = serialLog[0] + "\n" + serialLog[1] + "\n" + serialLog[2];



            //Loop
            Timer tmr = new Timer();
            tmr.Interval = 1000;
            tmr.Tick += Tmr_Tick;
            tmr.Start();


            //DisplayObjects
            changeMPBar(motorPower);

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            disconnectVideoStream(false);
        }

        private void SLbtn_Click(object sender, EventArgs e)
        {
            if (sld_form == null)
            {
                sld_form = new SerialLogDisplay(this);
            }
            sld_form.update_log(serialLog);
            sld_form.Show();
            sld_form.Activate();
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            disconnectVideoStream(false);
            System.Windows.Forms.Application.Exit();
        }

        private void minBtn_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            GC.Collect();
        }


        //Created Methods

        //Serial Log
        private void Tmr_Tick(object sender, EventArgs e)
        {
            String lm = "";
            for (int i = 4; i >= 0; i--)
            {
                if (serialLog[i] != null)
                {
                    lm += serialLog[i] + "\n";
                }
            }
            shortLog.Text = lm;
        }

        public void SerialLogDisplay_Close()
        {
            sld_form = null;
        }

        public void Add_Log(String text)
        {
            for (int i = serialLog.Length - 1; i > 0; i--)
            {
                serialLog[i] = serialLog[i - 1];
            }
            serialLog[0] = text;

            if(sld_form != null)
            {
                sld_form.update_log(serialLog);
            }
            
        }

        public void Serial_Command(String command)
        {
            Add_Log(command);
            //Send command to serial Port
        }



        //Camera Output
        private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {

            if (cameraDisplay.InvokeRequired)
            {
                    try
                    {
                        cameraDisplay.Invoke((MethodInvoker)delegate {
                            if (cameraDisplay.Image != null)
                                {
                                    cameraDisplay.Image.Dispose();
                                }
                                Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
                                cameraDisplay.Image = bmp;
                        });
                    }
                    catch (System.InvalidOperationException ex)
                    {
                        Add_Log("Error: " + ex);
                        disconnectVideoStream(true);
                    }

            }
            else
            {
                try
                {
                    if (cameraDisplay.Image != null)
                    {
                        cameraDisplay.Image.Dispose();
                    }
                    Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
                    cameraDisplay.Image = bmp;
                }
                catch (System.InvalidOperationException ex)
                {
                    Add_Log("Error: " + ex);
                    disconnectVideoStream(true);
                }
            }

            //GC.Collect();
        }

        private void disconnectVideoStream(bool showLog)
        {
            if (videoCaptureDevice.IsRunning == true)
            {
                if (showLog) { Add_Log("Disconnecting video stream..."); }
                videoCaptureDevice.SignalToStop();
                videoCaptureDevice.WaitForStop();
                videoCaptureDevice.Stop();
                cameraDisplay.Image = null;
            }

            if (showLog)
            {
                Add_Log("No camera connected!");
            }
            GC.Collect();
        }

        //Screen GUI

        private void changeMPBar(int nbar)
        {
            switch (nbar)
            {
                case 0:
                    MPbar1.BackColor = Color.Transparent;
                    MPbar2.BackColor = Color.Transparent;
                    MPbar3.BackColor = Color.Transparent;
                    MPbar4.BackColor = Color.Transparent;
                    break;
                case 1:
                    MPbar1.BackColor = Color.White;
                    MPbar2.BackColor = Color.Transparent;
                    MPbar3.BackColor = Color.Transparent;
                    MPbar4.BackColor = Color.Transparent;
                    break;
                case 2:
                    MPbar1.BackColor = Color.White;
                    MPbar2.BackColor = Color.White;
                    MPbar3.BackColor = Color.Transparent;
                    MPbar4.BackColor = Color.Transparent;
                    break;
                case 3:
                    MPbar1.BackColor = Color.White;
                    MPbar2.BackColor = Color.White;
                    MPbar3.BackColor = Color.White;
                    MPbar4.BackColor = Color.Transparent;
                    break;
                case 4:
                    MPbar1.BackColor = Color.White;
                    MPbar2.BackColor = Color.White;
                    MPbar3.BackColor = Color.White;
                    MPbar4.BackColor = Color.White;
                    break;
                default:
                    MPbar1.BackColor = Color.Transparent;
                    MPbar2.BackColor = Color.Transparent;
                    MPbar3.BackColor = Color.Transparent;
                    MPbar4.BackColor = Color.Transparent;
                    break;
            }


        }


    }
}

Eu tentei publicar esta dúvida no StackOverflow, mas a única resposta que tive foi de estar a usar a Picturebox(cameraDisplay) fora do Thread da UI.

Para resumir o problema, a aplicação funciona normalmente, mas de vez em quando ela trava completamente ou então a imagem da pictureBox deixa de atualizar.

Alguém sabe o motivo? Ou a forma correta de fazer?

Link to comment
Share on other sites

Os problemas "de vez em quando" são dos mais difíceis de encontrar por não se saber como replicar.
O melhor que posso dizer, por experiência, é que alguns tipos de recursos, como seja ligar a portas COM, acesso a dispositivos como câmaras, etc., é um tipo de interação que deve ser feito em thread própria, fora da thread principal da aplicação.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

Em 13/12/2022 às 10:06, M6 disse:

Os problemas "de vez em quando" são dos mais difíceis de encontrar por não se saber como replicar.
O melhor que posso dizer, por experiência, é que alguns tipos de recursos, como seja ligar a portas COM, acesso a dispositivos como câmaras, etc., é um tipo de interação que deve ser feito em thread própria, fora da thread principal da aplicação.

A libraria "AForge" cria um thread próprio para essa funcionalidade, o que disseram no stackOverflow foi que o problema podia ser de eu estar a aceder a picturebox,que está no thread da UI, do thread da criação de imagem criado pelo AForge.

O código acima possui algum erro que em determinadas condições faz com que a imagem transmitida pare ou ,em casos mais graves, toda a aplicação deixe de responder sem lançar nenhuma exceção. 😔

//Camera Output
//cameraDisplay -> PictureBox
        private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {

            if (cameraDisplay.InvokeRequired)
            {
                    try
                    {
                        cameraDisplay.Invoke((MethodInvoker)delegate {
                            if (cameraDisplay.Image != null)
                                {
                                    cameraDisplay.Image.Dispose();
                                }
                                Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
                                cameraDisplay.Image = bmp;
                        });
                    }
                    catch (System.InvalidOperationException ex)
                    {
                        Add_Log("Error: " + ex);
                        disconnectVideoStream(true);
                    }

            }
            else
            {
                try
                {
                    if (cameraDisplay.Image != null)
                    {
                        cameraDisplay.Image.Dispose();
                    }
                    Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
                    cameraDisplay.Image = bmp;
                }
                catch (System.InvalidOperationException ex)
                {
                    Add_Log("Error: " + ex);
                    disconnectVideoStream(true);
                }
            }

            //GC.Collect();
        }

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.