sélection d’un décodeur dans DirectShow Services d’édition
[Cette API n’est pas prise en charge et peut être modifiée ou non disponible à l’avenir.]
lorsque DirectShow Services de modification (DES) affichent un projet de montage vidéo, le moteur de rendu sélectionne automatiquement les décodeurs nécessaires. Cela peut se produire à l’intérieur de la méthode IRenderEngine :: ConnectFrontEnd , ou de manière dynamique pendant le rendu.
Un utilisateur peut installer plusieurs décodeurs capable de décoder un fichier particulier. quand plusieurs décodeurs sont disponibles, l’algorithme DES Connecter utilise l’algorithme Intelligent pour sélectionner le décodeur.
Il n’existe aucun moyen pour l’application de spécifier directement le décodeur à utiliser. Toutefois, vous pouvez choisir le décodeur indirectement par le biais de l’interface de rappel IAMGraphBuilderCallback . En implémentant cette interface dans votre application, vous pouvez recevoir des notifications pendant le processus de création de graphiques et rejeter certains filtres du graphique.
Commencez par implémenter une classe qui expose l’interface IAMGraphBuilderCallback :
class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
// Method declarations (not shown).
};
créez ensuite une instance du filtre Graph Manager et enregistrez votre classe pour recevoir des notifications de rappel :
// Declare an instance of the callback object.
GraphBuilderCB GraphCB;
// Create the Filter Graph Manager.
CComPtr<IGraphBuilder> pGraph;
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
// Handle error (not shown).
}
// Register to receive the callbacks.
CComQIPtr<IObjectWithSite> pSite(pGraph);
if (pSite)
{
hr = pSite->SetSite((IUnknown*)&GraphCB);
}
ensuite, créez le moteur de rendu et appelez la méthode IRenderEngine :: SetFilterGraph avec un pointeur vers le gestionnaire de Graph de filtre. cela garantit que le moteur de rendu ne crée pas son propre filtre Graph Manager, mais utilise à la place l’instance que vous avez configurée pour les rappels.
CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
// Handle error (not shown).
}
hr = pRender->SetFilterGraph(pGraph);
lorsque le projet est rendu, la méthode IAMGraphBuilderCallback :: SelectedFilter de l’application est appelée immédiatement avant que le gestionnaire de Graph de filtre crée un nouveau filtre. La méthode SelectedFilter reçoit un pointeur vers une interface IMoniker qui représente un moniker pour le filtre. Examinez le moniker et, si vous décidez de rejeter le filtre, retournez un code d’erreur à partir de la méthode SelectedFilter .
La partie difficile consiste à identifier les monikers qui représentent des décodeurs, et en particulier les monikers qui représentent des décodeurs que vous souhaitez rejeter. Une solution est la suivante :
Avant de restituer le projet, utilisez la méthode IFilterMapper2 :: EnumMatchingFilters pour créer une liste de filtres inscrits comme acceptant le type d’entrée souhaité. Pour les types de compression vidéo ou audio, cette liste doit être mappée à un ensemble de décodeurs.
La méthode EnumMatchingFilters retourne une collection de monikers. Pour chaque moniker de la collection, récupérez la propriété DisplayName , comme décrit dans utilisation du mappeur de filtre.
Stockez une liste des noms complets, mais omettez le nom complet qui correspond au filtre que vous souhaitez utiliser pour le décodage. Les noms d’affichage des filtres logiciels se présentent sous la forme suivante :
OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");where
CategoryGUIDest le GUID de la catégorie de filtre, et
FilterCLSIDest le CLSID du filtre. Pour DMOs, le format est le même, mais il prend la
swvaleurdmo.La liste contient maintenant des noms complets pour chaque filtre qui génère le type de média souhaité, mais n’est pas votre filtre préféré.
Dans la méthode SelectedFilter , récupérez la propriété DisplayName sur le moniker proposé et vérifiez-le par rapport à la liste stockée. Si le nom complet correspond à une entrée de la liste, rejeter ce filtre. Dans le cas contraire, acceptez-le en renvoyant S _ OK.