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

DirectX Discussion :

Optimiser affichage d'une vidéo stéréoscopique rendue en Direct3D


Sujet :

DirectX

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut Optimiser affichage d'une vidéo stéréoscopique rendue en Direct3D
    Bonjour à tous,

    Je souhaite afficher de la vidéo 3D issue de 2 caméras (type webcams) via les outils NVidia 3D Vision.

    J'utilise OpenCV pour toute la partie acquisition et Direct3D pour le rendu.

    En application, je ne dépasse pas les 4 FPS.

    L'algo :
    - Ouverture de la capture de la caméra 0
    - Ouverture de la capture de la caméra 1
    - Création de la fenêtre qui va recevoir la vidéo 3D
    - create3D : création et parametrage de l'interface Direct3D
    - create3D : création d'une surface D3D
    - set3D : Lock de la surface
    - set3D : Ecriture de la signature stéréo Nvidia
    - set3D : Unlock de la surface
    Tant que (1)
    - getImages : parametrage du rectangle de destination
    - getImages : récupération d'une image de la caméra 0
    - getImages : récupération d'une image de la caméra 1
    - getImages : chargement des data de l'image de la caméra 0 dans la surface D3D
    - getImages : décalage du rectangle de destination
    - getImages : chargement des data de l'image de la caméra 1 dans la surface D3D
    - paintEvent : Début de la scène 3D
    - paintEvent : paramétrage du rectangle de destination
    - paintEvent : Récupération du back buffer
    - paintEvent : Application de la surface sur le back buffer
    - paintEvent : Libération du back buffer
    - paintEvent : Fin de la scène 3D
    - paintEvent : Présentation de l'image créée
    Fin tant que
    - Libération des devices et destruction de la fenêtre.

    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
    136
    137
    138
    139
    140
    141
     
     
    int largeurCamera = 320;
    int hauteurCamera = 240;
     
     
    void MainWindow::openFlux()
    {
        HRESULT hr;
        MSG msg;
        destRect.top = 0;
        destRect.bottom = hauteurImg;
     
        // First Camera Setup
        capture0 = cvCreateCameraCapture(0);
        cvSetCaptureProperty(capture0, CV_CAP_PROP_FRAME_WIDTH, largeurCamera); // frame width
        cvSetCaptureProperty(capture0, CV_CAP_PROP_FRAME_HEIGHT, hauteurCamera);  // frame height
     
     
        // Second Camera Setup
        capture1 = cvCreateCameraCapture(1);
        cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_WIDTH, largeurCamera);   // frame width
        cvSetCaptureProperty(capture1, CV_CAP_PROP_FRAME_HEIGHT, hauteurCamera);  // frame height
     
        // Crea Fenetre
        HINSTANCE hInstance = (HINSTANCE)::GetModuleHandle(NULL);
        HWND hWnd = CreateWindow(L"test", L"test2", /*WS_EX_TOPMOST | WS_POPUP*/ WS_POPUPWINDOW, 0, 0, 1680, 1050, NULL, NULL, hInstance, NULL);
        ShowWindow(hWnd,1);
     
     
        // Injection create3D();
        _d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface
     
        D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information
     
        ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
        d3dpp.Windowed = FALSE;    // program fullscreen
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
        d3dpp.hDeviceWindow = winId();    // set the window to be used by Direct3D
        d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;  // set the back buffer format to 32 bit // or D3DFMT_R8G8B8
        d3dpp.BackBufferWidth = largeurImg;
        d3dpp.BackBufferHeight = hauteurImg;
        d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
        d3dpp.BackBufferCount = 1;
     
        // create a device class using this information and information from the d3dpp stuct
        hr = _d3d->CreateDevice(D3DADAPTER_DEFAULT,
                           D3DDEVTYPE_HAL,
                           winId(),
                           D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                           &d3dpp,
                           &_d3ddev);
     
        if (SUCCEEDED(hr)){
            //3D VISION uses a single surface 2x images wide and image high
            // create the surface
            hr = _d3ddev->CreateOffscreenPlainSurface(largeurImg*2, hauteurImg+1, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
        }
        // Fin create3D()
     
        // Injection set3D()
        D3DLOCKED_RECT lock;
        if (SUCCEEDED(hr)){
            hr = surface->LockRect(&lock,NULL,0);
        }
     
        // write stereo signature in the last raw of the stereo image
        LPNVSTEREOIMAGEHEADER pSIH = (LPNVSTEREOIMAGEHEADER)(((unsigned char *) lock.pBits) + (lock.Pitch * (hauteurImg)));
     
        // Update the signature header values
        pSIH->dwSignature = NVSTEREO_IMAGE_SIGNATURE;
        pSIH->dwBPP = 32;
        //pSIH->dwFlags = SIH_SWAP_EYES; // Src image has left on left and right on right, thats why this flag is not needed.
        pSIH->dwFlags = SIH_SCALE_TO_FIT;
        pSIH->dwWidth = largeurImg *2;
        pSIH->dwHeight = hauteurImg;
     
        if (SUCCEEDED(hr)){
            // Unlock surface
            hr = surface->UnlockRect();
        }
        // Fin set3D()
     
        // this struct holds Windows event messages
        while(TRUE)
        {
            // wait for the next message in the queue, store the result in 'msg'
            while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                // translate keystroke messages into the right format
                TranslateMessage(&msg);
     
                // send the message to the WindowProc function
                DispatchMessage(&msg);
            }
     
            // If the message is WM_QUIT, exit the while loop
            if(msg.message == WM_QUIT)
                break;
     
            // Injection getImages()
            destRect.left = largeurImg;
            destRect.right = largeurImg*2;
     
            // Chargement des deux frames dans une seule IPLIMAGE puis une seule instruction D3DXLoadSurfaceFromMemory
            frameFromCamera1 = cvQueryFrame(capture1);
            frameFromCamera0 = cvQueryFrame(capture0);
     
            qTime.start();
            hr = D3DXLoadSurfaceFromMemory(surface, NULL, &destRect, frameFromCamera1->imageData, D3DFMT_R8G8B8, frameFromCamera1->widthStep, NULL, &srcRect, D3DX_DEFAULT, 0);
     
            cout << "D3DXLoadSurfaceFromMemory : " << qTime.elapsed() << endl;
     
            destRect.left = 0;
            destRect.right = largeurImg;
     
            qTime.restart();
            hr = D3DXLoadSurfaceFromMemory(surface, NULL, &destRect, frameFromCamera0->imageData, D3DFMT_R8G8B8, frameFromCamera0->widthStep, NULL, &srcRect, D3DX_DEFAULT, 0);
            cout << "D3DXLoadSurfaceFromMemory 2 : " << qTime.elapsed() << endl;
            // Fin getImages
     
            // Injection paintEvent();
            hr = _d3ddev->BeginScene();    // begins the 3D scene
            destRect.bottom = hauteurImg;
            destRect.right = largeurImg;
     
            // Get the Backbuffer then Stretch the Surface on it.
            hr = _d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_backBuf);
            hr = _d3ddev->StretchRect(surface, NULL, _backBuf, &destRect, D3DTEXF_NONE);
            _backBuf->Release();
     
            hr = EndScene();
     
            hr = _d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame
     
        } // Fin While TRUE
     
        _d3ddev->Release();    // close and release the 3D device
        _d3d->Release();    // close and release Direct3D
        cvDestroyAllWindows();
    }
    Le souci est donc la vitesse d'affichage. Je cherche à obtenir une image 3D fluide (24/30 im/s) et avec un délai le plus petit possible.

    Je développe sous QT (plateforme utilisée dans ma boite) et les instructions critiques sont les 2 D3DXLoadSurfaceFromMemory aux lignes 110 et 118, elles prennent 150ms, et je voudrais donc les réduire à ~30 ms.

    Je ne suis pas un as du C++, encore moins de Direct3D et je suis bien conscient que mes méthodes de programmations ne sont très probablement pas "légales" :p. Néanmoins, j'ai vraiment besoin de votre aide !

    Si vous avez des suggestions, je suis preneur.

    Merci beaucoup et bonne journée !!

  2. #2
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    En fait tu utilises beaucoup de fonctions gourmandes en ressource, comme D3DXLoadSurfaceFromMemory ou GetBackBuffer.

    C'est pour cela que l'on a inventé la VMR9 puis l'EVR, les flux vidéo montant ne bloquent pas le bus graphique, enfin beaucoup moins.

    Dans ce genre de situation j'utiliserai les API de MediaFoundation pour la capture et l'EVR pour l'accélération graphique. Avec du matériel performant, et pour deux captures, même en HD, ça marchera facilement à 30 FPS.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Salut moldavi et merci pour ton retour.

    Avant de passer par OpenCV, je m'étais créé mon propre graphe qui sortait en VMR9, car j'avais lu que VMR9, en mode Renderless, pouvait me fournir directement une surface D3D, ce qui m'arrangeait grandement en vue de l'afficher en 3D via la techno Nvidia.

    En pratique, je n'ai pas réussi à aller au bout et je suis tombé sur un exemple presque complet sur stackoverflow, ou le gars passait par OpenCV. Voyant à quel point c'était simple et court vs. mes dizaines de lignes de code pour mon Graph, je m'étais précipité dessus, pensant qu'OpenCV faisait, en interne, tout ce que j'avais déjà codé (Webcam Video Capture -> AVI Decompressor -> VMR9).

    Et puis toute la partie Allocator ne m'inspirait pas vraiment, du coup, j'étais bien content de m'en débarrasser grâce à OpenCV.

    Concernant les fonctions D3DXLoadSurfaceFromMemory et GetBackBuffer, je les utilise car c'est ce qu'NVidia préconise pour afficher de la vidéo en 3D (cf. cette présentation, pages 36 à 40).

    Du coup, si je ne les utilise pas pour charger mes images dans ma surface puis pour afficher mon back buffer, je ne suis pas sûr que ça fonctionne à la sauce NVidia...

    Qu'en penses-tu ?

    Merci encore !

    [EDIT] Je resors mon boulot sur VMR9 et essaie d'aller au bout en attendant ton retour

  4. #4
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Bonjour,

    Le problème vient du fait qu'une capture video n'est pas sous la forme mémoire permettant un affichage simple par DirectX. En restant dans MediaFoundation, les performances seront au rendez-vous, au prix d'une délégation de la tâche d'affichage à un pilote que vous ne contrôlerez pas, et qui ne créera probablement à aucun moment de son pipeline une "vraie" image, dont on pourrait par exemple inspecter les pixels.
    Pour profiter de l'API NVidia, il faut par contre "réaliser" les images sous forme manipulable. C'est exactement ce que vous faites par cvQueryFrame/ ->imageData sous CV, et qui demanderait ConvertToContiguousBuffer sous MediaFoundation.

    Je n'ai pas testé de comparaison avec OpenCV, nous ne travaillons que sous MediaFoundation. Néanmoins, je suis assez confiant sur les performances si vous choisissez MediaFoundation, car nous n'avons pas de problème pour afficher à 60 Hz en HD, malgré une "matérialisation" au vol de l'image pour analyse. Cette "matérialisation" du flux video sous forme d'image devrait pouvoir vous servir comme source d'affichage pour DirectX, si vous choisissez un format MF ne nécessitant pas de conversion lors de l'appel à D3DXLoadSurfaceFromMemory (par exemple MFVideoFormat_RGB24, ou selon vos besoins).

    Nous n'utilisons que des ordinateurs ultra-performants pour nos applications, donc je ne suis pas sûr que ça marche dans le cas géénral, mais en tout cas je m'attendrai chez nous à des performances supérieures à 30 Hz sur votre type d'application.

    Bonne chance avec MF, c'est une API complètement systématique, mais un peu extrême à mon gout ("bonjour, je voudrais demander s'il est possible d'interroger Windows sur l'existence d'un système de requête autorisant l'inspection de liste de méthodes d'itération sur l'existence de caractéristiques autorisées pour la description enumérateurs de périphériques").
    "Maybe C++0x will inspire people to write tutorials emphasizing simple use, rather than just papers showing off cleverness." - Bjarne Stroustrup
    "Modern C++11 is not your daddy’s C++" - Herb Sutter

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Bonjour ac_wingless et merci pour votre réponse !

    Je me penche sur MF de suite et vous tiens au courant !

    [EDIT] C'est vrai que l'API MF a l'air vraiment difficile d'accès. Au premier abord, je pige rien.

    Je suis en train d'essayer de décrypter l'exemple MFCaptureD3D fourni avec le SDK Windows. C'est ce qui semble s'approcher le plus de ce que je veux faire.

  6. #6
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    La technologie NVidia 3D vision à l'air très intéressante, mais je n'ai pas eu l'occasion de me pencher dessus.

    Citation Envoyé par hubchau Voir le message
    Concernant les fonctions D3DXLoadSurfaceFromMemory et GetBackBuffer, je les utilise car c'est ce qu'NVidia préconise pour afficher de la vidéo en 3D (cf. cette présentation, pages 36 à 40).

    Du coup, si je ne les utilise pas pour charger mes images dans ma surface puis pour afficher mon back buffer, je ne suis pas sûr que ça fonctionne à la sauce NVidia...

    Qu'en penses-tu ?
    Ce que je vois, c'est que NVidia utilise une surface classique (au sens DirectX), et lui assigne une signature.

    L'EVR : http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx permet de mixer plusieurs flux vidéo (lire la documentation car il y a des contraintes, notamment sur les formats vidéo).

    En admettant que les deux cartes d'acquisition produisent le même format, l'EVR te fournira une surface pour chaque flux. Ce que je pense, c'est qu'il faudra juste faire une copie des deux surfaces sur la surface finale (celle avec la signature). Pour éviter une copie manuelle des deux surfaces, j'utiliserais un shader.

    Du fait de l'utilisation de Mediafoundation, pas besoin de D3DXLoadSurfaceFromMemory.
    Du fait que la surface finale est associé au BackBuffer avec l'EVR, pas besoin de faire un GetBackBuffer.

    Tout cela reste bien sûr à expérimenter. Je ne donne cette réponse que par rapport à mes connaissances sur l'EVR et au code source que tu nous as fournit. C'est du moins le première direction que je prendrais si j'avais un tel projet.

    Citation Envoyé par hubchau Voir le message
    C'est vrai que l'API MF a l'air vraiment difficile d'accès. Au premier abord, je pige rien.
    L'API MF peut paraître complexe, mais c'est parce que le monde de l'audio/vidéo est complexe. Il faut des mois de pratique et d'expérimentation avant de commencer à maîtriser un peu (lorsque l'on part de zéro, j'entends).

    Le mixage de plusieurs flux vidéo dans un environnement 3D est un des domaines les plus complexes dans cette API, je pense. Tu as un sample dans le SDK MediaFoundation : evrpresenter. Prends aussi le temps de lire toute la documentation de MediaFoundation. C'est un passage obligé.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    moldavi,

    Merci beaucoup pour toutes ces indications ! Je m'y mets de suite

    Ça fait plaisir de voir qu'on est pas tout seul ! Tu me refais ma journée !

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    So... Je galère un peu avec le combo MF/EVR.

    J'ai potassé un peu la doc mais c'est pas évident.

    J'essaie de transformer l'exemple MFCaptureD3D pour qu'il utilise l'EVR plutot que D3D pour faire le rendu de ma webcam, mais je bloque.
    Je me base aussi sur l'exemple MSDN Media Session Playback Example mais j'ai du mal à transformer le code qui permet de lire un fichier ou une URL en un code pour lire un stream de webcam.

    Un petit coup de main serait grandement apprécié :/

  9. #9
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Re.

    Utiliser MediaSession est la bonne direction.

    Il te faut un MediaSource pour construire la topologie avec l'EVR. Regarde du côté de "ActivateObject", pour transformer l'acquisition vidéo en MediaSource.

    Un truc dans ce genre :

    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
    HRESULT CreateMediaSourceFromCapture(IMFMediaSource** ppMediaSource){
     
        if (!ppMediaSource){
          return E_POINTER;
        }
     
        HRESULT hr = S_OK;
     
        IMFMediaSource* pVideoSource = NULL;
        IMFAttributes*  pAttributes = NULL;
     
        UINT32        cDevices = 0;
        IMFActivate** ppDevices = NULL;
     
        WCHAR* szFriendlyName = NULL;
     
        hr = MFCreateAttributes(&pAttributes, 1);
     
        if(SUCCEEDED(hr))
            hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
     
        // Enumerate devices.
        if(SUCCEEDED(hr))
          hr = MFEnumDeviceSources(pAttributes, &ppDevices, &cDevices);
     
        if(SUCCEEDED(hr))
            hr = ppDevices[0]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &szFriendlyName, NULL);
     
        // ToDo check FriendlyName is OK
        if(SUCCEEDED(hr))
            hr = ppDevices[0]->ActivateObject(__uuidof(IMFMediaSource), (void**)&pVideoSource);
     
        CoTaskMemFree(szFriendlyName);
     
        for(UINT32 i = 0; i < cDevices; i++)
            SafeRelease(&ppDevices[i]);
     
        CoTaskMemFree(ppDevices);
        ppDevices = NULL;
        cDevices = 0;
     
        SafeRelease(&pAttributes);
     
        if(SUCCEEDED(hr)){
            *ppMediaSource = pVideoSource;
            (*ppMediaSource)->AddRef();
        }
     
        SafeRelease(&pVideoSource);
     
        return hr;
    }

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Salut moldavi et merci pour ta réponse. Je pense qu'elle me sera d'une grande aide.

    Peux-tu me confirmer que mon algo de capture et d’affichage est bon ?

    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
    WinMain
    	Initialisation de l'application
    			InitInstance
    				Création de la fenêtre de l'appli
    				Affichage de la fenêtre
    	Boucle d'attente des messages
    WndProc
    	WM_CREATE
    		Enumérer les périph de capture
    		Stocker le pointeur de mes deux caméras
    		Créer la session media
    		Créer une source média pour chacune des caméras
    		Configurer la présentation ?
    		Créer la topologie contenant la source média ?
    		Lier la source media et l'EVR selon la topologie ?
    		Utiliser la session media pour lancer les sources média
    		Récupérer les 2 surfaces D3D issues de l'EVR
    		Faire le traitement Nvidia
    	WM_SIZE
    		Mettre à jour l'affichage
    	WM_DESTROY
    		Libérer toutes les ressources 
    		Fermer la session media
    		Fermer la fenêtre
    Dois-je clore ma session media plus tot ? Pour info, je n'aurais pas besoin de contrôle le média (pas besoin de lecture, pause, stop)

    Merci encore

  11. #11
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Oui c'est la direction à suivre.

    Par contre, pour la récupération des deux surfaces et le traitement NVidia, je ferais différemment. Je modifierais le sample "EvrPresenter", afin de faire le traitement NVidia directement dans l'EVR.

    Mais ta solution est peut-être fonctionnelle.

    PS: dans ce type de projet, j'aurai d'abord vérifier la compatibilité Evr/Nvidia, avant de me lancer dans la MediaSession.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    J'ai compilé l'exemple MFPlay avec succès et j'ai pu intégrer ta fonction CreateMediaSourceFromCapture (qui marche au poil, merci ).

    Du coup la prochaine étape est de passer cet exemple rudimentaire en EVR. Pour ça, je pensais intégrer la DLL EVR que l'on obtient en compilant l'exemple EVRPresenter mais, dans un premier temps, sans la modifier pour gérer ma partie NVidia. Comme ça je serais sûr que ça fonctionne et ça me permettra de me familiariser avec la bête.

    Pour utiliser la DLL EVR, je me base sur l'exemple MFPlayer qui ajoute une case à cocher dans la boite de dialogue du choix du fichier pour en faire le rendu via l'EVR.

    Je rame .

    Merci.

    Hub

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Bonjour à tous !

    J'ai réussi à modifier l'exemple MFplayer de Microsoft pour qu'il affiche une de mes webcams. Il appelle donc EVRPresenter.dll pour faire le rendu.

    Je pense que c'est pas du tout rigoureux/propre, mais ca fonctionne !

    Du coup j'essaie maintenant de modifier le code d'EVRPresenter pour qu'il gère les deux flux et la partie NVidia.

    Est ce que vous auriez des conseils sur ces deux points ?

    Je pensais utiliser la méthode IMFMediaSink::AddStreamSink, mias je ne sais pas à quel moment/endroit le faire. Et comme l'exemple EVRPresenter compile sous forme de DLL c'est quasi impossible de debugger...

    Un tuyau serait le bienvenu

    Merci

  14. #14
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Pour débugger une dll sous windows, il faut attacher le projet dll à un exécutable. Regarde dans les propriétés du projet, puis débugage, puis parcourir, et enfin sélectionner l'exe (ici MFPlayer.exe).

    Ensuite lancer le debugage. Lorsque l'exe charge la dll, le débugage s'effectue comme avec un exe.

    Pour le débuggage en lui-même, un outil pour tracer l'exécution est le bien venu. Télécharge mon projet open-source MFNode ici : http://sourceforge.net/projects/mfnode/

    Il y des outils de traçage très utiles dans le repertoire "Common".

    Citation Envoyé par hubchau Voir le message
    Je pensais utiliser la méthode IMFMediaSink::AddStreamSink, mias je ne sais pas à quel moment/endroit le faire.
    Tout se passe dans la topologie, tu as deux sources nodes (capture) et un sink node (evr). Un truc de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pSourceNode1->ConnectOutput(0, pOutputNode, 0);
    pSourceNode2->ConnectOutput(1, pOutputNode, 0);
    Avec cette méthode, MediaFoundation tentera de faire fonctionner le truc. Si ça ne marche pas, les choses se compliquent car il faudra gérer à la main.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Ca marche impecc ! J'ai mes deux caméras ! Merci beaucoup moldavi

    Maintenant je me penche sur l'EVR pour qu'il fasse la partie NVidia.

    Merci encore !

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/06/2010, 17h44
  2. [CSS 2] IE8: problème affichage d'une vidéo
    Par tintin72 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 02/06/2010, 17h40
  3. Affichage d'une vidéo
    Par vincbobor dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 25/04/2010, 22h51
  4. [Oracle] Optimiser affichage dans une table
    Par evil_mouss dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 24/07/2009, 18h49
  5. Affichage d'une vidéo en dehors du répertoire du serveur web
    Par Gouyon dans le forum Balisage (X)HTML et validation W3C
    Réponses: 13
    Dernier message: 16/01/2009, 08h53

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