Autofocus:Thread triplebuffering Problème Synchro - Cerner le problème

Bonjour,
Je deviens Chèvre.
Si quelqun pouvait m’aider j’en serai heureux. Des mois de recherche sans comprendre. Je suis tellement omnubilé par ce problème que je n’en vois pas la solution. Je developpe sous VC++.net

Voila : Je developpe un autofocus. Jai une camera CMOS 2Mpixel et des librairies dll, .h associé. (Micron)
J’utilise un port usb 2.0 pour acquerir un buffer 800
600 @25fps (40ms par image), un autre port usb2.0 relié à un microcontroleur qui recoit une trame USB , la converti en I2C vers un driver qui pilote la techno autofocus.
Voici la présentation de la boucle d’asservissement…

Je ne vous presente pas le code d’autofocus c’est des math.

Par contre voici l’architecture : jai deux thread un d’affichage, un de reception du buffer camera.
J’ai un triple buffer pour synchroniser les deux threads
A chaque trame recu par la camera je swap le buffer, je converti le raw bayer en YCbCr puis je traite la zone centrale de l’image pour sortir un indice reflétant le degré de défocus (thread d’affichage)
j’incremente la tension (la lentille bouge) et a la trame suivante je recalcule cet indice afin de maximiser la courbe d’indice obtenu au cours du deplacement lentille.
le sommet de cette courbe c’est le focus.

Voila mon problème : l’incrementation des tension sest en avance de 3 trames sur les images???
Je comprends pas!!! help!!!

Ton problème semble indiquer un soucis d’exclusion mutuelle : cela consiste à éviter qu’une de tes variables ne soit modifée par un autre thread.
Pour cela, il faut créer un contexte d’exclusion mutuel et l’assigner pour un lock sur ta variable, ainsi, aucun autre thread ne pourra modifier ta variable tant qu’elle est bloquée.
Tu en sauras plus ici.

tu parles du lock entercriticalsection???

bool CZoomDlg::TripleBufferFlip(unsigned char **pBuf, bool bPrimaryBuffer/=false/)
{
bool bFlipped = false;

EnterCriticalSection(&m_csLock);
{
    if (bPrimaryBuffer || m_bTripleBufferDirty)
    {
        unsigned char *pTmp = *pBuf;
        *pBuf = m_pTripleBuffer;
        m_pTripleBuffer = pTmp;
        bFlipped = true;
    }
    m_bTripleBufferDirty = bPrimaryBuffer;
}
LeaveCriticalSection(&m_csLock);
return bFlipped;

}

Oui, c’est bien ça, fait en de même pour la variable de la tension.

La tension est envoyée toutes les trames 1v/40ms. elle n’est modifiée par aucun process?? Pourquoi devrait elle etre proteger?
C’est l’image qui semble etre desynchroniser car l’effet de cette augmentation de tension n’est visible sur mon indice de focus que 3-4 trame aprés

Si c’est une variable globale et qu’elle est modifié par plus d’un thread, il faudra que tu la protège.
Si ce n’est pas le cas, peut être que tu pourrais affiner la synchronisation en utilisant les evenements ? (cf ici )

je fais ainsi :
dans le thread camera:
void Camera_Thread(void *param)
{
CZoomDlg *pSensor = (CZoomDlg )param;
ASSERT( pSensor!=NULL && pSensor->IsKindOf(RUNTIME_CLASS(CZoomDlg)) );
while (pSensor->m_bPlaying)
{
/

* grab a frame (ignore bad frames)
/
if (pSensor->m_pCamera->grabFrame(pSensor->m_pCamera, pSensor->m_pCameraBuffer, pSensor->m_pCamera->sensor->bufferSize) == MI_CAMERA_SUCCESS)
{
/

* store the new camera image into the triple buffer for processing
*/
pSensor->TripleBufferFlip(&pSensor->m_pCameraBuffer, true);
pSensor->m_cameraFrameCount++;
}
}
SetEvent(pSensor->m_hCameraThreadEventDead);
_endthread();
}

et dans le thread affichage :

je fais

while (pSensor->m_bPlaying)
{
/*
* get the latest available sensor buffer
*/

    if (!pSensor->TripleBufferFlip(&pSensor->m_pDisplayBuffer))
    {
        /*
         * there is no new image available so we release a little bit of processing time
         */
        Sleep(1);
        continue;
    }

est ce que par hasard un triple buffer ne crée pas intrinséqument un delai de deux frame?

N’étant pas spécialisé en prog gfx, je pense que oui, la particularité du triple buffering est que le rendu peut être variable, essaye en prenant en compte le vblank, histoire d’être synchro, ainsi tu ne rendera qu’une fois le vblank atteint.
Une idée comme ça :neutre: