2017-07-19 13 views
0

Je suis maintenant en train d'explorer la courbe d'apprentissage de Windows Media Foundation et je me concentre sur deux exemples de code très similaires pour m'aider à comprendre la technologie. Même si les deux utilisent Media Session pour un programme "Play" très simple qui lit la vidéo à partir d'un fichier, il existe des différences subtiles importantes.Quel exemple de code MF Play montre les techniques COM appropriées dans Media Foundation?

Le premier échantillon est MF Play de Microsoft à l'adresse:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd979592(v=vs.85).aspx

Il n'a pas initialize COM et ne fonctionne pas de verrous de section critique mais il joue vidéo très bien. Le manque d'utilisation de COM limitera-t-il son utilisation d'autres façons, par exemple lors du traitement de plusieurs flux vidéo pour séparer les fenêtres par multithreading? Puisque ce code est en ligne, je suppose que ce code est plus courant.

Le deuxième exemple provient du livre "Développement de Microsoft Media Foundation Applications - Par Anton Polinger". J'ai téléchargé exemple de code d'ici: https://www.microsoftpressstore.com/content/images/9780735656598/downloads/9780735656598_files.zip

Ce programme de lecture dans le dossier Chapitre 3 est un peu plus complexe en raison de l'utilisation de ces fonctions d'initialisation COM:

// initialize COM 
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 
... 
// uninitialize COM 
CoUninitialize(); 

Il utilise également plusieurs verrous de section critique à l'aide :

CComCritSecLock<CComAutoCriticalSection> lock(m_critSec); 

Mais mystérieusement, il n'y a pas de déblocage correspondant(). Donc, quelqu'un peut-il expliquer ces différences importantes potentielles entre ces deux échantillons de code et celles que je devrais utiliser? Je suis inquiet que si je n'utilise pas les méthodes COM, je pourrais avoir des problèmes plus tard quand j'essayer de diffuser plusieurs vidéos sur plusieurs fenêtres, ou pire je pourrais avoir des problèmes de fiabilité. Sur une note de côté, le code Polinger fonctionne mais ne gère pas le redimensionnement de la fenêtre pendant la lecture de la vidéo. Je tentais d'ajouter dans le code similaire à la façon dont le code MS fait en utilisant ce code après un événement redimensionnement de la fenêtre:

m_pVideoDisplay->SetVideoPosition(NULL, &rcDest) 

L'utilisation de ce programme juste fait de geler.

Toute aide serait grandement appréciée!

Répondre

1

À propos de "Il n'initialise pas COM" - vous avez vu pas tout le code de celui-ci - recherche Media Session Playback Example - vous trouverez l'appel MFStartup dans player.cpp - il suffit de MediaFoundation (MF). J'ai lu le livre de Polinger et dans le code il appelle une certaine fonction sensible de modèle de fil de COM - par exemple, DirectX. Mais, d'après mon expérience, il semble que MF appelle CoInitialize à partir du contexte de l'appel MFStartup. De plus, dans le code du livre de Polinger il y a appelez le modèle de fil d'appartement: hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);, mais MF prend en charge l'exécution à partir du modèle Multithread - il n'est pas sensible pour cela.

À propos de "Mais mystérieusement il n'y a pas de déblocage correspondant()". - CComCritSecLock est un wrapper orienté objet pour le verrouillage de section et unlocks() est appelé dans le destructeur de CComCritSecLock - ~CComCritSecLock().

A propos de redimensionnement - m_pVideoDisplay->SetVideoPosition(NULL, &rcDest) - il semble que ce rcDest a une valeur erronée - selon IMFVideoDisplayControl::SetVideoPosition method

The destination rectangle defines a rectangle within the clipping window where the video appears. It is specified in pixels, relative to the client area of the window. To fill the entire window, set the destination rectangle to {0, 0, width, height},

je peux conseiller la recherche de mon projet sur CodeProject site: NativeMediaFoundationPlayer: et WPFMediaFoundationPlayer

Cordialement, Evgeny Pereguda

+0

Merci pour votre réponse et vos liens! Et surtout pour éclaircir comment le destructeur fait le déblocage. Pas un tel mystère maintenant. –

1

L'exemple omet de façon incorrecte l'initialisation COM et cela est incorrect. Il aurait dû appeler CoInitialize [Ex] comme d'habitude. Vous pouvez vérifier les exemples Windows SDK 7.x pour Media Foundation et les exemples montrent une initialisation correcte. Par exemple, this est comment Transcode échantillon le fait.

Comme Evgeny mentionné, CComCritSecLock et CComAutoCriticalSection sont des classes ATL bien connues et documentées qui vous aident avec le déverrouillage automatique des sections critiques.

Utilisez cette classe pour verrouiller et déverrouiller objets d'une manière plus sûre que la classe CComCriticalSection ou CComAutoCriticalSection classe.

+0

Merci pour la clarification! Je n'ai pas recherché MFPlayer2 car il utilise l'API IMFPMediaPlayer obsolète mais je vais la regarder pour voir comment elle utilise les techniques de verrouillage COM. –

+0

Même si MFPlayer2 utilise peut-être deprecated (mauvais exemple), les règles COM s'appliquent de la même manière. –

0

Pour toute autre personne qui peut travailler le l'exemple de code Polinger j'ai parlé dans mon OP, j'ai pu ajouter avec succès le redimensionnement fenêtre à l'exemple Polinger en faisant ceci:

Dans le WINMAIN.CPP fichier, fonction de rappel WndProc, j'ajouté:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
... 
    case WM_SIZE: 
     OnResize(LOWORD(lParam), HIWORD(lParam)); 
     break; 

ensuite ajouté cette fonction au fichier WINMAIN.CPP:

// Handler for WM_SIZE messages. 
void OnResize(WORD width, WORD height) 
{ 
    if (g_pPlayer) 
    { 
     g_pPlayer->ResizeVideo(width, height); 
    } 
} 

Puis ajouté cette fonction au fichier Player.cpp:

HRESULT CPlayer::ResizeVideo(WORD width, WORD height) 
{ 
    HRESULT hr = S_OK; 

    CComCritSecLock<CComAutoCriticalSection> lock(m_critSec); 

    if (m_pVideoDisplay) 
    { 
     // Set the destination rectangle. 
     RECT rcDest = { 0, 0, width, height }; 
     hr = m_pVideoDisplay->SetVideoPosition(NULL, &rcDest); 
    } 

    return hr; 
}