windows - DirectShow - Sådan læses en fil fra et kildefilter

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skriver et DirectShow-kildefilter, der er registreret som en CLSID\_VideoInputDeviceCategory, så det kan ses som en Video Capture Device (fra Skype, for eksempel det vises som et andet WebCam).
Mit kildefilter er baseret på VCam-eksemplet herfra, og for øjeblikket producerer filteret det nøjagtige output som dette eksempel (tilfældigt farvede pixels med en videoudgangstast, ingen lyd endnu), alle implementeret i FillBuffer () -metoden for den eneste udgangsstift. [4]


Nu er det reelle scenarie lidt sværere. Filtret bruger et filhåndtag til en hardwareenhed, der åbnes ved hjælp af API'et CreateFile (). (Åbning af enheden er uden for min kontrol og udføres af et 3Party-bibliotek). Det skal derefter læse klumper af data fra dette håndtag (normalt 256-512 bytes chunk størrelser).
Enheden er en WinUSB-enhed, og 3Party-rammerne giver mig kun et åbent filhåndtag til at læse brikker fra.
Dataene, der læses af filteret, er en * .mp4-fil, som strømmer fra enheden til 'håndtaget'.


Dette scenario svarer til en kildefilterlæsning fra en * .mp4-fil på disken (i 'klumper') og skubber dens data til DirectShow-grafen, men uden evnen til at læse filen helt fra start til slut, så filen Størrelsen er ukendt (Korrekt?).


Jeg er ret ny til DirectShow, og jeg føler, at jeg mangler nogle grundlæggende begreber. Jeg vil være glad, hvis nogen kan lede mig til løsninger \ ressourcer \ forklaringer til følgende spørgsmål:


1) Fra forskellige kilder på nettet og Microsoft SDK (v7.1) prøver jeg, at for en applikation (f.eks. Skype) at opbygge en korrekt & gyldig DirectShow-graf (så det vil gøre videoen og lyden lykkedes), skal kildefilterpenet (arvet fra CSourceStream) implementere metoden 'GetMediaType'. Afhængigt af den returnerede værdi fra denne implementerede funktion, vil en applikation kunne opbygge den korrekte graf for at gøre dataene og således opbygge den korrekte rækkefølge af filtre. Hvis dette er korrekt - Hvordan ville jeg implementere det i mit tilfælde, så grafen vil blive bygget til at gøre * .mp4 input i biter (vi kan antage konstante chunk størrelser)?


2) Jeg har bemærket, at FillBuffer () -metoden skal kalde SetTime () for IMediaSample-objektet, den får (og udfyldes). Jeg læser rå * .mp4-data fra enheden. Skal jeg analysere dataene og udtrække rammerne & tidsværdier fra strømmen? Hvis ja - et eksempel ville være godt.


3) Skal jeg opdele de data, der er modtaget fra filhåndtaget ('bunkerne') til Video & Audio, eller kan dataene skubbes til grafen uden at skulle manipulere det i kildefiltret? Hvis split er nødvendig - Hvordan kan det gøres (dataene er ikke kontinuerlige og spredes til klumper) og vil det påvirke den ønskede implementering af 'GetMediaType'?


Du er velkommen til at rette mig, hvis jeg bruger forkert terminologi.


Tak :-)

Bedste reference


Dette er et godt spørgsmål. På den ene side er dette muligt, men der er nogle specifikke involverede.


Først og fremmest forventes dit filter, der er registreret under kategorien CLSID\_VideoInputDeviceCategory, at opføre sig som en levende videokilde. Ved at gøre det gør du det muligt at opdage det ved programmer (som Skype som du nævnte), og disse programmer vil forsøge at konfigurere videoopløsning, de forventer, at videoen skal gå i realtidsfrekvens, nogle programmer (f.eks. Skype) forventer ikke komprimeret video sådan H.264 der eller ville bare afvise en sådan enhed. Du kan heller ikke vedhæfte lyd til dette filter, da applikationer ikke engang ville lede efter lyd der (ikke sikker på om du har lyd på dit filter, men du nævnte .MP4 fil, så lyden kunne være der).


På dine spørgsmål:


1 - Du ville have et bedre billede af applikationskrav ved at kontrollere, hvilke grænseflademetoder applikationer kalder på dit filter. De fleste af metoderne implementeres af BaseClasses og konverterer opkald til interne metoder som GetMediaType. Ja, du har brug for at implementere det, og ved at gøre det vil du blandt andet gøre det muligt for dit filter at oprette forbindelse med downstream filterstifter ved at prøve specifikke medietyper, du understøtter.


Igen, dem kan ikke mig MP4 klumper, selvom en sådan tilgang kan fungere i andre DirectShow-grafer. Implementering af en videooptagelsesenhed, du skal levere nøjagtigt videorammer, helst dekomprimeres (godt dem kan også komprimeres, men du vil straks have kompatibilitetsudgivelser med applikationer).


En løsning, du måske tænker på, er at indlejre en fuldt udvalgt graf internt, som du injicerer dine MP4-stykker, så pipelinerne analyserer dem, dekoder og leverer til din brugerdefinerede renderer og tager rammer, som du genudlægger dem fra din virtuelle enhed . Dette kan være et godt design, men forudsætter en vis forståelse for, hvordan filtre virker internt.


2 - Din enhed behandles typisk som/forventes at være en levende kilde, hvilket betyder at du leverer video i realtid, og rammerne ikke nødvendigvis er stemplet. Så du kan sætte tider der og ja, du skal helt sikkert udtrække tidsstempler fra dine originale medier (eller få det gjort ved intern graf som nævnt i punkt 1 ovenfor), men vær forberedt på at applikationer striber tidsstempler specielt til preview-formål, da kilden er 'live'.


3 - Kom tilbage til lyd, du kan ikke implementere lyd på samme virtuelle enhed. Godt, du kan, og dette filter kan endda fungere i en brugerdefineret bygget graf, men det kommer ikke til at fungere med applikationer. De vil lede efter en separat lydenhed, og hvis du implementerer sådan, vil de opsøge det separat. Så du forventes at implementere både virtuel video og virtuel lydkilde og implementere intern synkronisering bag kulisserne. Dette er hvor tidsstempler vil være vigtige, ved at give dem korrekt, vil du holde læssynkronisering i live session til, hvad det oprindeligt var på mediefilen du streamer fra.