IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Capture video - AccessViolationException


Sujet :

C#

  1. #1
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut Capture video - AccessViolationException
    Bonjour,

    Je développe actuellement une application en C# de videosurveillance

    Tout fonctionne, sauf de temps en temps j'ai de cmessage d'erreur :

    Une exception de première chance de type 'System.AccessViolationException' s'est produite dans System.Drawing.dll

    Et dès que j'ai ce message, mon application s'arrête

    Pouvez vous m'aider ?

    VOici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    using System;
    using System.Data;
    using System.Text;
    using System.Drawing;
    using DirectX.Capture;
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Collections.Generic;
    using VideoSurveillance;
     
    namespace VideoSurveillance
    {
        public partial class Form1 : Form
        {
            int nombreintru = 0;
            private Filters InputOptions = new Filters();
            private Filter VideoInput = null;
            private Filter AudioInput = null;
            private Capture CaptureInfo = null;
            Color couleur ;
            Color couleur2 ;
            Bitmap bmp ;
            Bitmap bmp2;
     
            public Form1()
            {
                InitializeComponent();
                label1.Visible = false;
            }
     
     
     
            private void ErrorMessage(Exception e)
            {
                MessageBox.Show(e.Message, "VideoSurveillance", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
     
     
     
            private void button1_Click(object sender, EventArgs e)
            {
                this.Configure();
                CaptureInfo.CaptureFrame();
     
     
              //  CaptureInfo.Filename = Application.StartupPath +"/essai.avi";
              // CaptureInfo.Start();
            }
     
     
     
            private void aProposToolStripMenuItem1_Click(object sender, EventArgs e)
            {
                AboutBox1 apropos = new AboutBox1();
                apropos.Show();
     
     
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
     
     
     
                pictureEtat = true;
                CaptureInfo.CaptureFrame();
                timerPhoto.Start();
     
     
     
     
            }
     
            private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Application.Exit();
     
            }
     
     
     
            private void timerPhoto_Tick(object sender, EventArgs e)
            {
                while (timerPhoto.Interval <= 300000)
                {
                    timerPhoto.Interval += 1;
     
                }
                detection();
                CaptureInfo.CaptureFrame();
                timerPhoto.Interval = 1;
                timerPhoto.Stop();
                timerPhoto.Start();
     
            }
     
     
     
     
            private void detection()
            {
     
                bmp = pictureBox2.Image as Bitmap;
                bmp2 = pictureBox3.Image as Bitmap;
     
                couleur = bmp.GetPixel(0, 0);
                couleur2 = bmp2.GetPixel(0, 0);
     
     
     
     
                if (couleur.Equals(couleur2))
                {
                   // MessageBox.Show("C'est pareil");
                }
                else
                {
                 //   MessageBox.Show("Intrusion");
                    nombreintru++;
                    label1.Visible = true;
                    label1.Text = ("Nombre d'intrusions :  " + nombreintru);
                    //timerPhoto.Start();
                }
     
     
            }
     
     
     
     
     
     
     
        }
    }
    Merci et bonne journée

  2. #2
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    L'erreur ce produit tjr dans le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
            private void detection()
            {
     
                bmp = pictureBox2.Image as Bitmap;
                bmp2 = pictureBox3.Image as Bitmap;
     
                couleur = bmp.GetPixel(0, 0);
                couleur2 = bmp2.GetPixel(0, 0);
     
                
                
                
                if (couleur.Equals(couleur2))
                {
                   // MessageBox.Show("C'est pareil");
                }
                else
                {
                 //   MessageBox.Show("Intrusion");
                    nombreintru++;
                    label1.Visible = true;
                    label1.Text = ("Nombre d'intrusions :  " + nombreintru);
                    //timerPhoto.Start();
                }
     
                
            }
    Merci

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Le code n'est pas complet, si ? comment sont remplies les PictureBox ? je suppose qu'elles affichent les images qui viennent de la caméra ?

    Sinon, je ne pense pas que tu aies compris comment fonctionne un timer... que cherches-tu à faire en incrémentant l'intervalle dans une boucle ? En général on lui donne une valeur et on ne la change plus, sauf si on veut changer la fréquence de l'action exécutée dans le Tick. Ca n'a peut-être rien à voir avec le problème, mais en tous cas c'est bizarre...

  4. #4
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    slt

    En faite j'incrémente mon timer afin qu'au bout d'une durée n il enregistre une photo et relance un timer

    Sinon l'erreur est étrange, car il me dit toujours que la mémoire est tronqué et il me marque le bout de code que j'ai mis en rouge

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par offspring Voir le message
    En faite j'incrémente mon timer afin qu'au bout d'une durée n il enregistre une photo et relance un timer
    Tu n'as pas besoin de faire ça ! Si tu veux que la méthode detection soit appelée toutes les secondes, tu mets Interval à 1000ms (et tu n'y touches plus), et tu démarres le timer. Pas la peine de l'arrêter et de le relancer à chaque fois ! En plus, vu que tu remets Interval à 1 avant de relancer le timer, tu vas repasser dans l'évènement Tick presque tout de suite. Le code suivant devrait être suffisant pour l'évènement Tick :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            private void timerPhoto_Tick(object sender, EventArgs e)
            {
                CaptureInfo.CaptureFrame();
                detection();
            }
    (Au passage, j'ai mis la capture avant la détection : il me semble que c'est après avoir obtenu une nouvelle image que tu dois tester si quelque chose a bougé...)

    A mon avis ton problème est dû au fait que tu fais la capture beaucoup trop souvent à cause de tes bidouilles sur l'intervalle du Timer... essaie le code que je t'ai donné, avec une valeur raisonnable pour l'intervalle (1000ms par exemple), tu verras bien si ça marche mieux.

  6. #6
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    merci pour tes reponses
    En faite j'ai un bouton (bouton2) où quand je clique dessus, je veux que toutes les 3 secondes une photo soit prise pour ensuite lancer ma méthode de détection

    Peux tu m'aider ?

    Voici mon code actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
      private void button2_Click(object sender, EventArgs e)
            {
     
     
     
                pictureEtat = true;
                CaptureInfo.CaptureFrame();
                timerPhoto.Interval = 30000;
                timerPhoto.Enabled = true;
                timerPhoto.Start();
     
     
     
     
            }
     
            private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Application.Exit();
     
            }
     
     
     
            private void timerPhoto_Tick(object sender, EventArgs e)
            {
                CaptureInfo.CaptureFrame();
                detection();
     
            }
     
     
     
     
            private void detection()
            {
     
                bmp = pictureBox2.Image as Bitmap;
                bmp2 = pictureBox3.Image as Bitmap;
     
                couleur = bmp.GetPixel(0, 0);
                couleur2 = bmp2.GetPixel(0, 0);
     
     
     
     
                if (couleur.Equals(couleur2))
                {
                   // MessageBox.Show("C'est pareil");
                }
                else
                {
                 //   MessageBox.Show("Intrusion");
                    nombreintru++;
                    label1.Visible = true;
                    label1.Text = ("Nombre d'intrusions :  " + nombreintru);
                    //timerPhoto.Start();
                }

  7. #7
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    ok c'est bon j'ai reussi ce que je voulais faire (un grand merci a toi !)

    Le problème du départ vient du getpixel, je sais pas comment sa ce fait

  8. #8
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    j'ai toujours mon erreur de départ, sa se produit qd il fait la détection, est qu'il est possible de convertir un type color en int afin que je lui mettre une marge d'erreur ?

  9. #9
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    J'ai testé et j'ai toujours la meme erreur sur mon premier getPixel

    Voila le rapport :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    L'exception System.AccessViolationException n'a pas été gérée
      Message="Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée."
      Source="System.Drawing"
      StackTrace:
           à System.Drawing.SafeNativeMethods.Gdip.GdipBitmapGetPixel(HandleRef bitmap, Int32 x, Int32 y, Int32& argb)
           à System.Drawing.Bitmap.GetPixel(Int32 x, Int32 y)
           à VideoSurveillance.Form1.detection() dans C:\Documents and Settings\dric\Bureau\VideoSurveillance\Form1.cs:ligne 99
           à VideoSurveillance.Form1.timerPhoto_Tick(Object sender, EventArgs e) dans C:\Documents and Settings\dric\Bureau\VideoSurveillance\Form1.cs:ligne 87
           à System.Windows.Forms.Timer.OnTick(EventArgs e)
           à System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
           à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           à System.Windows.Forms.Application.Run(Form mainForm)
           à VideoSurveillance.Program.Main() dans C:\Documents and Settings\dric\Bureau\VideoSurveillance\Program.cs:ligne 17
           à System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           à System.Threading.ThreadHelper.ThreadStart()
    Peux tu m'aider ?

    Merci

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Alors là j'avoue que ça dépasse un peu le cadre de mes compétences... C'est peut-être un problème lié à l'interaction avec DirectX. Normalement, une violation d'accès en .NET n'est pas possible (puisque la mémoire est managée), mais GetPixel fait appel à des fonctions natives de Windows, qui accèdent à de la mémoire non managée.

    Quelqu'un ici à eu le même problème, mais il n'a pas l'air d'avoir trouvé de solution...

    Je me demande si ça ne pourrait pas être un conflit d'accès entre ton code qui essaie d'accéder à l'image et la classe Capture qui est en train de la modifier... Mais je ne connais pas du tout DirectX, donc je ne sais pas s'il y a des méthodes ou propriétés permettant de gérer la synchro entre les 2.

    Par curiosité, comment fais-tu le lien entre la capture et la PictureBox ?


    [EDIT] Au fait, Capture, c'est une classe à toi ou une classe DirectX ? Et d'où sort le namespace DirectX.Capture ? Je ne le trouve pas dans la MSDN...

  11. #11
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    Voila ma fonction pour inscrire une image dans un picturebox
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      void CaptureInfo_FrameCaptureComplete(PictureBox Frame)
            {
     
               if (pictureEtat == true)
                {
                    pictureBox2.Image = Frame.Image;
     
                }
                else
                {
                    pictureBox3.Image = Frame.Image;
                }
            }
    Sinon j'avais pensé enregistrer mon image dans un jpg, et comparer ensuite mes 2 images, tu en penses quoi ?

    Merci

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    C'est une idée aussi, mais ça ne résoudra pas le problème à mon avis.

    Mais maintenant je crois voir d'où vient le problème : quand tu appelles CaptureFrame(), en fait le résultat n'est pas immédiat, ça ne place pas immédiatement la frame capturée dans la PictureBox. Quand c'est terminé, tu es prévenu par l'évènement FrameCaptureComplete.

    Mais toi, tu appelles immédiatement la méthode detection, alors que la capture n'est peut-être pas terminée... je pense que c'est là qu'est le problème.

    Essaie de mettre l'appel à detection dans le code de l'évènement FrameCaptureComplete, après le bloc if/else. Là au moins tu es sûr que la capture n'est pas en cours.

  13. #13
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    En fait pour le traitement de l'image c'est GDI+ qui est utilisé car la classe Bitmap sous .NET c'est la classe managée qui encapsules les possibilités de l'API native de windows.

  14. #14
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    merci pour vos reponses, je vais regardé et je vous tiens au courant

  15. #15
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2006
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 389
    Points : 244
    Points
    244
    Par défaut
    Mais toi, tu appelles immédiatement la méthode detection, alors que la capture n'est peut-être pas terminée... je pense que c'est là qu'est le problème.

    Essaie de mettre l'appel à detection dans le code de l'évènement FrameCaptureComplete, après le bloc if/else. Là au moins tu es sûr que la capture n'est pas en cours.
    Merci Tomlev j'ai appliqué ce que tu m'as dit et sa fonctionne parfaitement

    Merci pour toutet bonne soirée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Driver de capture video virtuel en Directx
    Par Lio590 dans le forum DirectX
    Réponses: 2
    Dernier message: 22/01/2005, 12h14
  2. capture video directX9
    Par Tsunamis dans le forum DirectX
    Réponses: 8
    Dernier message: 23/11/2004, 11h49
  3. Capture vidéo d'une application OPENGL
    Par Mathieu.J dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 10/06/2004, 21h29
  4. Capture video depuis une carte DC30+
    Par Ertai dans le forum MFC
    Réponses: 2
    Dernier message: 19/02/2004, 15h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo