ACQUISITION VIDEO DIRECTSHOWLIB

Le
B#..
Bonjour,

Je cherche à travailler un flux video en C# , sujet lequel j'avais reçu
l'aide et les (précieux )conseils de Paul BACELAR et Rémi
THOMAS.(ACQUISITION VIDEO EN C# du 19/05). Effectivement, les voix de
recherches sont bien celles conseillées, mais je me heurte au manque de
documentation sur l'utilisation des filtres DIRECTSHOW. J'ai téléchargé le
SDK DirectX9, trouvés divers exemples de fonctionnement, bref je devrais
avoir tout pour developper ma propre implementationmais )
En fait :
a)J'ai un exemple qui modifie le flux d'une source fichier AVI et change la
couleur de l'image qui fonctionne correctement (a partir de la librairie
DirecShowLib)
b)J'ai un autre exemple qui capture le flux d'une WebCam correctement et
l'affiche (PreView) (a partir de la librairie DirecShowLib)
Mon problème étant de modifier comme a) le flux acquis comme b) Et je
n'arrive pas jonctionner les deux fonctionnements

Si quelqu'un maitrise DirectShowLib et les caractéristiques des filtres, et
a une idée sur les erreurs que je commets :
je suis parti sur les fonctionnement suivant :
Définir un graphe général dont de filtre d'acquisition est un filtre de
capture de flux basée sur la WebCam à partir de l'interface ICaptureBuiler2
(Fonctionne bien dans mon exemple a))
Définir un filtre de capture de trame à partir de l'interface
ISampleGrabber, le paramètrage de ce filtre permettant d'appeller en
Callback la fonction BufferCB dans laquelle je travaille la trame acquise
(changement de couleur) (Fonctionne bien dans l'exemple b) )
Afficher le résultat avec un filtre de rendu standard aux deux..

Mon code de construction de graphe est le suivant
void constructionDuGraphe()
{
try
{
//Construction des interfaces nécessaires
gb = (IGraphBuilder)new FilterGraph();
mc = (IMediaControl)gb;
me = (IMediaEventEx)gb;
mp = (IMediaPosition)gb;

//Affectation du gestionnaire d'evenement
me.SetNotifyWindow((IntPtr)this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);

// Creation du filtre de capture
Type t = Type.GetTypeFromCLSID(CgGuid);
cg = (ICaptureGraphBuilder2)Activator.CreateInstance(t);

//Affectation du graphe de capture au graphe général
cg.SetFiltergraph(gb);

//Obtention du périphérique connecté
if (chercheWebCam(out sf))
{
gb.AddFilter(sf, "Capture Video");
}
else
{
throw new Exception("Aucun peripherique");
}

//Creation du filtre d'acquisition des frames
sb = (ISampleGrabber)new SampleGrabber();
ConfigSampleGrabber(sb);

//Ajout du filtre d'acquisition
gb.AddFilter((IBaseFilter)sb, "SampleGrabber");

// Mise en place du filtre de rendu par connection intelligente
cg.RenderStream( PIN_CATEGORY_PREVIEW, MEDIATYPE_Video, sf, null, null);

//Propriétés video
bv = (IBasicVideo)gb;
bv.GetVideoSize(out videoWidth, out videoHeight)

// Fenêtrage
vw = (IVideoWindow)gb;
vw.put_Owner((IntPtr)this.Handle);
vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings |
WindowStyle.ClipChildren);
Rectangle rc = this.ClientRectangle;
vw.SetWindowPosition(0, 0, rc.Right, rc.Bottom);

//Lancement
mc.Run();
}

Et mon code de configuration du filtre SampleGrabber est le suivant :

AMMediaType media;

// Positionne les parametres
media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo;

// Affectation à l'interface ISampleGrabber
sb.SetMediaType(media);
DsUtils.FreeAMMediaType(media);
media = null;

// Le '1' représente le BufferCB, le SampleCB ne fonctionne pas correctement
sb.SetCallback(this, 1);

Le résultat est une visualisation du flux de la caméra (comme un Preview
normal) sans passer par la procédure BufferCD (Pourquoi n'est elle pas
appelée?)

Merci d'avance de vos conseils.

B#
Vos réponses
Trier par : date / pertinence
Remi THOMAS
Le #12243181
"B#.." écrivit
Bonjour,

Si quelqu'un maitrise DirectShowLib et les caractéristiques des filtres,
et a une idée sur les erreurs que je commets :
je suis parti sur les fonctionnement suivant :
Définir un graphe général dont de filtre d'acquisition est un filtre de
capture de flux basée sur la WebCam à partir de l'interface
ICaptureBuiler2
(Fonctionne bien dans mon exemple a))
Définir un filtre de capture de trame à partir de l'interface
ISampleGrabber, le paramètrage de ce filtre permettant d'appeller en
Callback la fonction BufferCB dans laquelle je travaille la trame acquise
(changement de couleur) (Fonctionne bien dans l'exemple b) )
Afficher le résultat avec un filtre de rendu standard aux deux..




Pour faire cela je mixe DirectShow pour la capture via BufferCB et DirectX
3D pour l'affichage.
En effet en DirectShow pur tu ne peux injecter un flux modifié.
Dans mon projet je fais la capture DirectShow en C++ car c'est plus simple.

Rémi
B#..
Le #12243171
Bonjour REMI,

Ok pour la modification du flux, mais pourquoi BufferCB n'est-il pas appellé
? En suivant l'exécution au déboggueur, l'appel ne se fait pas ....

B#

"Remi THOMAS"
"B#.." écrivit
Bonjour,



Pour faire cela je mixe DirectShow pour la capture via BufferCB et DirectX
3D pour l'affichage.
En effet en DirectShow pur tu ne peux injecter un flux modifié.
Dans mon projet je fais la capture DirectShow en C++ car c'est plus
simple.

Rémi


Publicité
Poster une réponse
Anonyme