Newsgroup: it.comp.programmare.win32
Titolo: domande sui filtri directshow custom e sul livello di default dei filter graph

[cross-posted - in english - on microsoft.public.multimedia.directx.dshow.programming, 
microsoft.public.win32.programmer.directx and microsoft.public.multimedia.directx.dshow.activemovie. though without 
answer yet]
ciao a tutti,
dunque, il problema è disporre di un filtro dshow (un input filter) capace di leggere un elementary stream (es) MPEG2 
proveniente da un programma chiamante attraverso la memoria. non avendolo trovato in giro (anzi, doveste conoscerne uno, 
vi prego di indicarmelo) mi sono messo a sviluparne uno per conto mio, partendo da uno degli esempi del directx sdk. il 
filtro accetta l'es e scambia dati col programma attraverso una named pipe e tutto il resto del protocollo è gestito da 
named events.
dopodichè ho dovuto trovare il modo di inserirlo nel mio programma e qui ho trovato due modi: dichiarare esplicitamente 
nel mio programma il grafo di filtri ma la mia scarsa conoscenza di programmazione sotto windows mi ha impedito di 
trovare il modo di mostrare il video in un'area fissa della mia applicazione ma solo in una nuova finestra aperta dal 
grafo (o meglio, dal filtro di rendering), proprio come avviene nel graph editor delle directx. (suggerimenti benvenuti)
l'altro approcio ha funzionato: ho creato un'estensione .xyz, l'ho registrata nel registry come video/mpeg e 
specificando (nella chiave MediaTypes di HKCR) che il "source filter" da utilizzare con quell'estensione è quello 
corrispondente al CLSID del mio filtro, che pertanto dev'essere registrato con regsvr32. quindi ho inserito un controllo 
  del media player al quale chiedo di fare il play di un file fittizio con quell'estensione provvedendo poi a fornire 
attraverso la pipe lo stream corretto. così sembra funzionare sebbene sia un pochino...come dire...delicato e sensibile.
a parte i suggerimenti che saranno ovviamente i benvenuti, quello di cui ho bisogno di sapere è questo:
quando clicco su un "file multimediale", wmp inizia a suonarlo e - credo - crea un grafo di filtri che è *esattamente* 
lo stesso che vedrei se provassi a renderizzare lo stesso file attraverso il graph editor del directx sdk, corretto?
assumendo che lo sia, sulla mia macchina ho due codec mpeg2 installati, ligos ed elecard. per quale motivo il graph 
editor sceglie di usarne uno per default al posto dell'altro. usa il codec moonlight-elecard e, quando de-registro il 
mux elecard, comincia ad usare il grafo con solo filtri della ligos. quindi, registrando di nuovo il mux, torna ad usare 
tutta la catena di filtri elecard. è possibile cambiare questo default senza deregistrare alcun filtro?
un passo oltre: si può associare un grafo specifico a particolari formati/estensioni? ad esempio, un mpeg2-program 
associato alla catena dei filtri ligos e gestire l'mpeg2-es con un mio personalissimo grafo di filtri custom. suppongo 
che questo possa essere fatto definendo un'estensione particolare e aggiungendo tutte le specifiche nel registry come ho 
descritto sopra. ma c'è un'altra strada?
ultima domanda: è possibile salvare in un file GRF il grafo di filtri per poi utilizzarlo nell'applicazione 
richiamandolo? ammetto che a questa domanda mi sarei potuto rispondere facilmente leggendo un po' di più la 
documentazione, però se sapete la risposta passate un po' sopra a queste mancanze... ;-)
beh, per ora grazie a tutti
l

Ciao, macheath!
Il giorno 24/11/2003 alle ore 10:59 hai scritto:
 m> dopodichč ho dovuto trovare il modo di inserirlo nel mio programma e qui
 m> ho trovato due modi: dichiarare esplicitamente nel mio programma il
 m> grafo di filtri ma la mia scarsa conoscenza di programmazione sotto
 m> windows mi ha impedito di trovare il modo di mostrare il video in
 m> un'area fissa della mia applicazione ma solo in una nuova finestra
 m> aperta dal grafo (o meglio, dal filtro di rendering), proprio come
 m> avviene nel graph editor delle directx. (suggerimenti benvenuti)
Se usi il Video Mixing Renderer sotto Windows XP (e credo con le DirectX 9
anche per gli altri sistemi operativi) dovresti impostarlo come WindowLess e
specificare l'hwnd e la posizione del riquadro con l'interfaccia
IVMRWindowLessControl.
 m> quando clicco su un "file multimediale", wmp inizia a suonarlo e - credo
 m> - crea un grafo di filtri che č *esattamente* lo stesso che vedrei se
 m> provassi a renderizzare lo stesso file attraverso il graph editor del
 m> directx sdk, corretto?
Direi di si, ma essendo un'applicazione Microsoft potrebbe fare di tutto
(sai com'e', loro fanno gli standard e usano le chiamate non
documentate...).
 m> assumendo che lo sia, sulla mia macchina ho due codec mpeg2 installati,
 m> ligos ed elecard. per quale motivo il graph editor sceglie di usarne uno
 m> per default al posto dell'altro.
Il filter graph seleziona i filtri in base al merit con cui vengono
registrati. Ora non ricordo precisamente l'ordine ma direi che piu' e' alto
il merit e maggiore priorita' ha il filtro che verra' quindi sempre inserito
per primo, se ovviamente gestisce il formato richiesto.
 m> un passo oltre: si puň associare un grafo specifico a particolari
 m> formati/estensioni?
Direi di no.
 m> ultima domanda: č possibile salvare in un file GRF il grafo di filtri
 m> per poi utilizzarlo nell'applicazione richiamandolo?
In teoria e' possibile chiamando renderfile della classe graphbuilder con il
file .grf da utilizzare. Personalmente non l'ho mai provato ma ho sempre
avuto grossi problemi a ricaricare un file .grf nel graphedit con errori di
filtri non trovati, ecc. (assurdo, salvo il grf, esco dal programma,
rilancio graphedit, ricarico il grf e mi da errore...).
Bye

 
strano, a me funziona... ;-)

Ciao, macheath!
Il giorno 24/11/2003 alle ore 16:50 hai scritto:
 m> hr = pFG->QueryInterface(IID_IGraphBuilder, (void **)&pBuilder);
 m> IPin* pin=GetPin(pSource,PINDIR_OUTPUT); //lo trovo!!!
 m> hr = pBuilder->Render(pin); //GULP!!! non esce mai...DEADLOCK
Io i pin li collego cosi':
   pOut = GetPin(pFileSource, PINDIR_OUTPUT);
   pIn = GetPin(pDemux, PINDIR_INPUT);
   if (pOut != NULL && pIn != NULL)
    hr = m_pFg->Connect(pOut, pIn);
   if (pOut != NULL)
    pOut->Release();
   if (pIn != NULL)
    pIn->Release();
 m> altra domanda: io ho creato una dialog ma non ho la più pallida idea di
 m> che risorsa/controllo aggiungere per indicare poi al VMR dove mostrare
 m> le immagini...per ora ho aggiunto un "Animation Control", ma per me
 m> potrebbe tranquillamente essere qualunque cosa, da un Edit Control ad un
 m> Picture Control.
Non serve aggiungere niente, ricavi l'hwnd della dialog e imposti origine e
dimensioni del rettangolo da visualizzare come ti pare.
Bye

 
ah! non finirò mai di stupirmi di fronte a quanto tutto sia in realtà molto più semplice di come ce lo immaginiamo (o 
come vogliano farcelo apparire)
ciao e buona giornata,
l

Ciao, macheath!
Il giorno 25/11/2003 alle ore 10:54 hai scritto:
 m> una sola cosa vorrei capire: quando si lancia la Connect, quale funzione
 m> bisogna aver implementato nel filtro per gestirla?
Bella domanda. In teoria dovrebbe essere sufficiente implementare
GetMediaType e CheckMediaType, ma ti consiglio di utilizzare come base di
partenza uno degli esempi forniti con l'SDK, io ci sono impazzito un mese
per avere un filtro che mi leggesse un file come volevo io, finche' non ho
adattato alle mie esigenze l'Async filter fornito negli esempi.
Bye

 
bene, noto conpiacere che è pratica comune...
è bello scoprire di non essere soli. in effetti quel filtro è piuttosto chiaro o almeno lo diventa dopo averlo 
analizzato un po'. prima di modificarlo l'ho riempito di linee di log per tracciare il suo comportamento e dopo un paio 
di giorni a cercare di capire perchè facesse certi tipi di richieste ho cambiato atteggiamento limitandomi ad accettare 
quello che chiede e gestendolo (non che ci siano molte altre strade a dire il vero).
in ogni caso ora il filtro è piuttosto diverso dall'originale. e infatti non funziona. ;-)
vabbè, ora mi metto a riscriverne una parte, alla peggio ci si risente in serata.
per ora grazie per l'aiuto e buona giornata.
l

 
g'day!
il mio debug procede, lentamente ma procede.
nel frattempo, visto che in realtà questa nuova versione più snella del mio filtro non ha nessuna intenzione di 
funzionare, mi sono riguardato ben bene l'help di directshow con tutte le base class e le IInterfacce. poi ho cercato di 
riportare tutto all'esempio (async) fornito dalle directx. il mio filtro è sufficientemente un adattamento di quell'esempio.
il mio obiettivo ora è realizzare un source filter che piazzi il suo bel quadratino nel graph edit SENZA chiedermi di 
aprire un file. ho pensato che se non avessi derivato CAsyncFilter da IFileSourceFilter (togliendo tutto, oggetti, 
riferimenti, implementazioni ecc...) avrei ottenuto lo scopo, ma una semplice compilata (con adeguata de/registrazione 
con regsvr32) non è bastata a fare in modo che quella finestra comparisse. infatti il mio filtro non ha nessuna 
necessità di derivare da IFileSourceFilter, visto che gli passo un ES via pipe. ho guardato tutta la gerarchia di classi 
dell'esempio ma non riesco a trovare dove induca il graph edit a piazzare quella fastidiosa finestrella con la scelta 
del file.
poi, se vorrai, ti spiegherò gli altri problemi, più legati all'"intelligent connect" (evidentemente intelligent secondo 
la definizione americana di *oggetto intelligente*)
ciao,
l

 
due domande:
- come si disabilita l'intelligent connect forzando il connect fra due pin di filtri già nel grafo senza che prima (da 
msdn)...
The Connect method connects and output pin to an input pin. This method adds intermediate filters if needed, using a 
variation of the algorithm described for the Render method:
Try a direct connection between the filters, with no intermediate filters.
Try cached filters.
Try filters in the graph.
Look up filters in the registry.
- che eccezioni lancia un programma dshow? COleException, CDXException...(sto inventando)
ciao e sempre grazie,
l

Ciao, macheath!
Il giorno 26/11/2003 alle ore 17:22 hai scritto:
 m> ora mi sembra tutto così banale, ma quanto ci ho messo!!!
E' sempre cosi'.
 m> - come si disabilita l'intelligent connect forzando il connect fra due
 m> pin di filtri già nel grafo senza che prima (da msdn)...
Non l'ho mai fatto ma credo che dovresti usare il metodo ConnectDirect di
IFilterGraph.
L'intelligent connect a volte e' fastidioso ma spesso toglie dalle pesche,
anche perche' se  decide che e' necessario inserire un filtro intermedio, al
99% ha ragione e si tratta o di un errore nella verifica dei media type
supportati o effettivamente il filtro a cui ci si vuole connettere non
supporta il media type richiesto.
 m> - che eccezioni lancia un programma dshow? COleException,
 m> CDXException...(sto inventando)
Eccezioni ? Cosa sono le eccezioni ? :-)
Io ho una filosofia: se il programma va deve andare sempre, se non va e'
giusto che crashi in malomodo perche' qualcuno ha messo le mani nella
configurazione del computer !
Bye