Écriture d’un projet dans un fichier

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

[Cette API n’est pas prise en charge et peut être modifiée ou indisponible à l’avenir.]

Cet article explique comment écrire un projet DirectShow Editing Services dans un fichier. Tout d’abord, il décrit comment écrire un fichier avec le moteur de rendu de base. Il décrit ensuite la recompression intelligente avec le moteur de rendu intelligent.

Pour obtenir une vue d’ensemble de la façon dont DirectShow Editing Services affiche les projets, consultez À propos des moteurs de rendu.

Utilisation du moteur de rendu de base

Commencez par créer le front-end du graphique, comme suit :

  1. Créez le moteur de rendu.
  2. Spécifiez le chronologie.
  3. Définissez la plage de rendu. (facultatif)
  4. Générez le front-end du graphique.

L’exemple de code suivant illustre ces étapes.

IRenderEngine *pRender = NULL; 
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
    IID_IRenderEngine, (void**) &pRender);

hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );

Ensuite, ajoutez des filtres de multiplexeur et d’écriture de fichiers au graphique de filtres. Le moyen le plus simple est d’utiliser le Générateur de graphiques de capture, un composant DirectShow permettant de créer des graphiques de capture. Le générateur de graphe de capture expose l’interface ICaptureGraphBuilder2 . Procédez comme suit :

  1. Créez une instance du générateur de graphe de capture.
  2. Obtenez un pointeur vers le graphique et passez-le au générateur de graphe.
  3. Spécifiez le nom et le type de média du fichier de sortie. Cette étape obtient également un pointeur vers le filtre mux, ce qui sera nécessaire ultérieurement.

L’exemple de code suivant illustre ces étapes.

CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, 
    IID_ICaptureGraphBuilder2, (void **)&pBuilder);

// Get a pointer to the graph front end.
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);

// Create the file-writing section.
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, 
    OLESTR("Output.avi"), &pMux, NULL);

Enfin, connectez les broches de sortie sur le front-end au filtre mux.

  1. Récupérez le nombre de groupes.
  2. Pour chaque broche, obtenez un pointeur vers l’épingle.
  3. Si vous le souhaitez, créez une instance d’un filtre de compression pour compresser le flux. Le type de compresseur dépend du type de support du groupe. Vous pouvez utiliser l’énumérateur d’appareils système pour énumérer les filtres de compression disponibles. Pour plus d’informations, consultez Énumération des appareils et des filtres.
  4. Si vous le souhaitez, définissez des paramètres de compression tels que la fréquence d’images clés. Cette étape est décrite en détail plus loin dans l’article.
  5. Appelez ICaptureGraphBuilder2::RenderStream. Cette méthode prend des pointeurs vers l’épingle, le filtre de compression (le cas échéant) et le multiplexeur.

L’exemple de code suivant montre comment connecter les broches de sortie.

long NumGroups;
pTimeline->GetGroupCount(&NumGroups);

// Loop through the groups and get the output pins.
for (i = 0; i < NumGroups; i++)
{
    IPin *pPin;
    if (pRender->GetGroupOutputPin(i, &pPin) == S_OK) 
    {
        IBaseFilter *pCompressor;
        // Create a compressor filter. (Not shown.)
        // Set compression parameters. (Not shown.)

        // Connect the pin.
        pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
        pCompressor->Release();
        pPin->Release();
    }
}

Pour définir des paramètres de compression (étape 4, précédemment), utilisez l’interface IAMVideoCompression . Cette interface est exposée sur les broches de sortie des filtres de compression. Énumérez les broches du filtre de compression et interrogez chaque broche de sortie pour IAMVideoCompression. (Pour plus d’informations sur l’énumération des broches, consultez Énumération des broches.) Veillez à libérer tous les pointeurs d’interface que vous avez obtenus lors de cette étape.

Après avoir généré le graphe de filtres, appelez la méthode IMediaControl::Run sur le gestionnaire de graphe de filtres. Au fur et à mesure que le graphique de filtre s’exécute, il écrit les données dans un fichier. Utilisez la notification d’événement pour attendre la fin de la lecture. (Voir Réponse aux événements.) Une fois la lecture terminée, vous devez appeler explicitement IMediaControl::Stop pour arrêter le graphique de filtre. Sinon, le fichier n’est pas écrit correctement.

Utilisation du moteur de rendu intelligent

Pour bénéficier des avantages de la recompression intelligente, utilisez le moteur de rendu intelligent à la place du moteur de rendu de base. Les étapes de création du graphe sont presque les mêmes. La principale différence est que la compression est gérée dans le front-end du graphique, et non dans la section d’écriture de fichier.

Important

N’utilisez pas le moteur de rendu intelligent pour lire ou écrire des fichiers Windows Media.

 

Chaque groupe vidéo a une propriété qui spécifie le format de compression de ce groupe. Le format de compression doit correspondre exactement au format non compressé du groupe en hauteur, largeur, profondeur de bits et fréquence d’images. Le moteur de rendu intelligent utilise le format de compression lorsqu’il construit le graphique. Avant de définir le format de compression, veillez à définir le format non compressé pour ce groupe en appelant IAMTimelineGroup::SetMediaType.

Pour définir le format de compression d’un groupe, appelez la méthode IAMTimelineGroup::SetSmartRecompressFormat . Cette méthode prend un pointeur vers une structure SCompFmt0 . La structure SCompFmt0 a deux membres : nFormatId, qui doit être égal à zéro, et MediaType, qui est une structure AM_MEDIA_TYPE . Initialisez la structure AM_MEDIA_TYPE avec les informations de format.

Notes

Si vous souhaitez que le projet final ait le même format que l’un de vos fichiers sources, vous pouvez obtenir la structure AM_MEDIA_TYPE directement à partir du fichier source, à l’aide du détecteur de média. Consultez IMediaDet::get_StreamMediaType.

 

Cassez la variable SCompFmt0 en pointeur de type long, comme illustré dans l’exemple suivant.

SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;

// Initialize pFormat->MediaType. (Not shown.)

pGroup->SetSmartRecompressFormat( (long*) pFormat );

Le moteur de rendu intelligent recherche automatiquement un filtre de compression compatible. Vous pouvez également spécifier un filtre de compression pour un groupe en appelant ISmartRenderEngine::SetGroupCompressor.

Pour générer le graphe, suivez les mêmes étapes que celles décrites pour le moteur de rendu de base dans la section précédente. Les seules différences sont les suivantes :

  • Utilisez le moteur de rendu intelligent, pas le moteur de rendu de base. L’identificateur de classe est CLSID_SmartRenderEngine.
  • Définissez les paramètres de compression après avoir généré le serveur frontal, mais avant d’afficher les broches de sortie. Appelez la méthode ISmartRenderEngine::GetGroupCompressor pour obtenir un pointeur vers le filtre de compression d’un groupe. Ensuite, interrogez l’interface IAMVideoCompression , comme décrit précédemment.
  • Lorsque vous affichez les broches de sortie, il n’est pas nécessaire d’insérer un filtre de compression. Le flux est déjà compressé.

Rendu d’un projet