Comment lire un fichier

cet article a pour but de vous fournir la version de DirectShow programmation. Il présente une application console simple qui lit un fichier audio ou vidéo. le programme ne fait que quelques lignes, mais il illustre une partie de la puissance de la programmation de DirectShow.

comme décrit dans l’article présentation de DirectShow application programming , une application DirectShow effectue toujours les mêmes étapes de base :

  1. créez une instance du gestionnaire de Graph de filtre.
  2. utilisez le gestionnaire de Graph de filtre pour générer un graphique de filtre.
  3. Exécuter le graphique, ce qui provoque le déplacement des données dans les filtres.

Pour compiler et lier le code dans cette rubrique, incluez le fichier d’en-tête DShow. h et un lien vers le fichier de bibliothèque statique strmiids. lib. pour plus d’informations, consultez génération d’Applications DirectShow.

Commencez par appeler CoInitialize ou CoInitializeEx pour initialiser la bibliothèque com :

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
    // Add error-handling code here. (Omitted for clarity.)
}

Pour simplifier les choses, cet exemple ignore la valeur de retour, mais vous devez toujours vérifier la valeur HRESULT à partir de n’importe quel appel de méthode.

ensuite, appelez CoCreateInstance pour créer le filtre Graph Manager :

IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, 
    CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

Comme indiqué, l’identificateur de classe (CLSID) est CLSID _ FilterGraph. le gestionnaire de Graph de filtre est fourni par une DLL in-process, le contexte d’exécution est donc CLSCTX _ inproc _ SERVER. DirectShow prend en charge le modèle de thread libre, vous pouvez également appeler CoInitializeEx avec l’indicateur coinit _ multithread .

L’appel à CoCreateInstance retourne l’interface IGraphBuilder , qui contient principalement des méthodes pour générer le graphique de filtre. Deux autres interfaces sont nécessaires pour cet exemple :

  • L' IMediaControl contrôle la diffusion en continu. Elle contient des méthodes pour l’arrêt et le démarrage du graphique.
  • IMediaEvent a des méthodes permettant d’obtenir des événements à partir du gestionnaire de Graph de filtre. Dans cet exemple, l’interface est utilisée pour attendre la fin de la lecture.

ces deux interfaces sont exposées par le gestionnaire de Graph de filtre. Utilisez le pointeur IGraphBuilder retourné pour effectuer une requête :

IMediaControl *pControl;
IMediaEvent   *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

Vous pouvez maintenant générer le graphique de filtre. Pour la lecture de fichiers, cette opération est effectuée par un appel de méthode unique :

hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);

La méthode IGraphBuilder :: RenderFile crée un graphique de filtre qui peut lire le fichier spécifié. Le premier paramètre est le nom de fichier, représenté sous la forme d’une chaîne de caractères larges (2 octets). Le deuxième paramètre est réservé et doit être égal à null.

Cette méthode peut échouer si le fichier spécifié n’existe pas ou si le format de fichier n’est pas reconnu. En supposant que la méthode aboutisse, toutefois, le graphique de filtre est maintenant prêt pour la lecture. Pour exécuter le graphique, appelez la méthode IMediaControl :: Run :

hr = pControl->Run();

Lorsque le graphique de filtre s’exécute, les données se déplacent dans les filtres et sont rendues en tant que vidéo et audio. La lecture se produit sur un thread séparé. Vous pouvez attendre la fin de la lecture en appelant la méthode IMediaEvent :: WaitForCompletion :

long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);

Cette méthode bloque jusqu’à ce que le fichier soit terminé, ou jusqu’à ce que l’intervalle de délai d’attente spécifié se soit écoulé. La valeur infinie signifie que l’application se bloque indéfiniment jusqu’à ce que le fichier soit terminé. Pour obtenir un exemple plus réaliste de gestion des événements, consultez réponse aux événements.

Lorsque l’application est terminée, libérez les pointeurs d’interface et fermez la bibliothèque COM :

pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();

Exemple de code

Voici le code complet de l’exemple décrit dans cet article :

#include <dshow.h>
void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;

    // Initialize the COM library.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

    // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Filter Graph Manager.");
        return;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph. IMPORTANT: Change this string to a file on your system.
    hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
            // can block indefinitely.
        }
    }
    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();
}

tâches de base DirectShow