BaseClasses.cs 397 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. using System.Diagnostics;
  6. using System.Reflection;
  7. using System.Runtime.InteropServices.ComTypes;
  8. using System.Security.Permissions;
  9. using System.Security;
  10. using System.Threading;
  11. using System.Windows.Forms;
  12. using Sonic;
  13. using DirectShow;
  14. using System.Drawing;
  15. using System.IO;
  16. #region Assembly
  17. [assembly: AssemblyTitle("DirectShow BaseClasses")]
  18. [assembly: AssemblyDescription(".NET Implementation of DirectShow BaseClasses")]
  19. [assembly: AssemblyConfiguration("")]
  20. [assembly: AssemblyCompany("")]
  21. [assembly: AssemblyProduct("")]
  22. [assembly: AssemblyCopyright("Copyright © Maxim Kartavenkov aka Sonic 2012")]
  23. [assembly: AssemblyTrademark("")]
  24. [assembly: AssemblyCulture("")]
  25. [assembly: CLSCompliant(false)]
  26. [assembly: ComVisible(true)]
  27. [assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
  28. [assembly: Guid("C842BC09-EFAE-417f-9EAE-6783CDC173A5")]
  29. [assembly: AssemblyVersion("1.0.0.6")]
  30. [assembly: AssemblyFileVersion("1.0.0.6")]
  31. [assembly: RegistryPermissionAttribute(SecurityAction.RequestMinimum, ViewAndModify = "HKEY_CLASSES_ROOT")]
  32. #endregion
  33. namespace DirectShow.BaseClasses
  34. {
  35. #region AMovieSetup Attribute
  36. [ComVisible(false)]
  37. [AttributeUsage(AttributeTargets.Class)]
  38. public class AMovieSetup : Attribute
  39. {
  40. #region Constants
  41. public const string CLSID_LegacyAmFilterCategory = "083863F1-70DE-11d0-BD40-00A0C911CE86";
  42. public const string CLSID_VideoInputDeviceCategory = "860BB310-5D01-11d0-BD3B-00A0C911CE86";
  43. public const string CLSID_VideoCompressorCategory = "33D9A760-90C8-11d0-BD43-00A0C911CE86";
  44. public const string CLSID_AudioCompressorCategory = "33D9A761-90C8-11d0-BD43-00A0C911CE86";
  45. public const string CLSID_AudioInputDeviceCategory = "33D9A762-90C8-11d0-BD43-00A0C911CE86";
  46. public const string CLSID_AudioRendererCategory = "E0F158E1-CB04-11d0-BD4E-00A0C911CE86";
  47. public const string CLSID_MidiRendererCategory = "4EFE2452-168A-11d1-BC76-00C04FB9453B";
  48. #endregion
  49. #region Varables
  50. protected bool m_bShouldRegister = true;
  51. protected Merit m_Merit = Merit.DoNotUse;
  52. protected int m_iVersion = 1;
  53. protected string m_sName = null;
  54. protected Guid m_Category = Guid.Empty;
  55. #endregion
  56. #region Constructor
  57. public AMovieSetup()
  58. {
  59. }
  60. public AMovieSetup(bool _register)
  61. : this()
  62. {
  63. m_bShouldRegister = _register;
  64. }
  65. public AMovieSetup(string _name)
  66. : this()
  67. {
  68. m_sName = _name;
  69. }
  70. public AMovieSetup(Merit _merit)
  71. : this()
  72. {
  73. m_Merit = _merit;
  74. }
  75. public AMovieSetup(Merit _merit, string _category)
  76. : this(_merit)
  77. {
  78. m_Category = new Guid(_category);
  79. }
  80. public AMovieSetup(string _name, Merit _merit)
  81. : this(_name)
  82. {
  83. m_Merit = _merit;
  84. }
  85. public AMovieSetup(string _name, Merit _merit, string _category)
  86. : this(_name, _merit)
  87. {
  88. m_Category = new Guid(_category);
  89. }
  90. #endregion
  91. #region Properties
  92. public string Name
  93. {
  94. get { return m_sName; }
  95. }
  96. public bool ShouldRegister
  97. {
  98. get { return m_bShouldRegister; }
  99. }
  100. public int Version
  101. {
  102. get { return m_iVersion; }
  103. }
  104. public Merit FilterMerit
  105. {
  106. get { return m_Merit; }
  107. }
  108. public Guid Category
  109. {
  110. get { return m_Category; }
  111. }
  112. #endregion
  113. }
  114. #endregion
  115. #region PropertyPages Attribute
  116. [ComVisible(false)]
  117. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  118. public class PropPageSetup : Attribute
  119. {
  120. #region Variables
  121. private List<Guid> m_Guids = new List<Guid>();
  122. #endregion
  123. #region Constructor
  124. public PropPageSetup(string _guid)
  125. {
  126. m_Guids.Add(new Guid(_guid));
  127. }
  128. public PropPageSetup(string _guid1, string _guid2)
  129. : this(_guid1)
  130. {
  131. m_Guids.Add(new Guid(_guid2));
  132. }
  133. public PropPageSetup(string _guid1, string _guid2, string _guid3)
  134. : this(_guid1, _guid2)
  135. {
  136. m_Guids.Add(new Guid(_guid3));
  137. }
  138. public PropPageSetup(Type _type)
  139. {
  140. m_Guids.Add(_type.GUID);
  141. }
  142. public PropPageSetup(Type _type1, Type _type2)
  143. : this(_type1)
  144. {
  145. m_Guids.Add(_type2.GUID);
  146. }
  147. public PropPageSetup(Type _type1, Type _type2, Type _type3)
  148. : this(_type1, _type2)
  149. {
  150. m_Guids.Add(_type3.GUID);
  151. }
  152. #endregion
  153. #region Properties
  154. public List<Guid> Guids
  155. {
  156. get { return m_Guids; }
  157. }
  158. #endregion
  159. }
  160. #endregion
  161. #region File Extension Register Attribute
  162. [ComVisible(false)]
  163. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  164. public class RegisterFileExtension : Attribute
  165. {
  166. #region Variables
  167. private string m_sExtension = "";
  168. private Guid m_MediaType = Guid.Empty;
  169. private Guid m_SubType = Guid.Empty;
  170. #endregion
  171. #region Constructor
  172. public RegisterFileExtension(string _extension)
  173. {
  174. m_sExtension = _extension;
  175. }
  176. public RegisterFileExtension(string _extension, string _MediaType, string _SubType)
  177. : this(_extension)
  178. {
  179. if (!String.IsNullOrEmpty(_MediaType))
  180. {
  181. m_MediaType = new Guid(_MediaType);
  182. }
  183. if (!String.IsNullOrEmpty(_SubType))
  184. {
  185. m_SubType = new Guid(_SubType);
  186. }
  187. }
  188. #endregion
  189. #region Properties
  190. public string Extension
  191. {
  192. get { return m_sExtension; }
  193. }
  194. public Guid MediaType
  195. {
  196. get { return m_MediaType; }
  197. }
  198. public Guid SubType
  199. {
  200. get { return m_SubType; }
  201. }
  202. #endregion
  203. }
  204. #endregion
  205. #region Protocol Register Attribute
  206. [ComVisible(false)]
  207. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  208. public class RegisterProtocolExtension : Attribute
  209. {
  210. #region Variables
  211. private string m_sProtocol = "";
  212. private List<string> m_Extensions = new List<string>();
  213. #endregion
  214. #region Constructor
  215. public RegisterProtocolExtension(string _protocol)
  216. {
  217. m_sProtocol = _protocol;
  218. }
  219. public RegisterProtocolExtension(string _protocol, string _extension)
  220. : this(_protocol)
  221. {
  222. if (!String.IsNullOrEmpty(_extension))
  223. {
  224. m_Extensions.Add(_extension);
  225. }
  226. }
  227. #endregion
  228. #region Properties
  229. public string Protocol
  230. {
  231. get { return m_sProtocol; }
  232. }
  233. public List<string> Extensions
  234. {
  235. get { return m_Extensions; }
  236. }
  237. #endregion
  238. }
  239. #endregion
  240. #region MediaType Register Attribute
  241. [ComVisible(false)]
  242. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  243. public class RegisterMediaType : Attribute
  244. {
  245. #region Constants
  246. public const string MEDIATYPE_Stream = "{E436EB83-524F-11CE-9F53-0020AF0BA770}";
  247. #endregion
  248. #region Variables
  249. private Guid m_FilterGuid = typeof(DSFileSourceAsync).GUID;
  250. private Guid m_MajorType = MediaType.Stream;
  251. private Guid m_SubType = Guid.Empty;
  252. private string m_Sequence = "";
  253. #endregion
  254. #region Constructor
  255. public RegisterMediaType(string _subtype, string _sequence)
  256. : this(null, null, _subtype, _sequence)
  257. {
  258. }
  259. public RegisterMediaType(string _filter, string _subtype, string _sequence)
  260. : this(_filter, null, _subtype, _sequence)
  261. {
  262. }
  263. public RegisterMediaType(string _filter, string _majortype, string _subtype, string _sequence)
  264. {
  265. if (!String.IsNullOrEmpty(_filter))
  266. {
  267. m_FilterGuid = new Guid(_filter);
  268. }
  269. if (!String.IsNullOrEmpty(_majortype))
  270. {
  271. m_MajorType = new Guid(_majortype);
  272. }
  273. if (!String.IsNullOrEmpty(_subtype))
  274. {
  275. m_SubType = new Guid(_subtype);
  276. }
  277. if (!String.IsNullOrEmpty(_sequence))
  278. {
  279. m_Sequence = _sequence;
  280. }
  281. }
  282. #endregion
  283. #region Properties
  284. public Guid FilterGuid
  285. {
  286. get { return m_FilterGuid; }
  287. }
  288. public Guid MajorType
  289. {
  290. get { return m_MajorType; }
  291. }
  292. public Guid SubType
  293. {
  294. get { return m_SubType; }
  295. }
  296. public string Sequence
  297. {
  298. get { return m_Sequence; }
  299. }
  300. #endregion
  301. }
  302. #endregion
  303. #region BaseEnum
  304. [ComVisible(false)]
  305. [ClassInterface(ClassInterfaceType.None)]
  306. public class BaseEnum : COMHelper
  307. {
  308. #region Variables
  309. protected int m_iIndex = 0;
  310. protected object m_Owner = null;
  311. protected int m_iCount = 0;
  312. #endregion
  313. #region Properties
  314. public object Owner
  315. {
  316. get { return m_Owner; }
  317. }
  318. public int Index
  319. {
  320. get { return m_iIndex; }
  321. }
  322. public int Count
  323. {
  324. get { return m_iCount; }
  325. }
  326. #endregion
  327. #region Constructor
  328. public BaseEnum(object _owner)
  329. {
  330. ASSERT(_owner != null);
  331. m_Owner = _owner;
  332. Reset();
  333. }
  334. ~BaseEnum()
  335. {
  336. ASSERT(m_Owner);
  337. m_Owner = null;
  338. }
  339. #endregion
  340. #region Protected Methods
  341. protected virtual bool IsOutOfSync()
  342. {
  343. return false;
  344. }
  345. protected virtual void OnReset()
  346. {
  347. }
  348. #endregion
  349. #region Public Methods
  350. public virtual int Reset()
  351. {
  352. m_iIndex = 0;
  353. if (IsOutOfSync())
  354. {
  355. OnReset();
  356. }
  357. return NOERROR;
  358. }
  359. public virtual int Skip(int cSkip)
  360. {
  361. if (IsOutOfSync()) return VFW_E_ENUM_OUT_OF_SYNC;
  362. if (m_iIndex + cSkip > m_iCount)
  363. {
  364. return S_FALSE;
  365. }
  366. m_iIndex += cSkip;
  367. return NOERROR;
  368. }
  369. #endregion
  370. }
  371. #endregion
  372. #region EnumPins
  373. [ComVisible(false)]
  374. [ClassInterface(ClassInterfaceType.None)]
  375. public class EnumPins : BaseEnum, IEnumPins
  376. {
  377. #region Constructor
  378. public EnumPins(BaseFilter _filter)
  379. : base(_filter)
  380. {
  381. m_iCount = _filter.Pins.Count;
  382. }
  383. #endregion
  384. #region Overridden Methods
  385. protected override bool IsOutOfSync()
  386. {
  387. lock ((m_Owner as BaseFilter).FilterLock)
  388. {
  389. return m_iCount != (m_Owner as BaseFilter).Pins.Count;
  390. }
  391. }
  392. protected override void OnReset()
  393. {
  394. lock ((m_Owner as BaseFilter).FilterLock)
  395. {
  396. m_iCount = (m_Owner as BaseFilter).Pins.Count;
  397. }
  398. }
  399. #endregion
  400. #region IEnumPins Members
  401. public virtual int Clone(out IEnumPins ppEnum)
  402. {
  403. ppEnum = new EnumPins((BaseFilter)m_Owner);
  404. return NOERROR;
  405. }
  406. public virtual int Next(int cPins, IPin[] ppPins, IntPtr pcFetched)
  407. {
  408. if (ppPins == null) return E_POINTER;
  409. ASSERT(ppPins.Length >= cPins);
  410. if (pcFetched != IntPtr.Zero)
  411. {
  412. Marshal.WriteInt32(pcFetched, 0);
  413. }
  414. else
  415. if (cPins > 1)
  416. {
  417. return E_INVALIDARG;
  418. }
  419. if (IsOutOfSync())
  420. {
  421. OnReset();
  422. }
  423. int _count = 0;
  424. if (m_iCount == m_iIndex) return S_FALSE;
  425. while (m_iIndex < m_iCount && _count < cPins)
  426. {
  427. if (IsOutOfSync()) return VFW_E_ENUM_OUT_OF_SYNC;
  428. lock ((m_Owner as BaseFilter).FilterLock)
  429. {
  430. ppPins[_count++] = (IPin)(m_Owner as BaseFilter).Pins[m_iIndex++];
  431. }
  432. }
  433. if (pcFetched != IntPtr.Zero)
  434. {
  435. Marshal.WriteInt32(pcFetched, _count);
  436. }
  437. return (_count == cPins ? S_OK : S_FALSE);
  438. }
  439. #endregion
  440. }
  441. #endregion
  442. #region EnumMediaTypes
  443. /// <summary>
  444. /// IEnumMediaTypes implementation
  445. /// </summary>
  446. [ComVisible(false)]
  447. [ClassInterface(ClassInterfaceType.None)]
  448. public class EnumMediaTypes : BaseEnum, IEnumMediaTypes
  449. {
  450. #region Constructor
  451. public EnumMediaTypes(BasePin _pin)
  452. : base(_pin)
  453. {
  454. }
  455. #endregion
  456. #region Overridden Methods
  457. protected override bool IsOutOfSync()
  458. {
  459. return false;
  460. }
  461. protected override void OnReset()
  462. {
  463. m_iCount = 0;// (m_Owner as BasePin).AMediaTypes.Count;
  464. }
  465. #endregion
  466. #region IEnumMediaTypes Members
  467. public virtual int Clone(out IntPtr ppEnum)
  468. {
  469. EnumMediaTypes _enum = new EnumMediaTypes((BasePin)m_Owner);
  470. ppEnum = Marshal.GetComInterfaceForObject(_enum, typeof(IEnumMediaTypes));
  471. return NOERROR;
  472. }
  473. public virtual int Next(int cMediaTypes, IntPtr ppMediaTypes, IntPtr pcFetched)
  474. {
  475. if (ppMediaTypes == IntPtr.Zero) return E_POINTER;
  476. if (pcFetched != IntPtr.Zero)
  477. {
  478. Marshal.WriteInt32(pcFetched, 0);
  479. }
  480. else
  481. if (cMediaTypes > 1)
  482. {
  483. return E_INVALIDARG;
  484. }
  485. if (IsOutOfSync())
  486. {
  487. OnReset();
  488. }
  489. int _count = 0;
  490. while (cMediaTypes > 0)
  491. {
  492. AMMediaType mt = null;
  493. AMMediaType.Init(ref mt);
  494. int hr = (m_Owner as BasePin).GetMediaType(m_iIndex++, ref mt);
  495. if (S_OK != hr)
  496. {
  497. break;
  498. }
  499. IntPtr _pmt = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(AMMediaType)));
  500. if (_pmt == IntPtr.Zero)
  501. {
  502. AMMediaType.Free(ref mt);
  503. GC.Collect();
  504. break;
  505. }
  506. Marshal.StructureToPtr(mt, _pmt, true);
  507. Marshal.WriteIntPtr(ppMediaTypes, _count * Marshal.SizeOf(typeof(IntPtr)), _pmt);
  508. _count++;
  509. cMediaTypes--;
  510. }
  511. if (pcFetched != IntPtr.Zero)
  512. {
  513. Marshal.WriteInt32(pcFetched, _count);
  514. }
  515. return (0 == cMediaTypes ? S_OK : S_FALSE);
  516. }
  517. public override int Skip(int cSkip)
  518. {
  519. if (cSkip == 0)
  520. {
  521. return S_OK;
  522. }
  523. if (IsOutOfSync()) return VFW_E_ENUM_OUT_OF_SYNC;
  524. m_iIndex += cSkip;
  525. AMMediaType mt = null;
  526. try
  527. {
  528. AMMediaType.Init(ref mt);
  529. return (S_OK == (m_Owner as BasePin).GetMediaType(m_iIndex - 1, ref mt)) ? S_OK : S_FALSE;
  530. }
  531. finally
  532. {
  533. AMMediaType.Free(ref mt);
  534. GC.Collect();
  535. }
  536. }
  537. #endregion
  538. };
  539. #endregion
  540. #region Base Prop Page Support
  541. [ComVisible(false)]
  542. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  543. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  544. [ClassInterface(ClassInterfaceType.None)]
  545. public class PropPageSupport : COMHelper, ISpecifyPropertyPages
  546. {
  547. #region Variables
  548. protected List<Guid> m_Pages = new List<Guid>();
  549. #endregion
  550. #region Properties
  551. public List<Guid> Pages
  552. {
  553. get { return m_Pages; }
  554. }
  555. #endregion
  556. #region Constructor
  557. protected PropPageSupport()
  558. {
  559. Attribute[] _attributes = Attribute.GetCustomAttributes(this.GetType(), typeof(PropPageSetup));
  560. if (_attributes != null)
  561. {
  562. foreach (PropPageSetup _setup in _attributes)
  563. {
  564. if (_setup != null && _setup.Guids.Count > 0)
  565. {
  566. for (int i = 0; i < _setup.Guids.Count; i++)
  567. {
  568. m_Pages.Add(_setup.Guids[i]);
  569. }
  570. }
  571. }
  572. }
  573. }
  574. #endregion
  575. #region ISpecifyPropertyPages Members
  576. public virtual int GetPages(out DsCAUUID pPages)
  577. {
  578. pPages = new DsCAUUID();
  579. try
  580. {
  581. if (m_Pages.Count > 0)
  582. {
  583. pPages.cElems = m_Pages.Count;
  584. int cb = Marshal.SizeOf(typeof(Guid));
  585. pPages.pElems = Marshal.AllocCoTaskMem(cb * m_Pages.Count);
  586. IntPtr _ptr = pPages.pElems;
  587. for (int i = 0; i < m_Pages.Count; i++)
  588. {
  589. Marshal.StructureToPtr(m_Pages[i], _ptr, false);
  590. _ptr = new IntPtr(_ptr.ToInt32() + cb);
  591. }
  592. return NOERROR;
  593. }
  594. else
  595. {
  596. pPages.cElems = 0;
  597. pPages.pElems = IntPtr.Zero;
  598. return E_NOTIMPL;
  599. }
  600. }
  601. finally
  602. {
  603. GC.Collect();
  604. }
  605. }
  606. #endregion
  607. }
  608. #endregion
  609. #region BasePin
  610. [ComVisible(false)]
  611. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  612. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  613. [ClassInterface(ClassInterfaceType.None)]
  614. public abstract class BasePin : PropPageSupport, IPin, IQualityControl
  615. {
  616. #region Variables
  617. protected BaseFilter m_Filter = null;
  618. protected string m_sName = "";
  619. protected object m_Lock = null;
  620. protected PinDirection m_Direction = PinDirection.Input;
  621. protected AMMediaType m_mt = null;
  622. protected bool m_bCanReconnectWhenActive = false;
  623. protected bool m_bTryMyTypesFirst = false;
  624. protected bool m_bRunTimeError = false;
  625. protected long m_tStart = 0;
  626. protected long m_tStop = MAX_LONG;
  627. protected double m_dRate = 1.0;
  628. protected IntPtr m_QualitySink = IntPtr.Zero;
  629. protected IntPtr m_ConnectedPin = IntPtr.Zero;
  630. protected IntPtr m_pAllocator = IntPtr.Zero;
  631. #endregion
  632. #region Properties
  633. public IQualityControl QualitySync
  634. {
  635. get
  636. {
  637. if (m_QualitySink != IntPtr.Zero)
  638. {
  639. return (IQualityControl)Marshal.GetObjectForIUnknown(m_QualitySink);
  640. }
  641. return null;
  642. }
  643. }
  644. public IMemAllocatorImpl Allocator
  645. {
  646. get
  647. {
  648. return new IMemAllocatorImpl(m_pAllocator);
  649. }
  650. }
  651. public IntPtr AllocatorPtr
  652. {
  653. get { return m_pAllocator; }
  654. set
  655. {
  656. if (m_pAllocator != IntPtr.Zero) Marshal.Release(m_pAllocator);
  657. m_pAllocator = value;
  658. if (m_pAllocator != IntPtr.Zero) Marshal.AddRef(m_pAllocator);
  659. }
  660. }
  661. public PinDirection Direction
  662. {
  663. get { return m_Direction; }
  664. }
  665. public BaseFilter Filter
  666. {
  667. get { return m_Filter; }
  668. }
  669. public string Name
  670. {
  671. get { return m_sName; }
  672. }
  673. public bool IsConnected
  674. {
  675. get { return m_ConnectedPin != IntPtr.Zero; }
  676. }
  677. public IPinImpl Connected
  678. {
  679. get
  680. {
  681. return new IPinImpl(m_ConnectedPin);
  682. }
  683. }
  684. public bool IsStopped
  685. {
  686. get { return m_Filter.State == FilterState.Stopped; }
  687. }
  688. public bool CanReconnectWhenActive
  689. {
  690. get { return m_bCanReconnectWhenActive; }
  691. set { m_bCanReconnectWhenActive = value; }
  692. }
  693. public long CurrentStopTime
  694. {
  695. get { return m_tStop; }
  696. }
  697. public long CurrentStartTime
  698. {
  699. get { return m_tStart; }
  700. }
  701. public double CurrentRate
  702. {
  703. get { return m_dRate; }
  704. }
  705. public AMMediaType CurrentMediaType
  706. {
  707. get { return m_mt; }
  708. set { AMMediaType.Copy(value, ref m_mt); }
  709. }
  710. #endregion
  711. #region Constructor
  712. public BasePin(string _name, BaseFilter _filter, object _lock, PinDirection _direction)
  713. {
  714. ASSERT(_filter != null && _lock != null);
  715. m_Filter = _filter;
  716. m_Lock = _lock;
  717. m_sName = _name;
  718. m_Direction = _direction;
  719. AMMediaType.Init(ref m_mt);
  720. }
  721. ~BasePin()
  722. {
  723. if (m_pAllocator != IntPtr.Zero)
  724. {
  725. Marshal.Release(m_pAllocator);
  726. }
  727. m_pAllocator = IntPtr.Zero;
  728. AMMediaType.Free(ref m_mt);
  729. m_Filter = null;
  730. if (m_ConnectedPin != IntPtr.Zero)
  731. {
  732. Marshal.Release(m_ConnectedPin);
  733. }
  734. m_ConnectedPin = IntPtr.Zero;
  735. if (m_QualitySink != IntPtr.Zero)
  736. {
  737. Marshal.Release(m_QualitySink);
  738. m_QualitySink = IntPtr.Zero;
  739. }
  740. }
  741. #endregion
  742. #region Abstract Methods
  743. public abstract int CheckMediaType(AMMediaType pmt);
  744. #endregion
  745. #region Virtual Methods
  746. #region Public Methods
  747. public virtual int BreakConnect()
  748. {
  749. return NOERROR;
  750. }
  751. public virtual int CompleteConnect(ref IPinImpl pReceivePin)
  752. {
  753. return NOERROR;
  754. }
  755. public virtual int Active()
  756. {
  757. return NOERROR;
  758. }
  759. public virtual int Inactive()
  760. {
  761. m_bRunTimeError = false;
  762. return NOERROR;
  763. }
  764. public virtual int Run(long tStart)
  765. {
  766. return NOERROR;
  767. }
  768. public virtual int CheckConnect(ref IPinImpl _pin)
  769. {
  770. PinDirection _direction;
  771. HRESULT hr = (HRESULT)_pin.QueryDirection(out _direction);
  772. if (hr.Failed) return hr;
  773. if (_direction == m_Direction)
  774. {
  775. return VFW_E_INVALID_DIRECTION;
  776. }
  777. return NOERROR;
  778. }
  779. public virtual int SetMediaType(AMMediaType mt)
  780. {
  781. AMMediaType.Copy(mt, ref m_mt);
  782. return NOERROR;
  783. }
  784. public virtual int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  785. {
  786. return E_UNEXPECTED;
  787. }
  788. #endregion
  789. #region Protected Methods
  790. protected virtual int DisconnectInternal()
  791. {
  792. if (m_ConnectedPin != IntPtr.Zero)
  793. {
  794. int hr = BreakConnect();
  795. if (FAILED(hr))
  796. {
  797. TRACE("WARNING: BreakConnect() failed in CBasePin::Disconnect().");
  798. return hr;
  799. }
  800. Marshal.Release(m_ConnectedPin);
  801. m_ConnectedPin = IntPtr.Zero;
  802. return S_OK;
  803. }
  804. else
  805. {
  806. return S_FALSE;
  807. }
  808. }
  809. protected virtual int AgreeMediaType(ref IPinImpl pReceivePin, AMMediaType pmt)
  810. {
  811. ASSERT(pReceivePin);
  812. IEnumMediaTypes pEnumMediaTypes = null;
  813. if ((pmt != null) && (!AMMediaType.IsPartiallySpecified(pmt)))
  814. {
  815. return AttemptConnection(ref pReceivePin, pmt);
  816. }
  817. int hrFailure = VFW_E_NO_ACCEPTABLE_TYPES;
  818. for (int i = 0; i < 2; i++)
  819. {
  820. int hr;
  821. IntPtr _ptr = IntPtr.Zero;
  822. if (i == (BOOL)m_bTryMyTypesFirst)
  823. {
  824. hr = pReceivePin.EnumMediaTypes(out _ptr);
  825. if (_ptr != IntPtr.Zero)
  826. {
  827. pEnumMediaTypes = (IEnumMediaTypes)new IEnumMediaTypesImpl(_ptr);
  828. }
  829. }
  830. else
  831. {
  832. hr = EnumMediaTypes(out _ptr);
  833. if (_ptr != IntPtr.Zero)
  834. {
  835. pEnumMediaTypes = (IEnumMediaTypes)Marshal.GetObjectForIUnknown(_ptr);
  836. }
  837. }
  838. if (SUCCEEDED(hr))
  839. {
  840. ASSERT(pEnumMediaTypes);
  841. hr = TryMediaTypes(ref pReceivePin, pmt, pEnumMediaTypes);
  842. if (Marshal.IsComObject(pEnumMediaTypes))
  843. {
  844. Marshal.ReleaseComObject(pEnumMediaTypes);
  845. }
  846. if (SUCCEEDED(hr))
  847. {
  848. return NOERROR;
  849. }
  850. else
  851. {
  852. if ((hr != E_FAIL) && (hr != E_INVALIDARG) && (hr != VFW_E_TYPE_NOT_ACCEPTED))
  853. {
  854. hrFailure = hr;
  855. }
  856. }
  857. }
  858. }
  859. return hrFailure;
  860. }
  861. protected virtual int AttemptConnection(ref IPinImpl pReceivePin, AMMediaType pmt)
  862. {
  863. int hr = CheckConnect(ref pReceivePin);
  864. if (FAILED(hr))
  865. {
  866. ASSERT(SUCCEEDED(BreakConnect()));
  867. return hr;
  868. }
  869. hr = CheckMediaType(pmt);
  870. if (hr == NOERROR)
  871. {
  872. m_ConnectedPin = pReceivePin.UnknownPtr;
  873. Marshal.AddRef(m_ConnectedPin);
  874. hr = SetMediaType(pmt);
  875. if (SUCCEEDED(hr))
  876. {
  877. IntPtr _ptr = Marshal.GetIUnknownForObject(this);
  878. Guid _guid = typeof(IPin).GUID;
  879. IntPtr _this;
  880. Marshal.QueryInterface(_ptr, ref _guid, out _this);
  881. Marshal.Release(_ptr);
  882. try
  883. {
  884. hr = pReceivePin.ReceiveConnection(_this, pmt);
  885. if (SUCCEEDED(hr))
  886. {
  887. hr = CompleteConnect(ref pReceivePin);
  888. if (SUCCEEDED(hr))
  889. {
  890. return hr;
  891. }
  892. else
  893. {
  894. pReceivePin.Disconnect();
  895. }
  896. }
  897. }
  898. finally
  899. {
  900. Marshal.Release(_this);
  901. }
  902. }
  903. }
  904. else
  905. {
  906. if (SUCCEEDED(hr) || (hr == E_FAIL) || (hr == E_INVALIDARG))
  907. {
  908. hr = VFW_E_TYPE_NOT_ACCEPTED;
  909. }
  910. }
  911. ASSERT(SUCCEEDED(BreakConnect()));
  912. if (m_ConnectedPin != IntPtr.Zero)
  913. {
  914. Marshal.Release(m_ConnectedPin);
  915. m_ConnectedPin = IntPtr.Zero;
  916. }
  917. return hr;
  918. }
  919. protected virtual int TryMediaTypes(ref IPinImpl pReceivePin, AMMediaType pmt, IEnumMediaTypes pEnum)
  920. {
  921. int hr = pEnum.Reset();
  922. if (FAILED(hr))
  923. {
  924. return hr;
  925. }
  926. int hrFailure = S_OK;
  927. IntPtr ulMediaCount = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(uint)));
  928. IntPtr pTypes = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
  929. try
  930. {
  931. for (; ; )
  932. {
  933. hr = pEnum.Next(1, pTypes, ulMediaCount);
  934. if (hr != S_OK)
  935. {
  936. if (S_OK == hrFailure)
  937. {
  938. hrFailure = VFW_E_NO_ACCEPTABLE_TYPES;
  939. }
  940. return hrFailure;
  941. }
  942. ASSERT(Marshal.ReadInt32(ulMediaCount) == 1);
  943. IntPtr _ptrStructure = Marshal.ReadIntPtr(pTypes);
  944. try
  945. {
  946. AMMediaType _type = null;
  947. if (_ptrStructure != IntPtr.Zero)
  948. {
  949. _type = (AMMediaType)Marshal.PtrToStructure(_ptrStructure, typeof(AMMediaType));
  950. }
  951. if ((pmt == null) || AMMediaType.MatchesPartial(_type, pmt))
  952. {
  953. hr = AttemptConnection(ref pReceivePin, _type);
  954. if (FAILED(hr)
  955. && SUCCEEDED(hrFailure)
  956. && (hr != E_FAIL)
  957. && (hr != E_INVALIDARG)
  958. && (hr != VFW_E_TYPE_NOT_ACCEPTED))
  959. {
  960. hrFailure = hr;
  961. }
  962. }
  963. else
  964. {
  965. hr = VFW_E_NO_ACCEPTABLE_TYPES;
  966. }
  967. _type = null;
  968. }
  969. finally
  970. {
  971. if (_ptrStructure != IntPtr.Zero)
  972. {
  973. Marshal.FreeCoTaskMem(_ptrStructure);
  974. }
  975. }
  976. if (S_OK == hr)
  977. {
  978. return hr;
  979. }
  980. }
  981. }
  982. finally
  983. {
  984. Marshal.FreeCoTaskMem(ulMediaCount);
  985. Marshal.FreeCoTaskMem(pTypes);
  986. }
  987. }
  988. #endregion
  989. #endregion
  990. #region IPin Members
  991. #region Abstract Methods
  992. public abstract int BeginFlush();
  993. public abstract int EndFlush();
  994. #endregion
  995. public virtual int ConnectionMediaType(AMMediaType pmt)
  996. {
  997. if (((object)pmt) == null) return E_POINTER;
  998. lock (m_Lock)
  999. {
  1000. if (IsConnected)
  1001. {
  1002. AMMediaType.Copy(m_mt, ref pmt);
  1003. return S_OK;
  1004. }
  1005. else
  1006. {
  1007. AMMediaType.Init(ref pmt);
  1008. return VFW_E_NOT_CONNECTED;
  1009. }
  1010. }
  1011. }
  1012. public virtual int ReceiveConnection(IntPtr pReceivePin, AMMediaType pmt)
  1013. {
  1014. if (pReceivePin == IntPtr.Zero || pmt == null) return E_POINTER;
  1015. lock (m_Lock)
  1016. {
  1017. IPinImpl _pin = new IPinImpl(pReceivePin);
  1018. if (m_ConnectedPin != IntPtr.Zero)
  1019. {
  1020. return VFW_E_ALREADY_CONNECTED;
  1021. }
  1022. if (!IsStopped && !m_bCanReconnectWhenActive)
  1023. {
  1024. return VFW_E_NOT_STOPPED;
  1025. }
  1026. int hr = CheckConnect(ref _pin);
  1027. if (FAILED(hr))
  1028. {
  1029. ASSERT(SUCCEEDED(BreakConnect()));
  1030. return hr;
  1031. }
  1032. hr = CheckMediaType(pmt);
  1033. if (hr != NOERROR)
  1034. {
  1035. ASSERT(SUCCEEDED(BreakConnect()));
  1036. if (SUCCEEDED(hr) || (hr == E_FAIL) || (hr == E_INVALIDARG))
  1037. {
  1038. hr = VFW_E_TYPE_NOT_ACCEPTED;
  1039. }
  1040. return hr;
  1041. }
  1042. m_ConnectedPin = pReceivePin;
  1043. Marshal.AddRef(m_ConnectedPin);
  1044. hr = SetMediaType(pmt);
  1045. if (SUCCEEDED(hr))
  1046. {
  1047. hr = CompleteConnect(ref _pin);
  1048. if (SUCCEEDED(hr))
  1049. {
  1050. return NOERROR;
  1051. }
  1052. }
  1053. Marshal.Release(m_ConnectedPin);
  1054. m_ConnectedPin = IntPtr.Zero;
  1055. {
  1056. ASSERT(SUCCEEDED(BreakConnect()));
  1057. }
  1058. return hr;
  1059. }
  1060. }
  1061. public virtual int Connect(IntPtr pReceivePin, AMMediaType pmt)
  1062. {
  1063. if (pReceivePin == IntPtr.Zero) return E_POINTER;
  1064. lock (m_Lock)
  1065. {
  1066. if (m_ConnectedPin != IntPtr.Zero)
  1067. {
  1068. return VFW_E_ALREADY_CONNECTED;
  1069. }
  1070. if (!IsStopped && !m_bCanReconnectWhenActive)
  1071. {
  1072. return VFW_E_NOT_STOPPED;
  1073. }
  1074. IPinImpl _pin = new IPinImpl(pReceivePin);
  1075. int hr = AgreeMediaType(ref _pin, pmt);
  1076. if (FAILED(hr))
  1077. {
  1078. ASSERT(SUCCEEDED(BreakConnect()));
  1079. return hr;
  1080. }
  1081. return NOERROR;
  1082. }
  1083. }
  1084. public virtual int Disconnect()
  1085. {
  1086. lock (m_Lock)
  1087. {
  1088. if (!IsStopped)
  1089. {
  1090. return VFW_E_NOT_STOPPED;
  1091. }
  1092. return DisconnectInternal();
  1093. }
  1094. }
  1095. public virtual int ConnectedTo(out IntPtr ppPin)
  1096. {
  1097. ppPin = m_ConnectedPin;
  1098. if (ppPin != IntPtr.Zero)
  1099. {
  1100. Marshal.AddRef(ppPin);
  1101. }
  1102. return (m_ConnectedPin == IntPtr.Zero ? VFW_E_NOT_CONNECTED : S_OK);
  1103. }
  1104. public virtual int QueryPinInfo(out PinInfo pInfo)
  1105. {
  1106. pInfo = new PinInfo();
  1107. pInfo.name = m_sName;
  1108. pInfo.dir = m_Direction;
  1109. pInfo.filter = (IBaseFilter)m_Filter;
  1110. return NOERROR;
  1111. }
  1112. public virtual int EndOfStream()
  1113. {
  1114. return NOERROR;
  1115. }
  1116. public virtual int QueryAccept(AMMediaType pmt)
  1117. {
  1118. if (pmt == null) return E_POINTER;
  1119. int hr = CheckMediaType(pmt);
  1120. if (FAILED(hr))
  1121. {
  1122. return S_FALSE;
  1123. }
  1124. return hr;
  1125. }
  1126. public virtual int NewSegment(long tStart, long tStop, double dRate)
  1127. {
  1128. m_tStart = tStart;
  1129. m_tStop = tStop;
  1130. m_dRate = dRate;
  1131. return S_OK;
  1132. }
  1133. public virtual int QueryDirection(out PinDirection pPinDir)
  1134. {
  1135. pPinDir = m_Direction;
  1136. return S_OK;
  1137. }
  1138. public virtual int QueryId(out string Id)
  1139. {
  1140. Id = m_sName;
  1141. return NOERROR;
  1142. }
  1143. public virtual int QueryInternalConnections(IntPtr ppPins, ref int nPin)
  1144. {
  1145. nPin = 0;
  1146. return E_NOTIMPL;
  1147. }
  1148. public virtual int EnumMediaTypes(out IntPtr ppEnum)
  1149. {
  1150. int hr = S_OK;
  1151. EnumMediaTypes _enum = new EnumMediaTypes(this);
  1152. ppEnum = Marshal.GetComInterfaceForObject(_enum, typeof(IEnumMediaTypes));
  1153. return hr;
  1154. }
  1155. #endregion
  1156. #region IQualityControl Members
  1157. public virtual int Notify(IntPtr pSelf, Quality q)
  1158. {
  1159. return E_NOTIMPL;
  1160. }
  1161. public virtual int SetSink(IntPtr piqc)
  1162. {
  1163. lock (m_Lock)
  1164. {
  1165. if (m_QualitySink != IntPtr.Zero)
  1166. {
  1167. Marshal.Release(m_QualitySink);
  1168. }
  1169. m_QualitySink = piqc;
  1170. if (m_QualitySink != IntPtr.Zero)
  1171. {
  1172. Marshal.AddRef(m_QualitySink);
  1173. }
  1174. }
  1175. return NOERROR;
  1176. }
  1177. #endregion
  1178. #region Static Methods
  1179. protected static HRESULT CreateMemoryAllocator(out IntPtr ppAlloc)
  1180. {
  1181. ppAlloc = IntPtr.Zero;
  1182. HRESULT hr = (HRESULT)API.CoCreateInstance(
  1183. typeof(MemoryAllocator).GUID,
  1184. IntPtr.Zero,
  1185. CLSCTX.CLSCTX_INPROC_SERVER,
  1186. typeof(IMemAllocator).GUID,
  1187. out ppAlloc);
  1188. return hr;
  1189. }
  1190. protected static HRESULT CreatePosPassThru(IntPtr _owner, IPin pPin, bool bRenderer, out IntPtr ppPassThru)
  1191. {
  1192. ppPassThru = IntPtr.Zero;
  1193. HRESULT hr = (HRESULT)API.CoCreateInstance(
  1194. typeof(SeekingPassThru).GUID,
  1195. _owner,
  1196. CLSCTX.CLSCTX_INPROC_SERVER,
  1197. typeof(ISeekingPassThru).GUID,
  1198. out ppPassThru);
  1199. if (FAILED(hr)) return hr;
  1200. ISeekingPassThruImpl _seek = new ISeekingPassThruImpl(ppPassThru);
  1201. hr = (HRESULT)_seek.Init(bRenderer, pPin);
  1202. if (FAILED(hr))
  1203. {
  1204. Marshal.Release(ppPassThru);
  1205. ppPassThru = IntPtr.Zero;
  1206. }
  1207. return hr;
  1208. }
  1209. #endregion
  1210. }
  1211. #endregion
  1212. #region Base InputPin
  1213. [ComVisible(false)]
  1214. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  1215. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  1216. [ClassInterface(ClassInterfaceType.None)]
  1217. public abstract class BaseInputPin : BasePin, IMemInputPin
  1218. {
  1219. #region Variables
  1220. protected bool m_bReadOnly = false;
  1221. protected bool m_bFlushing = false;
  1222. protected AMSample2Properties m_SampleProps = new AMSample2Properties();
  1223. protected IMediaSeekingImpl m_pSeeking = null;
  1224. #endregion
  1225. #region Properties
  1226. public IMediaSeekingImpl Seeking
  1227. {
  1228. get
  1229. {
  1230. if (m_pSeeking == null && IsConnected)
  1231. {
  1232. m_pSeeking = new IMediaSeekingImpl(m_ConnectedPin);
  1233. if (!m_pSeeking.IsValid)
  1234. {
  1235. m_pSeeking = null;
  1236. }
  1237. else
  1238. {
  1239. m_pSeeking._AddRef();
  1240. }
  1241. }
  1242. return m_pSeeking;
  1243. }
  1244. }
  1245. public bool IsReadOnly
  1246. {
  1247. get { return m_bReadOnly; }
  1248. }
  1249. public bool IsFlushing
  1250. {
  1251. get { return m_bFlushing; }
  1252. }
  1253. public AMSample2Properties SampleProps
  1254. {
  1255. get
  1256. {
  1257. ASSERT(m_SampleProps.cbData != 0);
  1258. return m_SampleProps;
  1259. }
  1260. }
  1261. #endregion
  1262. #region Constructor
  1263. public BaseInputPin(string _name, BaseFilter _filter)
  1264. : base(_name, _filter, _filter.FilterLock, PinDirection.Input)
  1265. {
  1266. }
  1267. ~BaseInputPin()
  1268. {
  1269. }
  1270. #endregion
  1271. #region Overridden Methods
  1272. public override int BreakConnect()
  1273. {
  1274. if (m_pAllocator != IntPtr.Zero)
  1275. {
  1276. int hr = Allocator.Decommit();
  1277. if (FAILED(hr))
  1278. {
  1279. return hr;
  1280. }
  1281. Marshal.Release(m_pAllocator);
  1282. m_pAllocator = IntPtr.Zero;
  1283. }
  1284. if (m_pSeeking != null)
  1285. {
  1286. m_pSeeking._Release();
  1287. m_pSeeking = null;
  1288. }
  1289. return NOERROR;
  1290. }
  1291. public override int BeginFlush()
  1292. {
  1293. lock (m_Lock)
  1294. {
  1295. ASSERT(!m_bFlushing);
  1296. m_bFlushing = true;
  1297. return S_OK;
  1298. }
  1299. }
  1300. public override int EndFlush()
  1301. {
  1302. lock (m_Lock)
  1303. {
  1304. ASSERT(m_bFlushing);
  1305. m_bFlushing = false;
  1306. m_bRunTimeError = false;
  1307. return S_OK;
  1308. }
  1309. }
  1310. public override int Notify(IntPtr pSelf, Quality q)
  1311. {
  1312. if (pSelf == IntPtr.Zero) return E_POINTER;
  1313. return NOERROR;
  1314. }
  1315. public override int Inactive()
  1316. {
  1317. m_bRunTimeError = false;
  1318. if (m_pAllocator == IntPtr.Zero)
  1319. {
  1320. return VFW_E_NO_ALLOCATOR;
  1321. }
  1322. m_bFlushing = false;
  1323. return Allocator.Decommit();
  1324. }
  1325. #endregion
  1326. #region Virtual Methods
  1327. public virtual int CheckStreaming()
  1328. {
  1329. ASSERT(IsConnected);
  1330. if (IsStopped)
  1331. {
  1332. return VFW_E_WRONG_STATE;
  1333. }
  1334. if (m_bFlushing)
  1335. {
  1336. return S_FALSE;
  1337. }
  1338. if (m_bRunTimeError)
  1339. {
  1340. return VFW_E_RUNTIME_ERROR;
  1341. }
  1342. return S_OK;
  1343. }
  1344. public virtual int PassNotify(Quality q)
  1345. {
  1346. if (m_QualitySink != IntPtr.Zero)
  1347. {
  1348. return this.QualitySync.Notify(Marshal.GetIUnknownForObject(m_Filter), q);
  1349. }
  1350. else
  1351. {
  1352. try
  1353. {
  1354. int hr = VFW_E_NOT_FOUND;
  1355. if (m_ConnectedPin != IntPtr.Zero)
  1356. {
  1357. IQualityControl pIQC = Marshal.GetObjectForIUnknown(m_ConnectedPin) as IQualityControl;
  1358. if (pIQC != null)
  1359. {
  1360. hr = pIQC.Notify(Marshal.GetIUnknownForObject(m_Filter), q);
  1361. if (Marshal.IsComObject(pIQC))
  1362. {
  1363. Marshal.ReleaseComObject(pIQC);
  1364. }
  1365. pIQC = null;
  1366. }
  1367. }
  1368. return hr;
  1369. }
  1370. finally
  1371. {
  1372. GC.Collect();
  1373. }
  1374. }
  1375. }
  1376. public virtual int OnReceive(ref IMediaSampleImpl _sample)
  1377. {
  1378. int hr = CheckStreaming();
  1379. if (S_OK != hr)
  1380. {
  1381. return hr;
  1382. }
  1383. Guid _guid = typeof(IMediaSample2).GUID;
  1384. IntPtr pSample2;
  1385. if (S_OK == _sample._QueryInterface(ref _guid, out pSample2))
  1386. {
  1387. IMediaSample2Impl _sample2 = new IMediaSample2Impl(pSample2);
  1388. IntPtr pStructure = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(AMSample2Properties)));
  1389. hr = _sample2.GetProperties(Marshal.SizeOf(typeof(AMSample2Properties)), pStructure);
  1390. m_SampleProps = (AMSample2Properties)Marshal.PtrToStructure(pStructure, typeof(AMSample2Properties));
  1391. Marshal.FreeCoTaskMem(pStructure);
  1392. _sample2._Release();
  1393. if (FAILED(hr))
  1394. {
  1395. return hr;
  1396. }
  1397. }
  1398. else
  1399. {
  1400. // Get the properties the hard way
  1401. m_SampleProps.cbData = Marshal.SizeOf(m_SampleProps);
  1402. m_SampleProps.dwTypeSpecificFlags = 0;
  1403. m_SampleProps.dwStreamId = (int)AMSamplePropertyFlags.Media;
  1404. m_SampleProps.dwSampleFlags = 0;
  1405. if (S_OK == _sample.IsDiscontinuity())
  1406. {
  1407. m_SampleProps.dwSampleFlags |= AMSamplePropertyFlags.DataDiscontinuity;
  1408. }
  1409. if (S_OK == _sample.IsPreroll())
  1410. {
  1411. m_SampleProps.dwSampleFlags |= AMSamplePropertyFlags.PreRoll;
  1412. }
  1413. if (S_OK == _sample.IsSyncPoint())
  1414. {
  1415. m_SampleProps.dwSampleFlags |= AMSamplePropertyFlags.SplicePoint;
  1416. }
  1417. if (SUCCEEDED(_sample.GetTime(out m_SampleProps.tStart,
  1418. out m_SampleProps.tStop)))
  1419. {
  1420. m_SampleProps.dwSampleFlags |= AMSamplePropertyFlags.TimeValid |
  1421. AMSamplePropertyFlags.StopValid;
  1422. }
  1423. AMMediaType mt;
  1424. if (S_OK == _sample.GetMediaType(out mt))
  1425. {
  1426. Marshal.StructureToPtr(mt, m_SampleProps.pMediaType, true);
  1427. m_SampleProps.dwSampleFlags |= AMSamplePropertyFlags.TypeChanged;
  1428. }
  1429. _sample.GetPointer(out m_SampleProps.pbBuffer);
  1430. m_SampleProps.lActual = _sample.GetActualDataLength();
  1431. m_SampleProps.cbBuffer = _sample.GetSize();
  1432. }
  1433. // Has the format changed in this sample
  1434. if ((m_SampleProps.dwSampleFlags & AMSamplePropertyFlags.TypeChanged) == 0)
  1435. {
  1436. return NOERROR;
  1437. }
  1438. //Debug.WriteLine("Failed Receive");
  1439. // Check the derived class accepts this format
  1440. // This shouldn't fail as the source must call QueryAccept first
  1441. hr = CheckMediaType((AMMediaType)Marshal.PtrToStructure(m_SampleProps.pMediaType, typeof(AMMediaType)));
  1442. if (hr == NOERROR)
  1443. {
  1444. return NOERROR;
  1445. }
  1446. // Raise a runtime error if we fail the media type
  1447. m_bRunTimeError = true;
  1448. EndOfStream();
  1449. m_Filter.NotifyEvent(EventCode.ErrorAbort, (IntPtr)((int)VFW_E_TYPE_NOT_ACCEPTED), IntPtr.Zero);
  1450. return VFW_E_INVALIDMEDIATYPE;
  1451. }
  1452. #endregion
  1453. #region IMemInputPin Members
  1454. public virtual int GetAllocator(out IntPtr ppAllocator)
  1455. {
  1456. lock (m_Lock)
  1457. {
  1458. ppAllocator = IntPtr.Zero;
  1459. if (m_pAllocator == IntPtr.Zero)
  1460. {
  1461. int hr = CreateMemoryAllocator(out m_pAllocator);
  1462. if (FAILED(hr))
  1463. {
  1464. return hr;
  1465. }
  1466. }
  1467. ASSERT(m_pAllocator != IntPtr.Zero);
  1468. ppAllocator = m_pAllocator;
  1469. Marshal.AddRef(ppAllocator);
  1470. }
  1471. return NOERROR;
  1472. }
  1473. public virtual int NotifyAllocator(IntPtr pAllocator, bool bReadOnly)
  1474. {
  1475. if (pAllocator == IntPtr.Zero) return E_POINTER;
  1476. lock (m_Lock)
  1477. {
  1478. if (m_pAllocator != pAllocator)
  1479. {
  1480. if (m_pAllocator != IntPtr.Zero)
  1481. {
  1482. Marshal.Release(m_pAllocator);
  1483. }
  1484. m_pAllocator = pAllocator;
  1485. if (m_pAllocator != IntPtr.Zero)
  1486. {
  1487. Marshal.AddRef(m_pAllocator);
  1488. }
  1489. }
  1490. m_bReadOnly = bReadOnly;
  1491. return NOERROR;
  1492. }
  1493. }
  1494. public virtual int GetAllocatorRequirements(AllocatorProperties pProps)
  1495. {
  1496. return E_NOTIMPL;
  1497. }
  1498. public virtual int Receive(IntPtr pSample)
  1499. {
  1500. IMediaSampleImpl _sample = new IMediaSampleImpl(pSample);
  1501. return OnReceive(ref _sample);
  1502. }
  1503. public virtual int ReceiveMultiple(IntPtr pSamples, int nSamples, out int nSamplesProcessed)
  1504. {
  1505. int hr = S_OK;
  1506. nSamplesProcessed = 0;
  1507. if (pSamples == IntPtr.Zero) return E_POINTER;
  1508. while (nSamples-- > 0)
  1509. {
  1510. IntPtr _sample = Marshal.ReadIntPtr(pSamples, nSamples * IntPtr.Size);
  1511. hr = Receive(_sample);
  1512. if (hr != S_OK)
  1513. {
  1514. break;
  1515. }
  1516. nSamplesProcessed++;
  1517. }
  1518. return hr;
  1519. }
  1520. public virtual int ReceiveCanBlock()
  1521. {
  1522. int cOutputPins = 0;
  1523. for (int i = 0; i < m_Filter.Pins.Count; i++)
  1524. {
  1525. BasePin _pin = m_Filter.Pins[i];
  1526. if (_pin.Direction == PinDirection.Output)
  1527. {
  1528. IntPtr pPtr;
  1529. int hr = _pin.ConnectedTo(out pPtr);
  1530. if (SUCCEEDED(hr))
  1531. {
  1532. cOutputPins++;
  1533. Guid _guid = typeof(IMemInputPin).GUID;
  1534. IntPtr pInputPin;
  1535. hr = Marshal.QueryInterface(pPtr, ref _guid, out pInputPin);
  1536. if (SUCCEEDED(hr))
  1537. {
  1538. IMemInputPinImpl _input = new IMemInputPinImpl(pInputPin);
  1539. Marshal.Release(pInputPin);
  1540. Marshal.Release(pPtr);
  1541. if (pInputPin != null)
  1542. {
  1543. hr = _input.ReceiveCanBlock();
  1544. if (hr != S_FALSE)
  1545. {
  1546. return S_OK;
  1547. }
  1548. }
  1549. else
  1550. {
  1551. return S_OK;
  1552. }
  1553. }
  1554. else
  1555. {
  1556. Marshal.Release(pPtr);
  1557. }
  1558. }
  1559. }
  1560. }
  1561. return cOutputPins == 0 ? S_OK : S_FALSE;
  1562. }
  1563. #endregion
  1564. }
  1565. #endregion
  1566. #region Base OutputPin
  1567. [ComVisible(false)]
  1568. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  1569. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  1570. [ClassInterface(ClassInterfaceType.None)]
  1571. public abstract class BaseOutputPin : BasePin
  1572. {
  1573. #region Variables
  1574. protected IntPtr m_pInputPin = IntPtr.Zero;
  1575. #endregion
  1576. #region Properties
  1577. public IMemInputPinImpl InputPin
  1578. {
  1579. get
  1580. {
  1581. return new IMemInputPinImpl(m_pInputPin);
  1582. }
  1583. }
  1584. #endregion
  1585. #region Constructor
  1586. public BaseOutputPin(string _name, BaseFilter _filter)
  1587. : base(_name, _filter, _filter.FilterLock, PinDirection.Output)
  1588. {
  1589. }
  1590. #endregion
  1591. #region Overridden Methods
  1592. public override int BeginFlush()
  1593. {
  1594. return E_UNEXPECTED;
  1595. }
  1596. public override int EndFlush()
  1597. {
  1598. return E_UNEXPECTED;
  1599. }
  1600. public override int EndOfStream()
  1601. {
  1602. return E_UNEXPECTED;
  1603. }
  1604. public override int Inactive()
  1605. {
  1606. m_bRunTimeError = false;
  1607. if (m_pAllocator == IntPtr.Zero)
  1608. {
  1609. return VFW_E_NO_ALLOCATOR;
  1610. }
  1611. return Allocator.Decommit();
  1612. }
  1613. public override int Active()
  1614. {
  1615. if (m_pAllocator == IntPtr.Zero)
  1616. {
  1617. return VFW_E_NO_ALLOCATOR;
  1618. }
  1619. return Allocator.Commit();
  1620. }
  1621. public override int BreakConnect()
  1622. {
  1623. if (m_pAllocator != IntPtr.Zero)
  1624. {
  1625. int hr = Allocator.Decommit();
  1626. if (FAILED(hr))
  1627. {
  1628. return hr;
  1629. }
  1630. Marshal.Release(m_pAllocator);
  1631. m_pAllocator = IntPtr.Zero;
  1632. }
  1633. if (m_pInputPin != IntPtr.Zero)
  1634. {
  1635. Marshal.Release(m_pInputPin);
  1636. m_pInputPin = IntPtr.Zero;
  1637. }
  1638. return NOERROR;
  1639. }
  1640. public override int CheckConnect(ref IPinImpl _pin)
  1641. {
  1642. int hr = base.CheckConnect(ref _pin);
  1643. if (FAILED(hr))
  1644. {
  1645. return hr;
  1646. }
  1647. Guid _guid = typeof(IMemInputPin).GUID;
  1648. hr = _pin._QueryInterface(ref _guid, out m_pInputPin);
  1649. if (FAILED(hr))
  1650. {
  1651. return E_NOINTERFACE;
  1652. }
  1653. return NOERROR;
  1654. }
  1655. public override int CompleteConnect(ref IPinImpl pReceivePin)
  1656. {
  1657. return DecideAllocator(InputPin, out m_pAllocator);
  1658. }
  1659. #endregion
  1660. #region Abstract Methods
  1661. public abstract int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop);
  1662. #endregion
  1663. #region Virtual Methods
  1664. public virtual int InitAllocator(out IntPtr ppAlloc)
  1665. {
  1666. return CreateMemoryAllocator(out ppAlloc);
  1667. }
  1668. public virtual int DecideAllocator(IMemInputPinImpl pPin, out IntPtr ppAlloc)
  1669. {
  1670. int hr = NOERROR;
  1671. ppAlloc = IntPtr.Zero;
  1672. AllocatorProperties prop = new AllocatorProperties();
  1673. prop.cbAlign = 0; prop.cbBuffer = 0; prop.cbPrefix = 0; prop.cBuffers = 0;
  1674. pPin.GetAllocatorRequirements(prop);
  1675. if (prop.cbAlign == 0)
  1676. {
  1677. prop.cbAlign = 1;
  1678. }
  1679. hr = pPin.GetAllocator(out ppAlloc);
  1680. if (SUCCEEDED(hr))
  1681. {
  1682. IMemAllocatorImpl _allocator = new IMemAllocatorImpl(ppAlloc);
  1683. hr = DecideBufferSize(ref _allocator, ref prop);
  1684. if (SUCCEEDED(hr))
  1685. {
  1686. hr = pPin.NotifyAllocator(ppAlloc, false);
  1687. if (SUCCEEDED(hr))
  1688. {
  1689. return NOERROR;
  1690. }
  1691. }
  1692. }
  1693. if (ppAlloc != IntPtr.Zero)
  1694. {
  1695. Marshal.Release(ppAlloc);
  1696. ppAlloc = IntPtr.Zero;
  1697. }
  1698. hr = InitAllocator(out ppAlloc);
  1699. if (SUCCEEDED(hr))
  1700. {
  1701. // note - the properties passed here are in the same
  1702. // structure as above and may have been modified by
  1703. // the previous call to DecideBufferSize
  1704. IMemAllocatorImpl _allocator = new IMemAllocatorImpl(ppAlloc);
  1705. hr = DecideBufferSize(ref _allocator, ref prop);
  1706. if (SUCCEEDED(hr))
  1707. {
  1708. hr = pPin.NotifyAllocator(ppAlloc, false);
  1709. if (SUCCEEDED(hr))
  1710. {
  1711. return NOERROR;
  1712. }
  1713. }
  1714. }
  1715. if (ppAlloc != IntPtr.Zero)
  1716. {
  1717. Marshal.Release(ppAlloc);
  1718. ppAlloc = IntPtr.Zero;
  1719. }
  1720. return hr;
  1721. }
  1722. public virtual int GetDeliveryBuffer(out IntPtr ppSample,
  1723. DsLong pStartTime,
  1724. DsLong pEndTime,
  1725. AMGBF dwFlags)
  1726. {
  1727. if (m_pAllocator != IntPtr.Zero)
  1728. {
  1729. IntPtr _start = IntPtr.Zero;
  1730. IntPtr _stop = IntPtr.Zero;
  1731. return Allocator.GetBuffer(out ppSample, _start, _stop, (int)dwFlags);
  1732. }
  1733. else
  1734. {
  1735. ppSample = IntPtr.Zero;
  1736. return E_NOINTERFACE;
  1737. }
  1738. }
  1739. public virtual int Deliver(ref IMediaSampleImpl _sample)
  1740. {
  1741. return Deliver(_sample.UnknownPtr);
  1742. }
  1743. public virtual int Deliver(IntPtr pSample)
  1744. {
  1745. if (m_pInputPin == IntPtr.Zero)
  1746. {
  1747. return VFW_E_NOT_CONNECTED;
  1748. }
  1749. return InputPin.Receive(pSample);
  1750. }
  1751. public virtual int DeliverEndOfStream()
  1752. {
  1753. if (m_ConnectedPin == IntPtr.Zero)
  1754. {
  1755. return VFW_E_NOT_CONNECTED;
  1756. }
  1757. return Connected.EndOfStream();
  1758. }
  1759. public virtual int DeliverBeginFlush()
  1760. {
  1761. if (m_ConnectedPin == IntPtr.Zero)
  1762. {
  1763. return VFW_E_NOT_CONNECTED;
  1764. }
  1765. return Connected.BeginFlush();
  1766. }
  1767. public virtual int DeliverEndFlush()
  1768. {
  1769. if (m_ConnectedPin == IntPtr.Zero)
  1770. {
  1771. return VFW_E_NOT_CONNECTED;
  1772. }
  1773. return Connected.EndFlush();
  1774. }
  1775. public virtual int DeliverNewSegment(long tStart, long tStop, double dRate)
  1776. {
  1777. if (m_ConnectedPin == IntPtr.Zero)
  1778. {
  1779. return VFW_E_NOT_CONNECTED;
  1780. }
  1781. return Connected.NewSegment(tStart, tStop, dRate);
  1782. }
  1783. #endregion
  1784. #region Helper Methods
  1785. public virtual int ReconnectPin()
  1786. {
  1787. if (m_Filter.FilterGraph != null)
  1788. {
  1789. HRESULT hr = E_FAIL;
  1790. IFilterGraph2 pGraph2 = (IFilterGraph2)m_Filter.FilterGraph;
  1791. if (pGraph2 != null)
  1792. {
  1793. int nIndex = 0;
  1794. AMMediaType pmt;
  1795. while (true)
  1796. {
  1797. pmt = new AMMediaType();
  1798. hr = (HRESULT)GetMediaType(nIndex++, ref pmt);
  1799. if (hr != S_OK) break;
  1800. hr = (HRESULT)pGraph2.ReconnectEx(this, pmt);
  1801. pmt.Free();
  1802. if (hr == S_OK) break;
  1803. }
  1804. pGraph2 = null;
  1805. }
  1806. if (!hr.Succeeded)
  1807. {
  1808. hr = (HRESULT)m_Filter.FilterGraph.Reconnect(this);
  1809. }
  1810. return hr;
  1811. }
  1812. else
  1813. {
  1814. return E_NOINTERFACE;
  1815. }
  1816. }
  1817. #endregion
  1818. }
  1819. #endregion
  1820. #region BaseFilter
  1821. [ComVisible(false)]
  1822. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  1823. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  1824. [ClassInterface(ClassInterfaceType.None)]
  1825. public abstract class BaseFilter : PropPageSupport, IPersistStream, IBaseFilter
  1826. {
  1827. #region Constants
  1828. private const string m_csRegistryPath = "Settings";
  1829. #endregion
  1830. #region Variables
  1831. private List<BasePin> m_Pins = null;
  1832. protected string m_sName = "";
  1833. protected object m_Lock = null;
  1834. protected IntPtr m_pClock = IntPtr.Zero;
  1835. protected IntPtr m_pGraph = IntPtr.Zero;
  1836. protected IntPtr m_pSink = IntPtr.Zero;
  1837. protected FilterState m_State = FilterState.Stopped;
  1838. protected long m_tStart = 0;
  1839. protected bool m_bPersistDirty = false;
  1840. #endregion
  1841. #region Properties
  1842. public string Name
  1843. {
  1844. get { return m_sName; }
  1845. }
  1846. public List<BasePin> Pins
  1847. {
  1848. get
  1849. {
  1850. if (m_Pins == null)
  1851. {
  1852. m_Pins = new List<BasePin>();
  1853. int hr = OnInitializePins();
  1854. ASSERT(SUCCEEDED(hr));
  1855. }
  1856. return m_Pins;
  1857. }
  1858. }
  1859. public FilterState State
  1860. {
  1861. get { return m_State; }
  1862. }
  1863. public IFilterGraph FilterGraph
  1864. {
  1865. get
  1866. {
  1867. if (m_pGraph == IntPtr.Zero) return null;
  1868. return (IFilterGraph)Marshal.GetObjectForIUnknown(m_pGraph);
  1869. }
  1870. }
  1871. public IMediaEventSink Sink
  1872. {
  1873. get
  1874. {
  1875. if (m_pGraph == IntPtr.Zero) return null;
  1876. return (IMediaEventSink)Marshal.GetObjectForIUnknown(m_pGraph);
  1877. }
  1878. }
  1879. public bool IsActive
  1880. {
  1881. get
  1882. {
  1883. lock (m_Lock)
  1884. {
  1885. return ((m_State == FilterState.Paused) || (m_State == FilterState.Running));
  1886. }
  1887. }
  1888. }
  1889. public bool IsStopped
  1890. {
  1891. get { return m_State == FilterState.Stopped; }
  1892. }
  1893. public object FilterLock
  1894. {
  1895. get { return m_Lock; }
  1896. }
  1897. public IReferenceClockImpl Clock
  1898. {
  1899. get
  1900. {
  1901. return new IReferenceClockImpl(m_pClock);
  1902. }
  1903. }
  1904. #endregion
  1905. #region Constructor
  1906. public BaseFilter(string _name)
  1907. : this(_name, new object())
  1908. {
  1909. }
  1910. public BaseFilter(string _name, object _lock)
  1911. {
  1912. ASSERT(_lock != null);
  1913. m_Lock = _lock;
  1914. m_sName = _name;
  1915. }
  1916. ~BaseFilter()
  1917. {
  1918. if (m_Pins != null)
  1919. {
  1920. while (m_Pins.Count > 0)
  1921. {
  1922. m_Pins.RemoveAt(0);
  1923. }
  1924. }
  1925. }
  1926. #endregion
  1927. #region Abstract Methods
  1928. protected abstract int OnInitializePins();
  1929. #endregion
  1930. #region Pins Helper
  1931. public int AddPin(BasePin _pin)
  1932. {
  1933. lock (m_Lock)
  1934. {
  1935. Pins.Add(_pin);
  1936. }
  1937. return S_OK;
  1938. }
  1939. public int RemovePin(BasePin _pin)
  1940. {
  1941. lock (m_Lock)
  1942. {
  1943. return Pins.Remove(_pin) ? S_OK : S_FALSE;
  1944. }
  1945. }
  1946. #endregion
  1947. #region Helper Methods
  1948. public virtual int NotifyEvent(EventCode _code, IntPtr _param1, IntPtr _param2)
  1949. {
  1950. IMediaEventSink pSink = Sink;
  1951. if (pSink != null)
  1952. {
  1953. IntPtr _pUnknown = Marshal.GetIUnknownForObject(this);
  1954. try
  1955. {
  1956. if (_code == EventCode.Complete)
  1957. {
  1958. _param2 = _pUnknown;
  1959. }
  1960. return pSink.Notify(_code, _param1, _param2);
  1961. }
  1962. finally
  1963. {
  1964. Marshal.Release(_pUnknown);
  1965. }
  1966. }
  1967. else
  1968. {
  1969. return E_NOTIMPL;
  1970. }
  1971. }
  1972. public virtual int ReconnectPin(IntPtr pPin, AMMediaType pmt)
  1973. {
  1974. return ReconnectPin((IPin)Marshal.GetObjectForIUnknown(pPin), pmt);
  1975. }
  1976. public virtual int ReconnectPin(IPin pPin, AMMediaType pmt)
  1977. {
  1978. if (m_pGraph != null)
  1979. {
  1980. int hr;
  1981. IFilterGraph2 pGraph2 = (IFilterGraph2)FilterGraph;
  1982. if (pGraph2 != null)
  1983. {
  1984. hr = pGraph2.ReconnectEx(pPin, pmt);
  1985. pGraph2 = null;
  1986. }
  1987. else
  1988. {
  1989. hr = FilterGraph.Reconnect(pPin);
  1990. }
  1991. return hr;
  1992. }
  1993. else
  1994. {
  1995. return E_NOINTERFACE;
  1996. }
  1997. }
  1998. public virtual int StreamTime(out long rtStream)
  1999. {
  2000. rtStream = 0;
  2001. if (m_pClock == IntPtr.Zero) return VFW_E_NO_CLOCK;
  2002. int hr = Clock.GetTime(out rtStream);
  2003. if (FAILED(hr)) return hr;
  2004. rtStream -= m_tStart;
  2005. return S_OK;
  2006. }
  2007. #endregion
  2008. #region IBaseFilter Members
  2009. public virtual int EnumPins(out IEnumPins ppEnum)
  2010. {
  2011. int hr = NOERROR;
  2012. if (m_Pins == null)
  2013. {
  2014. m_Pins = new List<BasePin>();
  2015. hr = OnInitializePins();
  2016. if (FAILED(hr))
  2017. {
  2018. ppEnum = null;
  2019. return hr;
  2020. }
  2021. }
  2022. ppEnum = new EnumPins(this);
  2023. return hr;
  2024. }
  2025. public virtual int GetClassID(out Guid pClassID)
  2026. {
  2027. pClassID = this.GetType().GUID;
  2028. return NOERROR;
  2029. }
  2030. public virtual int FindPin(string Id, out IPin ppPin)
  2031. {
  2032. lock (m_Lock)
  2033. {
  2034. int hr = NOERROR;
  2035. if (m_Pins == null)
  2036. {
  2037. m_Pins = new List<BasePin>();
  2038. hr = OnInitializePins();
  2039. if (FAILED(hr))
  2040. {
  2041. ppPin = null;
  2042. return hr;
  2043. }
  2044. }
  2045. ASSERT(m_Pins);
  2046. for (int i = 0; i < m_Pins.Count; i++)
  2047. {
  2048. BasePin _pin = m_Pins[i];
  2049. ASSERT(_pin);
  2050. if (_pin.Name == Id)
  2051. {
  2052. ppPin = (IPin)_pin;
  2053. return S_OK;
  2054. }
  2055. }
  2056. hr = VFW_E_NOT_FOUND;
  2057. ppPin = null;
  2058. return hr;
  2059. }
  2060. }
  2061. public virtual int GetState(int dwMilliSecsTimeout, out FilterState filtState)
  2062. {
  2063. filtState = m_State;
  2064. return NOERROR;
  2065. }
  2066. public virtual int GetSyncSource(out IntPtr pClock)
  2067. {
  2068. lock (m_Lock)
  2069. {
  2070. pClock = m_pClock;
  2071. if (m_pClock != IntPtr.Zero)
  2072. {
  2073. Marshal.AddRef(m_pClock);
  2074. }
  2075. }
  2076. return NOERROR;
  2077. }
  2078. public virtual int SetSyncSource(IntPtr pClock)
  2079. {
  2080. lock (m_Lock)
  2081. {
  2082. if (m_pClock != IntPtr.Zero)
  2083. {
  2084. Marshal.Release(m_pClock);
  2085. }
  2086. m_pClock = pClock;
  2087. if (m_pClock != IntPtr.Zero)
  2088. {
  2089. Marshal.AddRef(m_pClock);
  2090. }
  2091. }
  2092. return NOERROR;
  2093. }
  2094. public virtual int QueryVendorInfo(out string pVendorInfo)
  2095. {
  2096. pVendorInfo = null;
  2097. return E_NOTIMPL;
  2098. }
  2099. public virtual int QueryFilterInfo(out FilterInfo pInfo)
  2100. {
  2101. pInfo = new FilterInfo();
  2102. pInfo.achName = m_sName;
  2103. pInfo.pGraph = FilterGraph;
  2104. return S_OK;
  2105. }
  2106. public virtual int JoinFilterGraph(IntPtr pGraph, string pName)
  2107. {
  2108. lock (m_Lock)
  2109. {
  2110. if (m_pSink != IntPtr.Zero)
  2111. {
  2112. Marshal.Release(m_pSink);
  2113. m_pSink = IntPtr.Zero;
  2114. }
  2115. if (m_pGraph != IntPtr.Zero)
  2116. {
  2117. Marshal.Release(m_pGraph);
  2118. }
  2119. m_pGraph = pGraph;
  2120. if (m_pGraph != IntPtr.Zero)
  2121. {
  2122. Marshal.AddRef(m_pGraph);
  2123. Guid _guid = typeof(IMediaEventSink).GUID;
  2124. Marshal.QueryInterface(m_pGraph, ref _guid, out m_pSink);
  2125. }
  2126. if (pName != null)
  2127. {
  2128. m_sName = pName;
  2129. }
  2130. }
  2131. return NOERROR;
  2132. }
  2133. public virtual int Pause()
  2134. {
  2135. lock (m_Lock)
  2136. {
  2137. int hr;
  2138. if (m_State == FilterState.Stopped)
  2139. {
  2140. if (m_Pins == null)
  2141. {
  2142. m_Pins = new List<BasePin>();
  2143. hr = OnInitializePins();
  2144. if (FAILED(hr)) return hr;
  2145. }
  2146. ASSERT(m_Pins);
  2147. for (int i = 0; i < m_Pins.Count; i++)
  2148. {
  2149. if (m_Pins[i].IsConnected)
  2150. {
  2151. hr = m_Pins[i].Active();
  2152. if (FAILED(hr)) return hr;
  2153. }
  2154. }
  2155. }
  2156. m_State = FilterState.Paused;
  2157. }
  2158. return S_OK;
  2159. }
  2160. public virtual int Run(long tStart)
  2161. {
  2162. lock (m_Lock)
  2163. {
  2164. int hr;
  2165. m_tStart = tStart;
  2166. if (m_State == FilterState.Stopped)
  2167. {
  2168. hr = Pause();
  2169. if (FAILED(hr)) return hr;
  2170. }
  2171. if (m_State != FilterState.Running)
  2172. {
  2173. if (m_Pins == null)
  2174. {
  2175. m_Pins = new List<BasePin>();
  2176. hr = OnInitializePins();
  2177. if (FAILED(hr)) return hr;
  2178. }
  2179. ASSERT(m_Pins);
  2180. for (int i = 0; i < m_Pins.Count; i++)
  2181. {
  2182. if (m_Pins[i].IsConnected)
  2183. {
  2184. hr = m_Pins[i].Run(tStart);
  2185. if (FAILED(hr)) return hr;
  2186. }
  2187. }
  2188. }
  2189. m_State = FilterState.Running;
  2190. }
  2191. return S_OK;
  2192. }
  2193. public virtual int Stop()
  2194. {
  2195. lock (m_Lock)
  2196. {
  2197. int hr = NOERROR;
  2198. if (m_State != FilterState.Stopped)
  2199. {
  2200. if (m_Pins == null)
  2201. {
  2202. m_Pins = new List<BasePin>();
  2203. hr = OnInitializePins();
  2204. if (FAILED(hr)) return hr;
  2205. hr = NOERROR;
  2206. }
  2207. ASSERT(m_Pins);
  2208. for (int i = 0; i < m_Pins.Count; i++)
  2209. {
  2210. if (m_Pins[i].IsConnected)
  2211. {
  2212. int hrTmp = m_Pins[i].Inactive();
  2213. if (FAILED(hrTmp) && SUCCEEDED(hr))
  2214. {
  2215. hr = hrTmp;
  2216. }
  2217. }
  2218. }
  2219. }
  2220. m_State = FilterState.Stopped;
  2221. return hr;
  2222. }
  2223. }
  2224. #endregion
  2225. #region IPersistStream Members
  2226. public virtual int IsDirty()
  2227. {
  2228. return (m_bPersistDirty ? S_OK : S_FALSE);
  2229. }
  2230. public virtual int Load(IntPtr pStm)
  2231. {
  2232. if (pStm == IntPtr.Zero) return E_POINTER;
  2233. HRESULT hr = NOERROR;
  2234. Marshal.AddRef(pStm);
  2235. Stream _stream = null;
  2236. try
  2237. {
  2238. _stream = new COMStream(pStm);
  2239. hr = ReadFromStream(_stream);
  2240. if (hr.Succeeded)
  2241. {
  2242. SetDirty(false);
  2243. }
  2244. }
  2245. catch (Exception _exception)
  2246. {
  2247. hr = (HRESULT)Marshal.GetHRForException(_exception);
  2248. }
  2249. finally
  2250. {
  2251. if (_stream != null)
  2252. {
  2253. _stream.Dispose();
  2254. }
  2255. Marshal.Release(pStm);
  2256. }
  2257. return hr;
  2258. }
  2259. public virtual int Save(IntPtr pStm, bool fClearDirty)
  2260. {
  2261. if (pStm == IntPtr.Zero) return E_POINTER;
  2262. HRESULT hr = NOERROR;
  2263. Marshal.AddRef(pStm);
  2264. Stream _stream = null;
  2265. try
  2266. {
  2267. _stream = new COMStream(pStm);
  2268. hr = WriteToStream(_stream);
  2269. if (hr.Succeeded && fClearDirty)
  2270. {
  2271. SetDirty(false);
  2272. }
  2273. }
  2274. catch (Exception _exception)
  2275. {
  2276. hr = (HRESULT)Marshal.GetHRForException(_exception);
  2277. }
  2278. finally
  2279. {
  2280. if (_stream != null)
  2281. {
  2282. _stream.Dispose();
  2283. }
  2284. Marshal.Release(pStm);
  2285. }
  2286. return hr;
  2287. }
  2288. public virtual int GetSizeMax(out long pcbSize)
  2289. {
  2290. pcbSize = SizeMax();
  2291. return (pcbSize > 0 ? NOERROR : E_NOTIMPL);
  2292. }
  2293. #endregion
  2294. #region Persist Helper Methods
  2295. protected HRESULT SetDirty(bool bDirty)
  2296. {
  2297. m_bPersistDirty = bDirty;
  2298. return NOERROR;
  2299. }
  2300. protected virtual long SizeMax()
  2301. {
  2302. long _size = 0;
  2303. MemoryStream _stream = new MemoryStream();
  2304. try
  2305. {
  2306. _stream = new MemoryStream();
  2307. HRESULT hr = WriteToStream(_stream);
  2308. if (hr == S_OK)
  2309. {
  2310. _size = _stream.Length;
  2311. }
  2312. }
  2313. finally
  2314. {
  2315. _stream.Dispose();
  2316. }
  2317. return _size;
  2318. }
  2319. protected virtual HRESULT WriteToStream(Stream _stream)
  2320. {
  2321. return NOERROR;
  2322. }
  2323. protected virtual HRESULT ReadFromStream(Stream _stream)
  2324. {
  2325. return NOERROR;
  2326. }
  2327. #endregion
  2328. #region Registry Helper Functions
  2329. protected object GetFilterRegistryValue(string _name, object _default)
  2330. {
  2331. if (!string.IsNullOrEmpty(_name))
  2332. {
  2333. Microsoft.Win32.RegistryKey _key = null;
  2334. try
  2335. {
  2336. string _path = "CLSID\\" + this.GetType().GUID.ToString("B") + "\\" + m_csRegistryPath;
  2337. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_path);
  2338. return _key.GetValue(_name, _default);
  2339. }
  2340. catch (Exception _exception)
  2341. {
  2342. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  2343. hr.TraceWrite();
  2344. }
  2345. finally
  2346. {
  2347. if (_key != null)
  2348. {
  2349. _key.Close();
  2350. }
  2351. }
  2352. }
  2353. return _default;
  2354. }
  2355. protected bool SetFilterRegistryValue(string _name, object _value)
  2356. {
  2357. if (!string.IsNullOrEmpty(_name))
  2358. {
  2359. Microsoft.Win32.RegistryKey _key = null;
  2360. try
  2361. {
  2362. string _path = "CLSID\\" + this.GetType().GUID.ToString("B") + "\\" + m_csRegistryPath;
  2363. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_path);
  2364. _key.SetValue(_name, _value);
  2365. return true;
  2366. }
  2367. catch (Exception _exception)
  2368. {
  2369. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  2370. hr.TraceWrite();
  2371. }
  2372. finally
  2373. {
  2374. if (_key != null)
  2375. {
  2376. _key.Close();
  2377. }
  2378. }
  2379. }
  2380. return false;
  2381. }
  2382. #endregion
  2383. #region Setup Helper Methods
  2384. protected virtual int BeforeInstall(ref RegFilter2 _reginfo, ref IFilterMapper2 _mapper2)
  2385. {
  2386. return NOERROR;
  2387. }
  2388. protected virtual int AfterInstall(HRESULT hr, ref RegFilter2 _reginfo, ref IFilterMapper2 _mapper2)
  2389. {
  2390. return NOERROR;
  2391. }
  2392. protected virtual int BeforeUninstall(ref IFilterMapper2 _mapper2)
  2393. {
  2394. return NOERROR;
  2395. }
  2396. protected virtual int AfterUninstall(HRESULT hr, ref IFilterMapper2 _mapper2)
  2397. {
  2398. return NOERROR;
  2399. }
  2400. #endregion
  2401. #region DLLSetup
  2402. [ComRegisterFunctionAttribute]
  2403. [RegistryPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
  2404. public static void RegisterFunction(Type _type)
  2405. {
  2406. if (_type.IsClass)
  2407. {
  2408. AMovieSetup _setup = (AMovieSetup)Attribute.GetCustomAttribute(_type, typeof(AMovieSetup));
  2409. if (_setup != null && _setup.ShouldRegister)
  2410. {
  2411. if (_type.IsSubclassOf(typeof(BaseFilter)) || (_setup.Name != null && _setup.Name != ""))
  2412. {
  2413. BaseFilter _filter = (BaseFilter)Activator.CreateInstance(_type);
  2414. string _instance = null;
  2415. string _name = "";
  2416. if (_setup.Name != null && _setup.Name != "")
  2417. {
  2418. _name = _setup.Name;
  2419. }
  2420. else
  2421. {
  2422. _name = _filter.Name;
  2423. }
  2424. DsGuid _category = null;
  2425. if (_setup.Category != null && _setup.Category != Guid.Empty && _setup.Category != FilterCategory.LegacyAmFilterCategory)
  2426. {
  2427. _category = new DsGuid(_setup.Category);
  2428. }
  2429. IFilterMapper2 _mapper2 = (IFilterMapper2)new FilterMapper2();
  2430. ASSERT(_mapper2);
  2431. if (_mapper2 != null)
  2432. {
  2433. int hr = _mapper2.UnregisterFilter(_category, _instance, _type.GUID);
  2434. RegFilter2 _reg2 = new RegFilter2();
  2435. _reg2.dwVersion = (int)_setup.Version;
  2436. _reg2.dwMerit = _setup.FilterMerit;
  2437. _reg2.rgPins = IntPtr.Zero;
  2438. _reg2.cPins = 0;
  2439. hr = _filter.BeforeInstall(ref _reg2, ref _mapper2);
  2440. if (SUCCEEDED(hr))
  2441. {
  2442. IntPtr _register = Marshal.AllocCoTaskMem(Marshal.SizeOf(_reg2));
  2443. Marshal.StructureToPtr(_reg2, _register, true);
  2444. hr = _mapper2.RegisterFilter(_type.GUID, _name, IntPtr.Zero, _category, _instance, _register);
  2445. if (E_FILE_NOT_FOUND == hr)
  2446. {
  2447. hr = NOERROR;
  2448. }
  2449. Marshal.FreeCoTaskMem(_register);
  2450. _filter.AfterInstall((HRESULT)hr, ref _reg2, ref _mapper2);
  2451. }
  2452. ASSERT(SUCCEEDED(hr));
  2453. _mapper2 = null;
  2454. }
  2455. _filter = null;
  2456. }
  2457. }
  2458. }
  2459. }
  2460. [ComUnregisterFunctionAttribute]
  2461. [RegistryPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
  2462. public static void UnregisterFunction(Type _type)
  2463. {
  2464. if (_type.IsClass)
  2465. {
  2466. AMovieSetup _setup = (AMovieSetup)Attribute.GetCustomAttribute(_type, typeof(AMovieSetup));
  2467. if (_setup != null && _setup.ShouldRegister)
  2468. {
  2469. if (_type.IsSubclassOf(typeof(BaseFilter)) || (_setup.Name != null && _setup.Name != ""))
  2470. {
  2471. BaseFilter _filter = (BaseFilter)Activator.CreateInstance(_type);
  2472. string _instance = null;
  2473. string _name = "";
  2474. if (_setup.Name != null && _setup.Name != "")
  2475. {
  2476. _name = _setup.Name;
  2477. }
  2478. else
  2479. {
  2480. _name = _filter.Name;
  2481. }
  2482. DsGuid _category = null;
  2483. if (_setup.Category != null && _setup.Category != Guid.Empty && _setup.Category != FilterCategory.LegacyAmFilterCategory)
  2484. {
  2485. _category = new DsGuid(_setup.Category);
  2486. }
  2487. IFilterMapper2 _mapper2 = (IFilterMapper2)new FilterMapper2();
  2488. ASSERT(_mapper2);
  2489. if (_mapper2 != null)
  2490. {
  2491. int hr = _filter.BeforeUninstall(ref _mapper2);
  2492. hr = _mapper2.UnregisterFilter(_category, _instance, _type.GUID);
  2493. hr = _filter.AfterUninstall((HRESULT)hr, ref _mapper2);
  2494. ASSERT(SUCCEEDED(hr));
  2495. _mapper2 = null;
  2496. }
  2497. _filter = null;
  2498. Microsoft.Win32.RegistryKey _key = null;
  2499. try
  2500. {
  2501. string _path = "CLSID\\" + _type.GUID.ToString("B");
  2502. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_path);
  2503. if (_key != null)
  2504. {
  2505. _key.DeleteSubKeyTree(m_csRegistryPath);
  2506. }
  2507. }
  2508. catch
  2509. {
  2510. }
  2511. finally
  2512. {
  2513. if (_key != null)
  2514. {
  2515. _key.Close();
  2516. }
  2517. }
  2518. }
  2519. }
  2520. }
  2521. }
  2522. #endregion
  2523. }
  2524. #endregion
  2525. #region Transform Input Pin
  2526. [ComVisible(false)]
  2527. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  2528. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  2529. [ClassInterface(ClassInterfaceType.None)]
  2530. public class TransformInputPin : BaseInputPin
  2531. {
  2532. #region Constructor
  2533. public TransformInputPin(string _name, TransformFilter _filter)
  2534. : base(_name, _filter)
  2535. {
  2536. }
  2537. #endregion
  2538. #region Overriden Methods
  2539. public override int CheckConnect(ref IPinImpl _pin)
  2540. {
  2541. int hr = ((TransformFilter)m_Filter).CheckConnect(PinDirection.Input, ref _pin);
  2542. if (FAILED(hr))
  2543. {
  2544. return hr;
  2545. }
  2546. return base.CheckConnect(ref _pin);
  2547. }
  2548. public override int BreakConnect()
  2549. {
  2550. ASSERT(IsStopped);
  2551. ((TransformFilter)m_Filter).BreakConnect(PinDirection.Input);
  2552. return base.BreakConnect();
  2553. }
  2554. public override int CompleteConnect(ref IPinImpl pReceivePin)
  2555. {
  2556. int hr = ((TransformFilter)m_Filter).CompleteConnect(PinDirection.Input, ref pReceivePin);
  2557. if (FAILED(hr))
  2558. {
  2559. return hr;
  2560. }
  2561. return base.CompleteConnect(ref pReceivePin);
  2562. }
  2563. public override int CheckMediaType(AMMediaType mt)
  2564. {
  2565. int hr = ((TransformFilter)m_Filter).CheckInputType(mt);
  2566. if (S_OK != hr)
  2567. {
  2568. return hr;
  2569. }
  2570. // if the output pin is still connected, then we have
  2571. // to check the transform not just the input format
  2572. if ((((TransformFilter)m_Filter).Output != NULL) &&
  2573. (((TransformFilter)m_Filter).Output.IsConnected))
  2574. {
  2575. return ((TransformFilter)m_Filter).CheckTransform(
  2576. mt,
  2577. ((TransformFilter)m_Filter).Output.CurrentMediaType);
  2578. }
  2579. else
  2580. {
  2581. return hr;
  2582. }
  2583. }
  2584. public override int SetMediaType(AMMediaType mt)
  2585. {
  2586. int hr = base.SetMediaType(mt);
  2587. if (FAILED(hr))
  2588. {
  2589. return hr;
  2590. }
  2591. ASSERT(SUCCEEDED(((TransformFilter)m_Filter).CheckInputType(mt)));
  2592. return ((TransformFilter)m_Filter).SetMediaType(PinDirection.Input, mt);
  2593. }
  2594. public override int CheckStreaming()
  2595. {
  2596. ASSERT(((TransformFilter)m_Filter).Output != NULL);
  2597. if (!((TransformFilter)m_Filter).Output.IsConnected)
  2598. {
  2599. return VFW_E_NOT_CONNECTED;
  2600. }
  2601. else
  2602. {
  2603. // Shouldn't be able to get any data if we're not connected!
  2604. ASSERT(IsConnected);
  2605. // we're flushing
  2606. if (m_bFlushing)
  2607. {
  2608. return S_FALSE;
  2609. }
  2610. // Don't process stuff in Stopped state
  2611. if (IsStopped)
  2612. {
  2613. return VFW_E_WRONG_STATE;
  2614. }
  2615. return S_OK;
  2616. }
  2617. }
  2618. public override int OnReceive(ref IMediaSampleImpl _sample)
  2619. {
  2620. int hr = 0;
  2621. lock (((TransformFilter)m_Filter).ReceiveLock)
  2622. {
  2623. // check all is well with the base class
  2624. hr = base.OnReceive(ref _sample);
  2625. if (S_OK == hr)
  2626. {
  2627. hr = ((TransformFilter)m_Filter).OnReceive(ref _sample);
  2628. }
  2629. return hr;
  2630. }
  2631. }
  2632. public override int EndOfStream()
  2633. {
  2634. lock (((TransformFilter)m_Filter).ReceiveLock)
  2635. {
  2636. int hr = CheckStreaming();
  2637. if (S_OK == hr)
  2638. {
  2639. hr = ((TransformFilter)m_Filter).EndOfStream();
  2640. }
  2641. return hr;
  2642. }
  2643. }
  2644. public override int BeginFlush()
  2645. {
  2646. lock (m_Filter.FilterLock)
  2647. {
  2648. // Are we actually doing anything?
  2649. ASSERT(((TransformFilter)m_Filter).Output != NULL);
  2650. if (!IsConnected ||
  2651. !((TransformFilter)m_Filter).Output.IsConnected)
  2652. {
  2653. return VFW_E_NOT_CONNECTED;
  2654. }
  2655. int hr = base.BeginFlush();
  2656. if (FAILED(hr))
  2657. {
  2658. return hr;
  2659. }
  2660. return ((TransformFilter)m_Filter).BeginFlush();
  2661. }
  2662. }
  2663. public override int EndFlush()
  2664. {
  2665. lock (m_Filter.FilterLock)
  2666. {
  2667. // Are we actually doing anything?
  2668. ASSERT(((TransformFilter)m_Filter).Output != NULL);
  2669. if (!IsConnected ||
  2670. !((TransformFilter)m_Filter).Output.IsConnected)
  2671. {
  2672. return VFW_E_NOT_CONNECTED;
  2673. }
  2674. int hr = ((TransformFilter)m_Filter).EndFlush();
  2675. if (FAILED(hr))
  2676. {
  2677. return hr;
  2678. }
  2679. return base.EndFlush();
  2680. }
  2681. }
  2682. public override int NewSegment(long tStart, long tStop, double dRate)
  2683. {
  2684. base.NewSegment(tStart, tStop, dRate);
  2685. return ((TransformFilter)m_Filter).NewSegment(tStart, tStop, dRate);
  2686. }
  2687. #endregion
  2688. };
  2689. #endregion
  2690. #region Transform Output Pin
  2691. [ComVisible(false)]
  2692. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  2693. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  2694. [ClassInterface(ClassInterfaceType.None)]
  2695. public class TransformOutputPin : BaseOutputPin, IMediaSeeking
  2696. {
  2697. #region Constructor
  2698. public TransformOutputPin(string _name, TransformFilter _filter)
  2699. : base(_name, _filter)
  2700. {
  2701. }
  2702. ~TransformOutputPin()
  2703. {
  2704. }
  2705. #endregion
  2706. #region Properties
  2707. protected IMediaSeekingImpl Seeking
  2708. {
  2709. get
  2710. {
  2711. return ((TransformFilter)m_Filter).Input.Seeking;
  2712. }
  2713. }
  2714. #endregion
  2715. #region Overriden Methods
  2716. public override int BreakConnect()
  2717. {
  2718. ASSERT(IsStopped);
  2719. ((TransformFilter)m_Filter).BreakConnect(PinDirection.Output);
  2720. return base.BreakConnect();
  2721. }
  2722. public override int CheckConnect(ref IPinImpl _pin)
  2723. {
  2724. ASSERT(((TransformFilter)m_Filter).Input != null);
  2725. if (((TransformFilter)m_Filter).Input.IsConnected == false)
  2726. {
  2727. return E_UNEXPECTED;
  2728. }
  2729. int hr = ((TransformFilter)m_Filter).CheckConnect(PinDirection.Output, ref _pin);
  2730. if (FAILED(hr))
  2731. {
  2732. return hr;
  2733. }
  2734. return base.CheckConnect(ref _pin);
  2735. }
  2736. public override int CompleteConnect(ref IPinImpl pReceivePin)
  2737. {
  2738. int hr = ((TransformFilter)m_Filter).CompleteConnect(PinDirection.Output, ref pReceivePin);
  2739. if (FAILED(hr))
  2740. {
  2741. return hr;
  2742. }
  2743. return base.CompleteConnect(ref pReceivePin);
  2744. }
  2745. public override int CheckMediaType(AMMediaType mt)
  2746. {
  2747. // must have selected input first
  2748. ASSERT(((TransformFilter)m_Filter).Input != null);
  2749. if (!((TransformFilter)m_Filter).Input.IsConnected)
  2750. {
  2751. return E_INVALIDARG;
  2752. }
  2753. return ((TransformFilter)m_Filter).CheckTransform(
  2754. ((TransformFilter)m_Filter).Input.CurrentMediaType,
  2755. mt);
  2756. }
  2757. public override int SetMediaType(AMMediaType mt)
  2758. {
  2759. int hr = NOERROR;
  2760. ASSERT(((TransformFilter)m_Filter).Input != NULL);
  2761. ASSERT(AMMediaType.IsValid(((TransformFilter)m_Filter).Input.CurrentMediaType));
  2762. // Set the base class media type (should always succeed)
  2763. hr = base.SetMediaType(mt);
  2764. if (FAILED(hr))
  2765. {
  2766. return hr;
  2767. }
  2768. return ((TransformFilter)m_Filter).SetMediaType(PinDirection.Output, mt);
  2769. }
  2770. public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
  2771. {
  2772. return ((TransformFilter)m_Filter).DecideBufferSize(ref pAlloc, ref prop);
  2773. }
  2774. public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  2775. {
  2776. ASSERT(((TransformFilter)m_Filter).Input != null);
  2777. if (((TransformFilter)m_Filter).Input.IsConnected)
  2778. {
  2779. return ((TransformFilter)m_Filter).GetMediaType(iPosition, ref pMediaType);
  2780. }
  2781. else
  2782. {
  2783. return VFW_S_NO_MORE_ITEMS;
  2784. }
  2785. }
  2786. public override int Notify(IntPtr pSelf, Quality q)
  2787. {
  2788. int hr = ((TransformFilter)m_Filter).AlterQuality(q);
  2789. if (hr != S_FALSE)
  2790. {
  2791. return hr; // either S_OK or a failure
  2792. }
  2793. ASSERT(((TransformFilter)m_Filter).Input != null);
  2794. return ((TransformFilter)m_Filter).Input.PassNotify(q);
  2795. }
  2796. #endregion
  2797. #region IMediaSeeking Members
  2798. public int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  2799. {
  2800. IMediaSeekingImpl _seeking = Seeking;
  2801. if (_seeking != null)
  2802. {
  2803. return _seeking.CheckCapabilities(ref pCapabilities);
  2804. }
  2805. return E_NOINTERFACE;
  2806. }
  2807. public int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  2808. {
  2809. IMediaSeekingImpl _seeking = Seeking;
  2810. if (_seeking != null)
  2811. {
  2812. return _seeking.ConvertTimeFormat(out pTarget, pTargetFormat, Source, pSourceFormat);
  2813. }
  2814. pTarget = 0;
  2815. return E_NOINTERFACE;
  2816. }
  2817. public int GetAvailable(out long pEarliest, out long pLatest)
  2818. {
  2819. IMediaSeekingImpl _seeking = Seeking;
  2820. if (_seeking != null)
  2821. {
  2822. return _seeking.GetAvailable(out pEarliest, out pLatest);
  2823. }
  2824. pLatest = 0;
  2825. pEarliest = 0;
  2826. return E_NOINTERFACE;
  2827. }
  2828. public int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  2829. {
  2830. IMediaSeekingImpl _seeking = Seeking;
  2831. if (_seeking != null)
  2832. {
  2833. return _seeking.GetCapabilities(out pCapabilities);
  2834. }
  2835. pCapabilities = 0;
  2836. return E_NOINTERFACE;
  2837. }
  2838. public int GetCurrentPosition(out long pCurrent)
  2839. {
  2840. IMediaSeeking _seeking = (IMediaSeeking)Seeking;
  2841. if (_seeking != null)
  2842. {
  2843. return _seeking.GetCurrentPosition(out pCurrent);
  2844. }
  2845. pCurrent = 0;
  2846. return E_NOINTERFACE;
  2847. }
  2848. public int GetDuration(out long pDuration)
  2849. {
  2850. IMediaSeekingImpl _seeking = Seeking;
  2851. if (_seeking != null)
  2852. {
  2853. return _seeking.GetDuration(out pDuration);
  2854. }
  2855. pDuration = 0;
  2856. return E_NOINTERFACE;
  2857. }
  2858. public int GetPositions(out long pCurrent, out long pStop)
  2859. {
  2860. IMediaSeekingImpl _seeking = Seeking;
  2861. if (_seeking != null)
  2862. {
  2863. return _seeking.GetPositions(out pCurrent, out pStop);
  2864. }
  2865. pCurrent = 0;
  2866. pStop = 0;
  2867. return E_NOINTERFACE;
  2868. }
  2869. public int GetPreroll(out long pllPreroll)
  2870. {
  2871. IMediaSeekingImpl _seeking = Seeking;
  2872. if (_seeking != null)
  2873. {
  2874. return _seeking.GetPreroll(out pllPreroll);
  2875. }
  2876. pllPreroll = 0;
  2877. return E_NOINTERFACE;
  2878. }
  2879. public int GetRate(out double pdRate)
  2880. {
  2881. IMediaSeekingImpl _seeking = Seeking;
  2882. if (_seeking != null)
  2883. {
  2884. return _seeking.GetRate(out pdRate);
  2885. }
  2886. pdRate = 0;
  2887. return E_NOINTERFACE;
  2888. }
  2889. public int GetStopPosition(out long pStop)
  2890. {
  2891. IMediaSeekingImpl _seeking = Seeking;
  2892. if (_seeking != null)
  2893. {
  2894. return _seeking.GetStopPosition(out pStop);
  2895. }
  2896. pStop = 0;
  2897. return E_NOINTERFACE;
  2898. }
  2899. public int GetTimeFormat(out Guid pFormat)
  2900. {
  2901. IMediaSeekingImpl _seeking = Seeking;
  2902. if (_seeking != null)
  2903. {
  2904. return _seeking.GetTimeFormat(out pFormat);
  2905. }
  2906. pFormat = Guid.Empty;
  2907. return E_NOINTERFACE;
  2908. }
  2909. public int IsFormatSupported(Guid pFormat)
  2910. {
  2911. IMediaSeekingImpl _seeking = Seeking;
  2912. if (_seeking != null)
  2913. {
  2914. return _seeking.IsFormatSupported(pFormat);
  2915. }
  2916. return E_NOINTERFACE;
  2917. }
  2918. public int IsUsingTimeFormat(Guid pFormat)
  2919. {
  2920. IMediaSeekingImpl _seeking = Seeking;
  2921. if (_seeking != null)
  2922. {
  2923. return _seeking.IsUsingTimeFormat(pFormat);
  2924. }
  2925. return E_NOINTERFACE;
  2926. }
  2927. public int QueryPreferredFormat(out Guid pFormat)
  2928. {
  2929. IMediaSeekingImpl _seeking = Seeking;
  2930. if (_seeking != null)
  2931. {
  2932. return _seeking.QueryPreferredFormat(out pFormat);
  2933. }
  2934. pFormat = Guid.Empty;
  2935. return E_NOINTERFACE;
  2936. }
  2937. public int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  2938. {
  2939. IMediaSeekingImpl _seeking = Seeking;
  2940. if (_seeking != null)
  2941. {
  2942. return _seeking.SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
  2943. };
  2944. return E_NOINTERFACE;
  2945. }
  2946. public int SetRate(double dRate)
  2947. {
  2948. IMediaSeekingImpl _seeking = Seeking;
  2949. if (_seeking != null)
  2950. {
  2951. return _seeking.SetRate(dRate);
  2952. };
  2953. return E_NOINTERFACE;
  2954. }
  2955. public int SetTimeFormat(Guid pFormat)
  2956. {
  2957. IMediaSeekingImpl _seeking = Seeking;
  2958. if (_seeking != null)
  2959. {
  2960. return _seeking.SetTimeFormat(pFormat);
  2961. };
  2962. return E_NOINTERFACE;
  2963. }
  2964. #endregion
  2965. }
  2966. #endregion
  2967. #region Transform Filter
  2968. [ComVisible(false)]
  2969. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  2970. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  2971. [ClassInterface(ClassInterfaceType.None)]
  2972. public abstract class TransformFilter : BaseFilter
  2973. {
  2974. #region Variables
  2975. protected bool m_bEOSDelivered = false;
  2976. protected bool m_bQualityChanged = false;
  2977. protected bool m_bSampleSkipped = false;
  2978. protected object m_csReceive = new object();
  2979. #endregion
  2980. #region Properties
  2981. public object ReceiveLock
  2982. {
  2983. get { return m_csReceive; }
  2984. }
  2985. public TransformInputPin Input
  2986. {
  2987. get
  2988. {
  2989. if (Pins.Count >= 1)
  2990. {
  2991. return (TransformInputPin)Pins[0];
  2992. }
  2993. return null;
  2994. }
  2995. }
  2996. public TransformOutputPin Output
  2997. {
  2998. get
  2999. {
  3000. if (Pins.Count >= 2)
  3001. {
  3002. return (TransformOutputPin)Pins[1];
  3003. }
  3004. return null;
  3005. }
  3006. }
  3007. #endregion
  3008. #region Constructor
  3009. public TransformFilter(string _name)
  3010. : base(_name)
  3011. {
  3012. }
  3013. #endregion
  3014. #region Methods
  3015. #region Abstract Methods
  3016. public abstract int CheckInputType(AMMediaType pmt);
  3017. public abstract int CheckTransform(AMMediaType mtIn, AMMediaType mtOut);
  3018. public abstract int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop);
  3019. public abstract int GetMediaType(int iPosition, ref AMMediaType pMediaType);
  3020. public abstract int Transform(ref IMediaSampleImpl input, ref IMediaSampleImpl sample);
  3021. #endregion
  3022. #region Overridden Methods
  3023. protected override int OnInitializePins()
  3024. {
  3025. AddPin(new TransformInputPin("XForm In", this));
  3026. AddPin(new TransformOutputPin("XForm Out", this));
  3027. return NOERROR;
  3028. }
  3029. public override int FindPin(string Id, out IPin ppPin)
  3030. {
  3031. if (Id.IndexOf("In") != -1)
  3032. {
  3033. ppPin = Input;
  3034. return NOERROR;
  3035. }
  3036. if (Id.IndexOf("Out") != -1)
  3037. {
  3038. ppPin = Output;
  3039. return NOERROR;
  3040. }
  3041. return base.FindPin(Id, out ppPin);
  3042. }
  3043. public override int Pause()
  3044. {
  3045. lock (m_Lock)
  3046. {
  3047. int hr = NOERROR;
  3048. if (m_State == FilterState.Paused)
  3049. {
  3050. // (This space left deliberately blank)
  3051. }
  3052. else
  3053. if (Input == null || !Input.IsConnected)
  3054. {
  3055. if (Output != null && !m_bEOSDelivered)
  3056. {
  3057. Output.DeliverEndOfStream();
  3058. m_bEOSDelivered = true;
  3059. }
  3060. m_State = FilterState.Paused;
  3061. }
  3062. else
  3063. if (!Output.IsConnected)
  3064. {
  3065. m_State = FilterState.Paused;
  3066. }
  3067. else
  3068. {
  3069. if (m_State == FilterState.Stopped)
  3070. {
  3071. lock (m_csReceive)
  3072. {
  3073. hr = StartStreaming();
  3074. }
  3075. }
  3076. if (SUCCEEDED(hr))
  3077. {
  3078. hr = base.Pause();
  3079. }
  3080. }
  3081. m_bSampleSkipped = false;
  3082. m_bQualityChanged = false;
  3083. return hr;
  3084. }
  3085. }
  3086. public override int Stop()
  3087. {
  3088. lock (m_Lock)
  3089. {
  3090. if (m_State == FilterState.Stopped)
  3091. {
  3092. return NOERROR;
  3093. }
  3094. ASSERT(Input == null || Output != null);
  3095. if (Input == NULL || !Input.IsConnected || !Output.IsConnected)
  3096. {
  3097. m_State = FilterState.Stopped;
  3098. m_bEOSDelivered = false;
  3099. return NOERROR;
  3100. }
  3101. Input.Inactive();
  3102. lock (m_csReceive)
  3103. {
  3104. Output.Inactive();
  3105. int hr = StopStreaming();
  3106. if (SUCCEEDED(hr))
  3107. {
  3108. // complete the state transition
  3109. m_State = FilterState.Stopped;
  3110. m_bEOSDelivered = false;
  3111. }
  3112. return hr;
  3113. }
  3114. }
  3115. }
  3116. #endregion
  3117. #region Helper Methods for Overload
  3118. public virtual int AlterQuality(Quality q)
  3119. {
  3120. return S_FALSE;
  3121. }
  3122. public virtual int BeginFlush()
  3123. {
  3124. int hr = NOERROR;
  3125. if (Output != null)
  3126. {
  3127. hr = Output.DeliverBeginFlush();
  3128. }
  3129. return hr;
  3130. }
  3131. public virtual int EndFlush()
  3132. {
  3133. ASSERT(Output != null);
  3134. return Output.DeliverEndFlush();
  3135. }
  3136. public virtual int EndOfStream()
  3137. {
  3138. int hr = NOERROR;
  3139. if (Output != null)
  3140. {
  3141. hr = Output.DeliverEndOfStream();
  3142. }
  3143. return hr;
  3144. }
  3145. public virtual int NewSegment(long tStart, long tStop, double dRate)
  3146. {
  3147. int hr = NOERROR;
  3148. if (Output != null)
  3149. {
  3150. hr = Output.DeliverNewSegment(tStart, tStop, dRate);
  3151. }
  3152. return hr;
  3153. }
  3154. public virtual int BreakConnect(PinDirection _direction)
  3155. {
  3156. return NOERROR;
  3157. }
  3158. public virtual int CheckConnect(PinDirection _direction, ref IPinImpl pPin)
  3159. {
  3160. return NOERROR;
  3161. }
  3162. public virtual int CompleteConnect(PinDirection _direction, ref IPinImpl pPin)
  3163. {
  3164. return NOERROR;
  3165. }
  3166. public virtual int SetMediaType(PinDirection _direction, AMMediaType mt)
  3167. {
  3168. return NOERROR;
  3169. }
  3170. public virtual int StartStreaming()
  3171. {
  3172. return NOERROR;
  3173. }
  3174. public virtual int StopStreaming()
  3175. {
  3176. return NOERROR;
  3177. }
  3178. #endregion
  3179. #region Other Methods
  3180. protected virtual int InitializeOutputSample(ref IMediaSampleImpl _sample, out IMediaSampleImpl ppOutSample)
  3181. {
  3182. AMSample2Properties pProps = Input.SampleProps;
  3183. AMGBF dwFlags = m_bSampleSkipped ? AMGBF.PrevFrameSkipped : 0;
  3184. ppOutSample = null;
  3185. if ((pProps.dwSampleFlags & AMSamplePropertyFlags.SplicePoint) == 0)
  3186. {
  3187. dwFlags |= AMGBF.NotAsyncPoint;
  3188. }
  3189. IntPtr pOutputSample;
  3190. int hr = Output.GetDeliveryBuffer(
  3191. out pOutputSample
  3192. , ((pProps.dwSampleFlags & AMSamplePropertyFlags.TimeValid) > 0) ? (DsLong)pProps.tStart : null
  3193. , ((pProps.dwSampleFlags & AMSamplePropertyFlags.StopValid) > 0) ? (DsLong)pProps.tStop : null
  3194. , dwFlags
  3195. );
  3196. if (FAILED(hr))
  3197. {
  3198. return hr;
  3199. }
  3200. ppOutSample = new IMediaSampleImpl(pOutputSample);
  3201. Guid _guid = typeof(IMediaSample2).GUID;
  3202. IntPtr pSample2;
  3203. if (S_OK == ppOutSample._QueryInterface(ref _guid, out pSample2))
  3204. {
  3205. IMediaSample2Impl _sample2 = new IMediaSample2Impl(pSample2);
  3206. int cb = Marshal.SizeOf(typeof(AMSample2Properties));
  3207. IntPtr _properties = Marshal.AllocCoTaskMem(cb);
  3208. if (SUCCEEDED(_sample2.GetProperties(cb, _properties)))
  3209. {
  3210. AMSample2Properties OutProps = (AMSample2Properties)Marshal.PtrToStructure(_properties, typeof(AMSample2Properties));
  3211. OutProps.tStart = pProps.tStart;
  3212. OutProps.tStop = pProps.tStop;
  3213. OutProps.dwSampleFlags = (OutProps.dwSampleFlags & AMSamplePropertyFlags.TypeChanged)
  3214. | (pProps.dwSampleFlags & ~AMSamplePropertyFlags.TypeChanged);
  3215. OutProps.cbData = Marshal.OffsetOf(typeof(AMSample2Properties), "dwStreamId").ToInt32();
  3216. Marshal.StructureToPtr(OutProps, _properties, true);
  3217. hr = _sample2.SetProperties(OutProps.cbData, _properties);
  3218. }
  3219. Marshal.FreeCoTaskMem(_properties);
  3220. if ((pProps.dwSampleFlags & AMSamplePropertyFlags.DataDiscontinuity) > 0)
  3221. {
  3222. m_bSampleSkipped = false;
  3223. }
  3224. _sample2._Release();
  3225. }
  3226. else
  3227. {
  3228. if ((pProps.dwSampleFlags & AMSamplePropertyFlags.TimeValid) > 0)
  3229. {
  3230. ppOutSample.SetTime((DsLong)pProps.tStart, (DsLong)pProps.tStop);
  3231. }
  3232. if ((pProps.dwSampleFlags & AMSamplePropertyFlags.SplicePoint) > 0)
  3233. {
  3234. ppOutSample.SetSyncPoint(true);
  3235. }
  3236. if ((pProps.dwSampleFlags & AMSamplePropertyFlags.DataDiscontinuity) > 0)
  3237. {
  3238. ppOutSample.SetDiscontinuity(true);
  3239. m_bSampleSkipped = false;
  3240. }
  3241. long MediaStart, MediaEnd;
  3242. if (_sample.GetMediaTime(out MediaStart, out MediaEnd) == NOERROR)
  3243. {
  3244. ppOutSample.SetMediaTime((DsLong)MediaStart, (DsLong)MediaEnd);
  3245. }
  3246. }
  3247. return S_OK;
  3248. }
  3249. public virtual int OnReceive(ref IMediaSampleImpl _sample)
  3250. {
  3251. AMSample2Properties pProps = Input.SampleProps;
  3252. IMediaSampleImpl pOutSample = null;
  3253. try
  3254. {
  3255. if (pProps.dwStreamId != (int)AMSamplePropertyFlags.Media)
  3256. {
  3257. return Output.Deliver(ref _sample);
  3258. }
  3259. int hr = InitializeOutputSample(ref _sample, out pOutSample);
  3260. if (FAILED(hr))
  3261. {
  3262. return hr;
  3263. }
  3264. hr = Transform(ref _sample, ref pOutSample);
  3265. if (hr == NOERROR)
  3266. {
  3267. hr = Output.Deliver(ref pOutSample);
  3268. m_bSampleSkipped = false; // last thing no long
  3269. }
  3270. else
  3271. {
  3272. if (S_FALSE == hr)
  3273. {
  3274. m_bSampleSkipped = true;
  3275. if (!m_bQualityChanged)
  3276. {
  3277. NotifyEvent(EventCode.QualityChange, IntPtr.Zero, IntPtr.Zero);
  3278. m_bQualityChanged = true;
  3279. }
  3280. return NOERROR;
  3281. }
  3282. }
  3283. return hr;
  3284. }
  3285. finally
  3286. {
  3287. if (pOutSample != null)
  3288. {
  3289. pOutSample._Release();
  3290. }
  3291. }
  3292. }
  3293. #endregion
  3294. #endregion
  3295. }
  3296. #endregion
  3297. #region TransInPlace Input Pin
  3298. [ComVisible(false)]
  3299. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  3300. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  3301. [ClassInterface(ClassInterfaceType.None)]
  3302. public class TransInPlaceInputPin : TransformInputPin
  3303. {
  3304. #region Constructor
  3305. public TransInPlaceInputPin(string _name, TransInPlaceFilter _filter)
  3306. : base(_name, _filter)
  3307. {
  3308. m_bReadOnly = false;
  3309. }
  3310. #endregion
  3311. #region Overridden Methods
  3312. public override int CheckMediaType(AMMediaType mt)
  3313. {
  3314. int hr = ((TransInPlaceFilter)m_Filter).CheckInputType(mt);
  3315. if (hr != S_OK) return hr;
  3316. if (((TransInPlaceFilter)m_Filter).Output.IsConnected)
  3317. return ((TransInPlaceFilter)m_Filter).Output.Connected.QueryAccept(mt);
  3318. else
  3319. return S_OK;
  3320. }
  3321. public new int CompleteConnect(ref IPinImpl pReceivePin)
  3322. {
  3323. int hr = base.CompleteConnect(ref pReceivePin);
  3324. if (FAILED(hr))
  3325. {
  3326. return hr;
  3327. }
  3328. return ((TransformFilter)m_Filter).CompleteConnect(PinDirection.Input, ref pReceivePin);
  3329. }
  3330. //public override int EnumMediaTypes(out IEnumMediaTypes ppEnum)
  3331. public override int EnumMediaTypes(out IntPtr ppEnum)
  3332. {
  3333. if (!((TransInPlaceFilter)m_Filter).Output.IsConnected)
  3334. {
  3335. ppEnum = IntPtr.Zero;
  3336. return VFW_E_NOT_CONNECTED;
  3337. }
  3338. return ((TransInPlaceFilter)m_Filter).Output.Connected.EnumMediaTypes(out ppEnum);
  3339. }
  3340. public override int GetAllocator(out IntPtr ppAllocator)
  3341. {
  3342. lock (m_Lock)
  3343. {
  3344. int hr = NOERROR;
  3345. if (((TransInPlaceFilter)m_Filter).Output.IsConnected)
  3346. {
  3347. hr = ((TransInPlaceFilter)m_Filter).Output.InputPin.GetAllocator(out ppAllocator);
  3348. if (SUCCEEDED(hr))
  3349. {
  3350. ((TransInPlaceFilter)m_Filter).Output.AllocatorPtr = ppAllocator;
  3351. }
  3352. }
  3353. else
  3354. {
  3355. hr = base.GetAllocator(out ppAllocator);
  3356. }
  3357. return hr;
  3358. }
  3359. }
  3360. public override int GetAllocatorRequirements(AllocatorProperties pProps)
  3361. {
  3362. if (((TransInPlaceFilter)m_Filter).Output.IsConnected)
  3363. return ((TransInPlaceFilter)m_Filter).Output.InputPin.GetAllocatorRequirements(pProps);
  3364. else
  3365. return base.GetAllocatorRequirements(pProps);
  3366. }
  3367. public override int NotifyAllocator(IntPtr pAllocator, bool bReadOnly)
  3368. {
  3369. lock (m_Lock)
  3370. {
  3371. m_bReadOnly = bReadOnly;
  3372. if (!((TransInPlaceFilter)m_Filter).Output.IsConnected)
  3373. {
  3374. return base.NotifyAllocator(pAllocator, bReadOnly);
  3375. }
  3376. int hr = NOERROR;
  3377. if (bReadOnly && ((TransInPlaceFilter)m_Filter).ModifiesData)
  3378. {
  3379. IntPtr pOutputAllocator = ((TransInPlaceFilter)m_Filter).Output.AllocatorPtr;
  3380. if (pOutputAllocator == IntPtr.Zero)
  3381. {
  3382. hr = ((TransInPlaceFilter)m_Filter).Output.InputPin.GetAllocator(out pOutputAllocator);
  3383. if (FAILED(hr))
  3384. {
  3385. hr = CreateMemoryAllocator(out pOutputAllocator);
  3386. }
  3387. if (SUCCEEDED(hr))
  3388. {
  3389. ((TransInPlaceFilter)m_Filter).Output.AllocatorPtr = pOutputAllocator;
  3390. }
  3391. }
  3392. if (pAllocator == pOutputAllocator)
  3393. {
  3394. return E_FAIL;
  3395. }
  3396. else
  3397. if (SUCCEEDED(hr))
  3398. {
  3399. // Must copy so set the allocator properties on the output
  3400. AllocatorProperties Props = new AllocatorProperties(), Actual = new AllocatorProperties();
  3401. hr = ((IMemAllocator)Marshal.GetObjectForIUnknown(pAllocator)).GetProperties(Props);
  3402. GC.Collect();
  3403. if (SUCCEEDED(hr))
  3404. {
  3405. hr = ((IMemAllocator)Marshal.GetObjectForIUnknown(pOutputAllocator)).SetProperties(Props, Actual);
  3406. GC.Collect();
  3407. }
  3408. if (SUCCEEDED(hr))
  3409. {
  3410. if ((Props.cBuffers > Actual.cBuffers)
  3411. || (Props.cbBuffer > Actual.cbBuffer)
  3412. || (Props.cbAlign > Actual.cbAlign)
  3413. )
  3414. {
  3415. hr = E_FAIL;
  3416. }
  3417. }
  3418. // Set the allocator on the output pin
  3419. if (SUCCEEDED(hr))
  3420. {
  3421. hr = ((TransInPlaceFilter)m_Filter).Output.InputPin.NotifyAllocator(pOutputAllocator, false);
  3422. }
  3423. }
  3424. }
  3425. else
  3426. {
  3427. hr = ((TransInPlaceFilter)m_Filter).Output.InputPin.NotifyAllocator(pAllocator, bReadOnly);
  3428. if (SUCCEEDED(hr))
  3429. {
  3430. ((TransInPlaceFilter)m_Filter).Output.AllocatorPtr = pAllocator;
  3431. }
  3432. }
  3433. if (SUCCEEDED(hr))
  3434. {
  3435. AllocatorPtr = pAllocator;
  3436. }
  3437. return hr;
  3438. }
  3439. }
  3440. #endregion
  3441. }
  3442. #endregion
  3443. #region TransInPlace Output Pin
  3444. [ComVisible(false)]
  3445. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  3446. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  3447. [ClassInterface(ClassInterfaceType.None)]
  3448. public class TransInPlaceOutputPin : TransformOutputPin
  3449. {
  3450. #region Constructor
  3451. public TransInPlaceOutputPin(string _name, TransInPlaceFilter _filter)
  3452. : base(_name, _filter)
  3453. {
  3454. }
  3455. #endregion
  3456. #region Overridden Methods
  3457. public override int CheckMediaType(AMMediaType mt)
  3458. {
  3459. if (((TransInPlaceFilter)m_Filter).UsingDifferentAllocators && !m_Filter.IsStopped)
  3460. {
  3461. if (AMMediaType.AreEquals(mt, m_mt))
  3462. {
  3463. return S_OK;
  3464. }
  3465. else
  3466. {
  3467. return VFW_E_TYPE_NOT_ACCEPTED;
  3468. }
  3469. }
  3470. // Assumes the type does not change. That's why we're calling
  3471. // CheckINPUTType here on the OUTPUT pin.
  3472. int hr = ((TransInPlaceFilter)m_Filter).CheckInputType(mt);
  3473. if (hr != S_OK) return hr;
  3474. if (((TransInPlaceFilter)m_Filter).Input.IsConnected)
  3475. return ((TransInPlaceFilter)m_Filter).Input.Connected.QueryAccept(mt);
  3476. else
  3477. return S_OK;
  3478. }
  3479. public new int CompleteConnect(ref IPinImpl pReceivePin)
  3480. {
  3481. int hr = base.CompleteConnect(ref pReceivePin);
  3482. if (FAILED(hr))
  3483. {
  3484. return hr;
  3485. }
  3486. return ((TransformFilter)m_Filter).CompleteConnect(PinDirection.Output, ref pReceivePin);
  3487. }
  3488. //public override int EnumMediaTypes(out IEnumMediaTypes ppEnum)
  3489. public override int EnumMediaTypes(out IntPtr ppEnum)
  3490. {
  3491. if (!((TransInPlaceFilter)m_Filter).Input.IsConnected)
  3492. {
  3493. ppEnum = IntPtr.Zero;
  3494. return VFW_E_NOT_CONNECTED;
  3495. }
  3496. return ((TransInPlaceFilter)m_Filter).Input.Connected.EnumMediaTypes(out ppEnum);
  3497. }
  3498. #endregion
  3499. }
  3500. #endregion
  3501. #region TransInPlace Filter
  3502. [ComVisible(false)]
  3503. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  3504. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  3505. [ClassInterface(ClassInterfaceType.None)]
  3506. public abstract class TransInPlaceFilter : TransformFilter
  3507. {
  3508. #region Variabless
  3509. protected bool m_bModifiesData = true;
  3510. #endregion
  3511. #region Properties
  3512. public bool ModifiesData
  3513. {
  3514. get { return m_bModifiesData; }
  3515. }
  3516. public bool UsingDifferentAllocators
  3517. {
  3518. get { return Input.Allocator != Output.Allocator; }
  3519. }
  3520. public bool TypesMatch
  3521. {
  3522. get
  3523. {
  3524. return AMMediaType.AreEquals(Input.CurrentMediaType, Output.CurrentMediaType);
  3525. }
  3526. }
  3527. #endregion
  3528. #region Constructor
  3529. public TransInPlaceFilter(string _name)
  3530. : base(_name)
  3531. {
  3532. }
  3533. public TransInPlaceFilter(string _name, bool bModifiesData)
  3534. : this(_name)
  3535. {
  3536. m_bModifiesData = bModifiesData;
  3537. }
  3538. #endregion
  3539. #region Overridden Methods
  3540. protected override int OnInitializePins()
  3541. {
  3542. AddPin(new TransInPlaceInputPin("XForm In", this));
  3543. AddPin(new TransInPlaceOutputPin("XForm Out", this));
  3544. return NOERROR;
  3545. }
  3546. public override int CheckTransform(AMMediaType mtIn, AMMediaType mtOut)
  3547. {
  3548. return S_OK;
  3549. }
  3550. public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  3551. {
  3552. return E_UNEXPECTED;
  3553. }
  3554. public override int CompleteConnect(PinDirection _direction, ref IPinImpl pPin)
  3555. {
  3556. ASSERT(Input);
  3557. ASSERT(Output);
  3558. if (m_pGraph == null)
  3559. {
  3560. return VFW_E_NOT_IN_GRAPH;
  3561. }
  3562. if (_direction == PinDirection.Output)
  3563. {
  3564. if (Input.IsConnected)
  3565. {
  3566. return ReconnectPin(Input, Output.CurrentMediaType);
  3567. }
  3568. return NOERROR;
  3569. }
  3570. if (Output.IsConnected)
  3571. {
  3572. if (!TypesMatch)
  3573. {
  3574. return ReconnectPin(Output, Input.CurrentMediaType);
  3575. }
  3576. }
  3577. return NOERROR;
  3578. }
  3579. public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
  3580. {
  3581. AllocatorProperties Request = new AllocatorProperties(), Actual = new AllocatorProperties();
  3582. int hr;
  3583. if (Input.IsConnected)
  3584. {
  3585. // Get the input pin allocator, and get its size and count.
  3586. // we don't care about his alignment and prefix.
  3587. hr = Input.Allocator.GetProperties(Request);
  3588. if (FAILED(hr))
  3589. {
  3590. // Input connected but with a secretive allocator - enough!
  3591. return hr;
  3592. }
  3593. }
  3594. else
  3595. {
  3596. // We're reduced to blind guessing. Let's guess one byte and if
  3597. // this isn't enough then when the other pin does get connected
  3598. // we can revise it.
  3599. Request.cBuffers = 1;
  3600. Request.cbBuffer = 1;
  3601. Request.cbAlign = 0;
  3602. Request.cbPrefix = 0;
  3603. }
  3604. prop.cBuffers = Request.cBuffers;
  3605. prop.cbBuffer = Request.cbBuffer;
  3606. prop.cbAlign = Request.cbAlign;
  3607. if (prop.cBuffers <= 0) { prop.cBuffers = 1; }
  3608. if (prop.cbBuffer <= 0) { prop.cbBuffer = 1; }
  3609. hr = pAlloc.SetProperties(prop, Actual);
  3610. if (FAILED(hr))
  3611. {
  3612. return hr;
  3613. }
  3614. if ((Request.cBuffers > Actual.cBuffers)
  3615. || (Request.cbBuffer > Actual.cbBuffer)
  3616. || (Request.cbAlign > Actual.cbAlign)
  3617. )
  3618. {
  3619. return E_FAIL;
  3620. }
  3621. return NOERROR;
  3622. }
  3623. public override int OnReceive(ref IMediaSampleImpl _sample)
  3624. {
  3625. AMSample2Properties pProps = Input.SampleProps;
  3626. if (pProps.dwStreamId != (int)AMSamplePropertyFlags.Media)
  3627. {
  3628. return Output.Deliver(ref _sample);
  3629. }
  3630. int hr;
  3631. IMediaSampleImpl _output = null;
  3632. try
  3633. {
  3634. if (UsingDifferentAllocators)
  3635. {
  3636. // We have to copy the data.
  3637. hr = Copy(ref _sample, out _output);
  3638. if (hr != S_OK) return hr;
  3639. if (_output == null)
  3640. {
  3641. return E_UNEXPECTED;
  3642. }
  3643. }
  3644. else
  3645. {
  3646. _output = _sample;
  3647. }
  3648. hr = Transform(ref _output);
  3649. if (FAILED(hr))
  3650. {
  3651. return hr;
  3652. }
  3653. if (hr == NOERROR)
  3654. {
  3655. hr = Output.Deliver(ref _output);
  3656. }
  3657. else
  3658. {
  3659. if (S_FALSE == hr)
  3660. {
  3661. m_bSampleSkipped = true;
  3662. if (!m_bQualityChanged)
  3663. {
  3664. NotifyEvent(EventCode.QualityChange, IntPtr.Zero, IntPtr.Zero);
  3665. m_bQualityChanged = true;
  3666. }
  3667. hr = NOERROR;
  3668. }
  3669. }
  3670. }
  3671. finally
  3672. {
  3673. if (_output != null && UsingDifferentAllocators)
  3674. {
  3675. _output._Release();
  3676. }
  3677. }
  3678. return hr;
  3679. }
  3680. public override sealed int Transform(ref IMediaSampleImpl input, ref IMediaSampleImpl sample)
  3681. {
  3682. return E_NOTIMPL;
  3683. }
  3684. #endregion
  3685. #region Abstract Methods
  3686. public abstract int Transform(ref IMediaSampleImpl _sample);
  3687. #endregion
  3688. #region Helper Methods
  3689. protected int Copy(ref IMediaSampleImpl pSource, out IMediaSampleImpl pDest)
  3690. {
  3691. pDest = null;
  3692. int hr;
  3693. long tStart, tStop;
  3694. bool bTime = S_OK == pSource.GetTime(out tStart, out tStop);
  3695. IntPtr _dest;
  3696. hr = Output.GetDeliveryBuffer(
  3697. out _dest
  3698. , bTime ? (DsLong)tStart : null
  3699. , bTime ? (DsLong)tStop : null
  3700. , m_bSampleSkipped ? AMGBF.PrevFrameSkipped : 0
  3701. );
  3702. if (FAILED(hr))
  3703. {
  3704. return hr;
  3705. }
  3706. pDest = new IMediaSampleImpl(_dest);
  3707. Guid _guid = typeof(IMediaSample2).GUID;
  3708. IntPtr pSample2;
  3709. if (S_OK == pDest._QueryInterface(ref _guid, out pSample2))
  3710. {
  3711. IMediaSample2Impl _sample2 = new IMediaSample2Impl(pSample2);
  3712. int cb = Marshal.SizeOf(Input.SampleProps);
  3713. IntPtr _properties = Marshal.AllocCoTaskMem(cb);
  3714. Marshal.StructureToPtr(Input.SampleProps, _properties, true);
  3715. cb = Marshal.OffsetOf(typeof(AMSample2Properties), "pbBuffer").ToInt32();
  3716. hr = _sample2.SetProperties(cb, _properties);
  3717. Marshal.FreeCoTaskMem(_properties);
  3718. _sample2._Release();
  3719. if (FAILED(hr))
  3720. {
  3721. pDest = null;
  3722. return hr;
  3723. }
  3724. }
  3725. else
  3726. {
  3727. if (bTime)
  3728. {
  3729. pDest.SetTime((DsLong)tStart, (DsLong)tStop);
  3730. }
  3731. if (S_OK == pSource.IsSyncPoint())
  3732. {
  3733. pDest.SetSyncPoint(true);
  3734. }
  3735. if (S_OK == pSource.IsDiscontinuity() || m_bSampleSkipped)
  3736. {
  3737. pDest.SetDiscontinuity(true);
  3738. }
  3739. if (S_OK == pSource.IsPreroll())
  3740. {
  3741. pDest.SetPreroll(true);
  3742. }
  3743. // Copy the media type
  3744. AMMediaType mt;
  3745. if (S_OK == pSource.GetMediaType(out mt))
  3746. {
  3747. pDest.SetMediaType(mt);
  3748. AMMediaType.Free(ref mt);
  3749. }
  3750. }
  3751. m_bSampleSkipped = false;
  3752. // Copy the sample media times
  3753. long TimeStart, TimeEnd;
  3754. if (pSource.GetMediaTime(out TimeStart, out TimeEnd) == NOERROR)
  3755. {
  3756. pDest.SetMediaTime((DsLong)TimeStart, (DsLong)TimeEnd);
  3757. }
  3758. {
  3759. int lDataLength = pSource.GetActualDataLength();
  3760. pDest.SetActualDataLength(lDataLength);
  3761. // Copy the sample data
  3762. {
  3763. IntPtr pSourceBuffer, pDestBuffer;
  3764. int lSourceSize = pSource.GetSize();
  3765. int lDestSize = pDest.GetSize();
  3766. ASSERT(lDestSize >= lSourceSize && lDestSize >= lDataLength);
  3767. pSource.GetPointer(out pSourceBuffer);
  3768. pDest.GetPointer(out pDestBuffer);
  3769. ASSERT(lDestSize == 0 || pSourceBuffer != IntPtr.Zero && pDestBuffer != IntPtr.Zero);
  3770. API.CopyMemory(pDestBuffer, pSourceBuffer, lDataLength);
  3771. }
  3772. }
  3773. return hr;
  3774. }
  3775. #endregion
  3776. }
  3777. #endregion
  3778. #region Base Rendered Pin
  3779. [ComVisible(false)]
  3780. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  3781. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  3782. [ClassInterface(ClassInterfaceType.None)]
  3783. public abstract class RenderedInputPin : BaseInputPin
  3784. {
  3785. #region Varibles
  3786. protected bool m_bAtEndOfStream = false;
  3787. protected bool m_bCompleteNotified = false;
  3788. #endregion
  3789. #region Constructor
  3790. public RenderedInputPin(string _name, BaseFilter _filter)
  3791. : base(_name, _filter)
  3792. {
  3793. }
  3794. #endregion
  3795. #region Overridden Methods
  3796. public override int EndOfStream()
  3797. {
  3798. int hr = CheckStreaming();
  3799. // Do EC_COMPLETE handling for rendered pins
  3800. if (S_OK == hr && !m_bAtEndOfStream)
  3801. {
  3802. m_bAtEndOfStream = true;
  3803. FilterState fs;
  3804. ASSERT(SUCCEEDED(m_Filter.GetState(0, out fs)));
  3805. if (fs == FilterState.Running)
  3806. {
  3807. DoCompleteHandling();
  3808. }
  3809. }
  3810. return hr;
  3811. }
  3812. public override int EndFlush()
  3813. {
  3814. lock (m_Lock)
  3815. {
  3816. m_bAtEndOfStream = false;
  3817. m_bCompleteNotified = false;
  3818. return base.EndFlush();
  3819. }
  3820. }
  3821. public override int Active()
  3822. {
  3823. m_bAtEndOfStream = false;
  3824. m_bCompleteNotified = false;
  3825. return base.Active();
  3826. }
  3827. public override int Run(long tStart)
  3828. {
  3829. m_bCompleteNotified = false;
  3830. if (m_bAtEndOfStream)
  3831. {
  3832. DoCompleteHandling();
  3833. }
  3834. return S_OK;
  3835. }
  3836. #endregion
  3837. #region Private Methods
  3838. private void DoCompleteHandling()
  3839. {
  3840. ASSERT(m_bAtEndOfStream);
  3841. if (!m_bCompleteNotified)
  3842. {
  3843. m_bCompleteNotified = true;
  3844. m_Filter.NotifyEvent(EventCode.Complete, (IntPtr)((int)S_OK), IntPtr.Zero);
  3845. }
  3846. }
  3847. #endregion
  3848. }
  3849. #endregion
  3850. #region AMThread
  3851. [ComVisible(false)]
  3852. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  3853. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  3854. [ClassInterface(ClassInterfaceType.None)]
  3855. public abstract class AMThread : COMHelper, IDisposable
  3856. {
  3857. #region Delgates
  3858. [ComVisible(false)]
  3859. public delegate void ThreadCallback();
  3860. #endregion
  3861. #region Variables
  3862. private ManualResetEvent m_EventSend = new ManualResetEvent(false);
  3863. private AutoResetEvent m_EventComplete = new AutoResetEvent(false);
  3864. private int m_dwParam = 0;
  3865. private int m_dwReturnVal = 0;
  3866. protected object m_AccessLock = new object();
  3867. protected object m_WorkerLock = new object();
  3868. protected string m_sName = "";
  3869. #endregion
  3870. #region Constructor
  3871. public AMThread()
  3872. {
  3873. }
  3874. public AMThread(ThreadCallback _callback)
  3875. {
  3876. OnThreadLoop += _callback;
  3877. }
  3878. ~AMThread()
  3879. {
  3880. Dispose();
  3881. }
  3882. #endregion
  3883. #region Properties
  3884. public bool ThreadExists
  3885. {
  3886. get { return IsExists(); }
  3887. }
  3888. public EventWaitHandle RequestEvent
  3889. {
  3890. get { return m_EventSend; }
  3891. }
  3892. public int RequestParam
  3893. {
  3894. get { return m_dwParam; }
  3895. }
  3896. public string Name
  3897. {
  3898. get { return m_sName; }
  3899. set
  3900. {
  3901. if (value != null && value != m_sName && m_sName == "" && !IsExists())
  3902. {
  3903. m_sName = value;
  3904. }
  3905. }
  3906. }
  3907. #endregion
  3908. #region Abstract Methods
  3909. protected abstract bool OnCreate();
  3910. protected abstract bool OnClose(int _timeout);
  3911. protected abstract bool IsExists();
  3912. #endregion
  3913. #region Methods
  3914. public bool Join(int _timeout)
  3915. {
  3916. lock (m_AccessLock)
  3917. {
  3918. return OnClose(_timeout);
  3919. }
  3920. }
  3921. public bool Create()
  3922. {
  3923. lock (m_AccessLock)
  3924. {
  3925. if (ThreadExists)
  3926. {
  3927. return false;
  3928. }
  3929. bool bResult = OnCreate();
  3930. Thread.Sleep(20);
  3931. if (!bResult)
  3932. {
  3933. Close();
  3934. }
  3935. return bResult;
  3936. }
  3937. }
  3938. public bool Close()
  3939. {
  3940. return Join(Timeout.Infinite);
  3941. }
  3942. public int CallWorker(int dwParam)
  3943. {
  3944. lock (m_AccessLock)
  3945. {
  3946. if (!ThreadExists)
  3947. {
  3948. return E_FAIL;
  3949. }
  3950. m_dwParam = dwParam;
  3951. // signal the worker thread
  3952. m_EventSend.Set();
  3953. // wait for the completion to be signalled
  3954. m_EventComplete.WaitOne();
  3955. // done - this is the thread's return value
  3956. return m_dwReturnVal;
  3957. }
  3958. }
  3959. public bool CheckRequest(ref int pParam)
  3960. {
  3961. if (!m_EventSend.WaitOne(0, false))
  3962. {
  3963. return false;
  3964. }
  3965. else
  3966. {
  3967. pParam = m_dwParam;
  3968. return true;
  3969. }
  3970. }
  3971. public void Reply(int _param)
  3972. {
  3973. m_dwReturnVal = _param;
  3974. m_EventSend.Reset();
  3975. m_EventComplete.Set();
  3976. }
  3977. public int GetRequest()
  3978. {
  3979. m_EventSend.WaitOne();
  3980. return m_dwParam;
  3981. }
  3982. #endregion
  3983. #region Events
  3984. public event ThreadCallback OnThreadLoop;
  3985. #endregion
  3986. #region Protected Methods
  3987. protected void MainThreadProc()
  3988. {
  3989. if (OnThreadLoop != null) OnThreadLoop();
  3990. }
  3991. #endregion
  3992. #region IDisposable Members
  3993. public void Dispose()
  3994. {
  3995. Close();
  3996. }
  3997. #endregion
  3998. }
  3999. [ComVisible(false)]
  4000. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4001. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4002. [ClassInterface(ClassInterfaceType.None)]
  4003. public sealed class ManagedThread : AMThread
  4004. {
  4005. #region Variables
  4006. private Thread m_WorkerThread = null;
  4007. private ExecutionContext m_Context = null;
  4008. #endregion
  4009. #region Constructor
  4010. public ManagedThread()
  4011. {
  4012. }
  4013. public ManagedThread(ThreadCallback _callback)
  4014. : base(_callback)
  4015. {
  4016. }
  4017. #endregion
  4018. #region Overridden Methods
  4019. protected override bool OnCreate()
  4020. {
  4021. m_Context = ExecutionContext.Capture();
  4022. m_WorkerThread = new Thread(new ThreadStart(MainThreadProc));
  4023. if (!string.IsNullOrEmpty(m_sName))
  4024. {
  4025. m_WorkerThread.Name = m_sName;
  4026. }
  4027. m_WorkerThread.Start();
  4028. if (!m_WorkerThread.IsAlive)
  4029. {
  4030. Close();
  4031. return false;
  4032. }
  4033. return true;
  4034. }
  4035. protected override bool OnClose(int _timeout)
  4036. {
  4037. bool bResult = true;
  4038. if (m_WorkerThread != null)
  4039. {
  4040. if (m_WorkerThread.IsAlive)
  4041. {
  4042. bResult = m_WorkerThread.Join(_timeout);
  4043. }
  4044. if (bResult)
  4045. {
  4046. m_WorkerThread = null;
  4047. }
  4048. }
  4049. return bResult;
  4050. }
  4051. protected override bool IsExists()
  4052. {
  4053. return m_WorkerThread != null && m_WorkerThread.IsAlive;
  4054. }
  4055. #endregion
  4056. #region Private Methods
  4057. private void ContextRun(object _data)
  4058. {
  4059. MainThreadProc();
  4060. }
  4061. private void CurrentThreadProc()
  4062. {
  4063. ExecutionContext.Run(m_Context, ContextRun, null);
  4064. }
  4065. #endregion
  4066. }
  4067. #endregion
  4068. #region Source Stream Pin
  4069. [ComVisible(false)]
  4070. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4071. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4072. [ClassInterface(ClassInterfaceType.None)]
  4073. public abstract class SourceStream : BaseOutputPin, IDisposable
  4074. {
  4075. #region Variables
  4076. protected AMThread m_Thread = null;
  4077. #endregion
  4078. #region Constructor
  4079. public SourceStream(string _name, BaseSourceFilter _source)
  4080. : base(_name, _source)
  4081. {
  4082. m_Thread = new ManagedThread(this.ThreadCallbackProc);
  4083. }
  4084. ~SourceStream()
  4085. {
  4086. Dispose();
  4087. m_Thread.Dispose();
  4088. m_Thread = null;
  4089. }
  4090. #endregion
  4091. #region Abstract Methods
  4092. public abstract int FillBuffer(ref IMediaSampleImpl _sample);
  4093. #endregion
  4094. #region Overridden Methods
  4095. public override int Active()
  4096. {
  4097. lock (m_Filter.FilterLock)
  4098. {
  4099. if (m_Filter.IsActive)
  4100. {
  4101. return S_FALSE;
  4102. }
  4103. if (!IsConnected)
  4104. {
  4105. return NOERROR;
  4106. }
  4107. int hr = base.Active();
  4108. if (FAILED(hr))
  4109. {
  4110. return hr;
  4111. }
  4112. ASSERT(!m_Thread.ThreadExists);
  4113. if (!m_Thread.Create())
  4114. {
  4115. return E_FAIL;
  4116. }
  4117. hr = Init();
  4118. if (FAILED(hr))
  4119. {
  4120. return hr;
  4121. }
  4122. return Pause();
  4123. }
  4124. }
  4125. public override int Inactive()
  4126. {
  4127. lock (m_Filter.FilterLock)
  4128. {
  4129. if (!IsConnected)
  4130. {
  4131. return NOERROR;
  4132. }
  4133. int hr = 0;
  4134. if (m_Thread.ThreadExists)
  4135. {
  4136. hr = Stop();
  4137. if (FAILED(hr))
  4138. {
  4139. return hr;
  4140. }
  4141. hr = Exit();
  4142. if (FAILED(hr))
  4143. {
  4144. return hr;
  4145. }
  4146. m_Thread.Close();
  4147. }
  4148. hr = base.Inactive();
  4149. if (FAILED(hr))
  4150. {
  4151. return hr;
  4152. }
  4153. return NOERROR;
  4154. }
  4155. }
  4156. public override int CheckMediaType(AMMediaType pmt)
  4157. {
  4158. lock (m_Filter.FilterLock)
  4159. {
  4160. AMMediaType mt = null;
  4161. AMMediaType.Init(ref mt);
  4162. try
  4163. {
  4164. GetMediaType(ref mt);
  4165. if (AMMediaType.AreEquals(mt, pmt))
  4166. {
  4167. return NOERROR;
  4168. }
  4169. }
  4170. finally
  4171. {
  4172. AMMediaType.Free(ref mt);
  4173. mt = null;
  4174. }
  4175. }
  4176. return E_FAIL;
  4177. }
  4178. public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  4179. {
  4180. lock (m_Filter.FilterLock)
  4181. {
  4182. if (iPosition < 0)
  4183. {
  4184. return E_INVALIDARG;
  4185. }
  4186. if (iPosition > 0)
  4187. {
  4188. return VFW_S_NO_MORE_ITEMS;
  4189. }
  4190. return GetMediaType(ref pMediaType);
  4191. }
  4192. }
  4193. public virtual int GetMediaType(ref AMMediaType pMediaType)
  4194. {
  4195. return E_UNEXPECTED;
  4196. }
  4197. #endregion
  4198. #region Cmd Methods
  4199. [ComVisible(false)]
  4200. public enum Command : int { CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT };
  4201. public int Init() { return m_Thread.CallWorker((int)Command.CMD_INIT); }
  4202. public int Exit() { return m_Thread.CallWorker((int)Command.CMD_EXIT); }
  4203. public int Run() { return m_Thread.CallWorker((int)Command.CMD_RUN); }
  4204. public int Pause() { return m_Thread.CallWorker((int)Command.CMD_PAUSE); }
  4205. public int Stop() { return m_Thread.CallWorker((int)Command.CMD_STOP); }
  4206. protected Command GetRequest() { return (Command)m_Thread.GetRequest(); }
  4207. protected bool CheckRequest(ref Command pCom)
  4208. {
  4209. int iParam = (int)pCom;
  4210. if (m_Thread.CheckRequest(ref iParam))
  4211. {
  4212. pCom = (Command)iParam;
  4213. return true;
  4214. }
  4215. return false;
  4216. }
  4217. #endregion
  4218. #region Virtual Methods
  4219. protected virtual int DoBufferProcessingLoop()
  4220. {
  4221. Command com = 0;
  4222. OnThreadStartPlay();
  4223. do
  4224. {
  4225. while (!CheckRequest(ref com))
  4226. {
  4227. IntPtr pSample;
  4228. DsLong _start = new DsLong(0), _stop = new DsLong(0);
  4229. int hr = GetDeliveryBuffer(out pSample, _start, _stop, AMGBF.NoWait);
  4230. if (FAILED(hr))
  4231. {
  4232. Thread.Sleep(hr == VFW_E_TIMEOUT ? 5 : 1);
  4233. continue; // go round again. Perhaps the error will go away
  4234. // or the allocator is decommited & we will be asked to
  4235. // exit soon.
  4236. }
  4237. IMediaSampleImpl _sample = new IMediaSampleImpl(pSample);
  4238. try
  4239. {
  4240. // Virtual function user will override.
  4241. hr = FillBuffer(ref _sample);
  4242. if (hr == S_OK)
  4243. {
  4244. hr = Deliver(ref _sample);
  4245. // downstream filter returns S_FALSE if it wants us to
  4246. // stop or an error if it's reporting an error.
  4247. if (hr != S_OK)
  4248. {
  4249. TRACE(String.Format("Deliver() returned {0}; stopping", hr));
  4250. return S_OK;
  4251. }
  4252. }
  4253. else if (hr == S_FALSE)
  4254. {
  4255. // derived class wants us to stop pushing data
  4256. DeliverEndOfStream();
  4257. return S_OK;
  4258. }
  4259. else
  4260. {
  4261. // derived class encountered an error
  4262. TRACE(String.Format("Deliver() returned {0}; stopping", hr));
  4263. DeliverEndOfStream();
  4264. m_Filter.NotifyEvent(EventCode.ErrorAbort, (IntPtr)hr, IntPtr.Zero);
  4265. return hr;
  4266. }
  4267. }
  4268. finally
  4269. {
  4270. Marshal.Release(pSample);
  4271. pSample = IntPtr.Zero;
  4272. }
  4273. // all paths release the sample
  4274. }
  4275. // For all commands sent to us there must be a Reply call!
  4276. if (com == Command.CMD_RUN || com == Command.CMD_PAUSE)
  4277. {
  4278. m_Thread.Reply(NOERROR);
  4279. }
  4280. else if (com != Command.CMD_STOP)
  4281. {
  4282. m_Thread.Reply(E_UNEXPECTED);
  4283. TRACE("Unexpected command!!!");
  4284. }
  4285. } while (com != Command.CMD_STOP);
  4286. return S_FALSE;
  4287. }
  4288. protected virtual int ThreadProc()
  4289. {
  4290. int hr; // the return code from calls
  4291. Command com;
  4292. do
  4293. {
  4294. com = GetRequest();
  4295. if (com != Command.CMD_INIT)
  4296. {
  4297. m_Thread.Reply(E_UNEXPECTED);
  4298. }
  4299. } while (com != Command.CMD_INIT);
  4300. //TRACE("CSourceStream worker thread initializing");
  4301. hr = OnThreadCreate(); // perform set up tasks
  4302. if (FAILED(hr))
  4303. {
  4304. OnThreadDestroy();
  4305. m_Thread.Reply(hr); // send failed return code from OnThreadCreate
  4306. return 1;
  4307. }
  4308. m_Thread.Reply(NOERROR);
  4309. Command cmd;
  4310. do
  4311. {
  4312. cmd = GetRequest();
  4313. switch (cmd)
  4314. {
  4315. case Command.CMD_EXIT:
  4316. m_Thread.Reply(NOERROR);
  4317. break;
  4318. case Command.CMD_RUN:
  4319. //TRACE("CMD_RUN received before a CMD_PAUSE???");
  4320. m_Thread.Reply(NOERROR);
  4321. DoBufferProcessingLoop();
  4322. break;
  4323. case Command.CMD_PAUSE:
  4324. m_Thread.Reply(NOERROR);
  4325. DoBufferProcessingLoop();
  4326. break;
  4327. case Command.CMD_STOP:
  4328. m_Thread.Reply(NOERROR);
  4329. break;
  4330. default:
  4331. //TRACE(String.Format("Unknown command {0} received!", cmd));
  4332. m_Thread.Reply(E_NOTIMPL);
  4333. break;
  4334. }
  4335. } while (cmd != Command.CMD_EXIT);
  4336. hr = OnThreadDestroy(); // tidy up.
  4337. if (FAILED(hr))
  4338. {
  4339. //TRACE("CSourceStream::OnThreadDestroy failed. Exiting thread.");
  4340. return 1;
  4341. }
  4342. TRACE("CSourceStream worker thread exiting");
  4343. return 0;
  4344. }
  4345. protected virtual int OnThreadCreate()
  4346. {
  4347. return NOERROR;
  4348. }
  4349. protected virtual int OnThreadDestroy()
  4350. {
  4351. return NOERROR;
  4352. }
  4353. protected virtual int OnThreadStartPlay()
  4354. {
  4355. return NOERROR;
  4356. }
  4357. #endregion
  4358. #region Private Methods
  4359. private void ThreadCallbackProc()
  4360. {
  4361. ThreadProc();
  4362. }
  4363. #endregion
  4364. #region IDisposable Members
  4365. public void Dispose()
  4366. {
  4367. m_Thread.Close();
  4368. m_Filter.RemovePin(this);
  4369. }
  4370. #endregion
  4371. }
  4372. #endregion
  4373. #region Source Filter
  4374. [ComVisible(false)]
  4375. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4376. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4377. [ClassInterface(ClassInterfaceType.None)]
  4378. public abstract class BaseSourceFilter : BaseFilter
  4379. {
  4380. #region Constructor
  4381. public BaseSourceFilter(string _name)
  4382. : base(_name)
  4383. {
  4384. }
  4385. #endregion
  4386. }
  4387. #endregion
  4388. #region Output Queue
  4389. [ComVisible(false)]
  4390. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4391. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4392. [ClassInterface(ClassInterfaceType.None)]
  4393. public class OutputQueue : COMHelper, IDisposable
  4394. {
  4395. #region Constants
  4396. protected enum PacketType : int
  4397. {
  4398. Sample = 0,
  4399. NewSegment = 1,
  4400. EOS = 2,
  4401. };
  4402. #endregion
  4403. #region Structures
  4404. protected struct NewSegmentPacket
  4405. {
  4406. public long tStart;
  4407. public long tStop;
  4408. public double dRate;
  4409. }
  4410. protected class Packet
  4411. {
  4412. public PacketType Type;
  4413. public IntPtr Data;
  4414. public Packet(PacketType _type)
  4415. {
  4416. Type = _type;
  4417. Data = IntPtr.Zero;
  4418. }
  4419. public Packet(PacketType _type, IntPtr _data)
  4420. : this(_type)
  4421. {
  4422. Data = _data;
  4423. }
  4424. public Packet(long _start, long _stop, double _rate)
  4425. : this(PacketType.NewSegment)
  4426. {
  4427. NewSegmentPacket _data = new NewSegmentPacket();
  4428. _data.tStart = _start;
  4429. _data.tStop = _stop;
  4430. _data.dRate = _rate;
  4431. Data = Marshal.AllocCoTaskMem(Marshal.SizeOf(_data));
  4432. Marshal.StructureToPtr(_data, Data, true);
  4433. }
  4434. ~Packet()
  4435. {
  4436. if (Type == PacketType.NewSegment && Data != IntPtr.Zero)
  4437. {
  4438. Marshal.FreeCoTaskMem(Data);
  4439. Data = IntPtr.Zero;
  4440. }
  4441. }
  4442. }
  4443. #endregion
  4444. #region Variables
  4445. protected Queue<Packet> m_Packets = new Queue<Packet>();
  4446. protected IntPtr m_pOutputPin = IntPtr.Zero;
  4447. protected EventWaitHandle m_hEventPop = null;
  4448. protected AMThread m_Thread = null;
  4449. protected object m_csPacketsLock = new object();
  4450. protected object m_csPopLock = new object();
  4451. protected object m_csLastResult = new object();
  4452. protected ManualResetEvent m_Flushing = new ManualResetEvent(false);
  4453. protected ManualResetEvent m_Flushed = new ManualResetEvent(false);
  4454. protected ManualResetEvent m_evShutdown = new ManualResetEvent(false);
  4455. protected ManualResetEvent m_evReady = new ManualResetEvent(false);
  4456. protected HRESULT m_hr = S_OK;
  4457. protected bool m_bReset = false;
  4458. #endregion
  4459. #region Constructor
  4460. public OutputQueue(IntPtr pOutputPin)
  4461. {
  4462. m_pOutputPin = pOutputPin;
  4463. m_Thread = new ManagedThread(this.ThreadProc);
  4464. m_Thread.Create();
  4465. }
  4466. ~OutputQueue()
  4467. {
  4468. Dispose();
  4469. }
  4470. #endregion
  4471. #region Properties
  4472. public HRESULT LastResult
  4473. {
  4474. get
  4475. {
  4476. HRESULT hr;
  4477. lock (m_csLastResult)
  4478. {
  4479. hr = m_hr;
  4480. }
  4481. return hr;
  4482. }
  4483. }
  4484. public IPinImpl OutputPin
  4485. {
  4486. get { return new IPinImpl(m_pOutputPin); }
  4487. }
  4488. public EventWaitHandle PopEvent
  4489. {
  4490. get { return m_hEventPop; }
  4491. set
  4492. {
  4493. lock (m_csPopLock)
  4494. {
  4495. m_hEventPop = value;
  4496. }
  4497. }
  4498. }
  4499. #endregion
  4500. #region Public Methods
  4501. public void BeginFlush()
  4502. {
  4503. bool bNotify = false;
  4504. if (!m_Flushing.WaitOne(0, false))
  4505. {
  4506. m_Flushing.Set();
  4507. bNotify = true;
  4508. lock (m_csPacketsLock)
  4509. {
  4510. m_evReady.Set();
  4511. }
  4512. }
  4513. if (bNotify) OutputPin.BeginFlush();
  4514. }
  4515. public void EndFlush()
  4516. {
  4517. bool bNotify = false;
  4518. if (m_Flushing.WaitOne(0, false))
  4519. {
  4520. if (0 == WaitHandle.WaitAny(new WaitHandle[] { m_Flushed, m_evShutdown }))
  4521. {
  4522. m_Flushing.Reset();
  4523. m_Flushed.Reset();
  4524. bNotify = true;
  4525. }
  4526. }
  4527. if (bNotify) OutputPin.EndFlush();
  4528. }
  4529. public void EOS()
  4530. {
  4531. lock (m_csPacketsLock)
  4532. {
  4533. m_Packets.Enqueue(new Packet(PacketType.EOS));
  4534. m_evReady.Set();
  4535. }
  4536. }
  4537. public void NewSegment(long tStart, long tStop, double dRate)
  4538. {
  4539. lock (m_csPacketsLock)
  4540. {
  4541. m_Packets.Enqueue(new Packet(tStart, tStop, dRate));
  4542. m_evReady.Set();
  4543. }
  4544. }
  4545. public int Receive(IntPtr pSample)
  4546. {
  4547. if (pSample == IntPtr.Zero) return E_POINTER;
  4548. if (m_Flushing.WaitOne(0, false)) return S_FALSE;
  4549. lock (m_csLastResult)
  4550. {
  4551. if (m_hr != S_OK) return m_hr;
  4552. }
  4553. lock (m_csPacketsLock)
  4554. {
  4555. Marshal.AddRef(pSample);
  4556. m_Packets.Enqueue(new Packet(PacketType.Sample, pSample));
  4557. m_evReady.Set();
  4558. }
  4559. return S_OK;
  4560. }
  4561. public int Receive(ref IMediaSampleImpl pSample)
  4562. {
  4563. return Receive(pSample.UnknownPtr);
  4564. }
  4565. public void Reset()
  4566. {
  4567. if (!m_Flushing.WaitOne(0, false))
  4568. {
  4569. lock (m_csPacketsLock)
  4570. {
  4571. m_bReset = true;
  4572. m_evReady.Set();
  4573. }
  4574. m_Flushing.Set();
  4575. WaitHandle.WaitAny(new WaitHandle[] { m_Flushed, m_evShutdown });
  4576. }
  4577. m_Flushed.Reset();
  4578. m_Flushing.Reset();
  4579. lock (m_csLastResult)
  4580. {
  4581. m_hr = S_OK;
  4582. }
  4583. lock (m_csPacketsLock)
  4584. {
  4585. m_bReset = false;
  4586. }
  4587. }
  4588. public bool IsIdle()
  4589. {
  4590. return !m_evReady.WaitOne(0, false);
  4591. }
  4592. #endregion
  4593. #region Protected Methods
  4594. protected virtual void ThreadProc()
  4595. {
  4596. Guid _guid = typeof(IMemInputPin).GUID;
  4597. IntPtr pMemInputPin;
  4598. OutputPin._QueryInterface(ref _guid, out pMemInputPin);
  4599. IMemInputPinImpl _pin = new IMemInputPinImpl(pMemInputPin);
  4600. Packet _packet;
  4601. HRESULT hr = NOERROR;
  4602. while (true)
  4603. {
  4604. int nWait = WaitHandle.WaitAny(new WaitHandle[] { m_evReady, m_evShutdown });
  4605. if (nWait != 0)
  4606. {
  4607. lock (m_csPacketsLock)
  4608. {
  4609. while (m_Packets.Count > 0)
  4610. {
  4611. _packet = m_Packets.Dequeue();
  4612. if (_packet.Type == PacketType.Sample)
  4613. {
  4614. Marshal.Release(_packet.Data);
  4615. }
  4616. }
  4617. }
  4618. break;
  4619. }
  4620. bool bReset;
  4621. bool bFlushing = m_Flushing.WaitOne(0, false);
  4622. lock (m_csPacketsLock)
  4623. {
  4624. bReset = m_bReset;
  4625. if (m_Packets.Count > 0)
  4626. {
  4627. _packet = m_Packets.Dequeue();
  4628. }
  4629. else
  4630. {
  4631. m_evReady.Reset();
  4632. if (bFlushing)
  4633. {
  4634. m_Flushed.Set();
  4635. }
  4636. continue;
  4637. }
  4638. }
  4639. lock (m_csPopLock)
  4640. {
  4641. if (m_hEventPop != null)
  4642. {
  4643. m_hEventPop.Set();
  4644. }
  4645. }
  4646. if (_packet.Type == PacketType.EOS && !bReset)
  4647. {
  4648. lock (m_csLastResult)
  4649. {
  4650. if (m_hr != S_OK) continue;
  4651. }
  4652. hr = (HRESULT)OutputPin.EndOfStream();
  4653. if (hr.Failed)
  4654. {
  4655. TRACE("EndOfStream() " + hr.ToString());
  4656. }
  4657. }
  4658. if (_packet.Type == PacketType.NewSegment && !bReset)
  4659. {
  4660. NewSegmentPacket _segment = (NewSegmentPacket)Marshal.PtrToStructure(_packet.Data, typeof(NewSegmentPacket));
  4661. OutputPin.NewSegment(_segment.tStart, _segment.tStop, _segment.dRate);
  4662. }
  4663. if (_packet.Type == PacketType.Sample)
  4664. {
  4665. if (!bFlushing && !bReset)
  4666. {
  4667. bool bProceed;
  4668. lock (m_csLastResult)
  4669. {
  4670. bProceed = (m_hr == S_OK);
  4671. }
  4672. if (bProceed)
  4673. {
  4674. hr = (HRESULT)_pin.Receive(_packet.Data);
  4675. if (hr.Failed)
  4676. {
  4677. lock (m_csLastResult)
  4678. {
  4679. m_hr = hr;
  4680. }
  4681. }
  4682. }
  4683. }
  4684. Marshal.Release(_packet.Data);
  4685. }
  4686. }
  4687. _pin._Release();
  4688. }
  4689. #endregion
  4690. #region IDisposable Members
  4691. public void Dispose()
  4692. {
  4693. m_evShutdown.Set();
  4694. m_Thread.Dispose();
  4695. }
  4696. #endregion
  4697. }
  4698. #endregion
  4699. #region PropertyPages
  4700. [ComVisible(false)]
  4701. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4702. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4703. [ClassInterface(ClassInterfaceType.None)]
  4704. public class BasePropertyPage : Form, IPropertyPage
  4705. {
  4706. #region Variables
  4707. protected IPropertyPageSiteImpl m_pPageSite = null;
  4708. protected bool m_bDirty = false;
  4709. protected bool m_bObjectSet = false;
  4710. #endregion
  4711. #region Constructor
  4712. public BasePropertyPage()
  4713. {
  4714. Visible = false;
  4715. }
  4716. public BasePropertyPage(string _title)
  4717. : this()
  4718. {
  4719. this.Text = _title;
  4720. }
  4721. ~BasePropertyPage()
  4722. {
  4723. SetPageSite(IntPtr.Zero);
  4724. SetObjects(0, IntPtr.Zero);
  4725. }
  4726. #endregion
  4727. #region Properties
  4728. public bool Dirty
  4729. {
  4730. get { return m_bDirty; }
  4731. set
  4732. {
  4733. if (m_bDirty != value)
  4734. {
  4735. m_bDirty = value;
  4736. if (m_pPageSite != null)
  4737. {
  4738. m_pPageSite.OnStatusChange(m_bDirty ? PropStatus.Dirty : PropStatus.Clean);
  4739. }
  4740. }
  4741. }
  4742. }
  4743. public string Title
  4744. {
  4745. get
  4746. {
  4747. return this.Text;
  4748. }
  4749. set
  4750. {
  4751. this.Text = value;
  4752. }
  4753. }
  4754. #endregion
  4755. #region Overridden Methods
  4756. protected override CreateParams CreateParams
  4757. {
  4758. get
  4759. {
  4760. new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  4761. CreateParams _params = base.CreateParams;
  4762. unchecked
  4763. {
  4764. _params.Style &= (int)~0xF1CF0000;
  4765. _params.Style |= 0x40000000;
  4766. }
  4767. return _params;
  4768. }
  4769. }
  4770. #endregion
  4771. #region IPropertyPage Members
  4772. public virtual int SetPageSite(IntPtr pPageSite)
  4773. {
  4774. if (pPageSite == IntPtr.Zero)
  4775. {
  4776. if (m_pPageSite != null)
  4777. {
  4778. m_pPageSite._Release();
  4779. }
  4780. m_pPageSite = null;
  4781. }
  4782. else
  4783. {
  4784. m_pPageSite = new IPropertyPageSiteImpl(pPageSite);
  4785. m_pPageSite._AddRef();
  4786. }
  4787. if (m_pPageSite != null && m_bDirty)
  4788. {
  4789. m_pPageSite.OnStatusChange(PropStatus.Dirty);
  4790. }
  4791. return HRESULT.NOERROR;
  4792. }
  4793. public virtual int Activate(IntPtr hWndParent, DsRect pRect, bool bModal)
  4794. {
  4795. if (pRect == null) return HRESULT.E_POINTER;
  4796. if (m_bObjectSet == false)
  4797. {
  4798. return HRESULT.E_UNEXPECTED;
  4799. }
  4800. if (hWndParent == IntPtr.Zero)
  4801. {
  4802. return HRESULT.E_INVALIDARG;
  4803. }
  4804. this.CreateControl();
  4805. SetParent(Handle, hWndParent);
  4806. OnActivate();
  4807. (this as IPropertyPage).Move(pRect);
  4808. return (this as IPropertyPage).Show(SWOptions.Show);
  4809. }
  4810. public virtual new int Deactivate()
  4811. {
  4812. OnDeactivate();
  4813. Hide();
  4814. DestroyWindow(Handle);
  4815. return HRESULT.NOERROR;
  4816. }
  4817. public virtual int GetPageInfo(PropPageInfo pPageInfo)
  4818. {
  4819. if (pPageInfo == null) return HRESULT.E_POINTER;
  4820. pPageInfo.cb = Marshal.SizeOf(typeof(PropPageInfo));
  4821. pPageInfo.pszTitle = Marshal.StringToCoTaskMemAuto(this.Title);
  4822. pPageInfo.pszDocString = IntPtr.Zero;
  4823. pPageInfo.pszHelpFile = IntPtr.Zero;
  4824. pPageInfo.dwHelpContext = 0;
  4825. pPageInfo.size.cx = this.Width;
  4826. pPageInfo.size.cy = this.Height;
  4827. return HRESULT.NOERROR;
  4828. }
  4829. public virtual int SetObjects(uint cObjects, IntPtr ppUnk)
  4830. {
  4831. if (cObjects == 1)
  4832. {
  4833. if (m_bObjectSet) return HRESULT.E_UNEXPECTED;
  4834. if (ppUnk == IntPtr.Zero)
  4835. {
  4836. return HRESULT.E_POINTER;
  4837. }
  4838. IntPtr pObject = Marshal.ReadIntPtr(ppUnk);
  4839. if (pObject == IntPtr.Zero)
  4840. {
  4841. return COMHelper.E_POINTER;
  4842. }
  4843. // Set a flag to say that we have set the Object
  4844. m_bObjectSet = true;
  4845. return OnConnect(pObject);
  4846. }
  4847. else if (cObjects == 0)
  4848. {
  4849. if (!m_bObjectSet) return HRESULT.NOERROR;
  4850. // Set a flag to say that we have not set the Object for the page
  4851. m_bObjectSet = false;
  4852. return OnDisconnect();
  4853. }
  4854. return HRESULT.E_UNEXPECTED;
  4855. }
  4856. public virtual int Show(SWOptions nCmdShow)
  4857. {
  4858. Visible = !(nCmdShow == SWOptions.Hide);
  4859. return HRESULT.NOERROR;
  4860. }
  4861. public virtual new int Move(DsRect pRect)
  4862. {
  4863. MoveWindow(Handle, pRect.left, pRect.top, pRect.right - pRect.left, pRect.bottom - pRect.top, true);
  4864. return HRESULT.NOERROR;
  4865. }
  4866. public virtual int IsPageDirty()
  4867. {
  4868. return m_bDirty ? COMHelper.S_OK : COMHelper.S_FALSE;
  4869. }
  4870. public virtual int Apply()
  4871. {
  4872. if (m_bObjectSet == false)
  4873. {
  4874. return HRESULT.E_UNEXPECTED;
  4875. }
  4876. // Must have had a site set
  4877. if (m_pPageSite == null)
  4878. {
  4879. return HRESULT.E_UNEXPECTED;
  4880. }
  4881. // Has anything changed
  4882. if (m_bDirty == false)
  4883. {
  4884. return HRESULT.NOERROR;
  4885. }
  4886. // Commit derived class changes
  4887. HRESULT hr = OnApplyChanges();
  4888. if (hr.Succeeded)
  4889. {
  4890. Dirty = false;
  4891. }
  4892. return hr;
  4893. }
  4894. public virtual int Help(string sHelpDir)
  4895. {
  4896. return HRESULT.E_NOTIMPL;
  4897. }
  4898. public virtual int TranslateAccelerator(IntPtr pMsg)
  4899. {
  4900. return HRESULT.E_NOTIMPL;
  4901. }
  4902. #endregion
  4903. #region Virtual Methods
  4904. public virtual HRESULT OnConnect(IntPtr pUnknown)
  4905. {
  4906. return HRESULT.NOERROR;
  4907. }
  4908. public virtual HRESULT OnDisconnect()
  4909. {
  4910. return HRESULT.NOERROR;
  4911. }
  4912. public virtual HRESULT OnActivate()
  4913. {
  4914. return HRESULT.NOERROR;
  4915. }
  4916. public virtual HRESULT OnDeactivate()
  4917. {
  4918. return HRESULT.NOERROR;
  4919. }
  4920. public virtual HRESULT OnApplyChanges()
  4921. {
  4922. return HRESULT.NOERROR;
  4923. }
  4924. #endregion
  4925. #region Static Functions
  4926. public static bool ShowPropertyPages(IBaseFilter _filter, IntPtr _hwnd)
  4927. {
  4928. try
  4929. {
  4930. ISpecifyPropertyPages pProp = (ISpecifyPropertyPages)_filter;
  4931. if (pProp != null)
  4932. {
  4933. DsCAUUID pCAUUID;
  4934. if (COMHelper.SUCCEEDED(pProp.GetPages(out pCAUUID)))
  4935. {
  4936. object oDevice = (object)_filter;
  4937. int hr = OleCreatePropertyFrame(_hwnd, 0, 0, "Filter ", 1, ref oDevice, pCAUUID.cElems, pCAUUID.pElems, 0, 0, IntPtr.Zero);
  4938. if (hr < 0) Marshal.ThrowExceptionForHR(hr);
  4939. Marshal.FreeCoTaskMem(pCAUUID.pElems);
  4940. pProp = null;
  4941. return true;
  4942. }
  4943. }
  4944. }
  4945. catch (Exception)
  4946. {
  4947. }
  4948. finally
  4949. {
  4950. GC.Collect();
  4951. }
  4952. return false;
  4953. }
  4954. #endregion
  4955. #region API
  4956. /// <summary>
  4957. /// COM function helper for displaying properties dialog
  4958. /// </summary>
  4959. [DllImport("olepro32.dll")]
  4960. private static extern int OleCreatePropertyFrame(
  4961. IntPtr hwndOwner,
  4962. int x,
  4963. int y,
  4964. [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption,
  4965. int cObjects,
  4966. [MarshalAs(UnmanagedType.Interface, ArraySubType = UnmanagedType.IUnknown)]
  4967. ref object ppUnk,
  4968. int cPages,
  4969. IntPtr lpPageClsID,
  4970. int lcid,
  4971. int dwReserved,
  4972. IntPtr lpvReserved
  4973. );
  4974. [DllImport("user32.dll")]
  4975. private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  4976. [DllImport("user32.dll", SetLastError = true)]
  4977. private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
  4978. [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  4979. [return: MarshalAs(UnmanagedType.Bool)]
  4980. private static extern bool DestroyWindow(IntPtr hwnd);
  4981. #endregion
  4982. }
  4983. #endregion
  4984. #region PosPassThru
  4985. [ComVisible(false)]
  4986. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  4987. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  4988. [ClassInterface(ClassInterfaceType.None)]
  4989. public class PosPassThru : COMHelper, IMediaSeeking, IMediaPosition
  4990. {
  4991. #region Variables
  4992. private IntPtr m_pPin = IntPtr.Zero;
  4993. private object m_csLock = new object();
  4994. private IMediaSeekingImpl m_pSeeking = null;
  4995. #endregion
  4996. #region Constructor
  4997. public PosPassThru(ref HRESULT hr, IntPtr pPin)
  4998. {
  4999. hr = S_OK;
  5000. m_pPin = pPin;
  5001. if (m_pPin == IntPtr.Zero)
  5002. {
  5003. hr = E_POINTER;
  5004. }
  5005. }
  5006. #endregion
  5007. #region Properties
  5008. public HRESULT ForceRefresh
  5009. {
  5010. get { return S_OK; }
  5011. }
  5012. protected IMediaSeekingImpl Seeking
  5013. {
  5014. get
  5015. {
  5016. lock (m_csLock)
  5017. {
  5018. if (m_pSeeking == null)
  5019. {
  5020. IPinImpl _pin = new IPinImpl(m_pPin);
  5021. if (_pin.IsValid)
  5022. {
  5023. IntPtr _connected;
  5024. HRESULT hr = (HRESULT)_pin.ConnectedTo(out _connected);
  5025. if (SUCCEEDED(hr))
  5026. {
  5027. m_pSeeking = new IMediaSeekingImpl(_connected);
  5028. Marshal.Release(_connected);
  5029. }
  5030. }
  5031. }
  5032. return m_pSeeking;
  5033. }
  5034. }
  5035. }
  5036. #endregion
  5037. #region Virtual Methods
  5038. public virtual HRESULT GetMediaTime(out long pStartTime, out long pEndTime)
  5039. {
  5040. pStartTime = pEndTime = 0;
  5041. return E_FAIL;
  5042. }
  5043. #endregion
  5044. #region Methods
  5045. public void ResetSeeking()
  5046. {
  5047. lock (m_csLock)
  5048. {
  5049. m_pSeeking = null;
  5050. }
  5051. }
  5052. #endregion
  5053. #region IMediaSeeking Members
  5054. public int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  5055. {
  5056. pCapabilities = 0;
  5057. IMediaSeekingImpl _seeking = Seeking;
  5058. if (_seeking == null || !_seeking.IsValid)
  5059. {
  5060. return E_NOTIMPL;
  5061. }
  5062. return _seeking.GetCapabilities(out pCapabilities);
  5063. }
  5064. public int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  5065. {
  5066. IMediaSeekingImpl _seeking = Seeking;
  5067. if (_seeking == null || !_seeking.IsValid)
  5068. {
  5069. return E_NOTIMPL;
  5070. }
  5071. return _seeking.CheckCapabilities(ref pCapabilities);
  5072. }
  5073. public int IsFormatSupported(Guid pFormat)
  5074. {
  5075. IMediaSeekingImpl _seeking = Seeking;
  5076. if (_seeking == null || !_seeking.IsValid)
  5077. {
  5078. return E_NOTIMPL;
  5079. }
  5080. return _seeking.IsFormatSupported(pFormat);
  5081. }
  5082. public int QueryPreferredFormat(out Guid pFormat)
  5083. {
  5084. pFormat = Guid.Empty;
  5085. IMediaSeekingImpl _seeking = Seeking;
  5086. if (_seeking == null || !_seeking.IsValid)
  5087. {
  5088. return E_NOTIMPL;
  5089. }
  5090. return _seeking.QueryPreferredFormat(out pFormat);
  5091. }
  5092. public int GetTimeFormat(out Guid pFormat)
  5093. {
  5094. pFormat = Guid.Empty;
  5095. IMediaSeekingImpl _seeking = Seeking;
  5096. if (_seeking == null || !_seeking.IsValid)
  5097. {
  5098. return E_NOTIMPL;
  5099. }
  5100. return _seeking.GetTimeFormat(out pFormat);
  5101. }
  5102. public int IsUsingTimeFormat(Guid pFormat)
  5103. {
  5104. IMediaSeekingImpl _seeking = Seeking;
  5105. if (_seeking == null || !_seeking.IsValid)
  5106. {
  5107. return E_NOTIMPL;
  5108. }
  5109. return _seeking.IsUsingTimeFormat(pFormat);
  5110. }
  5111. public int SetTimeFormat(Guid pFormat)
  5112. {
  5113. IMediaSeekingImpl _seeking = Seeking;
  5114. if (_seeking == null || !_seeking.IsValid)
  5115. {
  5116. return E_NOTIMPL;
  5117. }
  5118. return _seeking.SetTimeFormat(pFormat);
  5119. }
  5120. public int GetDuration(out long pDuration)
  5121. {
  5122. pDuration = 0;
  5123. IMediaSeekingImpl _seeking = Seeking;
  5124. if (_seeking == null || !_seeking.IsValid)
  5125. {
  5126. return E_NOTIMPL;
  5127. }
  5128. return _seeking.GetDuration(out pDuration);
  5129. }
  5130. public int GetStopPosition(out long pStop)
  5131. {
  5132. pStop = 0;
  5133. IMediaSeekingImpl _seeking = Seeking;
  5134. if (_seeking == null || !_seeking.IsValid)
  5135. {
  5136. return E_NOTIMPL;
  5137. }
  5138. return _seeking.GetStopPosition(out pStop);
  5139. }
  5140. public int GetCurrentPosition(out long pCurrent)
  5141. {
  5142. pCurrent = 0;
  5143. long lEnd;
  5144. HRESULT hr = GetMediaTime(out pCurrent, out lEnd);
  5145. if (SUCCEEDED(hr))
  5146. {
  5147. hr = NOERROR;
  5148. }
  5149. else
  5150. {
  5151. IMediaSeekingImpl _seeking = Seeking;
  5152. if (_seeking == null || !_seeking.IsValid)
  5153. {
  5154. return E_NOTIMPL;
  5155. }
  5156. hr = (HRESULT)_seeking.GetCurrentPosition(out pCurrent);
  5157. }
  5158. return hr;
  5159. }
  5160. public int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  5161. {
  5162. pTarget = 0;
  5163. IMediaSeekingImpl _seeking = Seeking;
  5164. if (_seeking == null || !_seeking.IsValid)
  5165. {
  5166. return E_NOTIMPL;
  5167. }
  5168. return _seeking.ConvertTimeFormat(out pTarget, pTargetFormat, Source, pSourceFormat);
  5169. }
  5170. public int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  5171. {
  5172. IMediaSeekingImpl _seeking = Seeking;
  5173. if (_seeking == null || !_seeking.IsValid)
  5174. {
  5175. return E_NOTIMPL;
  5176. }
  5177. return _seeking.SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
  5178. }
  5179. public int GetPositions(out long pCurrent, out long pStop)
  5180. {
  5181. pCurrent = pStop = 0;
  5182. IMediaSeekingImpl _seeking = Seeking;
  5183. if (_seeking == null || !_seeking.IsValid)
  5184. {
  5185. return E_NOTIMPL;
  5186. }
  5187. return _seeking.GetPositions(out pCurrent, out pStop);
  5188. }
  5189. public int GetAvailable(out long pEarliest, out long pLatest)
  5190. {
  5191. pEarliest = pLatest = 0;
  5192. IMediaSeekingImpl _seeking = Seeking;
  5193. if (_seeking == null || !_seeking.IsValid)
  5194. {
  5195. return E_NOTIMPL;
  5196. }
  5197. return _seeking.GetAvailable(out pEarliest, out pLatest);
  5198. }
  5199. public int SetRate(double dRate)
  5200. {
  5201. if (0.0 == dRate)
  5202. {
  5203. return E_INVALIDARG;
  5204. }
  5205. IMediaSeekingImpl _seeking = Seeking;
  5206. if (_seeking == null || !_seeking.IsValid)
  5207. {
  5208. return E_NOTIMPL;
  5209. }
  5210. return _seeking.SetRate(dRate);
  5211. }
  5212. public int GetRate(out double pdRate)
  5213. {
  5214. pdRate = 0;
  5215. IMediaSeekingImpl _seeking = Seeking;
  5216. if (_seeking == null || !_seeking.IsValid)
  5217. {
  5218. return E_NOTIMPL;
  5219. }
  5220. return _seeking.GetRate(out pdRate);
  5221. }
  5222. public int GetPreroll(out long pllPreroll)
  5223. {
  5224. pllPreroll = 0;
  5225. IMediaSeekingImpl _seeking = Seeking;
  5226. if (_seeking == null || !_seeking.IsValid)
  5227. {
  5228. return E_NOTIMPL;
  5229. }
  5230. return _seeking.GetPreroll(out pllPreroll);
  5231. }
  5232. #endregion
  5233. #region IMediaPosition Members
  5234. public int get_Duration(out double pLength)
  5235. {
  5236. pLength = 0;
  5237. long lDuration;
  5238. int hr = GetDuration(out lDuration);
  5239. if (SUCCEEDED(hr))
  5240. {
  5241. pLength = (double)lDuration / (double)UNITS;
  5242. }
  5243. return hr;
  5244. }
  5245. public int put_CurrentPosition(double llTime)
  5246. {
  5247. long _position = (long)(llTime * UNITS);
  5248. return SetPositions(_position, AMSeekingSeekingFlags.AbsolutePositioning, 0, AMSeekingSeekingFlags.NoPositioning);
  5249. }
  5250. public int get_CurrentPosition(out double pllTime)
  5251. {
  5252. pllTime = 0;
  5253. long _position;
  5254. int hr = GetCurrentPosition(out _position);
  5255. if (SUCCEEDED(hr))
  5256. {
  5257. pllTime = ((double)_position / (double)UNITS);
  5258. }
  5259. return hr;
  5260. }
  5261. public int get_StopTime(out double pllTime)
  5262. {
  5263. pllTime = 0;
  5264. long _position;
  5265. int hr = GetStopPosition(out _position);
  5266. if (SUCCEEDED(hr))
  5267. {
  5268. pllTime = ((double)_position / (double)UNITS);
  5269. }
  5270. return hr;
  5271. }
  5272. public int put_StopTime(double llTime)
  5273. {
  5274. long _position = (long)(llTime * UNITS);
  5275. return SetPositions(0, AMSeekingSeekingFlags.NoPositioning, _position, AMSeekingSeekingFlags.AbsolutePositioning);
  5276. }
  5277. public int get_PrerollTime(out double pllTime)
  5278. {
  5279. pllTime = 0;
  5280. long _position;
  5281. int hr = GetPreroll(out _position);
  5282. if (SUCCEEDED(hr))
  5283. {
  5284. pllTime = ((double)_position / (double)UNITS);
  5285. }
  5286. return hr;
  5287. }
  5288. public int put_PrerollTime(double llTime)
  5289. {
  5290. return E_NOTIMPL;
  5291. }
  5292. public int put_Rate(double dRate)
  5293. {
  5294. return SetRate(dRate);
  5295. }
  5296. public int get_Rate(out double pdRate)
  5297. {
  5298. return GetRate(out pdRate);
  5299. }
  5300. public int CanSeekForward(out OABool pCanSeekForward)
  5301. {
  5302. pCanSeekForward = OABool.False;
  5303. AMSeekingSeekingCapabilities _caps = AMSeekingSeekingCapabilities.CanSeekForwards;
  5304. int hr = CheckCapabilities(ref _caps);
  5305. if (S_OK == hr)
  5306. {
  5307. pCanSeekForward = OABool.True;
  5308. }
  5309. if (S_FALSE == hr) hr = S_OK;
  5310. return hr;
  5311. }
  5312. public int CanSeekBackward(out OABool pCanSeekBackward)
  5313. {
  5314. pCanSeekBackward = OABool.False;
  5315. AMSeekingSeekingCapabilities _caps = AMSeekingSeekingCapabilities.CanSeekBackwards;
  5316. int hr = CheckCapabilities(ref _caps);
  5317. if (S_OK == hr)
  5318. {
  5319. pCanSeekBackward = OABool.True;
  5320. }
  5321. if (S_FALSE == hr) hr = S_OK;
  5322. return hr;
  5323. }
  5324. #endregion
  5325. }
  5326. #endregion
  5327. #region RendererPosPassThru
  5328. [ComVisible(false)]
  5329. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  5330. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  5331. [ClassInterface(ClassInterfaceType.None)]
  5332. public class RendererPosPassThru : PosPassThru
  5333. {
  5334. #region Variables
  5335. private object m_PositionLock = new object();
  5336. private long m_StartMedia = 0;
  5337. private long m_EndMedia = 0;
  5338. private bool m_bReset = true;
  5339. #endregion
  5340. #region Constructor
  5341. public RendererPosPassThru(ref HRESULT hr, IntPtr pPin)
  5342. : base(ref hr, pPin)
  5343. {
  5344. }
  5345. #endregion
  5346. #region Methods
  5347. public int RegisterMediaTime(ref IMediaSampleImpl _sample)
  5348. {
  5349. long StartMedia;
  5350. long EndMedia;
  5351. lock (m_PositionLock)
  5352. {
  5353. // Get the media times from the sample
  5354. int hr = _sample.GetTime(out StartMedia, out EndMedia);
  5355. if (FAILED(hr))
  5356. {
  5357. ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET);
  5358. return hr;
  5359. }
  5360. return RegisterMediaTime(StartMedia, EndMedia);
  5361. }
  5362. }
  5363. public int RegisterMediaTime(long StartTime, long EndTime)
  5364. {
  5365. lock (m_PositionLock)
  5366. {
  5367. m_StartMedia = StartTime;
  5368. m_EndMedia = EndTime;
  5369. m_bReset = false;
  5370. return NOERROR;
  5371. }
  5372. }
  5373. public override HRESULT GetMediaTime(out long pStartTime, out long pEndTime)
  5374. {
  5375. lock (m_PositionLock)
  5376. {
  5377. pStartTime = 0;
  5378. pEndTime = 0;
  5379. if (m_bReset == true)
  5380. {
  5381. return E_FAIL;
  5382. }
  5383. // We don't have to return the end time
  5384. int hr = ConvertTimeFormat(out pStartTime, DsGuid.Empty, m_StartMedia, (DsGuid)(TimeFormat.MediaTime));
  5385. if (SUCCEEDED(hr))
  5386. {
  5387. hr = ConvertTimeFormat(out pEndTime, DsGuid.Empty, m_EndMedia, (DsGuid)(TimeFormat.MediaTime));
  5388. }
  5389. return (HRESULT)hr;
  5390. }
  5391. }
  5392. public int ResetMediaTime()
  5393. {
  5394. lock (m_PositionLock)
  5395. {
  5396. m_StartMedia = 0;
  5397. m_EndMedia = 0;
  5398. m_bReset = true;
  5399. ResetSeeking();
  5400. return NOERROR;
  5401. }
  5402. }
  5403. public int EOS()
  5404. {
  5405. int hr;
  5406. if (m_bReset == true) hr = E_FAIL;
  5407. else
  5408. {
  5409. long llStop;
  5410. if (SUCCEEDED(hr = GetStopPosition(out llStop)))
  5411. {
  5412. lock (m_PositionLock)
  5413. {
  5414. m_StartMedia =
  5415. m_EndMedia = llStop;
  5416. }
  5417. }
  5418. }
  5419. return hr;
  5420. }
  5421. #endregion
  5422. }
  5423. #endregion
  5424. #region Base Renderer Pin
  5425. [ComVisible(false)]
  5426. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  5427. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  5428. [ClassInterface(ClassInterfaceType.None)]
  5429. public class RendererInputPin : BaseInputPin
  5430. {
  5431. #region Constructor
  5432. public RendererInputPin(string _name, BaseRendererFilter _filter)
  5433. : base(_name, _filter)
  5434. {
  5435. }
  5436. #endregion
  5437. #region Overridden Methods
  5438. public override int Active()
  5439. {
  5440. return ((BaseRendererFilter)m_Filter).Active();
  5441. }
  5442. public override int Inactive()
  5443. {
  5444. m_bRunTimeError = false;
  5445. return ((BaseRendererFilter)m_Filter).Inactive();
  5446. }
  5447. public override int BreakConnect()
  5448. {
  5449. int hr = ((BaseRendererFilter)m_Filter).BreakConnect();
  5450. if (FAILED(hr))
  5451. {
  5452. return hr;
  5453. }
  5454. return base.BreakConnect();
  5455. }
  5456. public override int CompleteConnect(ref IPinImpl pReceivePin)
  5457. {
  5458. int hr = (m_Filter as BaseRendererFilter).CompleteConnect(ref pReceivePin);
  5459. if (FAILED(hr))
  5460. {
  5461. return hr;
  5462. }
  5463. return base.CompleteConnect(ref pReceivePin);
  5464. }
  5465. public override int CheckMediaType(AMMediaType pmt)
  5466. {
  5467. return (m_Filter as BaseRendererFilter).CheckMediaType(pmt);
  5468. }
  5469. public override int SetMediaType(AMMediaType mt)
  5470. {
  5471. int hr = base.SetMediaType(mt);
  5472. if (FAILED(hr))
  5473. {
  5474. return hr;
  5475. }
  5476. return (m_Filter as BaseRendererFilter).SetMediaType(mt);
  5477. }
  5478. public override int EndOfStream()
  5479. {
  5480. BaseRendererFilter _filter = (m_Filter as BaseRendererFilter);
  5481. lock (_filter.FilterLock)
  5482. {
  5483. lock (_filter.RendererLock)
  5484. {
  5485. int hr = CheckStreaming();
  5486. if (hr != NOERROR)
  5487. {
  5488. return hr;
  5489. }
  5490. hr = _filter.EndOfStream();
  5491. if (SUCCEEDED(hr))
  5492. {
  5493. hr = base.EndOfStream();
  5494. }
  5495. return hr;
  5496. }
  5497. }
  5498. }
  5499. public override int BeginFlush()
  5500. {
  5501. BaseRendererFilter _filter = (m_Filter as BaseRendererFilter);
  5502. lock (_filter.FilterLock)
  5503. {
  5504. lock (_filter.RendererLock)
  5505. {
  5506. base.BeginFlush();
  5507. _filter.BeginFlush();
  5508. }
  5509. }
  5510. return _filter.ResetEndOfStream();
  5511. }
  5512. public override int EndFlush()
  5513. {
  5514. BaseRendererFilter _filter = (m_Filter as BaseRendererFilter);
  5515. lock (_filter.FilterLock)
  5516. {
  5517. lock (_filter.RendererLock)
  5518. {
  5519. int hr = _filter.EndFlush();
  5520. if (SUCCEEDED(hr))
  5521. {
  5522. hr = base.EndFlush();
  5523. }
  5524. return hr;
  5525. }
  5526. }
  5527. }
  5528. public override int OnReceive(ref IMediaSampleImpl pSample)
  5529. {
  5530. BaseRendererFilter _filter = (m_Filter as BaseRendererFilter);
  5531. int hr = _filter.OnReceive(ref pSample);
  5532. if (FAILED(hr))
  5533. {
  5534. lock (_filter.FilterLock)
  5535. {
  5536. if (!IsStopped && !IsFlushing && !_filter.IsAbort && !m_bRunTimeError)
  5537. {
  5538. _filter.NotifyEvent(EventCode.ErrorAbort, (IntPtr)hr, IntPtr.Zero);
  5539. lock (_filter.RendererLock)
  5540. {
  5541. if (_filter.IsStreaming && !_filter.IsEndOfStreamDelivered)
  5542. {
  5543. _filter.NotifyEndOfStream();
  5544. }
  5545. }
  5546. m_bRunTimeError = true;
  5547. }
  5548. }
  5549. }
  5550. return hr;
  5551. }
  5552. #endregion
  5553. #region Helper Methods
  5554. public int BaseReceive(ref IMediaSampleImpl pMediaSample)
  5555. {
  5556. return base.OnReceive(ref pMediaSample);
  5557. }
  5558. #endregion
  5559. }
  5560. #endregion
  5561. #region MessageDispatcher
  5562. [ComVisible(false)]
  5563. [ClassInterface(ClassInterfaceType.None)]
  5564. public class MessageDispatcher : IMessageFilter, IDisposable
  5565. {
  5566. #region Constants
  5567. private const string s_Message = "AMUnblock";
  5568. #endregion
  5569. #region Variables
  5570. protected int m_iMessage = 0;
  5571. protected bool m_bDisposed = false;
  5572. protected EventWaitHandle m_hAbort = null;
  5573. #endregion
  5574. #region Constructor
  5575. public MessageDispatcher(EventWaitHandle hAbort)
  5576. : this(hAbort, s_Message)
  5577. {
  5578. }
  5579. public MessageDispatcher(EventWaitHandle hAbort, string _message)
  5580. : this(hAbort, (int)RegisterWindowMessage(_message))
  5581. {
  5582. }
  5583. public MessageDispatcher(EventWaitHandle hAbort, int _message)
  5584. {
  5585. m_bDisposed = (hAbort == null);
  5586. if (!m_bDisposed)
  5587. {
  5588. m_iMessage = _message;
  5589. m_hAbort = hAbort;
  5590. Application.RegisterMessageLoop(this.MessageLoopCallback);
  5591. Application.AddMessageFilter(this);
  5592. }
  5593. }
  5594. ~MessageDispatcher()
  5595. {
  5596. Dispose();
  5597. }
  5598. #endregion
  5599. #region Methods
  5600. public bool MessageLoopCallback()
  5601. {
  5602. return !m_bDisposed;
  5603. }
  5604. #endregion
  5605. #region IMessageFilter Members
  5606. public bool PreFilterMessage(ref Message m)
  5607. {
  5608. if (!m_bDisposed)
  5609. {
  5610. if (m.Msg == m_iMessage)
  5611. {
  5612. m_hAbort.Set();
  5613. return true;
  5614. }
  5615. }
  5616. return false;
  5617. }
  5618. #endregion
  5619. #region IDisposable Members
  5620. public void Dispose()
  5621. {
  5622. if (!m_bDisposed)
  5623. {
  5624. m_bDisposed = true;
  5625. Application.RemoveMessageFilter(this);
  5626. }
  5627. }
  5628. #endregion
  5629. #region API
  5630. [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "RegisterWindowMessageW")]
  5631. private static extern uint RegisterWindowMessage([In, MarshalAs(UnmanagedType.LPWStr)] string lpString);
  5632. #endregion
  5633. }
  5634. #endregion
  5635. #region Base Renderer Filter
  5636. [ComVisible(false)]
  5637. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  5638. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  5639. [ClassInterface(ClassInterfaceType.None)]
  5640. public abstract class BaseRendererFilter : BaseFilter, IMediaSeeking
  5641. {
  5642. #region Constants
  5643. private const int TIMEOUT_DELIVERYWAIT = 50;
  5644. private const int TIMEOUT_RESOLUTION = 10;
  5645. private const int RENDER_TIMEOUT = 10000;
  5646. #endregion
  5647. #region Variables
  5648. private MessageDispatcher m_MessageDispatcher = null;
  5649. protected object m_RendererLock = new object();
  5650. protected bool m_bAbort = false;
  5651. protected bool m_bStreaming = false;
  5652. protected bool m_bEOS = false;
  5653. protected bool m_bEOSDelivered = false;
  5654. protected AutoResetEvent m_RenderEvent = new AutoResetEvent(false);
  5655. protected ManualResetEvent m_ThreadSignal = new ManualResetEvent(false);
  5656. protected ManualResetEvent m_evComplete = new ManualResetEvent(false);
  5657. protected ManualResetEvent m_evAbort = new ManualResetEvent(false);
  5658. protected ManualResetEvent m_evClear = new ManualResetEvent(true);
  5659. protected int m_dwAdvise = 0;
  5660. protected RendererPosPassThru m_pPosition = null;
  5661. protected IMediaSampleImpl m_pMediaSample = null;
  5662. protected bool m_bRepaintStatus = true;
  5663. protected long m_SignalTime = 0;
  5664. protected System.Threading.Timer m_EndOfStreamTimer = null;
  5665. #endregion
  5666. #region Constructor
  5667. public BaseRendererFilter(string _name)
  5668. : base(_name)
  5669. {
  5670. Ready();
  5671. }
  5672. ~BaseRendererFilter()
  5673. {
  5674. ASSERT(m_bStreaming == false);
  5675. ASSERT(m_EndOfStreamTimer == null);
  5676. StopStreaming();
  5677. ClearPendingSample();
  5678. if (m_EndOfStreamTimer != null)
  5679. {
  5680. m_EndOfStreamTimer.Dispose();
  5681. m_EndOfStreamTimer = null;
  5682. }
  5683. m_pPosition = null;
  5684. }
  5685. #endregion
  5686. #region Properties
  5687. public bool IsAbort
  5688. {
  5689. get { return m_bAbort; }
  5690. set { m_bAbort = value; }
  5691. }
  5692. public object RendererLock
  5693. {
  5694. get { return m_RendererLock; }
  5695. }
  5696. public bool IsStreaming
  5697. {
  5698. get { return m_bStreaming; }
  5699. }
  5700. public bool IsEndOfStreamDelivered
  5701. {
  5702. get { return m_bEOSDelivered; }
  5703. }
  5704. public bool IsEndOfStream
  5705. {
  5706. get { return m_bEOS; }
  5707. }
  5708. public RendererInputPin InputPin
  5709. {
  5710. get
  5711. {
  5712. if (Pins.Count >= 1)
  5713. {
  5714. return (RendererInputPin)Pins[0];
  5715. }
  5716. return null;
  5717. }
  5718. }
  5719. public EventWaitHandle RenderEvent
  5720. {
  5721. get { return m_RenderEvent; }
  5722. }
  5723. public bool IsReady
  5724. {
  5725. get { return m_evComplete.WaitOne(0, false); }
  5726. }
  5727. public FilterState RealState
  5728. {
  5729. get { return m_State; }
  5730. }
  5731. protected bool RepaintStatus
  5732. {
  5733. get { return m_bRepaintStatus; }
  5734. set
  5735. {
  5736. lock (m_RendererLock)
  5737. {
  5738. if (m_bRepaintStatus != value)
  5739. {
  5740. m_bRepaintStatus = value;
  5741. OnRepaintStatusChanged(value);
  5742. }
  5743. }
  5744. }
  5745. }
  5746. protected RendererPosPassThru Position
  5747. {
  5748. get
  5749. {
  5750. if (m_pPosition == null)
  5751. {
  5752. lock (m_Lock)
  5753. {
  5754. HRESULT hr = NOERROR;
  5755. IntPtr _pin = Marshal.GetComInterfaceForObject(InputPin, typeof(IPin));
  5756. m_pPosition = new RendererPosPassThru(ref hr, _pin);
  5757. Marshal.Release(_pin);
  5758. if (FAILED(hr))
  5759. {
  5760. m_pPosition = null;
  5761. }
  5762. }
  5763. }
  5764. return m_pPosition;
  5765. }
  5766. }
  5767. protected virtual bool HaveCurrentSample
  5768. {
  5769. get
  5770. {
  5771. lock (m_RendererLock)
  5772. {
  5773. return (m_pMediaSample == null ? false : true);
  5774. }
  5775. }
  5776. }
  5777. #endregion
  5778. #region Abstract Methods
  5779. public abstract int DoRenderSample(ref IMediaSampleImpl pMediaSample);
  5780. public abstract int CheckMediaType(AMMediaType pmt);
  5781. #endregion
  5782. #region Virtual Methods
  5783. public virtual int Active()
  5784. {
  5785. return NOERROR;
  5786. }
  5787. public virtual int Inactive()
  5788. {
  5789. if (Position != null)
  5790. {
  5791. Position.ResetMediaTime();
  5792. }
  5793. // People who derive from this may want to override this behaviour
  5794. // to keep hold of the sample in some circumstances
  5795. ClearPendingSample();
  5796. return NOERROR;
  5797. }
  5798. public virtual int BeginFlush()
  5799. {
  5800. if (m_State == FilterState.Paused)
  5801. {
  5802. NotReady();
  5803. }
  5804. SourceThreadCanWait(false);
  5805. CancelNotification();
  5806. ClearPendingSample();
  5807. // Wait for Receive to complete
  5808. WaitForReceiveToComplete();
  5809. return NOERROR;
  5810. }
  5811. public virtual int EndFlush()
  5812. {
  5813. if (Position != null)
  5814. {
  5815. Position.ResetMediaTime();
  5816. }
  5817. // There should be no outstanding advise
  5818. int hr = CancelNotification();
  5819. ASSERT(hr == S_FALSE);
  5820. SourceThreadCanWait(true);
  5821. return NOERROR;
  5822. }
  5823. public virtual int EndOfStream()
  5824. {
  5825. if (m_State == FilterState.Stopped)
  5826. {
  5827. return NOERROR;
  5828. }
  5829. // If we have a sample then wait for it to be rendered
  5830. m_bEOS = true;
  5831. if (m_pMediaSample != null)
  5832. {
  5833. return NOERROR;
  5834. }
  5835. // If we are waiting for pause then we are now ready since we cannot now
  5836. // carry on waiting for a sample to arrive since we are being told there
  5837. // won't be any. This sets an event that the GetState function picks up
  5838. Ready();
  5839. // Only signal completion now if we are running otherwise queue it until
  5840. // we do run in StartStreaming. This is used when we seek because a seek
  5841. // causes a pause where early notification of completion is misleading
  5842. if (m_bStreaming)
  5843. {
  5844. SendEndOfStream();
  5845. }
  5846. return NOERROR;
  5847. }
  5848. public virtual int ResetEndOfStream()
  5849. {
  5850. ResetEndOfStreamTimer();
  5851. lock (m_RendererLock)
  5852. {
  5853. m_bEOS = false;
  5854. m_bEOSDelivered = false;
  5855. m_SignalTime = 0;
  5856. return NOERROR;
  5857. }
  5858. }
  5859. public virtual int NotifyEndOfStream()
  5860. {
  5861. lock (m_RendererLock)
  5862. {
  5863. ASSERT(m_bEOSDelivered == false);
  5864. ASSERT(m_EndOfStreamTimer == null);
  5865. // Has the filter changed state
  5866. if (m_bStreaming == false)
  5867. {
  5868. ASSERT(m_EndOfStreamTimer == null);
  5869. return NOERROR;
  5870. }
  5871. // Reset the end of stream timer
  5872. if (m_EndOfStreamTimer != null)
  5873. {
  5874. m_EndOfStreamTimer.Dispose();
  5875. m_EndOfStreamTimer = null;
  5876. }
  5877. if (Position != null)
  5878. {
  5879. Position.EOS();
  5880. }
  5881. m_bEOSDelivered = true;
  5882. return NotifyEvent(EventCode.Complete, (IntPtr)((int)S_OK), Marshal.GetIUnknownForObject(this));
  5883. }
  5884. }
  5885. public virtual int SendEndOfStream()
  5886. {
  5887. if (m_bEOS == false || m_bEOSDelivered || m_EndOfStreamTimer != null)
  5888. {
  5889. return NOERROR;
  5890. }
  5891. // If there is no clock then signal immediately
  5892. if (m_pClock == IntPtr.Zero)
  5893. {
  5894. return NotifyEndOfStream();
  5895. }
  5896. // How long into the future is the delivery time
  5897. long Signal = m_tStart + m_SignalTime;
  5898. long CurrentTime;
  5899. Clock.GetTime(out CurrentTime);
  5900. int Delay = (int)((Signal - CurrentTime) / 10000);
  5901. // Wait for the delivery time to arrive
  5902. if (Delay < TIMEOUT_DELIVERYWAIT)
  5903. {
  5904. return NotifyEndOfStream();
  5905. }
  5906. // Signal a timer callback on another worker thread
  5907. m_EndOfStreamTimer = new System.Threading.Timer(new TimerCallback(TimerCallbackProc));
  5908. if (!m_EndOfStreamTimer.Change(Delay, Timeout.Infinite))
  5909. {
  5910. return NotifyEndOfStream();
  5911. }
  5912. return NOERROR;
  5913. }
  5914. public virtual int BreakConnect()
  5915. {
  5916. // Check we have a valid connection
  5917. if (InputPin.IsConnected == false)
  5918. {
  5919. return S_FALSE;
  5920. }
  5921. // Check we are stopped before disconnecting
  5922. if (m_State != FilterState.Stopped && !InputPin.CanReconnectWhenActive)
  5923. {
  5924. return VFW_E_NOT_STOPPED;
  5925. }
  5926. RepaintStatus = false;
  5927. ResetEndOfStream();
  5928. ClearPendingSample();
  5929. m_bAbort = false;
  5930. if (FilterState.Running == m_State)
  5931. {
  5932. StopStreaming();
  5933. }
  5934. m_pPosition = null;
  5935. return NOERROR;
  5936. }
  5937. public virtual int CompleteConnect(ref IPinImpl pReceivePin)
  5938. {
  5939. m_bAbort = false;
  5940. if (FilterState.Running == RealState)
  5941. {
  5942. int hr = StartStreaming();
  5943. if (FAILED(hr))
  5944. {
  5945. return hr;
  5946. }
  5947. RepaintStatus = false;
  5948. }
  5949. else
  5950. {
  5951. RepaintStatus = true;
  5952. }
  5953. return NOERROR;
  5954. }
  5955. public virtual int SetMediaType(AMMediaType mt)
  5956. {
  5957. return NOERROR;
  5958. }
  5959. public virtual int OnReceive(ref IMediaSampleImpl pSample)
  5960. {
  5961. ASSERT(pSample != null);
  5962. // It may return VFW_E_SAMPLE_REJECTED code to say don't bother
  5963. int hr = PrepareReceive(ref pSample);
  5964. if (hr != S_OK)
  5965. {
  5966. if (hr == VFW_E_SAMPLE_REJECTED)
  5967. {
  5968. return NOERROR;
  5969. }
  5970. return hr;
  5971. }
  5972. // We realize the palette in "PrepareRender()" so we have to give away the
  5973. // filter lock here.
  5974. if (m_State == FilterState.Paused)
  5975. {
  5976. PrepareRender();
  5977. // no need to use InterlockedExchange
  5978. m_evClear.Set();
  5979. {
  5980. // We must hold both these locks
  5981. lock (m_Lock)
  5982. {
  5983. if (m_State == FilterState.Stopped)
  5984. return NOERROR;
  5985. m_evClear.Reset();
  5986. lock (m_RendererLock)
  5987. {
  5988. OnReceiveFirstSample(ref pSample);
  5989. }
  5990. }
  5991. }
  5992. Ready();
  5993. }
  5994. // Having set an advise link with the clock we sit and wait. We may be
  5995. // awoken by the clock firing or by a state change. The rendering call
  5996. // will lock the critical section and check we can still render the data
  5997. hr = WaitForRenderTime();
  5998. if (FAILED(hr))
  5999. {
  6000. m_evClear.Set();
  6001. return NOERROR;
  6002. }
  6003. PrepareRender();
  6004. // Set this here and poll it until we work out the locking correctly
  6005. // It can't be right that the streaming stuff grabs the interface
  6006. // lock - after all we want to be able to wait for this stuff
  6007. // to complete
  6008. m_evClear.Set();
  6009. // We must hold both these locks
  6010. lock (m_Lock)
  6011. {
  6012. // since we gave away the filter wide lock, the sate of the filter could
  6013. // have chnaged to Stopped
  6014. if (m_State == FilterState.Stopped)
  6015. return NOERROR;
  6016. lock (m_RendererLock)
  6017. {
  6018. // Deal with this sample
  6019. Render(ref m_pMediaSample);
  6020. ClearPendingSample();
  6021. SendEndOfStream();
  6022. CancelNotification();
  6023. return NOERROR;
  6024. }
  6025. }
  6026. }
  6027. public virtual int PrepareReceive(ref IMediaSampleImpl pMediaSample)
  6028. {
  6029. lock (m_Lock)
  6030. {
  6031. m_evClear.Reset();
  6032. // Check our flushing and filter state
  6033. // This function must hold the interface lock because it calls
  6034. // CBaseInputPin::Receive() and CBaseInputPin::Receive() uses
  6035. // CBasePin::m_bRunTimeError.
  6036. int hr = InputPin.BaseReceive(ref pMediaSample);
  6037. if (hr != NOERROR)
  6038. {
  6039. m_evClear.Set();
  6040. return E_FAIL;
  6041. }
  6042. // Has the type changed on a media sample. We do all rendering
  6043. // synchronously on the source thread, which has a side effect
  6044. // that only one buffer is ever outstanding. Therefore when we
  6045. // have Receive called we can go ahead and change the format
  6046. // Since the format change can cause a SendMessage we just don't
  6047. // lock
  6048. if (InputPin.SampleProps.pMediaType != IntPtr.Zero)
  6049. {
  6050. AMMediaType mt = (AMMediaType)Marshal.PtrToStructure(InputPin.SampleProps.pMediaType, typeof(AMMediaType));
  6051. hr = InputPin.SetMediaType(mt);
  6052. if (FAILED(hr))
  6053. {
  6054. m_evClear.Set();
  6055. return hr;
  6056. }
  6057. }
  6058. lock (m_RendererLock)
  6059. {
  6060. ASSERT(IsActive == true);
  6061. ASSERT(InputPin.IsFlushing == false);
  6062. ASSERT(InputPin.IsConnected == true);
  6063. ASSERT(m_pMediaSample == null);
  6064. // Return an error if we already have a sample waiting for rendering
  6065. // source pins must serialise the Receive calls - we also check that
  6066. // no data is being sent after the source signalled an end of stream
  6067. if (m_pMediaSample != null || m_bEOS || m_bAbort)
  6068. {
  6069. Ready();
  6070. m_evClear.Set();
  6071. return E_UNEXPECTED;
  6072. }
  6073. // Store the media times from this sample
  6074. if (Position != null)
  6075. {
  6076. Position.RegisterMediaTime(ref pMediaSample);
  6077. }
  6078. // Schedule the next sample if we are streaming
  6079. if ((m_bStreaming == true) && (ScheduleSample(ref pMediaSample) == false))
  6080. {
  6081. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6082. ASSERT(CancelNotification() == S_FALSE);
  6083. m_evClear.Set();
  6084. return VFW_E_SAMPLE_REJECTED;
  6085. }
  6086. // Store the sample end time for EC_COMPLETE handling
  6087. m_SignalTime = InputPin.SampleProps.tStop;
  6088. // BEWARE we sometimes keep the sample even after returning the thread to
  6089. // the source filter such as when we go into a stopped state (we keep it
  6090. // to refresh the device with) so we must AddRef it to keep it safely. If
  6091. // we start flushing the source thread is released and any sample waiting
  6092. // will be released otherwise GetBuffer may never return (see BeginFlush)
  6093. m_pMediaSample = pMediaSample;
  6094. m_pMediaSample._AddRef();
  6095. if (m_bStreaming == false)
  6096. {
  6097. RepaintStatus = true;
  6098. }
  6099. return NOERROR;
  6100. }
  6101. }
  6102. }
  6103. public virtual IMediaSampleImpl GetCurrentSample()
  6104. {
  6105. lock (m_RendererLock)
  6106. {
  6107. if (m_pMediaSample != null)
  6108. {
  6109. m_pMediaSample._AddRef();
  6110. }
  6111. return m_pMediaSample;
  6112. }
  6113. }
  6114. public virtual int Render(ref IMediaSampleImpl pMediaSample)
  6115. {
  6116. if (pMediaSample == null || m_bStreaming == false)
  6117. {
  6118. return S_FALSE;
  6119. }
  6120. OnRenderStart(ref pMediaSample);
  6121. int hr = DoRenderSample(ref pMediaSample);
  6122. OnRenderEnd(ref pMediaSample);
  6123. return hr;
  6124. }
  6125. public virtual int SourceThreadCanWait(bool bCanWait)
  6126. {
  6127. if (bCanWait == true)
  6128. {
  6129. m_ThreadSignal.Reset();
  6130. }
  6131. else
  6132. {
  6133. m_ThreadSignal.Set();
  6134. }
  6135. return NOERROR;
  6136. }
  6137. public virtual int WaitForRenderTime()
  6138. {
  6139. WaitHandle[] WaitObjects = new WaitHandle[] { m_ThreadSignal, m_RenderEvent };
  6140. int Result = WaitHandle.WaitTimeout;
  6141. // Wait for either the time to arrive or for us to be stopped
  6142. OnWaitStart();
  6143. while (Result == WaitHandle.WaitTimeout)
  6144. {
  6145. Result = WaitHandle.WaitAny(WaitObjects, RENDER_TIMEOUT, false);
  6146. }
  6147. OnWaitEnd();
  6148. // We may have been awoken without the timer firing
  6149. if (Result == 0)
  6150. {
  6151. return VFW_E_STATE_CHANGED;
  6152. }
  6153. SignalTimerFired();
  6154. return NOERROR;
  6155. }
  6156. public virtual int CompleteStateChange(FilterState OldState)
  6157. {
  6158. if (InputPin.IsConnected == false)
  6159. {
  6160. Ready();
  6161. return S_OK;
  6162. }
  6163. // Have we run off the end of stream
  6164. if (IsEndOfStream == true)
  6165. {
  6166. Ready();
  6167. return S_OK;
  6168. }
  6169. // Make sure we get fresh data after being stopped
  6170. if (HaveCurrentSample)
  6171. {
  6172. if (OldState != FilterState.Stopped)
  6173. {
  6174. Ready();
  6175. return S_OK;
  6176. }
  6177. }
  6178. NotReady();
  6179. return S_FALSE;
  6180. }
  6181. public virtual bool ScheduleSample(ref IMediaSampleImpl pMediaSample)
  6182. {
  6183. long StartSample, EndSample;
  6184. // Is someone pulling our leg
  6185. if (pMediaSample == null)
  6186. {
  6187. return false;
  6188. }
  6189. // Get the next sample due up for rendering. If there aren't any ready
  6190. // then GetNextSampleTimes returns an error. If there is one to be done
  6191. // then it succeeds and yields the sample times. If it is due now then
  6192. // it returns S_OK other if it's to be done when due it returns S_FALSE
  6193. int hr = GetSampleTimes(ref pMediaSample, out StartSample, out EndSample);
  6194. if (FAILED(hr))
  6195. {
  6196. return false;
  6197. }
  6198. // If we don't have a reference clock then we cannot set up the advise
  6199. // time so we simply set the event indicating an image to render. This
  6200. // will cause us to run flat out without any timing or synchronisation
  6201. if (hr == S_OK)
  6202. {
  6203. m_RenderEvent.Set();
  6204. return true;
  6205. }
  6206. ASSERT(m_dwAdvise == 0);
  6207. ASSERT(m_pClock != IntPtr.Zero);
  6208. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6209. // We do have a valid reference clock interface so we can ask it to
  6210. // set an event when the image comes due for rendering. We pass in
  6211. // the reference time we were told to start at and also the current
  6212. // stream time which is the offset from the start reference time
  6213. long lTemp;
  6214. Clock.GetTime(out lTemp);
  6215. hr = Clock.AdviseTime(
  6216. m_tStart, // Start run time
  6217. StartSample, // Stream time
  6218. m_RenderEvent.SafeWaitHandle.DangerousGetHandle(), // Render notification
  6219. out m_dwAdvise); // Advise cookie
  6220. if (SUCCEEDED(hr))
  6221. {
  6222. return true;
  6223. }
  6224. // We could not schedule the next sample for rendering despite the fact
  6225. // we have a valid sample here. This is a fair indication that either
  6226. // the system clock is wrong or the time stamp for the sample is duff
  6227. ASSERT(m_dwAdvise == 0);
  6228. return false;
  6229. }
  6230. public virtual int GetSampleTimes(ref IMediaSampleImpl pMediaSample,
  6231. out long pStartTime,
  6232. out long pEndTime)
  6233. {
  6234. ASSERT(m_dwAdvise == 0);
  6235. ASSERT(pMediaSample != null);
  6236. // If the stop time for this sample is before or the same as start time,
  6237. // then just ignore it (release it) and schedule the next one in line
  6238. // Source filters should always fill in the start and end times properly!
  6239. if (SUCCEEDED(pMediaSample.GetTime(out pStartTime, out pEndTime)))
  6240. {
  6241. if (pEndTime < pStartTime)
  6242. {
  6243. return VFW_E_START_TIME_AFTER_END;
  6244. }
  6245. }
  6246. else
  6247. {
  6248. // no time set in the sample... draw it now?
  6249. return S_OK;
  6250. }
  6251. // Can't synchronise without a clock so we return S_OK which tells the
  6252. // caller that the sample should be rendered immediately without going
  6253. // through the overhead of setting a timer advise link with the clock
  6254. if (m_pClock == IntPtr.Zero)
  6255. {
  6256. return S_OK;
  6257. }
  6258. return ShouldDrawSampleNow(ref pMediaSample, ref pStartTime, ref pEndTime);
  6259. }
  6260. public virtual void SignalTimerFired()
  6261. {
  6262. m_dwAdvise = 0;
  6263. }
  6264. public virtual int CancelNotification()
  6265. {
  6266. int dwAdvise = m_dwAdvise;
  6267. // Have we a live advise link
  6268. if (m_dwAdvise != 0)
  6269. {
  6270. Clock.Unadvise(m_dwAdvise);
  6271. SignalTimerFired();
  6272. }
  6273. // Clear the event and return our status
  6274. m_RenderEvent.Reset();
  6275. return (dwAdvise != 0 ? S_OK : S_FALSE);
  6276. }
  6277. public virtual int ClearPendingSample()
  6278. {
  6279. lock (m_RendererLock)
  6280. {
  6281. if (m_pMediaSample != null)
  6282. {
  6283. m_pMediaSample._Release();
  6284. m_pMediaSample = null;
  6285. }
  6286. return NOERROR;
  6287. }
  6288. }
  6289. public virtual int StartStreaming()
  6290. {
  6291. lock (m_RendererLock)
  6292. {
  6293. if (m_bStreaming == true)
  6294. {
  6295. return NOERROR;
  6296. }
  6297. // Reset the streaming times ready for running
  6298. m_bStreaming = true;
  6299. OnStartStreaming();
  6300. // There should be no outstanding advise
  6301. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6302. ASSERT(CancelNotification() == S_FALSE);
  6303. // If we have an EOS and no data then deliver it now
  6304. if (m_pMediaSample == null)
  6305. {
  6306. return SendEndOfStream();
  6307. }
  6308. // Have the data rendered
  6309. ASSERT(m_pMediaSample != null);
  6310. if (!ScheduleSample(ref m_pMediaSample))
  6311. {
  6312. m_RenderEvent.Set();
  6313. }
  6314. return NOERROR;
  6315. }
  6316. }
  6317. public virtual int StopStreaming()
  6318. {
  6319. lock (m_RendererLock)
  6320. {
  6321. m_bEOSDelivered = false;
  6322. if (m_bStreaming == true)
  6323. {
  6324. m_bStreaming = false;
  6325. OnStopStreaming();
  6326. }
  6327. return NOERROR;
  6328. }
  6329. }
  6330. #endregion
  6331. #region Other Methods To Override
  6332. public virtual void OnReceiveFirstSample(ref IMediaSampleImpl pMediaSample)
  6333. {
  6334. }
  6335. public virtual void OnRenderStart(ref IMediaSampleImpl pMediaSample)
  6336. {
  6337. }
  6338. public virtual void OnRenderEnd(ref IMediaSampleImpl pMediaSample)
  6339. {
  6340. }
  6341. public virtual int OnStartStreaming()
  6342. {
  6343. return NOERROR;
  6344. }
  6345. public virtual int OnStopStreaming()
  6346. {
  6347. return NOERROR;
  6348. }
  6349. public virtual void OnWaitStart()
  6350. {
  6351. }
  6352. public virtual void OnWaitEnd()
  6353. {
  6354. }
  6355. public virtual void OnRepaintStatusChanged(bool bRepaint)
  6356. {
  6357. }
  6358. public virtual void PrepareRender()
  6359. {
  6360. }
  6361. public virtual int ShouldDrawSampleNow(ref IMediaSampleImpl pMediaSample,
  6362. ref long ptrStart,
  6363. ref long ptrEnd)
  6364. {
  6365. return S_FALSE;
  6366. }
  6367. #endregion
  6368. #region Overridden Methods
  6369. protected override int OnInitializePins()
  6370. {
  6371. AddPin(new RendererInputPin("In", this));
  6372. return NOERROR;
  6373. }
  6374. public override int Stop()
  6375. {
  6376. lock (m_Lock)
  6377. {
  6378. // Make sure there really is a state change
  6379. if (m_State == FilterState.Stopped)
  6380. {
  6381. return NOERROR;
  6382. }
  6383. // Is our input pin connected
  6384. if (InputPin.IsConnected == false)
  6385. {
  6386. TRACE("Input pin is not connected");
  6387. m_State = FilterState.Stopped;
  6388. return NOERROR;
  6389. }
  6390. base.Stop();
  6391. // If we are going into a stopped state then we must decommit whatever
  6392. // allocator we are using it so that any source filter waiting in the
  6393. // GetBuffer can be released and unlock themselves for a state change
  6394. if (InputPin.Allocator != null)
  6395. {
  6396. InputPin.Allocator.Decommit();
  6397. }
  6398. // Cancel any scheduled rendering
  6399. RepaintStatus = true;
  6400. StopStreaming();
  6401. SourceThreadCanWait(false);
  6402. ResetEndOfStream();
  6403. CancelNotification();
  6404. // There should be no outstanding clock advise
  6405. ASSERT(CancelNotification() == S_FALSE);
  6406. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6407. ASSERT(m_EndOfStreamTimer == null);
  6408. Ready();
  6409. WaitForReceiveToComplete();
  6410. m_bAbort = false;
  6411. return NOERROR;
  6412. }
  6413. }
  6414. public override int Pause()
  6415. {
  6416. lock (m_Lock)
  6417. {
  6418. FilterState OldState = m_State;
  6419. ASSERT(InputPin.IsFlushing == false);
  6420. if (m_State == FilterState.Stopped)
  6421. {
  6422. m_evAbort.Reset();
  6423. }
  6424. // Make sure there really is a state change
  6425. if (m_State == FilterState.Paused)
  6426. {
  6427. return CompleteStateChange(FilterState.Paused);
  6428. }
  6429. // Has our input pin been connected
  6430. if (InputPin.IsConnected == false)
  6431. {
  6432. m_State = FilterState.Paused;
  6433. return CompleteStateChange(FilterState.Paused);
  6434. }
  6435. // Pause the base filter class
  6436. int hr = base.Pause();
  6437. if (FAILED(hr))
  6438. {
  6439. TRACE("Pause failed");
  6440. return hr;
  6441. }
  6442. // Enable EC_REPAINT events again
  6443. RepaintStatus = true;
  6444. StopStreaming();
  6445. SourceThreadCanWait(true);
  6446. CancelNotification();
  6447. ResetEndOfStreamTimer();
  6448. // If we are going into a paused state then we must commit whatever
  6449. // allocator we are using it so that any source filter can call the
  6450. // GetBuffer and expect to get a buffer without returning an error
  6451. if (InputPin.Allocator != null)
  6452. {
  6453. InputPin.Allocator.Commit();
  6454. }
  6455. // There should be no outstanding advise
  6456. ASSERT(CancelNotification() == S_FALSE);
  6457. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6458. ASSERT(m_EndOfStreamTimer == null);
  6459. ASSERT(InputPin.IsFlushing == false);
  6460. // When we come out of a stopped state we must clear any image we were
  6461. // holding onto for frame refreshing. Since renderers see state changes
  6462. // first we can reset ourselves ready to accept the source thread data
  6463. // Paused or running after being stopped causes the current position to
  6464. // be reset so we're not interested in passing end of stream signals
  6465. if (OldState == FilterState.Stopped)
  6466. {
  6467. m_bAbort = false;
  6468. ClearPendingSample();
  6469. }
  6470. return CompleteStateChange(OldState);
  6471. }
  6472. }
  6473. public override int Run(long tStart)
  6474. {
  6475. lock (m_Lock)
  6476. {
  6477. FilterState OldState = m_State;
  6478. // Make sure there really is a state change
  6479. if (m_State == FilterState.Running)
  6480. {
  6481. return NOERROR;
  6482. }
  6483. // Send EC_COMPLETE if we're not connected
  6484. if (InputPin.IsConnected == false)
  6485. {
  6486. NotifyEvent(EventCode.Complete, (IntPtr)((int)S_OK), Marshal.GetIUnknownForObject(this));
  6487. m_State = FilterState.Running;
  6488. return NOERROR;
  6489. }
  6490. Ready();
  6491. // Pause the base filter class
  6492. int hr = base.Run(tStart);
  6493. if (FAILED(hr))
  6494. {
  6495. TRACE("Run failed");
  6496. return hr;
  6497. }
  6498. // Allow the source thread to wait
  6499. ASSERT(InputPin.IsFlushing == false);
  6500. SourceThreadCanWait(true);
  6501. RepaintStatus = false;
  6502. // There should be no outstanding advise
  6503. ASSERT(CancelNotification() == S_FALSE);
  6504. ASSERT(m_RenderEvent.WaitOne(0, false) == false);
  6505. ASSERT(m_EndOfStreamTimer == null);
  6506. ASSERT(InputPin.IsFlushing == false);
  6507. // If we are going into a running state then we must commit whatever
  6508. // allocator we are using it so that any source filter can call the
  6509. // GetBuffer and expect to get a buffer without returning an error
  6510. if (InputPin.Allocator != null)
  6511. {
  6512. InputPin.Allocator.Commit();
  6513. }
  6514. // When we come out of a stopped state we must clear any image we were
  6515. // holding onto for frame refreshing. Since renderers see state changes
  6516. // first we can reset ourselves ready to accept the source thread data
  6517. // Paused or running after being stopped causes the current position to
  6518. // be reset so we're not interested in passing end of stream signals
  6519. if (OldState == FilterState.Stopped)
  6520. {
  6521. m_bAbort = false;
  6522. ClearPendingSample();
  6523. }
  6524. return StartStreaming();
  6525. }
  6526. }
  6527. public override int GetState(int dwMilliSecsTimeout, out FilterState filtState)
  6528. {
  6529. if (!WaitDispatchingMessages(m_evComplete, dwMilliSecsTimeout, IntPtr.Zero, 0, m_evAbort))
  6530. {
  6531. filtState = m_State;
  6532. return VFW_S_STATE_INTERMEDIATE;
  6533. }
  6534. filtState = m_State;
  6535. return NOERROR;
  6536. }
  6537. public override int JoinFilterGraph(IntPtr pGraph, string pName)
  6538. {
  6539. int hr = base.JoinFilterGraph(pGraph, pName);
  6540. if (FAILED(hr)) return hr;
  6541. if (pGraph != IntPtr.Zero)
  6542. {
  6543. m_evAbort.Reset();
  6544. m_MessageDispatcher = new MessageDispatcher(m_evAbort);
  6545. }
  6546. else
  6547. {
  6548. if (m_MessageDispatcher != null)
  6549. {
  6550. m_MessageDispatcher.Dispose();
  6551. m_MessageDispatcher = null;
  6552. }
  6553. if (!m_evComplete.WaitOne(0, false))
  6554. {
  6555. lock (m_Lock)
  6556. {
  6557. m_evAbort.Set();
  6558. SourceThreadCanWait(false);
  6559. CancelNotification();
  6560. }
  6561. }
  6562. }
  6563. return hr;
  6564. }
  6565. #endregion
  6566. #region Helper Methods
  6567. private bool WaitDispatchingMessages(EventWaitHandle hObject, int dwWait, IntPtr hwnd, int uMsg, EventWaitHandle hEvent)
  6568. {
  6569. int nCount = null != hEvent ? 2 : 1;
  6570. WaitHandle[] hWaitObjects = new WaitHandle[nCount];
  6571. hWaitObjects[0] = hObject;
  6572. if (null != hEvent)
  6573. {
  6574. hWaitObjects[1] = hEvent;
  6575. }
  6576. return WaitHandle.WaitAny(hWaitObjects, dwWait, false) != WaitHandle.WaitTimeout;
  6577. }
  6578. public void Ready()
  6579. {
  6580. m_evComplete.Set();
  6581. }
  6582. public void NotReady()
  6583. {
  6584. m_evComplete.Reset();
  6585. }
  6586. public void SendRepaint()
  6587. {
  6588. lock (m_RendererLock)
  6589. {
  6590. // We should not send repaint notifications when...
  6591. // - An end of stream has been notified
  6592. // - Our input pin is being flushed
  6593. // - The input pin is not connected
  6594. // - We have aborted a video playback
  6595. // - There is a repaint already sent
  6596. if (m_bAbort == false)
  6597. {
  6598. if (InputPin.IsConnected == true)
  6599. {
  6600. if (InputPin.IsFlushing == false)
  6601. {
  6602. if (IsEndOfStream == false)
  6603. {
  6604. if (m_bRepaintStatus == true)
  6605. {
  6606. NotifyEvent(EventCode.Repaint, Marshal.GetIUnknownForObject(InputPin), IntPtr.Zero);
  6607. RepaintStatus = false;
  6608. }
  6609. }
  6610. }
  6611. }
  6612. }
  6613. }
  6614. }
  6615. public void SendNotifyWindow(IPin pPin, IntPtr hwnd)
  6616. {
  6617. IMediaEventSink pSink = (IMediaEventSink)pPin;
  6618. if (pSink != null)
  6619. {
  6620. pSink.Notify(EventCode.NotifyWindow, hwnd, IntPtr.Zero);
  6621. pSink = null;
  6622. }
  6623. NotifyEvent(EventCode.NotifyWindow, hwnd, IntPtr.Zero);
  6624. }
  6625. public bool OnDisplayChange()
  6626. {
  6627. lock (m_RendererLock)
  6628. {
  6629. if (InputPin.IsConnected == false)
  6630. {
  6631. return false;
  6632. }
  6633. // Pass our input pin as parameter on the event
  6634. NotifyEvent(EventCode.DisplayChanged, Marshal.GetIUnknownForObject(InputPin), IntPtr.Zero);
  6635. IsAbort = true;
  6636. ClearPendingSample();
  6637. return true;
  6638. }
  6639. }
  6640. protected void TimerCallbackProc(object state)
  6641. {
  6642. lock (m_RendererLock)
  6643. {
  6644. // See if we should signal end of stream now
  6645. if (m_EndOfStreamTimer != null)
  6646. {
  6647. m_EndOfStreamTimer.Dispose();
  6648. m_EndOfStreamTimer = null;
  6649. SendEndOfStream();
  6650. }
  6651. }
  6652. }
  6653. public void ResetEndOfStreamTimer()
  6654. {
  6655. if (m_EndOfStreamTimer != null)
  6656. {
  6657. m_EndOfStreamTimer.Dispose();
  6658. m_EndOfStreamTimer = null;
  6659. }
  6660. }
  6661. public void WaitForReceiveToComplete()
  6662. {
  6663. WaitHandle.WaitAny(new WaitHandle[] { m_evClear, m_evAbort });
  6664. lock (m_RendererLock)
  6665. {
  6666. if (m_evAbort.WaitOne(0, false))
  6667. {
  6668. CancelNotification();
  6669. ClearPendingSample();
  6670. }
  6671. }
  6672. }
  6673. #endregion
  6674. #region IMediaSeeking Members
  6675. public int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  6676. {
  6677. if (Position != null)
  6678. {
  6679. return Position.GetCapabilities(out pCapabilities);
  6680. }
  6681. pCapabilities = 0;
  6682. return E_NOINTERFACE;
  6683. }
  6684. public int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  6685. {
  6686. if (Position != null)
  6687. {
  6688. return Position.CheckCapabilities(ref pCapabilities);
  6689. }
  6690. return E_NOINTERFACE;
  6691. }
  6692. public int IsFormatSupported(Guid pFormat)
  6693. {
  6694. if (Position != null)
  6695. {
  6696. return Position.IsFormatSupported(pFormat);
  6697. }
  6698. return E_NOINTERFACE;
  6699. }
  6700. public int QueryPreferredFormat(out Guid pFormat)
  6701. {
  6702. if (Position != null)
  6703. {
  6704. return Position.QueryPreferredFormat(out pFormat);
  6705. }
  6706. pFormat = Guid.Empty;
  6707. return E_NOINTERFACE;
  6708. }
  6709. public int GetTimeFormat(out Guid pFormat)
  6710. {
  6711. if (Position != null)
  6712. {
  6713. return Position.GetTimeFormat(out pFormat);
  6714. }
  6715. pFormat = Guid.Empty;
  6716. return E_NOINTERFACE;
  6717. }
  6718. public int IsUsingTimeFormat(Guid pFormat)
  6719. {
  6720. if (Position != null)
  6721. {
  6722. return Position.IsUsingTimeFormat(pFormat);
  6723. }
  6724. return E_NOINTERFACE;
  6725. }
  6726. public int SetTimeFormat(Guid pFormat)
  6727. {
  6728. if (Position != null)
  6729. {
  6730. return Position.SetTimeFormat(pFormat);
  6731. }
  6732. return E_NOINTERFACE;
  6733. }
  6734. public int GetDuration(out long pDuration)
  6735. {
  6736. if (Position != null)
  6737. {
  6738. return Position.GetDuration(out pDuration);
  6739. }
  6740. pDuration = 0;
  6741. return E_NOINTERFACE;
  6742. }
  6743. public int GetStopPosition(out long pStop)
  6744. {
  6745. if (Position != null)
  6746. {
  6747. return Position.GetStopPosition(out pStop);
  6748. }
  6749. pStop = 0;
  6750. return E_NOINTERFACE;
  6751. }
  6752. public int GetCurrentPosition(out long pCurrent)
  6753. {
  6754. if (Position != null)
  6755. {
  6756. return Position.GetCurrentPosition(out pCurrent);
  6757. }
  6758. pCurrent = 0;
  6759. return E_NOINTERFACE;
  6760. }
  6761. public int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  6762. {
  6763. if (Position != null)
  6764. {
  6765. return Position.ConvertTimeFormat(out pTarget, pTargetFormat, Source, pSourceFormat);
  6766. }
  6767. pTarget = 0;
  6768. return E_NOINTERFACE;
  6769. }
  6770. public int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  6771. {
  6772. if (Position != null)
  6773. {
  6774. return Position.SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
  6775. }
  6776. return E_NOINTERFACE;
  6777. }
  6778. public int GetPositions(out long pCurrent, out long pStop)
  6779. {
  6780. if (Position != null)
  6781. {
  6782. return Position.GetPositions(out pCurrent, out pStop);
  6783. }
  6784. pCurrent = pStop = 0;
  6785. return E_NOINTERFACE;
  6786. }
  6787. public int GetAvailable(out long pEarliest, out long pLatest)
  6788. {
  6789. if (Position != null)
  6790. {
  6791. return Position.GetAvailable(out pEarliest, out pLatest);
  6792. }
  6793. pEarliest = pLatest = 0;
  6794. return E_NOINTERFACE;
  6795. }
  6796. public int SetRate(double dRate)
  6797. {
  6798. if (Position != null)
  6799. {
  6800. return Position.SetRate(dRate);
  6801. }
  6802. return E_NOINTERFACE;
  6803. }
  6804. public int GetRate(out double pdRate)
  6805. {
  6806. if (Position != null)
  6807. {
  6808. return Position.GetRate(out pdRate);
  6809. }
  6810. pdRate = 0;
  6811. return E_NOINTERFACE;
  6812. }
  6813. public int GetPreroll(out long pllPreroll)
  6814. {
  6815. if (Position != null)
  6816. {
  6817. return Position.GetPreroll(out pllPreroll);
  6818. }
  6819. pllPreroll = 0;
  6820. return E_NOINTERFACE;
  6821. }
  6822. #endregion
  6823. }
  6824. #endregion
  6825. #region Async Stream Reader
  6826. [ComVisible(false)]
  6827. [ClassInterface(ClassInterfaceType.None)]
  6828. public class AsyncStream : Stream
  6829. {
  6830. #region Variables
  6831. protected IAsyncReaderImpl m_Reader = null;
  6832. protected long m_lPosition = 0;
  6833. protected long m_lLenth = 0;
  6834. #endregion
  6835. #region Constructor
  6836. public AsyncStream(IntPtr pAsyncReader)
  6837. : this(new IAsyncReaderImpl(pAsyncReader))
  6838. {
  6839. }
  6840. public AsyncStream(IAsyncReaderImpl _reader)
  6841. {
  6842. m_Reader = _reader;
  6843. if (m_Reader != null)
  6844. {
  6845. m_Reader._AddRef();
  6846. }
  6847. }
  6848. #endregion
  6849. #region Overridden Methods
  6850. public override bool CanRead
  6851. {
  6852. get { return true; }
  6853. }
  6854. public override bool CanSeek
  6855. {
  6856. get { return true; }
  6857. }
  6858. public override bool CanWrite
  6859. {
  6860. get { return false; }
  6861. }
  6862. protected override void Dispose(bool disposing)
  6863. {
  6864. if (m_Reader != null)
  6865. {
  6866. m_Reader._Release();
  6867. m_Reader = null;
  6868. }
  6869. base.Dispose(disposing);
  6870. }
  6871. public override void Flush()
  6872. {
  6873. }
  6874. public override long Length
  6875. {
  6876. get
  6877. {
  6878. if (m_lLenth == 0)
  6879. {
  6880. long lTotal;
  6881. long lAvailable;
  6882. if (HRESULT.S_OK == m_Reader.Length(out lTotal, out lAvailable))
  6883. {
  6884. m_lLenth = lTotal;
  6885. }
  6886. }
  6887. return m_lLenth;
  6888. }
  6889. }
  6890. public override long Position
  6891. {
  6892. get
  6893. {
  6894. return m_lPosition;
  6895. }
  6896. set
  6897. {
  6898. Seek(value, SeekOrigin.Begin);
  6899. }
  6900. }
  6901. public override int Read(byte[] buffer, int offset, int count)
  6902. {
  6903. int _size = count - offset;
  6904. if (_size <= 0) return 0;
  6905. if (m_lPosition < 0 || m_lPosition >= Length) return 0;
  6906. if (m_Reader != null)
  6907. {
  6908. if (_size > Length - m_lPosition)
  6909. {
  6910. _size = (int)(Length - m_lPosition);
  6911. }
  6912. IntPtr _ptr = IntPtr.Zero;
  6913. try
  6914. {
  6915. _ptr = Marshal.AllocCoTaskMem(count - offset);
  6916. if (HRESULT.S_OK == m_Reader.SyncRead(m_lPosition, _size, _ptr))
  6917. {
  6918. Marshal.Copy(_ptr, buffer, offset, _size);
  6919. m_lPosition += _size;
  6920. }
  6921. else
  6922. {
  6923. _size = 0;
  6924. }
  6925. return _size;
  6926. }
  6927. finally
  6928. {
  6929. if (_ptr != IntPtr.Zero)
  6930. {
  6931. Marshal.FreeCoTaskMem(_ptr);
  6932. }
  6933. }
  6934. }
  6935. return 0;
  6936. }
  6937. public override long Seek(long offset, SeekOrigin origin)
  6938. {
  6939. long _length = Length;
  6940. switch (origin)
  6941. {
  6942. case SeekOrigin.Begin:
  6943. m_lPosition = offset;
  6944. break;
  6945. case SeekOrigin.Current:
  6946. m_lPosition += offset;
  6947. break;
  6948. case SeekOrigin.End:
  6949. m_lPosition = _length + offset;
  6950. break;
  6951. }
  6952. if (m_lPosition < 0)
  6953. {
  6954. m_lPosition = 0;
  6955. }
  6956. else if (m_lPosition >= _length)
  6957. {
  6958. m_lPosition = _length;
  6959. }
  6960. return m_lPosition;
  6961. }
  6962. public override void SetLength(long value)
  6963. {
  6964. }
  6965. public override void Write(byte[] buffer, int offset, int count)
  6966. {
  6967. }
  6968. #endregion
  6969. }
  6970. #endregion
  6971. #region COM Stream Implementation
  6972. [ComVisible(false)]
  6973. [ClassInterface(ClassInterfaceType.None)]
  6974. public class COMStream : Stream
  6975. {
  6976. #region Variables
  6977. protected IStreamImpl m_Reader = null;
  6978. #endregion
  6979. #region Constructor
  6980. public COMStream(IntPtr pStream)
  6981. : this(new IStreamImpl(pStream))
  6982. {
  6983. }
  6984. public COMStream(IStreamImpl _reader)
  6985. {
  6986. m_Reader = _reader;
  6987. if (m_Reader != null)
  6988. {
  6989. m_Reader._AddRef();
  6990. }
  6991. }
  6992. #endregion
  6993. #region Overridden Methods
  6994. public override bool CanRead
  6995. {
  6996. get { return true; }
  6997. }
  6998. public override bool CanSeek
  6999. {
  7000. get { return true; }
  7001. }
  7002. public override bool CanWrite
  7003. {
  7004. get { return true; }
  7005. }
  7006. protected override void Dispose(bool disposing)
  7007. {
  7008. if (m_Reader != null)
  7009. {
  7010. m_Reader._Release();
  7011. m_Reader = null;
  7012. }
  7013. base.Dispose(disposing);
  7014. }
  7015. public override void Flush()
  7016. {
  7017. }
  7018. public override long Length
  7019. {
  7020. get
  7021. {
  7022. System.Runtime.InteropServices.ComTypes.STATSTG _stat;
  7023. m_Reader.Stat(out _stat, 1);
  7024. return _stat.cbSize;
  7025. }
  7026. }
  7027. public override long Position
  7028. {
  7029. get
  7030. {
  7031. return Seek(0, SeekOrigin.Current);
  7032. }
  7033. set
  7034. {
  7035. Seek(value, SeekOrigin.Begin);
  7036. }
  7037. }
  7038. public override int Read(byte[] buffer, int offset, int count)
  7039. {
  7040. int _size = count - offset;
  7041. if (_size <= 0) return 0;
  7042. if (m_Reader != null)
  7043. {
  7044. IntPtr _ptr = IntPtr.Zero;
  7045. try
  7046. {
  7047. _ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
  7048. byte[] _result = buffer;
  7049. if (offset != 0)
  7050. {
  7051. _result = new byte[_size];
  7052. }
  7053. m_Reader.Read(_result, _size, _ptr);
  7054. int _readed = Marshal.ReadInt32(_ptr);
  7055. if (_readed > 0 && offset != 0)
  7056. {
  7057. Array.Copy(_result, 0, buffer, offset, _readed);
  7058. }
  7059. return _readed;
  7060. }
  7061. finally
  7062. {
  7063. if (_ptr != IntPtr.Zero)
  7064. {
  7065. Marshal.FreeCoTaskMem(_ptr);
  7066. }
  7067. }
  7068. }
  7069. return 0;
  7070. }
  7071. public override long Seek(long offset, SeekOrigin origin)
  7072. {
  7073. IntPtr _ptr = IntPtr.Zero;
  7074. long _position = 0;
  7075. try
  7076. {
  7077. _ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(long)));
  7078. m_Reader.Seek(offset, (int)origin, _ptr);
  7079. _position = Marshal.ReadInt64(_ptr);
  7080. }
  7081. finally
  7082. {
  7083. if (_ptr != IntPtr.Zero)
  7084. {
  7085. Marshal.FreeCoTaskMem(_ptr);
  7086. }
  7087. }
  7088. return _position;
  7089. }
  7090. public override void SetLength(long value)
  7091. {
  7092. m_Reader.SetSize(value);
  7093. }
  7094. public override void Write(byte[] buffer, int offset, int count)
  7095. {
  7096. int _size = count - offset;
  7097. if (_size > 0 && m_Reader != null)
  7098. {
  7099. byte[] _write = buffer;
  7100. if (offset != 0)
  7101. {
  7102. _write = new byte[_size];
  7103. Array.Copy(buffer, offset, _write, 0, _size);
  7104. }
  7105. m_Reader.Write(_write, _size, IntPtr.Zero);
  7106. }
  7107. }
  7108. #endregion
  7109. }
  7110. #endregion
  7111. #region Bit Stream Reader
  7112. [ComVisible(false)]
  7113. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  7114. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  7115. [ClassInterface(ClassInterfaceType.None)]
  7116. public class BitStreamReader : COMHelper, IDisposable, IAsyncReader, IStream
  7117. {
  7118. #region Variables
  7119. protected Stream m_Stream = null;
  7120. protected const int m_nCacheSize = 64 * 1024;
  7121. protected object m_csCacheLock = new object();
  7122. protected object m_csReadingLock = new object();
  7123. protected int m_nBufferSize = 0;
  7124. protected int m_nBitIndex = 0;
  7125. protected int m_nCacheIndex = 0;
  7126. protected byte[] m_pCacheBuffer = null;
  7127. protected byte[] m_btCurrentByte = new byte[1];
  7128. protected long m_llPosition = 0;
  7129. #endregion
  7130. #region Constructor
  7131. public BitStreamReader(Stream _stream)
  7132. {
  7133. m_Stream = _stream;
  7134. }
  7135. ~BitStreamReader()
  7136. {
  7137. Dispose();
  7138. }
  7139. #endregion
  7140. #region Properties
  7141. public long Position
  7142. {
  7143. get
  7144. {
  7145. lock (m_csCacheLock)
  7146. {
  7147. return (m_llPosition - (m_nBufferSize > 0 ? (m_nBufferSize - m_nCacheIndex) : 0));
  7148. }
  7149. }
  7150. set { Seek(value); }
  7151. }
  7152. public long TotalSize
  7153. {
  7154. get { return m_Stream.Length; }
  7155. }
  7156. public long AvailableSize
  7157. {
  7158. get
  7159. {
  7160. long _position = Position;
  7161. long _size = TotalSize;
  7162. return (_size > _position ? _size - _position : 0);
  7163. }
  7164. }
  7165. public bool CanRead
  7166. {
  7167. get { return IsAvailable(0); }
  7168. }
  7169. #endregion
  7170. #region Methods
  7171. public bool IsAvailable(long _size)
  7172. {
  7173. if (_size > 0)
  7174. {
  7175. return (AvailableSize >= _size);
  7176. }
  7177. return (AvailableSize > 0);
  7178. }
  7179. public HRESULT Seek(long ullPosition)
  7180. {
  7181. lock (m_csCacheLock)
  7182. {
  7183. if (ullPosition < m_llPosition && m_llPosition - (long)m_nBufferSize < ullPosition)
  7184. {
  7185. m_nCacheIndex = m_nBufferSize - (int)(m_llPosition - ullPosition);
  7186. }
  7187. else
  7188. {
  7189. m_llPosition = ullPosition;
  7190. m_nBufferSize = 0;
  7191. m_nCacheIndex = 0;
  7192. }
  7193. m_nBitIndex = 0;
  7194. if (ullPosition > TotalSize) return S_FALSE;
  7195. }
  7196. return NOERROR;
  7197. }
  7198. public HRESULT ReadData(byte[] pBuffer)
  7199. {
  7200. return ReadData(pBuffer, pBuffer.Length);
  7201. }
  7202. public HRESULT ReadData(byte[] pBuffer, int dwSize)
  7203. {
  7204. int dwReaded;
  7205. HRESULT hr = ReadData(pBuffer, dwSize, out dwReaded);
  7206. if (FAILED(hr)) return hr;
  7207. if (dwReaded != dwSize) return E_FAIL;
  7208. return hr;
  7209. }
  7210. public HRESULT ReadData(byte[] pBuffer, int dwSize, out int pdwReaded)
  7211. {
  7212. lock (m_csCacheLock)
  7213. {
  7214. if (m_pCacheBuffer == null)
  7215. {
  7216. m_pCacheBuffer = new byte[m_nCacheSize];
  7217. m_nBufferSize = 0;
  7218. }
  7219. int nOutputIndex = 0;
  7220. pdwReaded = 0;
  7221. while (dwSize > 0)
  7222. {
  7223. m_nBitIndex = 0;
  7224. if (m_nBufferSize == 0)
  7225. {
  7226. m_nCacheIndex = 0;
  7227. int _readed = 0;
  7228. {
  7229. HRESULT hr = ReadData(m_llPosition, m_pCacheBuffer, m_nCacheSize, out _readed);
  7230. if (!FAILED(hr) && _readed > 0)
  7231. {
  7232. m_nBufferSize = _readed;
  7233. m_llPosition += _readed;
  7234. }
  7235. else
  7236. {
  7237. return S_FALSE;
  7238. }
  7239. }
  7240. }
  7241. int nBytesToWrite = (m_nBufferSize - m_nCacheIndex <= (int)dwSize) ? (m_nBufferSize - m_nCacheIndex) : (int)dwSize;
  7242. Array.Copy(m_pCacheBuffer, m_nCacheIndex, pBuffer, nOutputIndex, nBytesToWrite);
  7243. nOutputIndex += nBytesToWrite;
  7244. dwSize -= nBytesToWrite;
  7245. pdwReaded += nBytesToWrite;
  7246. m_nCacheIndex += nBytesToWrite;
  7247. if (m_nCacheIndex >= m_nBufferSize)
  7248. {
  7249. m_nCacheIndex = 0;
  7250. m_nBufferSize = 0;
  7251. }
  7252. }
  7253. }
  7254. return NOERROR;
  7255. }
  7256. public HRESULT ReadData(long ullPosition, byte[] pBuffer, int dwSize, out int pdwReaded)
  7257. {
  7258. lock (m_csReadingLock)
  7259. {
  7260. m_Stream.Position = ullPosition;
  7261. pdwReaded = m_Stream.Read(pBuffer, 0, dwSize);
  7262. }
  7263. if (pdwReaded <= 0) return E_FAIL;
  7264. if (pdwReaded < dwSize) return S_FALSE;
  7265. return NOERROR;
  7266. }
  7267. #endregion
  7268. #region Bits Helper
  7269. public bool IsAligned() { return m_nBitIndex == 0; }
  7270. public void AlignNextByte() { if (m_nBitIndex != 0) SkipBits(m_nBitIndex); }
  7271. public int ReadBit()
  7272. {
  7273. if (m_nBitIndex == 0)
  7274. {
  7275. int _readed = 0;
  7276. HRESULT hr = ReadData(m_btCurrentByte, 1, out _readed);
  7277. if (_readed == 0) m_btCurrentByte[0] = 0;
  7278. m_nBitIndex = 8;
  7279. }
  7280. m_nBitIndex--;
  7281. return (m_btCurrentByte[0] >> m_nBitIndex) & 0x01;
  7282. }
  7283. public int ReadByte() { return (int)ReadBits(8); }
  7284. public int ReadWord() { return (int)ReadBits(16); }
  7285. public int ReadDword() { return (int)ReadBits(32); }
  7286. public long ReadQword() { return ReadBits(64); }
  7287. public long ReadBits(int nCount)
  7288. {
  7289. long _result = 0;
  7290. long _bit;
  7291. while (nCount-- > 0)
  7292. {
  7293. _result <<= 1;
  7294. _bit = ReadBit();
  7295. _result |= _bit;
  7296. }
  7297. return _result;
  7298. }
  7299. public long PeekBits(int nCount)
  7300. {
  7301. long llPosition = Position;
  7302. int nBitIndex = m_nBitIndex;
  7303. long _result = ReadBits(nCount);
  7304. Seek(llPosition);
  7305. while (nBitIndex != m_nBitIndex) SkipBit();
  7306. return _result;
  7307. }
  7308. public void SkipBit() { SkipBits(1); }
  7309. public void SkipBits(int nCount) { while (nCount-- > 0) ReadBit(); }
  7310. public void SkipBytes(int nCount) { SkipBits(nCount * 8); }
  7311. public uint ReadUE()
  7312. {
  7313. int cZeros = 0;
  7314. while (ReadBit() == 0)
  7315. {
  7316. cZeros++;
  7317. }
  7318. return (uint)(ReadBits(cZeros) + ((1 << cZeros) - 1));
  7319. }
  7320. public int ReadSE()
  7321. {
  7322. uint UE = ReadUE();
  7323. bool bPositive = (UE & 1) != 0;
  7324. int SE = (int)((UE + 1) >> 1);
  7325. if (!bPositive)
  7326. {
  7327. SE = -SE;
  7328. }
  7329. return SE;
  7330. }
  7331. #endregion
  7332. #region Values Helper
  7333. public object ReadValue(Type _type)
  7334. {
  7335. return ReadValue(_type, Marshal.SizeOf(_type));
  7336. }
  7337. public object ReadValue(Type _type, int nSize)
  7338. {
  7339. IntPtr _ptr = ReadValueAlloc(nSize);
  7340. if (_ptr != IntPtr.Zero)
  7341. {
  7342. try
  7343. {
  7344. return Marshal.PtrToStructure(_ptr, _type);
  7345. }
  7346. finally
  7347. {
  7348. Marshal.FreeCoTaskMem(_ptr);
  7349. }
  7350. }
  7351. return null;
  7352. }
  7353. public object ReadValue<T>()
  7354. {
  7355. return ReadValue(typeof(T));
  7356. }
  7357. public object ReadValue<T>(int nSize)
  7358. {
  7359. return ReadValue(typeof(T), nSize);
  7360. }
  7361. public IntPtr ReadValueAlloc(int _size)
  7362. {
  7363. if (_size <= 0) return IntPtr.Zero;
  7364. IntPtr _ptr = Marshal.AllocCoTaskMem(_size);
  7365. byte[] _data = new byte[_size];
  7366. if (IsAligned())
  7367. {
  7368. int dwReaded = 0;
  7369. HRESULT hr = ReadData(_data, _size, out dwReaded);
  7370. if (!(hr == S_OK && dwReaded == _size))
  7371. {
  7372. Marshal.FreeCoTaskMem(_ptr);
  7373. _ptr = IntPtr.Zero;
  7374. }
  7375. }
  7376. else
  7377. {
  7378. if (IsAvailable(_size))
  7379. {
  7380. for (int i = 0; i < _size; i++) _data[i] = (byte)ReadByte();
  7381. }
  7382. else
  7383. {
  7384. Marshal.FreeCoTaskMem(_ptr);
  7385. _ptr = IntPtr.Zero;
  7386. }
  7387. }
  7388. if (_ptr != IntPtr.Zero)
  7389. {
  7390. Marshal.Copy(_data, 0, _ptr, _size);
  7391. }
  7392. return _ptr;
  7393. }
  7394. public IntPtr ReadValueAlloc(Type _type)
  7395. {
  7396. return ReadValueAlloc(Marshal.SizeOf(_type));
  7397. }
  7398. public IntPtr ReadValueAlloc<T>()
  7399. {
  7400. return ReadValueAlloc(typeof(T));
  7401. }
  7402. #endregion
  7403. #region IDisposable Members
  7404. public void Dispose()
  7405. {
  7406. if (m_Stream != null)
  7407. {
  7408. m_Stream.Dispose();
  7409. m_Stream = null;
  7410. }
  7411. }
  7412. #endregion
  7413. #region IAsyncReader Members
  7414. public int RequestAllocator(IntPtr pPreferred, AllocatorProperties pProps, out IntPtr ppActual)
  7415. {
  7416. ppActual = IntPtr.Zero;
  7417. return E_NOTIMPL;
  7418. }
  7419. public int Request(IntPtr pSample, IntPtr dwUser)
  7420. {
  7421. return E_NOTIMPL;
  7422. }
  7423. public int WaitForNext(int dwTimeout, out IntPtr ppSample, out IntPtr pdwUser)
  7424. {
  7425. ppSample = IntPtr.Zero;
  7426. pdwUser = IntPtr.Zero;
  7427. return E_NOTIMPL;
  7428. }
  7429. public int SyncReadAligned(IntPtr pSample)
  7430. {
  7431. return E_NOTIMPL;
  7432. }
  7433. public int SyncRead(long llPosition, int lLength, IntPtr pBuffer)
  7434. {
  7435. byte[] _data = new byte[lLength];
  7436. int _readed;
  7437. HRESULT hr = ReadData(llPosition, _data, lLength, out _readed);
  7438. if (_readed > 0 && SUCCEEDED(hr))
  7439. {
  7440. Marshal.Copy(_data, 0, pBuffer, _readed);
  7441. }
  7442. return _readed == lLength ? NOERROR : S_FALSE;
  7443. }
  7444. public int Length(out long pTotal, out long pAvailable)
  7445. {
  7446. pTotal = m_Stream.Length;
  7447. pAvailable = pTotal;
  7448. return NOERROR;
  7449. }
  7450. public int BeginFlush()
  7451. {
  7452. return E_NOTIMPL;
  7453. }
  7454. public int EndFlush()
  7455. {
  7456. return E_NOTIMPL;
  7457. }
  7458. #endregion
  7459. #region IStream Members
  7460. public void Clone(out IStream ppstm)
  7461. {
  7462. throw new NotImplementedException();
  7463. }
  7464. public void Commit(int grfCommitFlags)
  7465. {
  7466. }
  7467. public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
  7468. {
  7469. throw new NotImplementedException();
  7470. }
  7471. public void LockRegion(long libOffset, long cb, int dwLockType)
  7472. {
  7473. throw new NotImplementedException();
  7474. }
  7475. public void Read(byte[] pv, int cb, IntPtr pcbRead)
  7476. {
  7477. int _readed;
  7478. ReadData(pv, cb, out _readed);
  7479. if (pcbRead != IntPtr.Zero)
  7480. {
  7481. Marshal.WriteInt32(pcbRead, _readed);
  7482. }
  7483. }
  7484. public void Revert()
  7485. {
  7486. throw new NotImplementedException();
  7487. }
  7488. public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
  7489. {
  7490. long _position = Position;
  7491. long _length = TotalSize;
  7492. switch ((SeekOrigin)dwOrigin)
  7493. {
  7494. case SeekOrigin.Begin:
  7495. _position = dlibMove;
  7496. break;
  7497. case SeekOrigin.Current:
  7498. _position += dlibMove;
  7499. break;
  7500. case SeekOrigin.End:
  7501. _position = _length + dlibMove;
  7502. break;
  7503. }
  7504. if (_position < 0)
  7505. {
  7506. _position = 0;
  7507. }
  7508. else if (_position >= _length)
  7509. {
  7510. _position = _length;
  7511. }
  7512. Seek(_position);
  7513. if (plibNewPosition != IntPtr.Zero)
  7514. {
  7515. Marshal.WriteInt64(plibNewPosition, _position);
  7516. }
  7517. }
  7518. public void SetSize(long libNewSize)
  7519. {
  7520. throw new NotImplementedException();
  7521. }
  7522. public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)
  7523. {
  7524. pstatstg = new System.Runtime.InteropServices.ComTypes.STATSTG();
  7525. pstatstg.cbSize = TotalSize;
  7526. pstatstg.clsid = Guid.Empty;
  7527. pstatstg.type = 2;
  7528. }
  7529. public void UnlockRegion(long libOffset, long cb, int dwLockType)
  7530. {
  7531. throw new NotImplementedException();
  7532. }
  7533. public void Write(byte[] pv, int cb, IntPtr pcbWritten)
  7534. {
  7535. throw new NotImplementedException();
  7536. }
  7537. #endregion
  7538. }
  7539. #endregion
  7540. #region Base Splitter Filter
  7541. #region Implementation
  7542. [ComVisible(false)]
  7543. [ClassInterface(ClassInterfaceType.None)]
  7544. public class PacketData : IDisposable
  7545. {
  7546. #region Variables
  7547. public long Start = -1;
  7548. public long Stop = -1;
  7549. public int Size = 0;
  7550. public bool SyncPoint = false;
  7551. public byte[] Buffer = null;
  7552. public long Position = -1;
  7553. #endregion
  7554. #region Constructor
  7555. public PacketData()
  7556. {
  7557. }
  7558. ~PacketData()
  7559. {
  7560. Dispose();
  7561. }
  7562. #endregion
  7563. #region IDisposable Members
  7564. public virtual void Dispose()
  7565. {
  7566. }
  7567. #endregion
  7568. }
  7569. [ComVisible(false)]
  7570. [ClassInterface(ClassInterfaceType.None)]
  7571. public class PacketsQueue : IDisposable
  7572. {
  7573. #region Variales
  7574. protected ManualResetEvent m_evNotFull = new ManualResetEvent(true);
  7575. protected List<PacketData> m_Packets = new List<PacketData>();
  7576. protected object m_csLock = new object();
  7577. protected long m_rtQueueStop = -1;
  7578. protected long m_rtCacheDuration = -1;
  7579. protected long m_rtQueueStart = -1;
  7580. protected int m_AddPosition = -1;
  7581. protected bool m_bSortable = false;
  7582. #endregion
  7583. #region Constructor
  7584. public PacketsQueue()
  7585. {
  7586. }
  7587. ~PacketsQueue()
  7588. {
  7589. Clear();
  7590. }
  7591. #endregion
  7592. #region Properties
  7593. public long Duration
  7594. {
  7595. get
  7596. {
  7597. if (m_rtQueueStop != -1 && m_rtQueueStart != -1)
  7598. {
  7599. long _duration = m_rtQueueStop - m_rtQueueStart;
  7600. return _duration > 0 ? _duration : 0;
  7601. }
  7602. return 0;
  7603. }
  7604. }
  7605. public long CacheDuration
  7606. {
  7607. get { return m_rtCacheDuration; }
  7608. set
  7609. {
  7610. m_rtCacheDuration = value;
  7611. if (m_rtCacheDuration > 0)
  7612. {
  7613. if (Duration >= m_rtCacheDuration)
  7614. {
  7615. m_evNotFull.Reset();
  7616. }
  7617. else
  7618. {
  7619. m_evNotFull.Set();
  7620. }
  7621. }
  7622. else
  7623. {
  7624. m_evNotFull.Set();
  7625. }
  7626. }
  7627. }
  7628. public long StartTime
  7629. {
  7630. get
  7631. {
  7632. if (m_rtQueueStart == -1)
  7633. {
  7634. return StopTime;
  7635. }
  7636. return m_rtQueueStart;
  7637. }
  7638. }
  7639. public long StopTime
  7640. {
  7641. get
  7642. {
  7643. return m_rtQueueStop != -1 ? m_rtQueueStop : 0;
  7644. }
  7645. }
  7646. public bool Sorted
  7647. {
  7648. get { return m_bSortable; }
  7649. set { m_bSortable = value; }
  7650. }
  7651. public bool IsFull
  7652. {
  7653. get { return !m_evNotFull.WaitOne(0, false); }
  7654. }
  7655. public bool IsEmpty
  7656. {
  7657. get { return Count == 0; }
  7658. }
  7659. public int Count
  7660. {
  7661. get
  7662. {
  7663. lock (m_csLock)
  7664. {
  7665. return m_Packets.Count;
  7666. }
  7667. }
  7668. }
  7669. #endregion
  7670. #region Methods
  7671. public void Clear()
  7672. {
  7673. lock (m_csLock)
  7674. {
  7675. while (m_Packets.Count > 0)
  7676. {
  7677. m_Packets[0].Dispose();
  7678. m_Packets.RemoveAt(0);
  7679. }
  7680. m_rtQueueStop = -1;
  7681. m_rtQueueStart = -1;
  7682. m_AddPosition = -1;
  7683. m_evNotFull.Set();
  7684. }
  7685. }
  7686. public void Add(PacketData pPacket)
  7687. {
  7688. if (pPacket != null)
  7689. {
  7690. lock (m_csLock)
  7691. {
  7692. if (pPacket.Start < 0 || !m_bSortable)
  7693. {
  7694. if (pPacket.Start >= 0 && m_rtQueueStop < pPacket.Start)
  7695. {
  7696. m_rtQueueStop = (pPacket.Stop > 0 && pPacket.Stop > pPacket.Start) ? pPacket.Stop : pPacket.Start;
  7697. if (m_Packets.Count == 0)
  7698. {
  7699. m_rtQueueStart = pPacket.Start;
  7700. }
  7701. }
  7702. if (m_AddPosition == -1)
  7703. {
  7704. m_Packets.Add(pPacket);
  7705. }
  7706. else
  7707. {
  7708. m_Packets.Insert(m_AddPosition++, pPacket);
  7709. }
  7710. }
  7711. else
  7712. {
  7713. if (m_rtQueueStop <= pPacket.Start)
  7714. {
  7715. if (m_Packets.Count == 0)
  7716. {
  7717. m_rtQueueStart = pPacket.Start;
  7718. }
  7719. m_Packets.Add(pPacket);
  7720. m_AddPosition = m_Packets.Count - 1;
  7721. m_rtQueueStop = (pPacket.Stop > 0 && pPacket.Stop > pPacket.Start) ? pPacket.Stop : pPacket.Start;
  7722. }
  7723. else
  7724. {
  7725. if (m_Packets.Count == 0)
  7726. {
  7727. m_Packets.Add(pPacket);
  7728. m_AddPosition = 0;
  7729. m_rtQueueStart = pPacket.Start;
  7730. m_rtQueueStop = (pPacket.Stop > 0 && pPacket.Stop > pPacket.Start) ? pPacket.Stop : pPacket.Start;
  7731. }
  7732. else
  7733. {
  7734. int _position = m_Packets.Count - 1;
  7735. int _skip = _position;
  7736. while (true)
  7737. {
  7738. PacketData _packet = m_Packets[_position];
  7739. if (_packet.Start != -1)
  7740. {
  7741. if (_packet.Start < pPacket.Start)
  7742. {
  7743. m_Packets.Insert(_skip, pPacket);
  7744. m_AddPosition = _skip;
  7745. break;
  7746. }
  7747. _skip = _position;
  7748. }
  7749. if (--_position < 0)
  7750. {
  7751. m_Packets.Insert(0, pPacket);
  7752. m_AddPosition = 0;
  7753. m_rtQueueStart = pPacket.Start;
  7754. break;
  7755. }
  7756. }
  7757. }
  7758. }
  7759. }
  7760. }
  7761. }
  7762. if (m_rtCacheDuration > 0)
  7763. {
  7764. if (Duration >= m_rtCacheDuration)
  7765. {
  7766. m_evNotFull.Reset();
  7767. }
  7768. else
  7769. {
  7770. m_evNotFull.Set();
  7771. }
  7772. }
  7773. }
  7774. public bool Peek(out PacketData ppPacket, bool bRemove)
  7775. {
  7776. ppPacket = null;
  7777. bool bShouldReset = false;
  7778. {
  7779. lock (m_csLock)
  7780. {
  7781. if (m_Packets.Count == 0) return false;
  7782. ppPacket = m_Packets[0];
  7783. if (bRemove)
  7784. {
  7785. if (m_AddPosition == 0)
  7786. {
  7787. m_AddPosition = -1;
  7788. }
  7789. m_Packets.Remove(ppPacket);
  7790. if (ppPacket.Stop != -1)
  7791. {
  7792. if (ppPacket.Stop > m_rtQueueStart)
  7793. {
  7794. m_rtQueueStart = ppPacket.Stop;
  7795. bShouldReset = true;
  7796. }
  7797. }
  7798. else
  7799. {
  7800. if (ppPacket.Start != -1 && ppPacket.Start > m_rtQueueStart)
  7801. {
  7802. m_rtQueueStart = ppPacket.Start;
  7803. bShouldReset = true;
  7804. }
  7805. }
  7806. }
  7807. }
  7808. }
  7809. if (bRemove && bShouldReset)
  7810. {
  7811. m_evNotFull.Set();
  7812. }
  7813. return true;
  7814. }
  7815. #endregion
  7816. #region Operators
  7817. public static implicit operator EventWaitHandle(PacketsQueue _queue)
  7818. {
  7819. return _queue.m_evNotFull;
  7820. }
  7821. #endregion
  7822. #region IDisposable Members
  7823. public void Dispose()
  7824. {
  7825. Clear();
  7826. }
  7827. #endregion
  7828. }
  7829. [ComVisible(false)]
  7830. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  7831. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  7832. [ClassInterface(ClassInterfaceType.None)]
  7833. public abstract class DemuxTrack : COMHelper, IDisposable
  7834. {
  7835. #region Enums
  7836. [ComVisible(false)]
  7837. public enum TrackType
  7838. {
  7839. Unknown = -1,
  7840. Video = 0,
  7841. Audio = 1,
  7842. SubPicture = 2,
  7843. Subtitles = 3,
  7844. }
  7845. #endregion
  7846. #region Variables
  7847. protected PacketsQueue m_Queue = new PacketsQueue();
  7848. protected FileParser m_pParser = null;
  7849. protected TrackType m_Type = TrackType.Unknown;
  7850. protected long m_rtOffset = 0;
  7851. protected long m_rtSampleTime = 0;
  7852. protected long m_rtDuration = 0;
  7853. protected long m_rtPosition = 0;
  7854. protected bool m_bActive = false;
  7855. protected EventWaitHandle m_hFlush = null;
  7856. protected ManualResetEvent m_evReady = new ManualResetEvent(false);
  7857. protected bool m_bFirstSample = true;
  7858. protected bool m_bInvalidTrack = false;
  7859. protected string m_sName = "";
  7860. protected bool m_bEnabled = true;
  7861. protected int m_lcid = 0;
  7862. #endregion
  7863. #region Constructor
  7864. protected DemuxTrack(FileParser _parser, TrackType _type)
  7865. {
  7866. m_pParser = _parser;
  7867. m_Type = _type;
  7868. }
  7869. ~DemuxTrack()
  7870. {
  7871. Dispose();
  7872. }
  7873. #endregion
  7874. #region Properties
  7875. public TrackType Type
  7876. {
  7877. get { return m_Type; }
  7878. }
  7879. public string Name
  7880. {
  7881. get { return m_sName; }
  7882. set { m_sName = value; }
  7883. }
  7884. public bool Enabled
  7885. {
  7886. get { return m_bEnabled; }
  7887. set { m_bEnabled = value; }
  7888. }
  7889. public int LCID
  7890. {
  7891. get { return m_lcid; }
  7892. set { m_lcid = value; }
  7893. }
  7894. public bool IsTrackValid
  7895. {
  7896. get { return !m_bInvalidTrack; }
  7897. }
  7898. public bool IsStartSample
  7899. {
  7900. get { return m_bFirstSample; }
  7901. }
  7902. public long Offset
  7903. {
  7904. get { return m_rtOffset; }
  7905. }
  7906. public long Duration
  7907. {
  7908. get { if (m_rtDuration > 0) return m_rtDuration; else return m_pParser.Duration; }
  7909. set { TrackDuration = value; }
  7910. }
  7911. public long TrackDuration
  7912. {
  7913. get { return m_rtDuration; }
  7914. set { m_rtDuration = value; }
  7915. }
  7916. public long Position
  7917. {
  7918. get { return m_rtPosition; }
  7919. }
  7920. public bool Active
  7921. {
  7922. get { return m_bActive; }
  7923. set { m_bActive = value; }
  7924. }
  7925. public long Allocated
  7926. {
  7927. get
  7928. {
  7929. long _time = m_Queue.CacheDuration;
  7930. if (_time > 0) return _time;
  7931. return 0;
  7932. }
  7933. }
  7934. public bool IsWaiting
  7935. {
  7936. get { return !m_evReady.WaitOne(0, false) && IsEOS; }
  7937. }
  7938. public EventWaitHandle FlushEvent
  7939. {
  7940. get { return m_hFlush; }
  7941. set { m_hFlush = value; }
  7942. }
  7943. public bool IsEOS
  7944. {
  7945. get { return m_bActive && m_pParser.EOSEvent.WaitOne(0, false) && m_Queue.IsEmpty; }
  7946. }
  7947. #endregion
  7948. #region Helper Methods
  7949. public virtual bool Reset()
  7950. {
  7951. if (IsWaiting)
  7952. {
  7953. m_evReady.Set();
  7954. return true;
  7955. }
  7956. return false;
  7957. }
  7958. public virtual void Alloc(long _time)
  7959. {
  7960. m_Queue.CacheDuration = _time;
  7961. }
  7962. public virtual void Flush()
  7963. {
  7964. m_Queue.Clear();
  7965. m_evReady.Reset();
  7966. }
  7967. public virtual bool AddToCache(ref PacketData pPacket)
  7968. {
  7969. if (pPacket != null)
  7970. {
  7971. if (Active)
  7972. {
  7973. if (m_Queue.IsFull && pPacket.Start >= m_Queue.StopTime)
  7974. {
  7975. if (0 != WaitHandle.WaitAny(new WaitHandle[] { m_Queue, m_pParser.QuitEvent, m_hFlush }))
  7976. {
  7977. pPacket.Dispose();
  7978. return false;
  7979. }
  7980. }
  7981. m_Queue.Add(pPacket);
  7982. m_evReady.Set();
  7983. return true;
  7984. }
  7985. else
  7986. {
  7987. pPacket.Dispose();
  7988. return false;
  7989. }
  7990. }
  7991. return false;
  7992. }
  7993. public virtual PacketData GetNextPacket()
  7994. {
  7995. while (0 == WaitHandle.WaitAny(new WaitHandle[] { m_evReady, m_pParser.QuitEvent, m_hFlush }))
  7996. {
  7997. PacketData pPacket;
  7998. if (m_Queue.Peek(out pPacket, true))
  7999. {
  8000. return pPacket;
  8001. }
  8002. else
  8003. {
  8004. if (IsEOS) break;
  8005. }
  8006. {
  8007. if (m_Queue.IsEmpty)
  8008. {
  8009. m_evReady.Reset();
  8010. }
  8011. }
  8012. }
  8013. return null;
  8014. }
  8015. #endregion
  8016. #region Basic Methods For Override
  8017. public virtual HRESULT GetTrackAllocatorRequirements(ref int plBufferSize, ref short pwBuffers)
  8018. {
  8019. return S_FALSE;
  8020. }
  8021. public virtual HRESULT SetMediaType(AMMediaType pmt)
  8022. {
  8023. if (pmt.formatPtr == IntPtr.Zero) return VFW_E_INVALIDMEDIATYPE;
  8024. return NOERROR;
  8025. }
  8026. public virtual HRESULT ReadMediaSample(ref IMediaSampleImpl pSample)
  8027. {
  8028. PacketData _packet = GetNextPacket();
  8029. if (_packet == null) return S_FALSE;
  8030. pSample.SetMediaTime(null, null);
  8031. pSample.SetPreroll(false);
  8032. pSample.SetDiscontinuity(false);
  8033. pSample.SetSyncPoint(_packet.SyncPoint);
  8034. if (_packet.Start >= 0)
  8035. {
  8036. long _start = _packet.Start;
  8037. long _stop = _packet.Stop;
  8038. if (_start < m_rtOffset)
  8039. {
  8040. pSample.SetPreroll(true);
  8041. pSample.SetSyncPoint(false);
  8042. if (m_Type != TrackType.Audio)
  8043. {
  8044. pSample.SetDiscontinuity(true);
  8045. }
  8046. }
  8047. if (_stop < 0 || _stop <= _start || _start == _stop + 1)
  8048. {
  8049. if (m_rtSampleTime > 0) _stop = _start + m_rtSampleTime;
  8050. }
  8051. _start -= m_rtOffset;
  8052. if (_stop > 0)
  8053. {
  8054. _stop -= m_rtOffset;
  8055. pSample.SetTime(_start, _stop);
  8056. }
  8057. else
  8058. {
  8059. pSample.SetTime(_start, null);
  8060. }
  8061. m_rtPosition = _start;
  8062. }
  8063. IntPtr pBuffer;
  8064. pSample.GetPointer(out pBuffer);
  8065. int _readed = 0;
  8066. ASSERT(pSample.GetSize() >= _packet.Size);
  8067. _readed = FillSampleBuffer(pBuffer, pSample.GetSize(), ref _packet);
  8068. _packet.Dispose();
  8069. pSample.SetActualDataLength(_readed);
  8070. m_bFirstSample = false;
  8071. if (_readed == 0) return S_FALSE;
  8072. return NOERROR;
  8073. }
  8074. public virtual HRESULT SeekTrack(long _time)
  8075. {
  8076. Flush();
  8077. m_rtPosition = _time;
  8078. m_bFirstSample = true;
  8079. return NOERROR;
  8080. }
  8081. protected virtual int FillSampleBuffer(IntPtr pBuffer, int _size, ref PacketData _packet)
  8082. {
  8083. int _readed = 0;
  8084. if (_packet.Buffer != null)
  8085. {
  8086. _readed = _packet.Size <= _size ? _packet.Size : _size;
  8087. Marshal.Copy(_packet.Buffer, 0, pBuffer, _readed);
  8088. }
  8089. else
  8090. {
  8091. byte[] _buffer = new byte[_packet.Size];
  8092. m_pParser.Stream.ReadData(_packet.Position, _buffer, _packet.Size, out _readed);
  8093. if (_readed > 0)
  8094. {
  8095. Marshal.Copy(_buffer, 0, pBuffer, _readed);
  8096. }
  8097. }
  8098. return _readed;
  8099. }
  8100. #endregion
  8101. #region Abstract Methods
  8102. public abstract HRESULT GetMediaType(int iPosition, ref AMMediaType pmt);
  8103. #endregion
  8104. #region IDisposable Members
  8105. public virtual void Dispose()
  8106. {
  8107. }
  8108. #endregion
  8109. }
  8110. [ComVisible(false)]
  8111. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  8112. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  8113. [ClassInterface(ClassInterfaceType.None)]
  8114. public abstract class FileParser : COMHelper, IDisposable
  8115. {
  8116. #region Variables
  8117. protected BitStreamReader m_Stream = null;
  8118. protected List<DemuxTrack> m_Tracks = new List<DemuxTrack>();
  8119. protected long m_rtDuration = 0;
  8120. protected EventWaitHandle m_hQuit = null;
  8121. protected EventWaitHandle m_hEOS = null;
  8122. private bool m_bRequireDemuxThread = false;
  8123. protected string m_sFileName = "";
  8124. #endregion
  8125. #region Constructor
  8126. protected FileParser()
  8127. : this(true)
  8128. {
  8129. }
  8130. protected FileParser(bool bRequireDemuxThread)
  8131. {
  8132. m_bRequireDemuxThread = bRequireDemuxThread;
  8133. }
  8134. ~FileParser()
  8135. {
  8136. CloseInput();
  8137. }
  8138. #endregion
  8139. #region Properties
  8140. public string FileName
  8141. {
  8142. get { return m_sFileName; }
  8143. }
  8144. public DemuxTrack this[int iIndex]
  8145. {
  8146. get { return m_Tracks[iIndex]; }
  8147. }
  8148. public bool RequireDemuxThread
  8149. {
  8150. get { return m_bRequireDemuxThread; }
  8151. set { m_bRequireDemuxThread = value; }
  8152. }
  8153. public int Count
  8154. {
  8155. get { return m_Tracks.Count; }
  8156. }
  8157. public long Duration
  8158. {
  8159. get
  8160. {
  8161. if (m_rtDuration == 0)
  8162. {
  8163. foreach (DemuxTrack _track in m_Tracks)
  8164. {
  8165. long _duration = _track.TrackDuration + _track.Offset;
  8166. if (m_rtDuration < _duration)
  8167. {
  8168. m_rtDuration = _duration;
  8169. }
  8170. }
  8171. }
  8172. return m_rtDuration;
  8173. }
  8174. }
  8175. public long Position
  8176. {
  8177. get
  8178. {
  8179. long _time = MAX_LONG;
  8180. foreach (DemuxTrack _track in m_Tracks)
  8181. {
  8182. if (_track.Active)
  8183. {
  8184. long _position = _track.Position;
  8185. if (_position > 0 && _position < _time)
  8186. {
  8187. _time = _position;
  8188. }
  8189. }
  8190. }
  8191. return _time == MAX_LONG ? 0 : _time;
  8192. }
  8193. }
  8194. public EventWaitHandle EOSEvent
  8195. {
  8196. get { return m_hEOS; }
  8197. set { m_hEOS = value; }
  8198. }
  8199. public EventWaitHandle QuitEvent
  8200. {
  8201. get { return m_hQuit; }
  8202. set { m_hQuit = value; }
  8203. }
  8204. public BitStreamReader Stream
  8205. {
  8206. get { return m_Stream; }
  8207. }
  8208. #endregion
  8209. #region Helper Methods
  8210. public DemuxTrack GetTrackByType(DemuxTrack.TrackType _type)
  8211. {
  8212. foreach (DemuxTrack _track in m_Tracks)
  8213. {
  8214. if (_track.Type == _type)
  8215. {
  8216. return _track;
  8217. }
  8218. }
  8219. return null;
  8220. }
  8221. public bool HaveTrack(DemuxTrack.TrackType _type)
  8222. {
  8223. return GetTrackByType(_type) != null;
  8224. }
  8225. public int GetTracksCountByType(DemuxTrack.TrackType _type)
  8226. {
  8227. int nCount = 0;
  8228. foreach (DemuxTrack _track in m_Tracks)
  8229. {
  8230. if (_track.Type == _type)
  8231. {
  8232. nCount++;
  8233. }
  8234. }
  8235. return nCount;
  8236. }
  8237. public int GetActiveTracksCount()
  8238. {
  8239. return GetActiveTracksCount(DemuxTrack.TrackType.Unknown);
  8240. }
  8241. public int GetActiveTracksCount(DemuxTrack.TrackType _type)
  8242. {
  8243. int nCount = 0;
  8244. foreach (DemuxTrack _track in m_Tracks)
  8245. {
  8246. if ((_type == DemuxTrack.TrackType.Unknown || _track.Type == _type) && _track.Active)
  8247. {
  8248. nCount++;
  8249. }
  8250. }
  8251. return nCount;
  8252. }
  8253. #endregion
  8254. #region Virtual Methods
  8255. public virtual HRESULT CloseInput()
  8256. {
  8257. while (m_Tracks.Count > 0)
  8258. {
  8259. m_Tracks[0].Dispose();
  8260. m_Tracks.RemoveAt(0);
  8261. }
  8262. if (m_Stream != null)
  8263. {
  8264. m_Stream.Dispose();
  8265. m_Stream = null;
  8266. }
  8267. m_rtDuration = 0;
  8268. m_sFileName = "";
  8269. return NOERROR;
  8270. }
  8271. public virtual HRESULT OpenInput(BitStreamReader _stream)
  8272. {
  8273. CloseInput();
  8274. if (_stream == null) return E_POINTER;
  8275. m_Stream = _stream;
  8276. HRESULT hr = CheckFile();
  8277. if (hr == S_OK)
  8278. {
  8279. hr = LoadTracks();
  8280. }
  8281. if (hr != S_OK)
  8282. {
  8283. CloseInput();
  8284. }
  8285. return hr;
  8286. }
  8287. public virtual HRESULT OpenInput(string sFileName)
  8288. {
  8289. CloseInput();
  8290. if (string.IsNullOrEmpty(sFileName)) return E_POINTER;
  8291. m_sFileName = sFileName;
  8292. HRESULT hr = CheckFile();
  8293. if (hr == S_OK)
  8294. {
  8295. hr = LoadTracks();
  8296. }
  8297. if (hr != S_OK)
  8298. {
  8299. CloseInput();
  8300. }
  8301. return hr;
  8302. }
  8303. public virtual HRESULT SeekToTime(long _time)
  8304. {
  8305. foreach (DemuxTrack _track in m_Tracks)
  8306. {
  8307. _track.SeekTrack(_time);
  8308. }
  8309. return NOERROR;
  8310. }
  8311. public virtual HRESULT OnDemuxStart()
  8312. {
  8313. return NOERROR;
  8314. }
  8315. public virtual HRESULT OnDemuxStop()
  8316. {
  8317. return NOERROR;
  8318. }
  8319. public virtual HRESULT ProcessDemuxPackets()
  8320. {
  8321. return S_FALSE;
  8322. }
  8323. public virtual HRESULT GetOpeningProgress(out long pllTotal, out long pllCurrent)
  8324. {
  8325. pllTotal = 0;
  8326. pllCurrent = 0;
  8327. return E_NOTIMPL;
  8328. }
  8329. #endregion
  8330. #region Abstract Methods
  8331. protected abstract HRESULT CheckFile();
  8332. protected abstract HRESULT LoadTracks();
  8333. #endregion
  8334. #region IDisposable Members
  8335. public virtual void Dispose()
  8336. {
  8337. CloseInput();
  8338. }
  8339. #endregion
  8340. }
  8341. [ComVisible(false)]
  8342. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  8343. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  8344. [ClassInterface(ClassInterfaceType.None)]
  8345. public class SplitterInputPin : BasePin
  8346. {
  8347. #region Constructor
  8348. public SplitterInputPin(string _name, BaseSplitter _filter)
  8349. : base(_name, _filter, _filter.FilterLock, PinDirection.Input)
  8350. {
  8351. }
  8352. #endregion
  8353. #region Overridden Methods
  8354. public override int CheckMediaType(AMMediaType pmt)
  8355. {
  8356. return NOERROR;
  8357. }
  8358. public override int BeginFlush()
  8359. {
  8360. return (m_Filter as BaseSplitter).BeginFlush();
  8361. }
  8362. public override int EndFlush()
  8363. {
  8364. return (m_Filter as BaseSplitter).EndFlush();
  8365. }
  8366. public override int CompleteConnect(ref IPinImpl pReceivePin)
  8367. {
  8368. int hr = base.CompleteConnect(ref pReceivePin);
  8369. if (FAILED(hr)) return hr;
  8370. return (m_Filter as BaseSplitter).CompleteConnect(ref pReceivePin);
  8371. }
  8372. public override int BreakConnect()
  8373. {
  8374. (m_Filter as BaseSplitter).UnloadFile();
  8375. return base.BreakConnect();
  8376. }
  8377. #endregion
  8378. }
  8379. [ComVisible(false)]
  8380. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  8381. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  8382. [ClassInterface(ClassInterfaceType.None)]
  8383. public class SplitterOutputPin : BaseOutputPin, IMediaSeeking
  8384. {
  8385. #region Variables
  8386. protected DemuxTrack m_pTrack = null;
  8387. protected object m_csThreadLock = new object();
  8388. protected object m_csEnableLock = new object();
  8389. protected object m_csFlushLock = new object();
  8390. protected ManualResetEvent m_evQuit = new ManualResetEvent(false);
  8391. protected ManualResetEvent m_evReady = new ManualResetEvent(true);
  8392. protected ManualResetEvent m_evFlush = new ManualResetEvent(false);
  8393. protected bool m_bEOSDelivered = false;
  8394. protected long m_rtPosition = -1;
  8395. protected bool m_bHaveException = false;
  8396. protected AMThread m_WorkerThread = null;
  8397. protected bool m_bStreamEnabled = true;
  8398. #endregion
  8399. #region Constructor
  8400. public SplitterOutputPin(DemuxTrack _track, string _name, BaseSplitter _filter)
  8401. : base(_name, _filter)
  8402. {
  8403. m_pTrack = _track;
  8404. ASSERT(m_pTrack != null);
  8405. m_pTrack.FlushEvent = m_evFlush;
  8406. m_WorkerThread = new ManagedThread(this.ThreadProc);
  8407. }
  8408. ~SplitterOutputPin()
  8409. {
  8410. StopThread();
  8411. }
  8412. #endregion
  8413. #region Properties
  8414. public bool EOSDelivered
  8415. {
  8416. get { return m_bEOSDelivered; }
  8417. }
  8418. public DemuxTrack Track
  8419. {
  8420. get { return m_pTrack; }
  8421. }
  8422. public bool StreamEnabled
  8423. {
  8424. get { return m_bStreamEnabled; }
  8425. set
  8426. {
  8427. lock (m_csEnableLock)
  8428. {
  8429. if (m_bStreamEnabled != value)
  8430. {
  8431. m_bStreamEnabled = value;
  8432. }
  8433. }
  8434. }
  8435. }
  8436. #endregion
  8437. #region Overridden Methods
  8438. public override int Active()
  8439. {
  8440. m_bHaveException = false;
  8441. int hr = base.Active();
  8442. if (SUCCEEDED(hr) && IsConnected)
  8443. {
  8444. StartThread();
  8445. }
  8446. return hr;
  8447. }
  8448. public override int Inactive()
  8449. {
  8450. int hr = base.Inactive();
  8451. StopThread();
  8452. m_rtPosition = -1;
  8453. return hr;
  8454. }
  8455. public override int DeliverBeginFlush()
  8456. {
  8457. HRESULT hr = NOERROR;
  8458. lock (m_csFlushLock)
  8459. {
  8460. if (!m_evFlush.WaitOne(0, false))
  8461. {
  8462. TRACE("Begin Flush");
  8463. {
  8464. m_evFlush.Set();
  8465. if (IsConnected)
  8466. {
  8467. hr = (HRESULT)base.DeliverBeginFlush();
  8468. hr.Assert();
  8469. }
  8470. }
  8471. }
  8472. }
  8473. return hr;
  8474. }
  8475. public override int DeliverEndFlush()
  8476. {
  8477. HRESULT hr = NOERROR;
  8478. lock (m_csFlushLock)
  8479. {
  8480. if (m_evFlush.WaitOne(0, false))
  8481. {
  8482. m_pTrack.Flush();
  8483. if (IsConnected)
  8484. {
  8485. lock (m_csThreadLock)
  8486. {
  8487. hr = (HRESULT)base.DeliverEndFlush();
  8488. }
  8489. hr.Assert();
  8490. }
  8491. TRACE("End Flush");
  8492. m_evFlush.Reset();
  8493. }
  8494. }
  8495. return hr;
  8496. }
  8497. public override int CompleteConnect(ref IPinImpl pReceivePin)
  8498. {
  8499. int hr = base.CompleteConnect(ref pReceivePin);
  8500. if (SUCCEEDED(hr) && m_pTrack != null)
  8501. {
  8502. long _time = 2 * UNITS;
  8503. m_pTrack.Alloc(_time);
  8504. m_pTrack.Active = true;
  8505. }
  8506. return hr;
  8507. }
  8508. public override int BreakConnect()
  8509. {
  8510. int hr = base.BreakConnect();
  8511. if (m_pTrack != null)
  8512. {
  8513. m_pTrack.Flush();
  8514. m_pTrack.Active = false;
  8515. }
  8516. (m_Filter as BaseSplitter).DeselectSeekingPin(this);
  8517. return hr;
  8518. }
  8519. public override int CheckMediaType(AMMediaType pmt)
  8520. {
  8521. return NOERROR;
  8522. }
  8523. public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  8524. {
  8525. if (iPosition < 0) return E_INVALIDARG;
  8526. return m_pTrack.GetMediaType(iPosition, ref pMediaType);
  8527. }
  8528. public override int SetMediaType(AMMediaType mt)
  8529. {
  8530. HRESULT hr = m_pTrack.SetMediaType(mt);
  8531. if (FAILED(hr)) return hr;
  8532. return base.SetMediaType(mt);
  8533. }
  8534. public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
  8535. {
  8536. if (!IsConnected) return VFW_E_NOT_CONNECTED;
  8537. if (m_mt.majorType == MediaType.Video)
  8538. {
  8539. BitmapInfoHeader _bmi = m_mt;
  8540. if (_bmi == null) return VFW_E_INVALIDMEDIATYPE;
  8541. int lSize = m_mt.sampleSize;
  8542. lSize = Math.Max(lSize, _bmi.ImageSize);
  8543. lSize = Math.Max(lSize, _bmi.Width * Math.Abs(_bmi.Height) * _bmi.BitCount / 8);
  8544. if (_bmi.BitCount == 0)
  8545. {
  8546. lSize = Math.Max(lSize, _bmi.Width * Math.Abs(_bmi.Height) * 4);
  8547. }
  8548. if (_bmi.Width == 0 || _bmi.Height == 0)
  8549. {
  8550. lSize = Math.Max(lSize, GetSystemMetrics(0) * GetSystemMetrics(1) * 4);
  8551. }
  8552. if (lSize > prop.cbBuffer)
  8553. {
  8554. prop.cbBuffer = lSize;
  8555. }
  8556. if (prop.cBuffers < 4)
  8557. {
  8558. prop.cBuffers = 4;
  8559. }
  8560. }
  8561. if (m_mt.majorType == MediaType.Audio)
  8562. {
  8563. WaveFormatEx _wfx = m_mt;
  8564. if (_wfx == null) return VFW_E_INVALIDMEDIATYPE;
  8565. if (_wfx.nAvgBytesPerSec > 0)
  8566. {
  8567. prop.cbBuffer = _wfx.nAvgBytesPerSec;
  8568. }
  8569. else
  8570. {
  8571. prop.cbBuffer = _wfx.nSamplesPerSec * _wfx.nBlockAlign;
  8572. }
  8573. prop.cBuffers = 4;
  8574. prop.cbAlign = _wfx.nBlockAlign;
  8575. if (prop.cbBuffer == 0)
  8576. {
  8577. prop.cbBuffer = (_wfx.nSamplesPerSec * _wfx.nChannels) << 3;
  8578. }
  8579. }
  8580. {
  8581. int lBufferSize = prop.cbBuffer;
  8582. short wBuffers = (short)prop.cBuffers;
  8583. if (S_OK == m_pTrack.GetTrackAllocatorRequirements(ref lBufferSize, ref wBuffers))
  8584. {
  8585. if (wBuffers > 0) prop.cBuffers = wBuffers;
  8586. if (lBufferSize > 0) prop.cbBuffer = lBufferSize;
  8587. }
  8588. }
  8589. if (prop.cbAlign < 1)
  8590. {
  8591. prop.cbAlign = 1;
  8592. }
  8593. prop.cbPrefix = 0;
  8594. if (prop.cbBuffer == 0) return E_UNEXPECTED;
  8595. AllocatorProperties _actual = new AllocatorProperties();
  8596. int hr = pAlloc.SetProperties(prop, _actual);
  8597. if (FAILED(hr)) return hr;
  8598. if (_actual.cbBuffer < prop.cbBuffer) return E_FAIL;
  8599. return NOERROR;
  8600. }
  8601. public override int Notify(IntPtr pSelf, Quality q)
  8602. {
  8603. return NOERROR;
  8604. }
  8605. #endregion
  8606. #region Methods
  8607. public void StartThread()
  8608. {
  8609. m_evQuit.Reset();
  8610. if (m_evReady.WaitOne(0, false))
  8611. {
  8612. m_WorkerThread.Create();
  8613. }
  8614. }
  8615. public void StopThread()
  8616. {
  8617. m_evQuit.Set();
  8618. if (!m_evReady.WaitOne(0, false))
  8619. {
  8620. bool bFlush = false;
  8621. if (m_WorkerThread.ThreadExists)
  8622. {
  8623. if (!m_WorkerThread.Join(10000))
  8624. {
  8625. lock (m_csFlushLock)
  8626. {
  8627. if (!m_evFlush.WaitOne(0, false))
  8628. {
  8629. m_evFlush.Set();
  8630. bFlush = true;
  8631. }
  8632. }
  8633. }
  8634. }
  8635. if (bFlush)
  8636. {
  8637. m_evFlush.Reset();
  8638. }
  8639. }
  8640. m_WorkerThread.Close();
  8641. }
  8642. #endregion
  8643. #region Protected Methods
  8644. protected virtual void ThreadProc()
  8645. {
  8646. m_bEOSDelivered = false;
  8647. IMediaSampleImpl _sample;
  8648. long _start, _stop;
  8649. double _rate;
  8650. (m_Filter as BaseSplitter).GetPositions(out _start, out _stop, out _rate);
  8651. DeliverNewSegment(_start, _stop, _rate);
  8652. m_evReady.Reset();
  8653. long _shift = 0;
  8654. bool bEnabled;
  8655. lock (m_csEnableLock)
  8656. {
  8657. bEnabled = m_bStreamEnabled;
  8658. }
  8659. while (!m_evQuit.WaitOne(0, false))
  8660. {
  8661. long tStart = 0, tStop = 0;
  8662. bool bEOS = m_pTrack.IsEOS;
  8663. _sample = null;
  8664. HRESULT hr;
  8665. if (!bEOS)
  8666. {
  8667. lock (m_csThreadLock)
  8668. {
  8669. IntPtr pSample;
  8670. hr = (HRESULT)GetDeliveryBuffer(out pSample, null, null, AMGBF.None);
  8671. if (hr.Succeeded)
  8672. {
  8673. _sample = new IMediaSampleImpl(pSample);
  8674. AMMediaType pmt;
  8675. if (_sample.GetMediaType(out pmt) == NOERROR)
  8676. {
  8677. if (FAILED(SetMediaType(pmt)))
  8678. {
  8679. _sample.SetMediaType(null);
  8680. }
  8681. pmt.Free();
  8682. }
  8683. hr = m_pTrack.ReadMediaSample(ref _sample);
  8684. if (hr == S_FALSE || FAILED(hr))
  8685. {
  8686. bEOS = true;
  8687. }
  8688. else
  8689. {
  8690. if (S_OK == _sample.GetTime(out tStart, out tStop))
  8691. {
  8692. if (
  8693. (tStart > tStop && tStop > _stop)
  8694. || (tStart <= tStop && tStart > _stop)
  8695. )
  8696. {
  8697. bEOS = true;
  8698. }
  8699. else
  8700. {
  8701. tStart -= _start;
  8702. tStop -= _start;
  8703. m_rtPosition = tStart;
  8704. if (_rate != 1.0)
  8705. {
  8706. tStart = (long)(tStart / _rate);
  8707. tStop = (long)(tStop / _rate);
  8708. }
  8709. }
  8710. if (bEnabled)
  8711. {
  8712. tStart -= _shift;
  8713. tStop -= _shift;
  8714. }
  8715. else
  8716. {
  8717. _shift += tStop - tStart;
  8718. }
  8719. if (tStart < 0)
  8720. {
  8721. _sample.SetPreroll(true);
  8722. }
  8723. _sample.SetTime(tStart, tStop);
  8724. }
  8725. }
  8726. }
  8727. else
  8728. {
  8729. break;
  8730. }
  8731. }
  8732. //TRACE(string.Format("Sample: start {0}, stop {1}", tStart / 10000, tStop / 10000));
  8733. }
  8734. if (bEOS)
  8735. {
  8736. if (_sample != null) _sample._Release();
  8737. if (!m_evFlush.WaitOne(0, false) && !(m_Filter as BaseSplitter).QuitEvent.WaitOne(0, false) && !m_evQuit.WaitOne(0, false))
  8738. {
  8739. DeliverBeginFlush();
  8740. DeliverEndFlush();
  8741. TRACE("EOS Delivered");
  8742. #if !DEBUG
  8743. try {
  8744. #endif
  8745. DeliverEndOfStream();
  8746. #if !DEBUG
  8747. } catch
  8748. {
  8749. m_bHaveException = true;
  8750. TRACE("EOS exception");
  8751. m_Filter.NotifyEvent(EventCode.ErrorAbort, (IntPtr)((int)E_UNEXPECTED), IntPtr.Zero);
  8752. }
  8753. #endif
  8754. m_bEOSDelivered = true;
  8755. }
  8756. break;
  8757. }
  8758. if (_sample != null)
  8759. {
  8760. if (m_evFlush.WaitOne(0, false) && m_pTrack.Type == DemuxTrack.TrackType.Audio)
  8761. {
  8762. _sample.SetDiscontinuity(true);
  8763. }
  8764. lock (m_csEnableLock)
  8765. {
  8766. bEnabled = m_bStreamEnabled;
  8767. }
  8768. if (!bEnabled)
  8769. {
  8770. _sample._Release();
  8771. continue;
  8772. }
  8773. #if !DEBUG
  8774. try {
  8775. #endif
  8776. hr = (HRESULT)Deliver(ref _sample);
  8777. _sample._Release();
  8778. if (hr != S_OK)
  8779. {
  8780. break;
  8781. }
  8782. #if !DEBUG
  8783. } catch
  8784. {
  8785. m_bHaveException = true;
  8786. TRACE("Pin delivery exception");
  8787. if (_sample != null)
  8788. {
  8789. Allocator.ReleaseBuffer(_sample.UnknownPtr);
  8790. _sample = null;
  8791. }
  8792. if (!m_evFlush.WaitOne(0,false) && !m_bEOSDelivered)
  8793. {
  8794. TRACE("EOS Delivered");
  8795. DeliverEndOfStream();
  8796. m_bEOSDelivered = true;
  8797. }
  8798. m_pTrack.Flush();
  8799. m_Filter.NotifyEvent(EventCode.ErrorAbort, (IntPtr)((int)E_UNEXPECTED), IntPtr.Zero);
  8800. break;
  8801. }
  8802. #endif
  8803. }
  8804. }
  8805. m_evReady.Set();
  8806. }
  8807. #endregion
  8808. #region IMediaSeeking Members
  8809. public virtual int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  8810. {
  8811. pCapabilities = AMSeekingSeekingCapabilities.CanSeekAbsolute |
  8812. AMSeekingSeekingCapabilities.CanSeekForwards |
  8813. AMSeekingSeekingCapabilities.CanSeekBackwards |
  8814. AMSeekingSeekingCapabilities.CanGetDuration |
  8815. AMSeekingSeekingCapabilities.CanGetCurrentPos |
  8816. AMSeekingSeekingCapabilities.CanGetStopPos;
  8817. return NOERROR;
  8818. }
  8819. public virtual int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  8820. {
  8821. AMSeekingSeekingCapabilities dwActual;
  8822. GetCapabilities(out dwActual);
  8823. if ((int)((int)pCapabilities & (~(int)dwActual)) == 0)
  8824. {
  8825. return S_FALSE;
  8826. }
  8827. return S_OK;
  8828. }
  8829. public virtual int IsFormatSupported(Guid pFormat)
  8830. {
  8831. if (pFormat == TimeFormat.MediaTime)
  8832. {
  8833. return S_OK;
  8834. }
  8835. return S_FALSE;
  8836. }
  8837. public virtual int QueryPreferredFormat(out Guid pFormat)
  8838. {
  8839. pFormat = TimeFormat.MediaTime;
  8840. return S_OK;
  8841. }
  8842. public virtual int GetTimeFormat(out Guid pFormat)
  8843. {
  8844. return QueryPreferredFormat(out pFormat);
  8845. }
  8846. public virtual int IsUsingTimeFormat(Guid pFormat)
  8847. {
  8848. Guid guidActual;
  8849. int hr = GetTimeFormat(out guidActual);
  8850. if (SUCCEEDED(hr) && (guidActual == pFormat))
  8851. {
  8852. return S_OK;
  8853. }
  8854. else
  8855. {
  8856. return S_FALSE;
  8857. }
  8858. }
  8859. public virtual int SetTimeFormat(Guid pFormat)
  8860. {
  8861. if (pFormat == TimeFormat.MediaTime)
  8862. {
  8863. return (m_Filter as BaseSplitter).SelectSeekingPin(this) ? S_OK : E_NOTIMPL;
  8864. }
  8865. else
  8866. if (pFormat == TimeFormat.None)
  8867. {
  8868. (m_Filter as BaseSplitter).DeselectSeekingPin(this);
  8869. return S_OK;
  8870. }
  8871. return E_NOTIMPL;
  8872. }
  8873. public virtual int GetDuration(out long pDuration)
  8874. {
  8875. pDuration = 0;
  8876. if (m_pTrack != null)
  8877. {
  8878. pDuration = m_pTrack.Duration + m_pTrack.Offset;
  8879. }
  8880. return NOERROR;
  8881. }
  8882. public virtual int GetStopPosition(out long pStop)
  8883. {
  8884. long _current;
  8885. return GetPositions(out _current, out pStop);
  8886. }
  8887. public virtual int GetCurrentPosition(out long pCurrent)
  8888. {
  8889. long _stop;
  8890. return GetPositions(out pCurrent, out _stop);
  8891. }
  8892. public virtual int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  8893. {
  8894. pTarget = 0;
  8895. if (pTargetFormat == null || pTargetFormat == TimeFormat.MediaTime)
  8896. {
  8897. if (pSourceFormat == null || pSourceFormat == TimeFormat.MediaTime)
  8898. {
  8899. pTarget = Source;
  8900. return S_OK;
  8901. }
  8902. }
  8903. return E_INVALIDARG;
  8904. }
  8905. public virtual int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  8906. {
  8907. BaseSplitter _filter = (m_Filter as BaseSplitter);
  8908. if (_filter.SelectSeekingPin(this))
  8909. {
  8910. long _start, _stop;
  8911. double _rate;
  8912. _filter.GetPositions(out _start, out _stop, out _rate);
  8913. if (((int)dwCurrentFlags & (int)AMSeekingSeekingFlags.AbsolutePositioning) != 0)
  8914. {
  8915. _start = pCurrent;
  8916. }
  8917. else if (((int)dwCurrentFlags & (int)AMSeekingSeekingFlags.RelativePositioning) != 0)
  8918. {
  8919. _start += pCurrent;
  8920. }
  8921. if (((int)dwStopFlags & (int)AMSeekingSeekingFlags.AbsolutePositioning) != 0)
  8922. {
  8923. _stop = pStop;
  8924. }
  8925. else if (((int)dwStopFlags & (int)AMSeekingSeekingFlags.IncrementalPositioning) != 0)
  8926. {
  8927. _stop = pStop + _start;
  8928. }
  8929. else
  8930. {
  8931. if (((int)dwStopFlags & (int)AMSeekingSeekingFlags.RelativePositioning) != 0)
  8932. {
  8933. _stop += pStop;
  8934. }
  8935. }
  8936. if (((int)dwCurrentFlags & (int)AMSeekingSeekingFlags.PositioningBitsMask) != 0)
  8937. {
  8938. return _filter.SetPositions(_start, _stop, -1);
  8939. }
  8940. else if (((int)dwStopFlags & (int)AMSeekingSeekingFlags.PositioningBitsMask) != 0)
  8941. {
  8942. // stop change only
  8943. return _filter.SetPositions(-1, _stop, -1);
  8944. }
  8945. else
  8946. {
  8947. return S_FALSE;
  8948. }
  8949. }
  8950. return NOERROR;
  8951. }
  8952. public virtual int GetPositions(out long pCurrent, out long pStop)
  8953. {
  8954. double _rate;
  8955. (m_Filter as BaseSplitter).GetPositions(out pCurrent, out pStop, out _rate);
  8956. if (m_rtPosition >= 0)
  8957. {
  8958. pCurrent = m_rtPosition;
  8959. }
  8960. return NOERROR;
  8961. }
  8962. public virtual int GetAvailable(out long pEarliest, out long pLatest)
  8963. {
  8964. pEarliest = 0;
  8965. pLatest = m_pTrack.Duration;
  8966. return NOERROR;
  8967. }
  8968. public virtual int SetRate(double dRate)
  8969. {
  8970. if ((m_Filter as BaseSplitter).SelectSeekingPin(this))
  8971. {
  8972. return (m_Filter as BaseSplitter).SetPositions(-1, -1, dRate);
  8973. }
  8974. return NOERROR;
  8975. }
  8976. public virtual int GetRate(out double pdRate)
  8977. {
  8978. long _start, _stop;
  8979. (m_Filter as BaseSplitter).GetPositions(out _start, out _stop, out pdRate);
  8980. return NOERROR;
  8981. }
  8982. public virtual int GetPreroll(out long pllPreroll)
  8983. {
  8984. pllPreroll = m_pTrack.Offset;
  8985. return NOERROR;
  8986. }
  8987. #endregion
  8988. #region API
  8989. [DllImport("User32.dll")]
  8990. private static extern int GetSystemMetrics(int nIndex);
  8991. #endregion
  8992. }
  8993. [ComVisible(false)]
  8994. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  8995. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  8996. [ClassInterface(ClassInterfaceType.None)]
  8997. public abstract class BaseSplitter : BaseFilter, IMediaSeeking, IAMStreamSelect
  8998. {
  8999. #region Variables
  9000. protected string m_sFileName = "";
  9001. protected object m_csSeeking = new object();
  9002. protected long m_tStartTime = 0;
  9003. protected long m_tStopTime = MAX_LONG;
  9004. protected double m_dRate = 1.0;
  9005. protected SplitterOutputPin m_pSeekingPin = null;
  9006. protected ManualResetEvent m_evQuit = new ManualResetEvent(false);
  9007. protected ManualResetEvent m_evReady = new ManualResetEvent(true);
  9008. protected ManualResetEvent m_evEOS = new ManualResetEvent(true);
  9009. protected AutoResetEvent m_evDemuxStarted = new AutoResetEvent(false);
  9010. protected bool m_bLoading = false;
  9011. protected object m_csThreadLock = new object();
  9012. protected FileParser m_pFileParser = null;
  9013. protected AMThread m_WorkerThread = null;
  9014. protected List<FileParser> m_Parsers = new List<FileParser>();
  9015. #endregion
  9016. #region Constructor
  9017. protected BaseSplitter(string _name)
  9018. : base(_name)
  9019. {
  9020. m_WorkerThread = new ManagedThread(this.ThreadProc);
  9021. }
  9022. ~BaseSplitter()
  9023. {
  9024. UnloadFile();
  9025. }
  9026. #endregion
  9027. #region Properties
  9028. public string FileName
  9029. {
  9030. get
  9031. {
  9032. if (string.IsNullOrEmpty(m_sFileName) && InputPin != null)
  9033. {
  9034. try
  9035. {
  9036. PinInfo _info;
  9037. InputPin.QueryPinInfo(out _info);
  9038. if (_info.filter != null)
  9039. {
  9040. IFileSourceFilter _source = (IFileSourceFilter)_info.filter;
  9041. _source.GetCurFile(out m_sFileName, null);
  9042. }
  9043. _info.filter = null;
  9044. }
  9045. catch
  9046. {
  9047. }
  9048. }
  9049. return m_sFileName;
  9050. }
  9051. }
  9052. public EventWaitHandle QuitEvent
  9053. {
  9054. get { return m_evQuit; }
  9055. }
  9056. public SplitterInputPin InputPin
  9057. {
  9058. get
  9059. {
  9060. if (Pins.Count > 0 && Pins[0].Direction == PinDirection.Input)
  9061. {
  9062. return (Pins[0] as SplitterInputPin);
  9063. }
  9064. return null;
  9065. }
  9066. }
  9067. public SplitterOutputPin SeekingPin
  9068. {
  9069. get
  9070. {
  9071. lock (m_csSeeking)
  9072. {
  9073. if (m_pSeekingPin != null && !m_pSeekingPin.IsConnected)
  9074. {
  9075. m_pSeekingPin = null;
  9076. }
  9077. if (m_pSeekingPin == null)
  9078. {
  9079. foreach (BasePin _pin in Pins)
  9080. {
  9081. if (_pin.Direction == PinDirection.Output && _pin.IsConnected)
  9082. {
  9083. m_pSeekingPin = (_pin as SplitterOutputPin);
  9084. break;
  9085. }
  9086. }
  9087. foreach (BasePin _pin in Pins)
  9088. {
  9089. if (_pin.Direction == PinDirection.Output)
  9090. {
  9091. if (m_pSeekingPin == null)
  9092. {
  9093. m_pSeekingPin = (_pin as SplitterOutputPin);
  9094. }
  9095. else
  9096. {
  9097. if (_pin.IsConnected && _pin != m_pSeekingPin)
  9098. {
  9099. if (m_pSeekingPin.Track.TrackDuration < (_pin as SplitterOutputPin).Track.TrackDuration)
  9100. {
  9101. m_pSeekingPin = (_pin as SplitterOutputPin);
  9102. }
  9103. }
  9104. }
  9105. }
  9106. }
  9107. }
  9108. }
  9109. return m_pSeekingPin;
  9110. }
  9111. }
  9112. #endregion
  9113. #region Overridden Methods
  9114. protected override int OnInitializePins()
  9115. {
  9116. return NOERROR;
  9117. }
  9118. public override int Pause()
  9119. {
  9120. if (m_State == FilterState.Stopped)
  9121. {
  9122. HRESULT hr = StartThread();
  9123. if (hr.Failed) return hr;
  9124. }
  9125. return base.Pause();
  9126. }
  9127. public override int Stop()
  9128. {
  9129. StopThread();
  9130. return base.Stop();
  9131. }
  9132. protected override int AfterInstall(HRESULT hr, ref RegFilter2 _reginfo, ref IFilterMapper2 _mapper2)
  9133. {
  9134. if (hr.Succeeded)
  9135. {
  9136. Type _type = this.GetType();
  9137. RegisterProtocol(_type);
  9138. RegisterFileExtension(_type);
  9139. RegisterMediaType(_type);
  9140. foreach (FileParser _parser in m_Parsers)
  9141. {
  9142. _type = _parser.GetType();
  9143. RegisterProtocol(_type);
  9144. RegisterFileExtension(_type);
  9145. RegisterMediaType(_type);
  9146. }
  9147. }
  9148. return base.AfterInstall(hr, ref _reginfo, ref _mapper2);
  9149. }
  9150. protected override int AfterUninstall(HRESULT hr, ref IFilterMapper2 _mapper2)
  9151. {
  9152. Type _type = this.GetType();
  9153. UnregisterProtocol(_type);
  9154. UnregisterFileExtension(_type);
  9155. UnregisterMediaType(_type);
  9156. foreach (FileParser _parser in m_Parsers)
  9157. {
  9158. _type = _parser.GetType();
  9159. UnregisterProtocol(_type);
  9160. UnregisterFileExtension(_type);
  9161. UnregisterMediaType(_type);
  9162. }
  9163. return base.AfterUninstall(hr, ref _mapper2);
  9164. }
  9165. #endregion
  9166. #region Virtual Methods
  9167. public virtual HRESULT BeginFlush()
  9168. {
  9169. foreach (BasePin _pin in Pins)
  9170. {
  9171. if (_pin.Direction == PinDirection.Output)
  9172. {
  9173. (_pin as SplitterOutputPin).DeliverBeginFlush();
  9174. }
  9175. }
  9176. return NOERROR;
  9177. }
  9178. public virtual HRESULT EndFlush()
  9179. {
  9180. foreach (BasePin _pin in Pins)
  9181. {
  9182. if (_pin.Direction == PinDirection.Output)
  9183. {
  9184. (_pin as SplitterOutputPin).DeliverEndFlush();
  9185. }
  9186. }
  9187. return NOERROR;
  9188. }
  9189. public virtual HRESULT CompleteConnect(ref IPinImpl pReceivePin)
  9190. {
  9191. UnloadFile();
  9192. m_bLoading = true;
  9193. BitStreamReader _stream = null;
  9194. Guid _guid = typeof(IAsyncReader).GUID;
  9195. IntPtr pAsyncReader = IntPtr.Zero;
  9196. if (S_OK == pReceivePin._QueryInterface(ref _guid, out pAsyncReader))
  9197. {
  9198. _stream = new BitStreamReader(new AsyncStream(pAsyncReader));
  9199. try
  9200. {
  9201. if (S_OK == DecideFileParser(_stream))
  9202. {
  9203. m_bLoading = false;
  9204. return NOERROR;
  9205. }
  9206. }
  9207. catch
  9208. {
  9209. }
  9210. finally
  9211. {
  9212. Marshal.Release(pAsyncReader);
  9213. }
  9214. }
  9215. UnloadFile();
  9216. if (_stream != null)
  9217. {
  9218. _stream.Dispose();
  9219. _stream = null;
  9220. }
  9221. m_sFileName = FileName;
  9222. if (!string.IsNullOrEmpty(m_sFileName))
  9223. {
  9224. try
  9225. {
  9226. if (S_OK == DecideFileParser(m_sFileName))
  9227. {
  9228. m_bLoading = false;
  9229. return NOERROR;
  9230. }
  9231. }
  9232. catch
  9233. {
  9234. }
  9235. }
  9236. m_bLoading = false;
  9237. UnloadFile();
  9238. return VFW_E_CANNOT_CONNECT;
  9239. }
  9240. public virtual HRESULT UnloadFile()
  9241. {
  9242. m_evQuit.Set();
  9243. lock (m_Lock)
  9244. {
  9245. m_sFileName = "";
  9246. {
  9247. lock (m_csSeeking)
  9248. {
  9249. m_pSeekingPin = null;
  9250. }
  9251. }
  9252. while (Pins.Count > 0)
  9253. {
  9254. BasePin _pin = Pins[Pins.Count - 1];
  9255. if (_pin.Direction == PinDirection.Input) break;
  9256. Pins.Remove(_pin);
  9257. if (_pin.IsConnected)
  9258. {
  9259. _pin.Connected.Disconnect();
  9260. _pin.Disconnect();
  9261. }
  9262. }
  9263. if (m_pFileParser != null)
  9264. {
  9265. m_pFileParser.CloseInput();
  9266. m_pFileParser = null;
  9267. }
  9268. }
  9269. m_evQuit.Reset();
  9270. return NOERROR;
  9271. }
  9272. protected virtual HRESULT DecideFileParser(string sFileName)
  9273. {
  9274. foreach (FileParser _parser in m_Parsers)
  9275. {
  9276. _parser.QuitEvent = m_evQuit;
  9277. _parser.EOSEvent = m_evEOS;
  9278. if (S_OK == _parser.OpenInput(sFileName))
  9279. {
  9280. if (_parser.Count > 0)
  9281. {
  9282. m_pFileParser = _parser;
  9283. if (InitializeOutputPins() == S_OK)
  9284. {
  9285. return S_OK;
  9286. }
  9287. else
  9288. {
  9289. _parser.CloseInput();
  9290. m_pFileParser = null;
  9291. }
  9292. }
  9293. else
  9294. {
  9295. _parser.CloseInput();
  9296. }
  9297. }
  9298. }
  9299. return E_FAIL;
  9300. }
  9301. protected virtual HRESULT DecideFileParser(BitStreamReader _reader)
  9302. {
  9303. if (_reader == null) return E_POINTER;
  9304. foreach (FileParser _parser in m_Parsers)
  9305. {
  9306. _parser.QuitEvent = m_evQuit;
  9307. _parser.EOSEvent = m_evEOS;
  9308. if (S_OK == _parser.OpenInput(_reader))
  9309. {
  9310. if (_parser.Count > 0)
  9311. {
  9312. m_pFileParser = _parser;
  9313. if (InitializeOutputPins() == S_OK)
  9314. {
  9315. return S_OK;
  9316. }
  9317. else
  9318. {
  9319. _parser.CloseInput();
  9320. m_pFileParser = null;
  9321. }
  9322. }
  9323. else
  9324. {
  9325. _parser.CloseInput();
  9326. }
  9327. }
  9328. }
  9329. return E_FAIL;
  9330. }
  9331. protected virtual HRESULT InitializeOutputPins()
  9332. {
  9333. if (m_pFileParser == null) return E_UNEXPECTED;
  9334. int nAdded = 0;
  9335. int nCount = m_pFileParser.Count;
  9336. int[] _indexes = new int[(int)DemuxTrack.TrackType.Subtitles + 1];
  9337. bool[] _useIndexes = new bool[_indexes.Length];
  9338. for (int i = 0; i < _indexes.Length; i++)
  9339. {
  9340. _indexes[i] = 0;
  9341. _useIndexes[i] = (m_pFileParser.GetTracksCountByType((DemuxTrack.TrackType)i) > 1);
  9342. }
  9343. for (int i = 0; i < nCount; i++)
  9344. {
  9345. DemuxTrack _track = m_pFileParser[i];
  9346. if (_track != null && _track.IsTrackValid)
  9347. {
  9348. string _name = _track.Name;
  9349. if (string.IsNullOrEmpty(_name))
  9350. {
  9351. _name = "Unknown";
  9352. switch (_track.Type)
  9353. {
  9354. case DemuxTrack.TrackType.Video:
  9355. _name = "Video";
  9356. break;
  9357. case DemuxTrack.TrackType.Audio:
  9358. _name = "Audio";
  9359. break;
  9360. case DemuxTrack.TrackType.Subtitles:
  9361. _name = "Subtitles";
  9362. break;
  9363. case DemuxTrack.TrackType.SubPicture:
  9364. _name = "Sub Picture";
  9365. break;
  9366. }
  9367. int _type = (int)_track.Type;
  9368. if (_type >= 0 && _type < _indexes.Length)
  9369. {
  9370. if (_useIndexes[_type])
  9371. {
  9372. _name += " " + (_indexes[_type]++).ToString();
  9373. }
  9374. }
  9375. }
  9376. if (!_track.Enabled)
  9377. {
  9378. _name = "~" + _name;
  9379. }
  9380. AddPin(new SplitterOutputPin(_track, _name, this));
  9381. nAdded++;
  9382. }
  9383. }
  9384. return (nAdded == 0 ? VFW_E_NO_ACCEPTABLE_TYPES : NOERROR);
  9385. }
  9386. #endregion
  9387. #region Registration Helpers
  9388. public virtual HRESULT RegisterProtocol(Type _type)
  9389. {
  9390. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterProtocolExtension));
  9391. if (_attributes != null)
  9392. {
  9393. foreach (RegisterProtocolExtension _setup in _attributes)
  9394. {
  9395. if (_setup != null && !string.IsNullOrEmpty(_setup.Protocol))
  9396. {
  9397. Microsoft.Win32.RegistryKey _key = null;
  9398. try
  9399. {
  9400. if (_setup.Extensions.Count > 0)
  9401. {
  9402. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_setup.Protocol + "\\Extensions");
  9403. foreach (string _extension in _setup.Extensions)
  9404. {
  9405. if (!string.IsNullOrEmpty(_extension))
  9406. {
  9407. _key.SetValue(_extension, this.GetType().GUID.ToString("B"));
  9408. }
  9409. }
  9410. }
  9411. else
  9412. {
  9413. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_setup.Protocol);
  9414. _key.SetValue("Source Filter", this.GetType().GUID.ToString("B"));
  9415. }
  9416. }
  9417. catch (Exception _exception)
  9418. {
  9419. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9420. hr.TraceWrite();
  9421. }
  9422. finally
  9423. {
  9424. if (_key != null)
  9425. {
  9426. _key.Close();
  9427. }
  9428. }
  9429. }
  9430. }
  9431. }
  9432. return NOERROR;
  9433. }
  9434. public virtual HRESULT RegisterFileExtension(Type _type)
  9435. {
  9436. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterFileExtension));
  9437. if (_attributes != null)
  9438. {
  9439. foreach (RegisterFileExtension _setup in _attributes)
  9440. {
  9441. if (_setup != null && !string.IsNullOrEmpty(_setup.Extension))
  9442. {
  9443. Microsoft.Win32.RegistryKey _key = null;
  9444. try
  9445. {
  9446. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey("Media Type\\Extensions\\" + _setup.Extension);
  9447. _key.SetValue("Source Filter", this.GetType().GUID.ToString("B"));
  9448. if (_setup.MediaType != Guid.Empty)
  9449. {
  9450. _key.SetValue("Media Type", _setup.MediaType.ToString("B"));
  9451. }
  9452. if (_setup.SubType != Guid.Empty)
  9453. {
  9454. _key.SetValue("SubType", _setup.SubType.ToString("B"));
  9455. }
  9456. }
  9457. catch (Exception _exception)
  9458. {
  9459. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9460. hr.TraceWrite();
  9461. }
  9462. finally
  9463. {
  9464. if (_key != null)
  9465. {
  9466. _key.Close();
  9467. }
  9468. }
  9469. }
  9470. }
  9471. }
  9472. return NOERROR;
  9473. }
  9474. public virtual HRESULT RegisterMediaType(Type _type)
  9475. {
  9476. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterMediaType));
  9477. if (_attributes != null)
  9478. {
  9479. foreach (RegisterMediaType _setup in _attributes)
  9480. {
  9481. if (_setup != null && !string.IsNullOrEmpty(_setup.Sequence))
  9482. {
  9483. Microsoft.Win32.RegistryKey _key = null;
  9484. try
  9485. {
  9486. string _path = "Media Type\\";
  9487. if (_setup.MajorType != Guid.Empty)
  9488. {
  9489. _path += _setup.MajorType.ToString("B") + "\\";
  9490. }
  9491. else
  9492. {
  9493. _path += MediaType.Stream.ToString("B") + "\\";
  9494. }
  9495. _path += _setup.SubType.ToString("B");
  9496. _key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(_path);
  9497. if (_setup.FilterGuid == Guid.Empty)
  9498. {
  9499. if (this.InputPin == null)
  9500. {
  9501. _key.SetValue("Source Filter", this.GetType().GUID.ToString("B"));
  9502. }
  9503. else
  9504. {
  9505. _key.SetValue("Source Filter", typeof(DSFileSourceAsync).GUID.ToString("B"));
  9506. }
  9507. }
  9508. else
  9509. {
  9510. _key.SetValue("Source Filter", _setup.FilterGuid.ToString("B"));
  9511. }
  9512. int nIndex = 0;
  9513. while (null != _key.GetValue(nIndex.ToString(), null)) { nIndex++; }
  9514. _key.SetValue(nIndex.ToString(), _setup.Sequence);
  9515. }
  9516. catch (Exception _exception)
  9517. {
  9518. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9519. hr.TraceWrite();
  9520. }
  9521. finally
  9522. {
  9523. if (_key != null)
  9524. {
  9525. _key.Close();
  9526. }
  9527. }
  9528. }
  9529. }
  9530. }
  9531. return NOERROR;
  9532. }
  9533. public virtual HRESULT UnregisterProtocol(Type _type)
  9534. {
  9535. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterProtocolExtension));
  9536. if (_attributes != null)
  9537. {
  9538. foreach (RegisterProtocolExtension _setup in _attributes)
  9539. {
  9540. if (_setup != null && !string.IsNullOrEmpty(_setup.Protocol))
  9541. {
  9542. Microsoft.Win32.RegistryKey _key = null;
  9543. try
  9544. {
  9545. if (_setup.Extensions.Count > 0)
  9546. {
  9547. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(_setup.Protocol + "\\Extensions");
  9548. if (_key != null)
  9549. {
  9550. foreach (string _extension in _setup.Extensions)
  9551. {
  9552. if (!string.IsNullOrEmpty(_extension))
  9553. {
  9554. _key.DeleteValue(_extension);
  9555. }
  9556. }
  9557. if (_key.ValueCount == 0 && _key.SubKeyCount == 0)
  9558. {
  9559. _key.Close();
  9560. _key = null;
  9561. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(_setup.Protocol);
  9562. _key.DeleteSubKeyTree("Extensions");
  9563. if (_key.ValueCount == 0 && _key.SubKeyCount == 0)
  9564. {
  9565. _key.Close();
  9566. _key = null;
  9567. Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(_setup.Protocol);
  9568. }
  9569. }
  9570. }
  9571. }
  9572. else
  9573. {
  9574. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(_setup.Protocol);
  9575. if (_key != null)
  9576. {
  9577. _key.DeleteValue("Source Filter");
  9578. if (_key.ValueCount == 0 && _key.SubKeyCount == 0)
  9579. {
  9580. _key.Close();
  9581. _key = null;
  9582. Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(_setup.Protocol);
  9583. }
  9584. }
  9585. }
  9586. }
  9587. catch (Exception _exception)
  9588. {
  9589. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9590. hr.TraceWrite();
  9591. }
  9592. finally
  9593. {
  9594. if (_key != null)
  9595. {
  9596. _key.Close();
  9597. }
  9598. }
  9599. }
  9600. }
  9601. }
  9602. return NOERROR;
  9603. }
  9604. public virtual HRESULT UnregisterFileExtension(Type _type)
  9605. {
  9606. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterFileExtension));
  9607. if (_attributes != null)
  9608. {
  9609. foreach (RegisterFileExtension _setup in _attributes)
  9610. {
  9611. if (_setup != null && !string.IsNullOrEmpty(_setup.Extension))
  9612. {
  9613. Microsoft.Win32.RegistryKey _key = null;
  9614. try
  9615. {
  9616. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("Media Type\\Extensions\\" + _setup.Extension);
  9617. if (_key != null)
  9618. {
  9619. string _guid = (string)_key.GetValue("Source Filter", "");
  9620. if (_guid == this.GetType().GUID.ToString("B"))
  9621. {
  9622. _key.Close();
  9623. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("Media Type\\Extensions");
  9624. _key.DeleteSubKeyTree(_setup.Extension);
  9625. }
  9626. }
  9627. }
  9628. catch (Exception _exception)
  9629. {
  9630. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9631. hr.TraceWrite();
  9632. }
  9633. finally
  9634. {
  9635. if (_key != null)
  9636. {
  9637. _key.Close();
  9638. }
  9639. }
  9640. }
  9641. }
  9642. }
  9643. return NOERROR;
  9644. }
  9645. public virtual HRESULT UnregisterMediaType(Type _type)
  9646. {
  9647. Attribute[] _attributes = Attribute.GetCustomAttributes(_type, typeof(RegisterMediaType));
  9648. if (_attributes != null)
  9649. {
  9650. foreach (RegisterMediaType _setup in _attributes)
  9651. {
  9652. if (_setup != null && !string.IsNullOrEmpty(_setup.Sequence))
  9653. {
  9654. Microsoft.Win32.RegistryKey _key = null;
  9655. try
  9656. {
  9657. string _path = "Media Type\\";
  9658. if (_setup.MajorType != Guid.Empty)
  9659. {
  9660. _path += _setup.MajorType.ToString("B");
  9661. }
  9662. else
  9663. {
  9664. _path += MediaType.Stream.ToString("B");
  9665. }
  9666. _key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(_path);
  9667. if (_key != null)
  9668. {
  9669. _key.DeleteSubKeyTree(_setup.SubType.ToString("B"));
  9670. }
  9671. }
  9672. catch (Exception _exception)
  9673. {
  9674. HRESULT hr = (HRESULT)Marshal.GetHRForException(_exception);
  9675. hr.TraceWrite();
  9676. }
  9677. finally
  9678. {
  9679. if (_key != null)
  9680. {
  9681. _key.Close();
  9682. }
  9683. }
  9684. }
  9685. }
  9686. }
  9687. return NOERROR;
  9688. }
  9689. #endregion
  9690. #region Helper Methods
  9691. public bool SelectSeekingPin(SplitterOutputPin pPin)
  9692. {
  9693. lock (m_csSeeking)
  9694. {
  9695. if (m_pSeekingPin == null)
  9696. {
  9697. m_pSeekingPin = pPin;
  9698. }
  9699. return (m_pSeekingPin == pPin);
  9700. }
  9701. }
  9702. public void DeselectSeekingPin(SplitterOutputPin pPin)
  9703. {
  9704. lock (m_csSeeking)
  9705. {
  9706. if (pPin == m_pSeekingPin)
  9707. {
  9708. m_pSeekingPin = null;
  9709. }
  9710. }
  9711. }
  9712. public void GetPositions(out long pStart, out long pStop, out double pdRate)
  9713. {
  9714. pStart = m_tStartTime;
  9715. pStop = m_tStopTime;
  9716. pdRate = m_dRate;
  9717. }
  9718. public HRESULT SetPositions(long _start, long _stop, double _rate)
  9719. {
  9720. bool _seek = false;
  9721. {
  9722. if (_start != -1)
  9723. {
  9724. if (SeekingPin != null)
  9725. {
  9726. long _position;
  9727. SeekingPin.GetCurrentPosition(out _position);
  9728. if (_position != _start)
  9729. {
  9730. _seek = true;
  9731. }
  9732. }
  9733. else
  9734. {
  9735. _seek = (_start != m_tStartTime);
  9736. }
  9737. }
  9738. else
  9739. {
  9740. _start = m_tStartTime;
  9741. }
  9742. if (_stop != -1)
  9743. {
  9744. if (m_tStopTime != _stop)
  9745. {
  9746. _seek = true;
  9747. }
  9748. }
  9749. else
  9750. {
  9751. _stop = m_tStopTime;
  9752. }
  9753. if (_rate > 0 && _rate <= 2.0)
  9754. {
  9755. if (m_dRate != _rate)
  9756. {
  9757. _seek = true;
  9758. }
  9759. }
  9760. else
  9761. {
  9762. _rate = m_dRate;
  9763. }
  9764. }
  9765. if (_seek)
  9766. {
  9767. if (IsActive)
  9768. {
  9769. BeginFlush();
  9770. StopThread();
  9771. foreach (BasePin _pin in Pins)
  9772. {
  9773. if (_pin.Direction == PinDirection.Output)
  9774. {
  9775. (_pin as SplitterOutputPin).StopThread();
  9776. }
  9777. }
  9778. EndFlush();
  9779. }
  9780. lock (m_csSeeking)
  9781. {
  9782. m_tStartTime = _start;
  9783. m_tStopTime = _stop;
  9784. m_dRate = _rate;
  9785. }
  9786. if (!IsActive || (m_pFileParser != null && !m_pFileParser.RequireDemuxThread))
  9787. {
  9788. m_pFileParser.SeekToTime(m_tStartTime);
  9789. }
  9790. if (IsActive)
  9791. {
  9792. StartThread();
  9793. foreach (BasePin _pin in Pins)
  9794. {
  9795. if (_pin.Direction == PinDirection.Output)
  9796. {
  9797. (_pin as SplitterOutputPin).StartThread();
  9798. }
  9799. }
  9800. }
  9801. }
  9802. return NOERROR;
  9803. }
  9804. #endregion
  9805. #region Thread Methods
  9806. protected virtual HRESULT StartThread()
  9807. {
  9808. if (m_pFileParser != null)
  9809. {
  9810. m_evEOS.Reset();
  9811. m_evQuit.Reset();
  9812. if (m_pFileParser.RequireDemuxThread)
  9813. {
  9814. m_evDemuxStarted.Reset();
  9815. lock (m_csThreadLock)
  9816. {
  9817. if (m_evReady.WaitOne(0, false))
  9818. {
  9819. m_evDemuxStarted.Reset();
  9820. m_evReady.Reset();
  9821. m_WorkerThread.Create();
  9822. int nResult = WaitHandle.WaitAny(new WaitHandle[] { m_evDemuxStarted, m_evReady });
  9823. if (nResult != 0)
  9824. {
  9825. m_evQuit.Set();
  9826. m_WorkerThread.Close();
  9827. return E_FAIL;
  9828. }
  9829. }
  9830. }
  9831. }
  9832. }
  9833. return NOERROR;
  9834. }
  9835. protected virtual void StopThread()
  9836. {
  9837. if (m_pFileParser != null)
  9838. {
  9839. m_evQuit.Set();
  9840. if (m_pFileParser.RequireDemuxThread)
  9841. {
  9842. lock (m_csThreadLock)
  9843. {
  9844. m_evReady.WaitOne();
  9845. m_WorkerThread.Close();
  9846. }
  9847. }
  9848. }
  9849. }
  9850. protected virtual void ThreadProc()
  9851. {
  9852. HRESULT hr;
  9853. m_evReady.Reset();
  9854. m_evEOS.Reset();
  9855. TRACE("Demux Started");
  9856. ASSERT(m_pFileParser != null);
  9857. m_pFileParser.SeekToTime(m_tStartTime);
  9858. hr = m_pFileParser.OnDemuxStart();
  9859. hr.Assert();
  9860. if (hr.Succeeded)
  9861. {
  9862. m_evDemuxStarted.Set();
  9863. do
  9864. {
  9865. try
  9866. {
  9867. hr = m_pFileParser.ProcessDemuxPackets();
  9868. if (hr != S_OK)
  9869. {
  9870. m_evEOS.Set();
  9871. break;
  9872. }
  9873. }
  9874. catch (Exception _exception)
  9875. {
  9876. TRACE("Demux Exception \"" + _exception.Message + "\"");
  9877. m_evEOS.Set();
  9878. #if DEBUG
  9879. throw _exception;
  9880. #else
  9881. break;
  9882. #endif
  9883. }
  9884. }
  9885. while (!m_evQuit.WaitOne(0, false) && !m_evEOS.WaitOne(0, false));
  9886. m_pFileParser.OnDemuxStop();
  9887. if (!m_evQuit.WaitOne(0, false))
  9888. {
  9889. while (!m_evQuit.WaitOne(0, false))
  9890. {
  9891. long _duration = UNITS;
  9892. int nCount = 0;
  9893. foreach (BasePin pPin in Pins)
  9894. {
  9895. if (pPin.Direction == PinDirection.Output)
  9896. {
  9897. SplitterOutputPin _pin = (pPin as SplitterOutputPin);
  9898. if (_pin.EOSDelivered || !_pin.IsConnected)
  9899. {
  9900. nCount++;
  9901. }
  9902. else
  9903. {
  9904. if (_pin.Track == null || !_pin.Track.Active)
  9905. {
  9906. nCount++;
  9907. }
  9908. else
  9909. {
  9910. if (_pin.Track.Reset())
  9911. {
  9912. nCount++;
  9913. }
  9914. }
  9915. }
  9916. }
  9917. else
  9918. {
  9919. nCount++;
  9920. }
  9921. }
  9922. if (nCount != Pins.Count)
  9923. {
  9924. m_evQuit.WaitOne((int)(_duration / 10000), false);
  9925. }
  9926. else
  9927. {
  9928. break;
  9929. }
  9930. }
  9931. }
  9932. }
  9933. m_evReady.Set();
  9934. TRACE("Demux Quit");
  9935. }
  9936. #endregion
  9937. #region IFileSourceFilter Members
  9938. public int Load(string pszFileName, AMMediaType pmt)
  9939. {
  9940. UnloadFile();
  9941. m_bLoading = true;
  9942. m_sFileName = pszFileName;
  9943. try
  9944. {
  9945. if (S_OK == DecideFileParser(m_sFileName))
  9946. {
  9947. m_bLoading = false;
  9948. return NOERROR;
  9949. }
  9950. }
  9951. catch
  9952. {
  9953. }
  9954. UnloadFile();
  9955. m_sFileName = pszFileName;
  9956. BitStreamReader _stream = null;
  9957. try
  9958. {
  9959. _stream = new BitStreamReader(new FileStream(m_sFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
  9960. if (S_OK == DecideFileParser(_stream))
  9961. {
  9962. m_bLoading = false;
  9963. return NOERROR;
  9964. }
  9965. }
  9966. catch
  9967. {
  9968. }
  9969. m_bLoading = false;
  9970. UnloadFile();
  9971. if (_stream != null)
  9972. {
  9973. _stream.Dispose();
  9974. _stream = null;
  9975. }
  9976. return VFW_E_CANNOT_CONNECT;
  9977. }
  9978. public int GetCurFile(out string pszFileName, AMMediaType pmt)
  9979. {
  9980. pszFileName = null;
  9981. if (string.IsNullOrEmpty(m_sFileName)) return VFW_E_NOT_CONNECTED;
  9982. pszFileName = m_sFileName;
  9983. return NOERROR;
  9984. }
  9985. #endregion
  9986. #region IAMOpenProgress Members
  9987. public int QueryProgress(out long pllTotal, out long pllCurrent)
  9988. {
  9989. pllTotal = 0;
  9990. pllCurrent = 0;
  9991. if (!m_bLoading) return VFW_E_WRONG_STATE;
  9992. if (m_pFileParser != null)
  9993. {
  9994. return m_pFileParser.GetOpeningProgress(out pllTotal, out pllCurrent);
  9995. }
  9996. return NOERROR;
  9997. }
  9998. public int AbortOperation()
  9999. {
  10000. if (!m_bLoading) return VFW_E_WRONG_STATE;
  10001. m_evQuit.Set();
  10002. if (InputPin != null && InputPin.IsConnected)
  10003. {
  10004. FilterGraph.Disconnect((IPin)Marshal.GetObjectForIUnknown(InputPin.Connected.UnknownPtr));
  10005. FilterGraph.Disconnect(InputPin);
  10006. }
  10007. UnloadFile();
  10008. return NOERROR;
  10009. }
  10010. #endregion
  10011. #region IMediaSeeking Members
  10012. public int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  10013. {
  10014. pCapabilities = AMSeekingSeekingCapabilities.None;
  10015. if (SeekingPin != null)
  10016. {
  10017. return SeekingPin.GetCapabilities(out pCapabilities);
  10018. }
  10019. return E_NOINTERFACE;
  10020. }
  10021. public int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  10022. {
  10023. if (SeekingPin != null)
  10024. {
  10025. return SeekingPin.CheckCapabilities(ref pCapabilities);
  10026. }
  10027. return E_NOINTERFACE;
  10028. }
  10029. public int IsFormatSupported(Guid pFormat)
  10030. {
  10031. if (SeekingPin != null)
  10032. {
  10033. return SeekingPin.IsFormatSupported(pFormat);
  10034. }
  10035. return E_NOINTERFACE;
  10036. }
  10037. public int QueryPreferredFormat(out Guid pFormat)
  10038. {
  10039. pFormat = TimeFormat.None;
  10040. if (SeekingPin != null)
  10041. {
  10042. return SeekingPin.QueryPreferredFormat(out pFormat);
  10043. }
  10044. return E_NOINTERFACE;
  10045. }
  10046. public int GetTimeFormat(out Guid pFormat)
  10047. {
  10048. pFormat = TimeFormat.None;
  10049. if (SeekingPin != null)
  10050. {
  10051. return SeekingPin.GetTimeFormat(out pFormat);
  10052. }
  10053. return E_NOINTERFACE;
  10054. }
  10055. public int IsUsingTimeFormat(Guid pFormat)
  10056. {
  10057. if (SeekingPin != null)
  10058. {
  10059. return SeekingPin.IsUsingTimeFormat(pFormat);
  10060. }
  10061. return E_NOINTERFACE;
  10062. }
  10063. public int SetTimeFormat(Guid pFormat)
  10064. {
  10065. if (SeekingPin != null)
  10066. {
  10067. return SeekingPin.IsUsingTimeFormat(pFormat);
  10068. }
  10069. return E_NOINTERFACE;
  10070. }
  10071. public int GetDuration(out long pDuration)
  10072. {
  10073. pDuration = 0;
  10074. if (m_pFileParser != null)
  10075. {
  10076. pDuration = m_pFileParser.Duration;
  10077. return NOERROR;
  10078. }
  10079. return E_NOINTERFACE;
  10080. }
  10081. public int GetStopPosition(out long pStop)
  10082. {
  10083. pStop = 0;
  10084. if (SeekingPin != null)
  10085. {
  10086. return SeekingPin.GetStopPosition(out pStop);
  10087. }
  10088. return E_NOINTERFACE;
  10089. }
  10090. public int GetCurrentPosition(out long pCurrent)
  10091. {
  10092. pCurrent = 0;
  10093. if (SeekingPin != null)
  10094. {
  10095. return SeekingPin.GetCurrentPosition(out pCurrent);
  10096. }
  10097. return E_NOINTERFACE;
  10098. }
  10099. public int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  10100. {
  10101. pTarget = 0;
  10102. if (SeekingPin != null)
  10103. {
  10104. return SeekingPin.ConvertTimeFormat(out pTarget, pTargetFormat, Source, pSourceFormat);
  10105. }
  10106. return E_NOINTERFACE;
  10107. }
  10108. public int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  10109. {
  10110. if (SeekingPin != null)
  10111. {
  10112. return SeekingPin.SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
  10113. }
  10114. return E_NOINTERFACE;
  10115. }
  10116. public int GetPositions(out long pCurrent, out long pStop)
  10117. {
  10118. pCurrent = 0;
  10119. pStop = 0;
  10120. if (SeekingPin != null)
  10121. {
  10122. return SeekingPin.GetPositions(out pCurrent, out pStop);
  10123. }
  10124. return E_NOINTERFACE;
  10125. }
  10126. public int GetAvailable(out long pEarliest, out long pLatest)
  10127. {
  10128. pEarliest = 0;
  10129. pLatest = 0;
  10130. if (SeekingPin != null)
  10131. {
  10132. return SeekingPin.GetAvailable(out pEarliest, out pLatest);
  10133. }
  10134. return E_NOINTERFACE;
  10135. }
  10136. public int SetRate(double dRate)
  10137. {
  10138. if (SeekingPin != null)
  10139. {
  10140. return SeekingPin.SetRate(dRate);
  10141. }
  10142. return E_NOINTERFACE;
  10143. }
  10144. public int GetRate(out double pdRate)
  10145. {
  10146. pdRate = 1.0;
  10147. if (SeekingPin != null)
  10148. {
  10149. return SeekingPin.GetRate(out pdRate);
  10150. }
  10151. return E_NOINTERFACE;
  10152. }
  10153. public int GetPreroll(out long pllPreroll)
  10154. {
  10155. pllPreroll = 0;
  10156. if (SeekingPin != null)
  10157. {
  10158. return SeekingPin.GetPreroll(out pllPreroll);
  10159. }
  10160. return E_NOINTERFACE;
  10161. }
  10162. #endregion
  10163. #region IAMStreamSelect Members
  10164. public int Count(out int pcStreams)
  10165. {
  10166. pcStreams = 0;
  10167. if (m_pFileParser == null) return VFW_E_NOT_CONNECTED;
  10168. pcStreams = m_pFileParser.GetTracksCountByType(DemuxTrack.TrackType.Audio);
  10169. return NOERROR;
  10170. }
  10171. public int Info(int lIndex, IntPtr ppmt, IntPtr pdwFlags, IntPtr plcid, IntPtr pdwGroup, IntPtr ppszName, IntPtr ppObject, IntPtr ppUnk)
  10172. {
  10173. SplitterOutputPin _selected = null;
  10174. int _index = lIndex;
  10175. foreach (BasePin _pin in Pins)
  10176. {
  10177. if (_pin.Direction == PinDirection.Output)
  10178. {
  10179. if ((_pin as SplitterOutputPin).Track.Type == DemuxTrack.TrackType.Audio)
  10180. {
  10181. if ((_index-- == 0))
  10182. {
  10183. _selected = (_pin as SplitterOutputPin);
  10184. break;
  10185. }
  10186. }
  10187. }
  10188. }
  10189. if (_selected == null) return S_FALSE;
  10190. if (ppmt != IntPtr.Zero)
  10191. {
  10192. bool bHaveType = true;
  10193. AMMediaType mt = new AMMediaType();
  10194. if (_selected.IsConnected)
  10195. {
  10196. mt.Set(_selected.CurrentMediaType);
  10197. }
  10198. else
  10199. {
  10200. if (S_OK != _selected.GetMediaType(0, ref mt))
  10201. {
  10202. bHaveType = false;
  10203. }
  10204. }
  10205. if (bHaveType)
  10206. {
  10207. IntPtr _pmt = Marshal.AllocCoTaskMem(Marshal.SizeOf(mt));
  10208. Marshal.StructureToPtr(mt, _pmt, true);
  10209. Marshal.WriteIntPtr(ppmt, _pmt);
  10210. }
  10211. else
  10212. {
  10213. Marshal.WriteIntPtr(ppmt, IntPtr.Zero);
  10214. }
  10215. }
  10216. if (pdwFlags != IntPtr.Zero)
  10217. {
  10218. if (!_selected.StreamEnabled)
  10219. {
  10220. Marshal.WriteInt32(pdwFlags, 0);
  10221. }
  10222. else
  10223. {
  10224. Marshal.WriteInt32(pdwFlags, (int)AMSTREAMSELECTINFOFLAGS.ENABLED);
  10225. }
  10226. }
  10227. if (plcid != IntPtr.Zero)
  10228. {
  10229. int _lcid = _selected.Track.LCID;
  10230. if (_lcid == 0)
  10231. {
  10232. _lcid = LOCALE_NEUTRAL;
  10233. }
  10234. Marshal.WriteInt32(plcid, _lcid);
  10235. }
  10236. if (pdwGroup != IntPtr.Zero)
  10237. {
  10238. Marshal.WriteInt32(pdwGroup, 0);
  10239. }
  10240. if (ppszName != IntPtr.Zero)
  10241. {
  10242. string _name = _selected.Track.Name;
  10243. if (string.IsNullOrEmpty(_name))
  10244. {
  10245. _name = "Audio #" + lIndex.ToString();
  10246. }
  10247. Marshal.WriteIntPtr(ppszName, Marshal.StringToCoTaskMemUni(_name));
  10248. }
  10249. if (ppObject != IntPtr.Zero)
  10250. {
  10251. Marshal.WriteIntPtr(ppObject, Marshal.GetIUnknownForObject(_selected));
  10252. }
  10253. if (ppUnk != IntPtr.Zero)
  10254. {
  10255. Marshal.WriteIntPtr(ppUnk, IntPtr.Zero);
  10256. }
  10257. return NOERROR;
  10258. }
  10259. public int Enable(int lIndex, AMSTREAMSELECTENABLEFLAGS dwFlags)
  10260. {
  10261. if (dwFlags == AMSTREAMSELECTENABLEFLAGS.DISABLE)
  10262. {
  10263. foreach (BasePin _pin in Pins)
  10264. {
  10265. if (_pin.Direction == PinDirection.Output)
  10266. {
  10267. if ((_pin as SplitterOutputPin).Track.Type == DemuxTrack.TrackType.Audio)
  10268. {
  10269. (_pin as SplitterOutputPin).StreamEnabled = false;
  10270. }
  10271. }
  10272. }
  10273. }
  10274. if (dwFlags == AMSTREAMSELECTENABLEFLAGS.ENABLEALL)
  10275. {
  10276. foreach (BasePin _pin in Pins)
  10277. {
  10278. if (_pin.Direction == PinDirection.Output)
  10279. {
  10280. if ((_pin as SplitterOutputPin).Track.Type == DemuxTrack.TrackType.Audio)
  10281. {
  10282. (_pin as SplitterOutputPin).StreamEnabled = true;
  10283. }
  10284. }
  10285. }
  10286. }
  10287. if (dwFlags == AMSTREAMSELECTENABLEFLAGS.ENABLED)
  10288. {
  10289. foreach (BasePin _pin in Pins)
  10290. {
  10291. if (_pin.Direction == PinDirection.Output)
  10292. {
  10293. if ((_pin as SplitterOutputPin).Track.Type == DemuxTrack.TrackType.Audio)
  10294. {
  10295. (_pin as SplitterOutputPin).StreamEnabled = (lIndex-- == 0);
  10296. }
  10297. }
  10298. }
  10299. }
  10300. if (IsActive && dwFlags != AMSTREAMSELECTENABLEFLAGS.DISABLE)
  10301. {
  10302. try
  10303. {
  10304. IMediaSeeking _seeking = (IMediaSeeking)FilterGraph;
  10305. if (_seeking != null)
  10306. {
  10307. long _current;
  10308. _seeking.GetCurrentPosition(out _current);
  10309. _current -= UNITS / 10;
  10310. _seeking.SetPositions(_current, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);
  10311. _current += UNITS / 10;
  10312. _seeking.SetPositions(_current, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);
  10313. }
  10314. }
  10315. catch
  10316. {
  10317. }
  10318. }
  10319. return NOERROR;
  10320. }
  10321. #endregion
  10322. }
  10323. #endregion
  10324. #region Base Classes
  10325. [ComVisible(false)]
  10326. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10327. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10328. [ClassInterface(ClassInterfaceType.None)]
  10329. public class BaseSplitterFilter : BaseSplitter
  10330. {
  10331. #region Constructor
  10332. protected BaseSplitterFilter(string _name, FileParser _parser)
  10333. : base(_name)
  10334. {
  10335. if (_parser != null)
  10336. {
  10337. m_Parsers.Add(_parser);
  10338. }
  10339. AddPin(new SplitterInputPin("Input", this));
  10340. }
  10341. #endregion
  10342. }
  10343. [ComVisible(false)]
  10344. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10345. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10346. [ClassInterface(ClassInterfaceType.None)]
  10347. public class BaseFileSourceFilter : BaseSplitter, IFileSourceFilter, IAMOpenProgress
  10348. {
  10349. #region Constructor
  10350. protected BaseFileSourceFilter(string _name, FileParser _parser)
  10351. : base(_name)
  10352. {
  10353. if (_parser != null)
  10354. {
  10355. m_Parsers.Add(_parser);
  10356. }
  10357. }
  10358. #endregion
  10359. }
  10360. #endregion
  10361. #region Generic Templates
  10362. [ComVisible(false)]
  10363. [ClassInterface(ClassInterfaceType.None)]
  10364. public class BaseSplitterFilterTemplate<Parser> : BaseSplitterFilter where Parser : FileParser, new()
  10365. {
  10366. public BaseSplitterFilterTemplate(string _name)
  10367. : base(_name, new Parser())
  10368. {
  10369. }
  10370. }
  10371. [ComVisible(false)]
  10372. [ClassInterface(ClassInterfaceType.None)]
  10373. public class BaseSourceFilterTemplate<Parser> : BaseFileSourceFilter where Parser : FileParser, new()
  10374. {
  10375. public BaseSourceFilterTemplate(string _name)
  10376. : base(_name, new Parser())
  10377. {
  10378. }
  10379. }
  10380. #endregion
  10381. #endregion
  10382. #region Base Muxer Filter
  10383. [ComVisible(false)]
  10384. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10385. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10386. [ClassInterface(ClassInterfaceType.None)]
  10387. public class BitStreamWriter : COMHelper, IDisposable
  10388. {
  10389. #region Variables
  10390. protected Stream m_Stream = null;
  10391. protected object m_csWritingLock = new object();
  10392. protected int m_nBitIndex = 0;
  10393. protected byte[] m_btCurrentByte = new byte[1];
  10394. protected long m_llPosition = 0;
  10395. #endregion
  10396. #region Constructor
  10397. public BitStreamWriter(Stream _stream)
  10398. {
  10399. m_Stream = _stream;
  10400. }
  10401. ~BitStreamWriter()
  10402. {
  10403. Dispose();
  10404. }
  10405. #endregion
  10406. /*
  10407. #region Properties
  10408. public long Position
  10409. {
  10410. get
  10411. {
  10412. lock (m_csCacheLock)
  10413. {
  10414. return (m_llPosition - (m_nBufferSize > 0 ? (m_nBufferSize - m_nCacheIndex) : 0));
  10415. }
  10416. }
  10417. set { Seek(value); }
  10418. }
  10419. public long TotalSize
  10420. {
  10421. get { return m_Stream.Length; }
  10422. }
  10423. #endregion
  10424. #region Methods
  10425. public HRESULT Seek(long ullPosition)
  10426. {
  10427. lock (m_csCacheLock)
  10428. {
  10429. if (ullPosition < m_llPosition && m_llPosition - (long)m_nBufferSize < ullPosition)
  10430. {
  10431. m_nCacheIndex = m_nBufferSize - (int)(m_llPosition - ullPosition);
  10432. }
  10433. else
  10434. {
  10435. m_llPosition = ullPosition;
  10436. m_nBufferSize = 0;
  10437. m_nCacheIndex = 0;
  10438. }
  10439. m_nBitIndex = 0;
  10440. if (ullPosition > TotalSize) return S_FALSE;
  10441. }
  10442. return NOERROR;
  10443. }
  10444. #endregion
  10445. #region Bits Helper
  10446. public bool IsAligned() { return m_nBitIndex == 0; }
  10447. public void AlignNextByte() { if (m_nBitIndex != 0) WriteBits(m_nBitIndex,0); }
  10448. public void WriteBit(bool bBit) { WriteBit(bBit ? 1 : 0); }
  10449. public void WriteBit(int nBit)
  10450. {
  10451. /*
  10452. if (m_nBitIndex == 0)
  10453. {
  10454. int _readed = 0;
  10455. HRESULT hr = WriteData(m_btCurrentByte, 1, out _readed);
  10456. if (_readed == 0) m_btCurrentByte[0] = 0;
  10457. m_nBitIndex = 8;
  10458. }
  10459. m_nBitIndex--;
  10460. return (m_btCurrentByte[0] >> m_nBitIndex) & 0x01;
  10461. //* /
  10462. }
  10463. public void WriteByte(int _byte) { WriteBits(8, _byte); }
  10464. public void WriteWord(int _word) { WriteBits(16, _word); }
  10465. public void WriteDword(int _dword) { WriteBits(32, _dword); }
  10466. public void WriteQword(long _qword) { WriteBits(64, _qword); }
  10467. public void WriteBits(int nCount, long _value)
  10468. {
  10469. long u = (_value << (Marshal.SizeOf(_value) * 8 - nCount));
  10470. long mask = (((long)0x01) << (Marshal.SizeOf(_value) * 8 - 1));
  10471. while (nCount-- > 0)
  10472. {
  10473. bool _bit = ((u & mask) == mask);
  10474. WriteBit(_bit);
  10475. u <<= 0x01;
  10476. }
  10477. }
  10478. #endregion
  10479. */
  10480. #region Value Helper
  10481. #endregion
  10482. #region IDisposable Members
  10483. public void Dispose()
  10484. {
  10485. if (m_Stream != null)
  10486. {
  10487. m_Stream.Dispose();
  10488. m_Stream = null;
  10489. }
  10490. }
  10491. #endregion
  10492. }
  10493. [ComVisible(false)]
  10494. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10495. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10496. [ClassInterface(ClassInterfaceType.None)]
  10497. public abstract class MuxerTrack : COMHelper, IDisposable
  10498. {
  10499. #region Enums
  10500. [ComVisible(false)]
  10501. public enum TrackType
  10502. {
  10503. Unknown = -1,
  10504. Video = 0,
  10505. Audio = 1,
  10506. SubPicture = 2,
  10507. Subtitles = 3,
  10508. }
  10509. #endregion
  10510. #region Variables
  10511. protected PacketsQueue m_Queue = new PacketsQueue();
  10512. protected FileWriter m_pWriter = null;
  10513. protected TrackType m_Type = TrackType.Unknown;
  10514. protected long m_rtPosition = 0;
  10515. protected EventWaitHandle m_hFlush = null;
  10516. protected ManualResetEvent m_evReady = new ManualResetEvent(false);
  10517. protected bool m_bFirstSample = true;
  10518. protected AMMediaType m_mt = new AMMediaType();
  10519. protected bool m_bEOS = true;
  10520. protected object m_csPostionLock = new object();
  10521. #endregion
  10522. #region Constructor
  10523. protected MuxerTrack(FileWriter _writer, AMMediaType mt)
  10524. {
  10525. m_pWriter = _writer;
  10526. m_mt = mt;
  10527. }
  10528. #endregion
  10529. #region Properties
  10530. public TrackType Type
  10531. {
  10532. get { return m_Type; }
  10533. }
  10534. public bool IsStartSample
  10535. {
  10536. get { return m_bFirstSample; }
  10537. }
  10538. public long Position
  10539. {
  10540. get
  10541. {
  10542. long _position;
  10543. lock (m_csPostionLock)
  10544. {
  10545. _position = m_rtPosition;
  10546. }
  10547. return _position;
  10548. }
  10549. }
  10550. public AMMediaType CurrentMediaType
  10551. {
  10552. get { return m_mt; }
  10553. set { m_mt.Set(value); }
  10554. }
  10555. public long Allocated
  10556. {
  10557. get
  10558. {
  10559. long _time = m_Queue.CacheDuration;
  10560. if (_time > 0) return _time;
  10561. return 0;
  10562. }
  10563. }
  10564. public EventWaitHandle FlushEvent
  10565. {
  10566. get { return m_hFlush; }
  10567. set { m_hFlush = value; }
  10568. }
  10569. public bool IsWaiting
  10570. {
  10571. get { return !m_evReady.WaitOne(0, false) && m_Queue.IsEmpty; }
  10572. }
  10573. public bool IsEOS
  10574. {
  10575. get { return m_bEOS; }
  10576. set { m_bEOS = true; }
  10577. }
  10578. #endregion
  10579. #region Helper Methods
  10580. public virtual bool Reset()
  10581. {
  10582. if (IsWaiting)
  10583. {
  10584. m_evReady.Set();
  10585. return true;
  10586. }
  10587. return false;
  10588. }
  10589. public virtual void Alloc(long _time)
  10590. {
  10591. m_Queue.CacheDuration = _time;
  10592. }
  10593. public virtual void Flush()
  10594. {
  10595. m_Queue.Clear();
  10596. m_evReady.Reset();
  10597. lock (m_csPostionLock)
  10598. {
  10599. m_rtPosition = 0;
  10600. }
  10601. m_bEOS = false;
  10602. m_bFirstSample = true;
  10603. }
  10604. public virtual bool AddToCache(ref PacketData pPacket)
  10605. {
  10606. if (pPacket != null)
  10607. {
  10608. if (m_Queue.IsFull && pPacket.Start >= m_Queue.StopTime)
  10609. {
  10610. if (0 != WaitHandle.WaitAny(new WaitHandle[] { m_Queue, m_pWriter.QuitEvent, m_hFlush }))
  10611. {
  10612. pPacket.Dispose();
  10613. return false;
  10614. }
  10615. }
  10616. m_Queue.Add(pPacket);
  10617. m_evReady.Set();
  10618. return true;
  10619. }
  10620. return false;
  10621. }
  10622. public virtual PacketData GetNextPacket()
  10623. {
  10624. while (true)
  10625. {
  10626. WaitHandle.WaitAny(new WaitHandle[] { m_evReady, m_pWriter.QuitEvent, m_hFlush });
  10627. if (m_evReady.WaitOne(0, false))
  10628. {
  10629. PacketData pPacket;
  10630. if (m_Queue.Peek(out pPacket, true))
  10631. {
  10632. return pPacket;
  10633. }
  10634. else
  10635. {
  10636. if (IsEOS) break;
  10637. }
  10638. {
  10639. if (m_Queue.IsEmpty)
  10640. {
  10641. m_evReady.Reset();
  10642. }
  10643. }
  10644. }
  10645. else
  10646. {
  10647. break;
  10648. }
  10649. }
  10650. return null;
  10651. }
  10652. public virtual HRESULT Receive(ref IMediaSampleImpl _sample)
  10653. {
  10654. PacketData _packet = new PacketData();
  10655. _packet.SyncPoint = _sample.IsSyncPoint() == S_OK;
  10656. long _start, _stop;
  10657. _sample.GetTime(out _start, out _stop);
  10658. _packet.Start = _start;
  10659. _packet.Stop = _stop;
  10660. _packet.Size = _sample.GetActualDataLength();
  10661. _packet.Buffer = new byte[_packet.Size];
  10662. IntPtr pBuffer;
  10663. _sample.GetPointer(out pBuffer);
  10664. Marshal.Copy(pBuffer, _packet.Buffer, 0, _packet.Size);
  10665. AddToCache(ref _packet);
  10666. return NOERROR;
  10667. }
  10668. #endregion
  10669. #region Methods To Override
  10670. public virtual HRESULT OnStartWriting()
  10671. {
  10672. return NOERROR;
  10673. }
  10674. public virtual HRESULT OnStopWriting()
  10675. {
  10676. return NOERROR;
  10677. }
  10678. public virtual HRESULT WritePacket(PacketData _packet)
  10679. {
  10680. if (_packet.Start > 0)
  10681. {
  10682. lock (m_csPostionLock)
  10683. {
  10684. m_rtPosition = _packet.Start;
  10685. }
  10686. }
  10687. m_bFirstSample = false;
  10688. return NOERROR;
  10689. }
  10690. #endregion
  10691. #region Abstract Methods
  10692. public abstract HRESULT InitTrack();
  10693. #endregion
  10694. #region IDisposable Members
  10695. public virtual void Dispose()
  10696. {
  10697. m_mt.Free();
  10698. }
  10699. #endregion
  10700. }
  10701. [ComVisible(false)]
  10702. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10703. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10704. [ClassInterface(ClassInterfaceType.None)]
  10705. public abstract class FileWriter : COMHelper, IDisposable
  10706. {
  10707. #region Variables
  10708. protected BitStreamWriter m_Stream = null;
  10709. protected List<MuxerTrack> m_Tracks = new List<MuxerTrack>();
  10710. private bool m_bRequireMuxThread = false;
  10711. protected string m_sFileName = "";
  10712. protected EventWaitHandle m_hQuit = null;
  10713. protected bool m_bThreadExists = false;
  10714. protected bool m_bRealtimeSync = false;
  10715. protected bool m_bAppendOnSeek = true;
  10716. protected bool m_bOverwrite = true;
  10717. #endregion
  10718. #region Constructor
  10719. protected FileWriter()
  10720. : this(true)
  10721. {
  10722. }
  10723. protected FileWriter(bool bRequireMuxThread)
  10724. {
  10725. m_bRequireMuxThread = bRequireMuxThread;
  10726. }
  10727. ~FileWriter()
  10728. {
  10729. Dispose();
  10730. }
  10731. #endregion
  10732. #region Properties
  10733. public string FileName
  10734. {
  10735. get { return m_sFileName; }
  10736. }
  10737. public MuxerTrack this[int iIndex]
  10738. {
  10739. get { return m_Tracks[iIndex]; }
  10740. }
  10741. public bool RequireMuxThread
  10742. {
  10743. get { return m_bRequireMuxThread; }
  10744. set { m_bRequireMuxThread = value; }
  10745. }
  10746. public int Count
  10747. {
  10748. get { return m_Tracks.Count; }
  10749. }
  10750. public long Position
  10751. {
  10752. get
  10753. {
  10754. long _time = MAX_LONG;
  10755. foreach (MuxerTrack _track in m_Tracks)
  10756. {
  10757. long _position = _track.Position;
  10758. if (_position > 0 && _position < _time)
  10759. {
  10760. _time = _position;
  10761. }
  10762. }
  10763. return _time == MAX_LONG ? 0 : _time;
  10764. }
  10765. }
  10766. public EventWaitHandle QuitEvent
  10767. {
  10768. get { return m_hQuit; }
  10769. set { m_hQuit = value; }
  10770. }
  10771. public BitStreamWriter Stream
  10772. {
  10773. get { return m_Stream; }
  10774. }
  10775. public bool ThreadExists
  10776. {
  10777. get { return m_bThreadExists; }
  10778. set { m_bThreadExists = value; }
  10779. }
  10780. public bool RealtimeSync
  10781. {
  10782. get { return m_bRealtimeSync; }
  10783. }
  10784. public bool AppendOnSeek
  10785. {
  10786. get { return m_bAppendOnSeek; }
  10787. }
  10788. #endregion
  10789. #region Virtual Methods
  10790. public virtual HRESULT OpenOutput(string sFileName, bool bOverwrite)
  10791. {
  10792. m_sFileName = sFileName;
  10793. m_bOverwrite = bOverwrite;
  10794. HRESULT hr = OpenFile();
  10795. if (hr == S_OK) return hr;
  10796. FileStream _stream = new FileStream(sFileName, bOverwrite ? FileMode.Create : FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
  10797. return OpenOutput(new BitStreamWriter(_stream), bOverwrite);
  10798. }
  10799. public virtual HRESULT OpenOutput(BitStreamWriter _stream, bool bOverwrite)
  10800. {
  10801. m_Stream = _stream;
  10802. m_bOverwrite = bOverwrite;
  10803. return OpenStream();
  10804. }
  10805. public virtual HRESULT CloseOutput()
  10806. {
  10807. if (m_Stream != null)
  10808. {
  10809. m_Stream.Dispose();
  10810. m_Stream = null;
  10811. }
  10812. return NOERROR;
  10813. }
  10814. public virtual HRESULT CheckInputType(AMMediaType pmt)
  10815. {
  10816. if (pmt == null) return E_POINTER;
  10817. MuxerTrack _track = CreateTrackForType(pmt);
  10818. if (_track == null) return VFW_E_CANNOT_CONNECT;
  10819. HRESULT hr = _track.InitTrack();
  10820. RemoveTrack(_track);
  10821. return hr;
  10822. }
  10823. public virtual MuxerTrack CreateTrackForType(AMMediaType pmt)
  10824. {
  10825. MuxerTrack _track = CreateTrack(pmt);
  10826. if (_track != null)
  10827. {
  10828. m_Tracks.Add(_track);
  10829. }
  10830. return _track;
  10831. }
  10832. public virtual HRESULT RemoveTrack(MuxerTrack _track)
  10833. {
  10834. if (_track != null)
  10835. {
  10836. _track.Dispose();
  10837. if (m_Tracks.Remove(_track))
  10838. {
  10839. return S_OK;
  10840. }
  10841. }
  10842. return S_FALSE;
  10843. }
  10844. public virtual int GetMaxTrackCount()
  10845. {
  10846. return -1;
  10847. }
  10848. public virtual HRESULT GetMediaType(int iPosition, ref AMMediaType pmt)
  10849. {
  10850. if (iPosition < 0) return E_INVALIDARG;
  10851. if (iPosition > 0) return VFW_S_NO_MORE_ITEMS;
  10852. pmt.majorType = MediaType.Stream;
  10853. pmt.subType = MediaSubType.None;
  10854. pmt.formatType = FormatType.None;
  10855. return NOERROR;
  10856. }
  10857. public virtual HRESULT SetMediaType(AMMediaType pmt)
  10858. {
  10859. if (pmt == null) return E_POINTER;
  10860. if (pmt.majorType != MediaType.Stream) return VFW_E_CANNOT_CONNECT;
  10861. return NOERROR;
  10862. }
  10863. #endregion
  10864. #region Helper Methods
  10865. public MuxerTrack GetTrackByType(MuxerTrack.TrackType _type)
  10866. {
  10867. foreach (MuxerTrack _track in m_Tracks)
  10868. {
  10869. if (_track.Type == _type)
  10870. {
  10871. return _track;
  10872. }
  10873. }
  10874. return null;
  10875. }
  10876. public bool HaveTrack(MuxerTrack.TrackType _type)
  10877. {
  10878. return GetTrackByType(_type) != null;
  10879. }
  10880. public int GetTracksCountByType(MuxerTrack.TrackType _type)
  10881. {
  10882. int nCount = 0;
  10883. foreach (MuxerTrack _track in m_Tracks)
  10884. {
  10885. if (_track.Type == _type)
  10886. {
  10887. nCount++;
  10888. }
  10889. }
  10890. return nCount;
  10891. }
  10892. #endregion
  10893. #region Writer Methods
  10894. public virtual HRESULT OnStartWriting()
  10895. {
  10896. foreach (MuxerTrack _track in m_Tracks)
  10897. {
  10898. _track.OnStartWriting();
  10899. }
  10900. return NOERROR;
  10901. }
  10902. public virtual HRESULT OnStopWriting()
  10903. {
  10904. foreach (MuxerTrack _track in m_Tracks)
  10905. {
  10906. _track.OnStopWriting();
  10907. }
  10908. return NOERROR;
  10909. }
  10910. public virtual HRESULT WritePacket(MuxerTrack _track, PacketData _packet)
  10911. {
  10912. return _track.WritePacket(_packet);
  10913. }
  10914. public virtual HRESULT OpenFile()
  10915. {
  10916. return E_NOTIMPL;
  10917. }
  10918. public virtual HRESULT OpenStream()
  10919. {
  10920. return E_NOTIMPL;
  10921. }
  10922. #endregion
  10923. #region Abstract Methods
  10924. protected abstract MuxerTrack CreateTrack(AMMediaType pmt);
  10925. #endregion
  10926. #region IDisposable Members
  10927. public virtual void Dispose()
  10928. {
  10929. CloseOutput();
  10930. while (m_Tracks.Count > 0)
  10931. {
  10932. RemoveTrack(m_Tracks[0]);
  10933. }
  10934. }
  10935. #endregion
  10936. }
  10937. [ComVisible(false)]
  10938. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  10939. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  10940. [ClassInterface(ClassInterfaceType.None)]
  10941. public class MuxerInputPin : BaseInputPin
  10942. {
  10943. #region Variables
  10944. protected MuxerTrack m_pTrack = null;
  10945. protected bool m_bEOSDelivered = false;
  10946. protected RendererPosPassThru m_pPosition = null;
  10947. protected long m_rtLastSampleTime = -1;
  10948. protected long m_rtStartPosition = 0;
  10949. protected long m_rtWritingPosition = 0;
  10950. protected long m_lSampleSize = 0;
  10951. protected ManualResetEvent m_evFlush = new ManualResetEvent(false);
  10952. protected ManualResetEvent m_evRenderTime = new ManualResetEvent(true);
  10953. protected IReferenceClockImpl m_pClock = null;
  10954. protected object m_csTrackLock = new object();
  10955. #endregion
  10956. #region Constructor
  10957. public MuxerInputPin(string _name, BaseMuxer _filter)
  10958. : base(_name, _filter)
  10959. {
  10960. }
  10961. #endregion
  10962. #region Properties
  10963. public RendererPosPassThru Position
  10964. {
  10965. get
  10966. {
  10967. if (m_pPosition == null)
  10968. {
  10969. lock (m_Lock)
  10970. {
  10971. HRESULT hr = NOERROR;
  10972. IntPtr _pin = Marshal.GetComInterfaceForObject(this, typeof(IPin));
  10973. m_pPosition = new RendererPosPassThru(ref hr, _pin);
  10974. Marshal.Release(_pin);
  10975. if (FAILED(hr))
  10976. {
  10977. m_pPosition = null;
  10978. }
  10979. }
  10980. }
  10981. return m_pPosition;
  10982. }
  10983. }
  10984. public bool EOSDelivered
  10985. {
  10986. get { return m_bEOSDelivered; }
  10987. }
  10988. public MuxerTrack Track
  10989. {
  10990. get { return m_pTrack; }
  10991. }
  10992. #endregion
  10993. #region Overridden Methods
  10994. public override int Active()
  10995. {
  10996. RendererPosPassThru _position = Position;
  10997. if (_position != null)
  10998. {
  10999. _position.ResetMediaTime();
  11000. }
  11001. m_evFlush.Reset();
  11002. m_bEOSDelivered = false;
  11003. if (m_pTrack != null)
  11004. {
  11005. m_rtLastSampleTime = 0;
  11006. m_rtWritingPosition = 0;
  11007. m_rtStartPosition = 0;
  11008. m_evRenderTime.Reset();
  11009. m_pTrack.Flush();
  11010. if ((m_Filter as BaseMuxer).Writer.RealtimeSync)
  11011. {
  11012. lock (m_Filter.FilterLock)
  11013. {
  11014. m_pClock = m_Filter.Clock;
  11015. if (m_pClock.IsValid)
  11016. {
  11017. m_pClock._AddRef();
  11018. }
  11019. else
  11020. {
  11021. m_pClock = null;
  11022. }
  11023. }
  11024. }
  11025. }
  11026. else
  11027. {
  11028. m_bEOSDelivered = true;
  11029. }
  11030. return base.Active();
  11031. }
  11032. public override int Inactive()
  11033. {
  11034. int hr = base.Inactive();
  11035. m_bEOSDelivered = true;
  11036. m_evRenderTime.Set();
  11037. if (m_pTrack != null)
  11038. {
  11039. m_pTrack.Flush();
  11040. }
  11041. if (m_pClock != null)
  11042. {
  11043. m_pClock._Release();
  11044. m_pClock = null;
  11045. }
  11046. return hr;
  11047. }
  11048. public override int EndOfStream()
  11049. {
  11050. m_bEOSDelivered = true;
  11051. int hr = base.EndOfStream();
  11052. RendererPosPassThru _position = Position;
  11053. if (_position != null)
  11054. {
  11055. _position.EOS();
  11056. }
  11057. lock (m_csTrackLock)
  11058. {
  11059. m_pTrack.IsEOS = true;
  11060. }
  11061. (m_Filter as BaseMuxer).EndOfStream();
  11062. return hr;
  11063. }
  11064. public override int CheckMediaType(AMMediaType pmt)
  11065. {
  11066. if (S_OK != (m_Filter as BaseMuxer).Writer.CheckInputType(pmt))
  11067. {
  11068. return VFW_E_INVALIDMEDIATYPE;
  11069. }
  11070. return NOERROR;
  11071. }
  11072. public override int CompleteConnect(ref IPinImpl pReceivePin)
  11073. {
  11074. HRESULT hr = (HRESULT)base.CompleteConnect(ref pReceivePin);
  11075. if (hr.Failed) return hr;
  11076. lock (m_csTrackLock)
  11077. {
  11078. if (m_pTrack != null)
  11079. {
  11080. (m_Filter as BaseMuxer).Writer.RemoveTrack(m_pTrack);
  11081. }
  11082. m_pTrack = (m_Filter as BaseMuxer).Writer.CreateTrackForType(m_mt);
  11083. if (m_pTrack == null) return VFW_E_CANNOT_CONNECT;
  11084. m_pTrack.Alloc(2 * UNITS);
  11085. m_pTrack.FlushEvent = m_evFlush;
  11086. hr = (m_Filter as BaseMuxer).CompleteConnect(this);
  11087. if (hr.Failed)
  11088. {
  11089. (m_Filter as BaseMuxer).Writer.RemoveTrack(m_pTrack);
  11090. m_pTrack = null;
  11091. }
  11092. }
  11093. return hr;
  11094. }
  11095. public override int BreakConnect()
  11096. {
  11097. HRESULT hr = (HRESULT)base.BreakConnect();
  11098. lock (m_csTrackLock)
  11099. {
  11100. (m_Filter as BaseMuxer).Writer.RemoveTrack(m_pTrack);
  11101. m_pTrack = null;
  11102. }
  11103. return hr;
  11104. }
  11105. public override int BeginFlush()
  11106. {
  11107. int hr = base.BeginFlush();
  11108. m_evRenderTime.Set();
  11109. m_evFlush.Set();
  11110. if ((m_Filter as BaseMuxer).SeekingPin == this)
  11111. {
  11112. (m_Filter as BaseMuxer).BeginFlush();
  11113. }
  11114. return hr;
  11115. }
  11116. public override int EndFlush()
  11117. {
  11118. RendererPosPassThru _position = Position;
  11119. if (_position != null)
  11120. {
  11121. _position.ResetMediaTime();
  11122. }
  11123. if ((m_Filter as BaseMuxer).Writer.AppendOnSeek)
  11124. {
  11125. lock (m_csTrackLock)
  11126. {
  11127. m_rtWritingPosition += m_pTrack.Position;
  11128. }
  11129. }
  11130. if ((m_Filter as BaseMuxer).SeekingPin == this)
  11131. {
  11132. (m_Filter as BaseMuxer).EndFlush();
  11133. }
  11134. lock (m_csTrackLock)
  11135. {
  11136. m_pTrack.Flush();
  11137. m_rtStartPosition = 0;
  11138. m_evFlush.Reset();
  11139. }
  11140. return base.EndFlush();
  11141. }
  11142. public override int OnReceive(ref IMediaSampleImpl _sample)
  11143. {
  11144. HRESULT hr = (HRESULT)CheckStreaming();
  11145. if (hr == S_OK && !m_bEOSDelivered && !m_evFlush.WaitOne(0, false))
  11146. {
  11147. hr = (HRESULT)base.OnReceive(ref _sample);
  11148. if (hr != S_OK) return hr;
  11149. long _start, _stop;
  11150. hr = (HRESULT)_sample.GetTime(out _start, out _stop);
  11151. int lSize = _sample.GetActualDataLength();
  11152. if (hr != S_OK)
  11153. {
  11154. if (hr != VFW_S_NO_STOP_TIME)
  11155. {
  11156. _start = m_rtStartPosition;
  11157. }
  11158. if (m_mt.majorType == MediaType.Audio)
  11159. {
  11160. if (m_lSampleSize != 0)
  11161. {
  11162. _stop = _start + m_rtLastSampleTime * lSize / m_lSampleSize;
  11163. }
  11164. else
  11165. {
  11166. _stop = _start + m_rtLastSampleTime;
  11167. }
  11168. }
  11169. if (m_mt.subType == MediaType.Video)
  11170. {
  11171. if (m_rtLastSampleTime == 0)
  11172. {
  11173. _stop = _start + m_rtLastSampleTime;
  11174. }
  11175. else
  11176. {
  11177. _stop = _start + m_mt.GetFrameRate();
  11178. }
  11179. }
  11180. }
  11181. else
  11182. {
  11183. m_lSampleSize = lSize;
  11184. m_rtLastSampleTime = _stop - _start;
  11185. }
  11186. if (m_pClock != null)
  11187. {
  11188. m_evRenderTime.Reset();
  11189. int dwAdvise = 0;
  11190. hr = (HRESULT)m_pClock.AdviseTime(
  11191. (m_Filter as BaseMuxer).StartTime, // Start run time
  11192. _start, // Stream time
  11193. m_evRenderTime.SafeWaitHandle.DangerousGetHandle(), // Render notification
  11194. out dwAdvise);
  11195. if (SUCCEEDED(hr))
  11196. {
  11197. int dwResult = WaitHandle.WaitAny(new WaitHandle[] { m_evRenderTime, (m_Filter as BaseMuxer).Writer.QuitEvent });
  11198. m_pClock.Unadvise(dwAdvise);
  11199. if (dwResult != 0)
  11200. {
  11201. return S_FALSE;
  11202. }
  11203. }
  11204. }
  11205. if (m_pPosition != null)
  11206. {
  11207. m_pPosition.RegisterMediaTime(_start, _stop);
  11208. }
  11209. lock (m_csTrackLock)
  11210. {
  11211. m_rtStartPosition = _stop;
  11212. _start += m_rtWritingPosition;
  11213. _stop += m_rtWritingPosition;
  11214. _sample.SetTime(_start, _stop);
  11215. hr = m_pTrack.Receive(ref _sample);
  11216. }
  11217. }
  11218. return hr;
  11219. }
  11220. #endregion
  11221. }
  11222. [ComVisible(false)]
  11223. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  11224. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  11225. [ClassInterface(ClassInterfaceType.None)]
  11226. public class MuxerOutputPin : BaseOutputPin
  11227. {
  11228. #region Constructor
  11229. public MuxerOutputPin(BaseMuxer _filter)
  11230. : base("Output", _filter)
  11231. {
  11232. }
  11233. #endregion
  11234. #region Overridden Methods
  11235. public override int CheckMediaType(AMMediaType pmt)
  11236. {
  11237. return NOERROR;
  11238. }
  11239. public override int SetMediaType(AMMediaType mt)
  11240. {
  11241. int hr = base.SetMediaType(mt);
  11242. if (FAILED(hr)) return hr;
  11243. hr = (m_Filter as BaseMuxer).SetMediaType(mt);
  11244. return hr;
  11245. }
  11246. public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
  11247. {
  11248. return (m_Filter as BaseMuxer).GetMediaType(iPosition, ref pMediaType);
  11249. }
  11250. public override int CompleteConnect(ref IPinImpl pReceivePin)
  11251. {
  11252. return base.CompleteConnect(ref pReceivePin);
  11253. }
  11254. public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
  11255. {
  11256. if (pAlloc == null) return E_POINTER;
  11257. if (prop == null) return E_POINTER;
  11258. prop.cbPrefix = 0;
  11259. prop.cbAlign = 1;
  11260. prop.cBuffers = 3;
  11261. prop.cbBuffer = 1;
  11262. foreach (BasePin _pin in m_Filter.Pins)
  11263. {
  11264. if (_pin.Direction == PinDirection.Input && _pin.IsConnected)
  11265. {
  11266. AllocatorProperties _allocated = new AllocatorProperties();
  11267. if (S_OK == _pin.Allocator.GetProperties(_allocated))
  11268. {
  11269. if (_allocated.cbBuffer > prop.cbBuffer)
  11270. {
  11271. prop.cbBuffer = _allocated.cbBuffer;
  11272. }
  11273. }
  11274. }
  11275. }
  11276. AllocatorProperties _actual = new AllocatorProperties();
  11277. int hr = pAlloc.SetProperties(prop, _actual);
  11278. if (FAILED(hr))
  11279. {
  11280. prop.cbBuffer = 1024;
  11281. hr = pAlloc.SetProperties(prop, _actual);
  11282. }
  11283. return hr;
  11284. }
  11285. #endregion
  11286. }
  11287. [ComVisible(false)]
  11288. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  11289. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  11290. [ClassInterface(ClassInterfaceType.None)]
  11291. public abstract class BaseMuxer : BaseFilter, IMediaSeeking, IAMFilterMiscFlags
  11292. {
  11293. #region Variables
  11294. protected FileWriter m_pFileWriter = null;
  11295. protected string m_sFileName = "";
  11296. protected bool m_bOverwrite = true;
  11297. protected MuxerInputPin m_pSeekingPin = null;
  11298. protected bool m_bIsOpened = false;
  11299. protected object m_csThreadLock = new object();
  11300. protected AMThread m_WorkerThread = null;
  11301. protected ManualResetEvent m_evQuit = new ManualResetEvent(false);
  11302. protected ManualResetEvent m_evReady = new ManualResetEvent(true);
  11303. protected AutoResetEvent m_evMuxStarted = new AutoResetEvent(false);
  11304. #endregion
  11305. #region Constructor
  11306. protected BaseMuxer(string _name, FileWriter _writer)
  11307. : base(_name)
  11308. {
  11309. m_pFileWriter = _writer;
  11310. m_pFileWriter.QuitEvent = m_evQuit;
  11311. m_WorkerThread = new ManagedThread(this.ThreadProc);
  11312. }
  11313. #endregion
  11314. #region Properties
  11315. public MuxerOutputPin OutputPin
  11316. {
  11317. get
  11318. {
  11319. foreach (BasePin _pin in Pins)
  11320. {
  11321. if (_pin.Direction == PinDirection.Output)
  11322. {
  11323. return (_pin as MuxerOutputPin);
  11324. }
  11325. }
  11326. return null;
  11327. }
  11328. }
  11329. public FileWriter Writer
  11330. {
  11331. get { return m_pFileWriter; }
  11332. }
  11333. public MuxerInputPin SeekingPin
  11334. {
  11335. get
  11336. {
  11337. if (m_pSeekingPin == null)
  11338. {
  11339. foreach (BasePin _pin in Pins)
  11340. {
  11341. if (_pin.Direction == PinDirection.Input && _pin.IsConnected)
  11342. {
  11343. if ((_pin as MuxerInputPin).Position != null)
  11344. {
  11345. m_pSeekingPin = (_pin as MuxerInputPin);
  11346. break;
  11347. }
  11348. }
  11349. }
  11350. }
  11351. return m_pSeekingPin;
  11352. }
  11353. }
  11354. public bool ThreadExists
  11355. {
  11356. get { return m_WorkerThread.ThreadExists; }
  11357. }
  11358. public long StartTime
  11359. {
  11360. get { return m_tStart; }
  11361. }
  11362. #endregion
  11363. #region Overridden Methods
  11364. protected override int OnInitializePins()
  11365. {
  11366. AddPin(CreateNewInputPin());
  11367. return NOERROR;
  11368. }
  11369. public override int Pause()
  11370. {
  11371. if (m_State == FilterState.Stopped)
  11372. {
  11373. m_pFileWriter.ThreadExists = false;
  11374. HRESULT hr;
  11375. if (m_pFileWriter.RequireMuxThread)
  11376. {
  11377. hr = StartThread();
  11378. }
  11379. else
  11380. {
  11381. hr = OpenFile();
  11382. }
  11383. if (hr.Failed) return hr;
  11384. }
  11385. return base.Pause();
  11386. }
  11387. public override int Stop()
  11388. {
  11389. HRESULT hr = (HRESULT)base.Stop();
  11390. StopThread();
  11391. CloseFile();
  11392. m_pSeekingPin = null;
  11393. return hr;
  11394. }
  11395. #endregion
  11396. #region Virtual Methods
  11397. public virtual HRESULT BeginFlush()
  11398. {
  11399. MuxerOutputPin _pin = OutputPin;
  11400. if (_pin != null)
  11401. {
  11402. _pin.DeliverBeginFlush();
  11403. }
  11404. if (!m_pFileWriter.AppendOnSeek && !m_bOverwrite)
  11405. {
  11406. StopThread();
  11407. CloseFile();
  11408. }
  11409. return NOERROR;
  11410. }
  11411. public virtual HRESULT EndFlush()
  11412. {
  11413. MuxerOutputPin _pin = OutputPin;
  11414. if (_pin != null)
  11415. {
  11416. _pin.DeliverEndFlush();
  11417. }
  11418. if (!m_pFileWriter.AppendOnSeek && !m_bOverwrite)
  11419. {
  11420. m_pFileWriter.ThreadExists = false;
  11421. HRESULT hr;
  11422. if (m_pFileWriter.RequireMuxThread)
  11423. {
  11424. hr = StartThread();
  11425. }
  11426. else
  11427. {
  11428. hr = OpenFile();
  11429. }
  11430. return hr;
  11431. }
  11432. return NOERROR;
  11433. }
  11434. public virtual HRESULT EndOfStream()
  11435. {
  11436. if (m_State == FilterState.Stopped)
  11437. {
  11438. return NOERROR;
  11439. }
  11440. int nEOS = 0;
  11441. foreach (BasePin _pin in Pins)
  11442. {
  11443. if (_pin.Direction == PinDirection.Input && _pin.IsConnected)
  11444. {
  11445. if ((_pin as MuxerInputPin).EOSDelivered) nEOS++;
  11446. }
  11447. }
  11448. if (m_pFileWriter.Count == nEOS)
  11449. {
  11450. MuxerOutputPin _pin = OutputPin;
  11451. if (_pin != null)
  11452. {
  11453. _pin.DeliverEndOfStream();
  11454. }
  11455. StopThread();
  11456. CloseFile();
  11457. NotifyEvent(EventCode.Complete, (IntPtr)((int)S_OK), Marshal.GetIUnknownForObject(this));
  11458. }
  11459. return NOERROR;
  11460. }
  11461. public virtual HRESULT SetMediaType(AMMediaType pmt)
  11462. {
  11463. if (m_pFileWriter != null)
  11464. {
  11465. return m_pFileWriter.SetMediaType(pmt);
  11466. }
  11467. return NOERROR;
  11468. }
  11469. public virtual HRESULT GetMediaType(int iPosition, ref AMMediaType pmt)
  11470. {
  11471. if (m_pFileWriter != null)
  11472. {
  11473. return m_pFileWriter.GetMediaType(iPosition, ref pmt);
  11474. }
  11475. return E_NOTIMPL;
  11476. }
  11477. public virtual HRESULT CompleteConnect(MuxerInputPin _pin)
  11478. {
  11479. int nConnected = 0;
  11480. int nCount = 0;
  11481. foreach (BasePin _existingPin in Pins)
  11482. {
  11483. if (_existingPin.Direction == PinDirection.Input)
  11484. {
  11485. nCount++;
  11486. if (_existingPin.IsConnected)
  11487. {
  11488. nConnected++;
  11489. }
  11490. }
  11491. }
  11492. if (nCount == nConnected)
  11493. {
  11494. int _max = m_pFileWriter.GetMaxTrackCount();
  11495. if (_max > 0)
  11496. {
  11497. if (nCount >= _max)
  11498. {
  11499. return NOERROR;
  11500. }
  11501. }
  11502. AddPin(CreateNewInputPin());
  11503. }
  11504. return NOERROR;
  11505. }
  11506. protected virtual MuxerInputPin CreateNewInputPin()
  11507. {
  11508. int nIndex = 1;
  11509. foreach (BasePin _pin in Pins)
  11510. {
  11511. if (_pin.Direction == PinDirection.Input) nIndex++;
  11512. }
  11513. return new MuxerInputPin("Input " + nIndex.ToString(), this);
  11514. }
  11515. #endregion
  11516. #region Methods
  11517. protected HRESULT OpenFile()
  11518. {
  11519. if (!m_bIsOpened)
  11520. {
  11521. HRESULT hr = E_FAIL;
  11522. if (hr.Failed)
  11523. {
  11524. MuxerOutputPin _output = OutputPin;
  11525. if (_output != null)
  11526. {
  11527. Guid _guid = typeof(IStream).GUID;
  11528. IntPtr pStream;
  11529. hr = _output.Connected._QueryInterface(ref _guid, out pStream);
  11530. if (hr.Succeeded)
  11531. {
  11532. BitStreamWriter _writer = new BitStreamWriter(new COMStream(pStream));
  11533. try
  11534. {
  11535. hr = m_pFileWriter.OpenOutput(_writer, m_bOverwrite);
  11536. }
  11537. catch (Exception _exception)
  11538. {
  11539. hr = (HRESULT)Marshal.GetHRForException(_exception);
  11540. _writer.Dispose();
  11541. }
  11542. finally
  11543. {
  11544. Marshal.Release(pStream);
  11545. }
  11546. if (hr != S_OK)
  11547. {
  11548. m_pFileWriter.CloseOutput();
  11549. }
  11550. }
  11551. }
  11552. }
  11553. if (hr.Failed)
  11554. {
  11555. if (!String.IsNullOrEmpty(m_sFileName))
  11556. {
  11557. try
  11558. {
  11559. hr = m_pFileWriter.OpenOutput(m_sFileName, m_bOverwrite);
  11560. }
  11561. catch (Exception _exception)
  11562. {
  11563. hr = (HRESULT)Marshal.GetHRForException(_exception);
  11564. }
  11565. if (hr != S_OK)
  11566. {
  11567. m_pFileWriter.CloseOutput();
  11568. }
  11569. }
  11570. }
  11571. if (hr == S_OK)
  11572. {
  11573. hr = m_pFileWriter.OnStartWriting();
  11574. if (hr != S_OK)
  11575. {
  11576. m_pFileWriter.CloseOutput();
  11577. }
  11578. }
  11579. m_bIsOpened = (hr == S_OK);
  11580. return hr;
  11581. }
  11582. return NOERROR;
  11583. }
  11584. protected HRESULT CloseFile()
  11585. {
  11586. if (m_bIsOpened)
  11587. {
  11588. m_pFileWriter.OnStopWriting();
  11589. m_pFileWriter.CloseOutput();
  11590. m_bIsOpened = false;
  11591. }
  11592. return NOERROR;
  11593. }
  11594. #endregion
  11595. #region Thread Methods
  11596. protected virtual HRESULT StartThread()
  11597. {
  11598. m_evQuit.Reset();
  11599. if (m_pFileWriter.RequireMuxThread)
  11600. {
  11601. m_evMuxStarted.Reset();
  11602. lock (m_csThreadLock)
  11603. {
  11604. if (m_evReady.WaitOne(0, false))
  11605. {
  11606. m_evMuxStarted.Reset();
  11607. m_evReady.Reset();
  11608. m_WorkerThread.Create();
  11609. int nResult = WaitHandle.WaitAny(new WaitHandle[] { m_evMuxStarted, m_evReady });
  11610. if (nResult != 0)
  11611. {
  11612. m_evQuit.Set();
  11613. m_WorkerThread.Close();
  11614. return E_FAIL;
  11615. }
  11616. }
  11617. }
  11618. }
  11619. return NOERROR;
  11620. }
  11621. protected virtual void StopThread()
  11622. {
  11623. m_evQuit.Set();
  11624. if (m_WorkerThread.ThreadExists)
  11625. {
  11626. lock (m_csThreadLock)
  11627. {
  11628. m_evReady.WaitOne();
  11629. m_WorkerThread.Close();
  11630. }
  11631. }
  11632. }
  11633. protected virtual void ThreadProc()
  11634. {
  11635. HRESULT hr;
  11636. m_evReady.Reset();
  11637. TRACE("Mux Started");
  11638. ASSERT(m_pFileWriter != null);
  11639. m_pFileWriter.ThreadExists = true;
  11640. hr = OpenFile();
  11641. if (hr.Succeeded)
  11642. {
  11643. m_evMuxStarted.Set();
  11644. bool bFlush = false;
  11645. long _minPosition;
  11646. long _maxPosition;
  11647. while (!bFlush)
  11648. {
  11649. bFlush = m_evQuit.WaitOne(5, false);
  11650. if (!bFlush)
  11651. {
  11652. _minPosition = MAX_LONG;
  11653. _maxPosition = 0;
  11654. foreach (BasePin _pin in Pins)
  11655. {
  11656. if (_pin.Direction == PinDirection.Input && _pin.IsConnected)
  11657. {
  11658. if (!(_pin as MuxerInputPin).EOSDelivered)
  11659. {
  11660. MuxerTrack _track = (_pin as MuxerInputPin).Track;
  11661. if (_minPosition > _track.Position)
  11662. {
  11663. _minPosition = _track.Position;
  11664. }
  11665. if (_track.Position > _maxPosition)
  11666. {
  11667. _maxPosition = _track.Position;
  11668. }
  11669. }
  11670. }
  11671. }
  11672. }
  11673. else
  11674. {
  11675. _minPosition = 0;
  11676. _maxPosition = MAX_LONG;
  11677. }
  11678. if (_minPosition != MAX_LONG)
  11679. {
  11680. foreach (BasePin _pin in Pins)
  11681. {
  11682. if (_pin.Direction == PinDirection.Input && _pin.IsConnected)
  11683. {
  11684. if (!(_pin as MuxerInputPin).EOSDelivered)
  11685. {
  11686. MuxerTrack _track = (_pin as MuxerInputPin).Track;
  11687. if (_track.Position >= _minPosition)
  11688. {
  11689. while (true)
  11690. {
  11691. PacketData _packet = _track.GetNextPacket();
  11692. if (_packet == null) break;
  11693. m_pFileWriter.WritePacket(_track, _packet);
  11694. _packet.Dispose();
  11695. if (_track.Position >= _maxPosition) break;
  11696. }
  11697. }
  11698. }
  11699. }
  11700. }
  11701. }
  11702. }
  11703. CloseFile();
  11704. }
  11705. m_evReady.Set();
  11706. TRACE("Mux Quit");
  11707. }
  11708. #endregion
  11709. #region IAMFilterMiscFlags Members
  11710. public int GetMiscFlags()
  11711. {
  11712. return 1;
  11713. }
  11714. #endregion
  11715. #region IFileSinkFilter Members
  11716. public int SetFileName(string pszFileName, AMMediaType pmt)
  11717. {
  11718. if (IsActive) return VFW_E_WRONG_STATE;
  11719. m_sFileName = pszFileName;
  11720. return NOERROR;
  11721. }
  11722. public int GetCurFile(out string pszFileName, AMMediaType pmt)
  11723. {
  11724. pszFileName = m_sFileName;
  11725. return NOERROR;
  11726. }
  11727. #endregion
  11728. #region IFileSinkFilter2 Members
  11729. public int SetMode(AMFileSinkFlags dwFlags)
  11730. {
  11731. m_bOverwrite = (dwFlags == AMFileSinkFlags.OverWrite);
  11732. return NOERROR;
  11733. }
  11734. public int GetMode(out AMFileSinkFlags dwFlags)
  11735. {
  11736. dwFlags = (m_bOverwrite ? AMFileSinkFlags.OverWrite : AMFileSinkFlags.None);
  11737. return NOERROR;
  11738. }
  11739. #endregion
  11740. #region IMediaSeeking Members
  11741. public int GetCapabilities(out AMSeekingSeekingCapabilities pCapabilities)
  11742. {
  11743. pCapabilities = AMSeekingSeekingCapabilities.None;
  11744. if (SeekingPin != null)
  11745. {
  11746. return SeekingPin.Position.GetCapabilities(out pCapabilities);
  11747. }
  11748. return E_NOINTERFACE;
  11749. }
  11750. public int CheckCapabilities(ref AMSeekingSeekingCapabilities pCapabilities)
  11751. {
  11752. if (SeekingPin != null)
  11753. {
  11754. return SeekingPin.Position.CheckCapabilities(ref pCapabilities);
  11755. }
  11756. return E_NOINTERFACE;
  11757. }
  11758. public int IsFormatSupported(Guid pFormat)
  11759. {
  11760. if (SeekingPin != null)
  11761. {
  11762. return SeekingPin.Position.IsFormatSupported(pFormat);
  11763. }
  11764. return E_NOINTERFACE;
  11765. }
  11766. public int QueryPreferredFormat(out Guid pFormat)
  11767. {
  11768. pFormat = TimeFormat.None;
  11769. if (SeekingPin != null)
  11770. {
  11771. return SeekingPin.Position.QueryPreferredFormat(out pFormat);
  11772. }
  11773. return E_NOINTERFACE;
  11774. }
  11775. public int GetTimeFormat(out Guid pFormat)
  11776. {
  11777. pFormat = TimeFormat.None;
  11778. if (SeekingPin != null)
  11779. {
  11780. return SeekingPin.Position.GetTimeFormat(out pFormat);
  11781. }
  11782. return E_NOINTERFACE;
  11783. }
  11784. public int IsUsingTimeFormat(Guid pFormat)
  11785. {
  11786. if (SeekingPin != null)
  11787. {
  11788. return SeekingPin.Position.IsUsingTimeFormat(pFormat);
  11789. }
  11790. return E_NOINTERFACE;
  11791. }
  11792. public int SetTimeFormat(Guid pFormat)
  11793. {
  11794. if (SeekingPin != null)
  11795. {
  11796. return SeekingPin.Position.IsUsingTimeFormat(pFormat);
  11797. }
  11798. return E_NOINTERFACE;
  11799. }
  11800. public int GetDuration(out long pDuration)
  11801. {
  11802. pDuration = 0;
  11803. if (SeekingPin != null)
  11804. {
  11805. SeekingPin.Position.GetDuration(out pDuration);
  11806. return NOERROR;
  11807. }
  11808. return E_NOINTERFACE;
  11809. }
  11810. public int GetStopPosition(out long pStop)
  11811. {
  11812. pStop = 0;
  11813. if (SeekingPin != null)
  11814. {
  11815. return SeekingPin.Position.GetStopPosition(out pStop);
  11816. }
  11817. return E_NOINTERFACE;
  11818. }
  11819. public int GetCurrentPosition(out long pCurrent)
  11820. {
  11821. pCurrent = 0;
  11822. if (SeekingPin != null)
  11823. {
  11824. return SeekingPin.Position.GetCurrentPosition(out pCurrent);
  11825. }
  11826. return E_NOINTERFACE;
  11827. }
  11828. public int ConvertTimeFormat(out long pTarget, DsGuid pTargetFormat, long Source, DsGuid pSourceFormat)
  11829. {
  11830. pTarget = 0;
  11831. if (SeekingPin != null)
  11832. {
  11833. return SeekingPin.Position.ConvertTimeFormat(out pTarget, pTargetFormat, Source, pSourceFormat);
  11834. }
  11835. return E_NOINTERFACE;
  11836. }
  11837. public int SetPositions(DsLong pCurrent, AMSeekingSeekingFlags dwCurrentFlags, DsLong pStop, AMSeekingSeekingFlags dwStopFlags)
  11838. {
  11839. if (SeekingPin != null)
  11840. {
  11841. return SeekingPin.Position.SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
  11842. }
  11843. return E_NOINTERFACE;
  11844. }
  11845. public int GetPositions(out long pCurrent, out long pStop)
  11846. {
  11847. pCurrent = 0;
  11848. pStop = 0;
  11849. if (SeekingPin != null)
  11850. {
  11851. return SeekingPin.Position.GetPositions(out pCurrent, out pStop);
  11852. }
  11853. return E_NOINTERFACE;
  11854. }
  11855. public int GetAvailable(out long pEarliest, out long pLatest)
  11856. {
  11857. pEarliest = 0;
  11858. pLatest = 0;
  11859. if (SeekingPin != null)
  11860. {
  11861. return SeekingPin.Position.GetAvailable(out pEarliest, out pLatest);
  11862. }
  11863. return E_NOINTERFACE;
  11864. }
  11865. public int SetRate(double dRate)
  11866. {
  11867. if (SeekingPin != null)
  11868. {
  11869. return SeekingPin.Position.SetRate(dRate);
  11870. }
  11871. return E_NOINTERFACE;
  11872. }
  11873. public int GetRate(out double pdRate)
  11874. {
  11875. pdRate = 1.0;
  11876. if (SeekingPin != null)
  11877. {
  11878. return SeekingPin.Position.GetRate(out pdRate);
  11879. }
  11880. return E_NOINTERFACE;
  11881. }
  11882. public int GetPreroll(out long pllPreroll)
  11883. {
  11884. pllPreroll = 0;
  11885. if (SeekingPin != null)
  11886. {
  11887. return SeekingPin.Position.GetPreroll(out pllPreroll);
  11888. }
  11889. return E_NOINTERFACE;
  11890. }
  11891. #endregion
  11892. }
  11893. #region Base Classes
  11894. [ComVisible(false)]
  11895. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  11896. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  11897. [ClassInterface(ClassInterfaceType.None)]
  11898. public class BaseMuxerFilter : BaseMuxer
  11899. {
  11900. #region Constructor
  11901. protected BaseMuxerFilter(string _name, FileWriter _writer)
  11902. : base(_name, _writer)
  11903. {
  11904. AddPin(new MuxerOutputPin(this));
  11905. }
  11906. #endregion
  11907. }
  11908. [ComVisible(false)]
  11909. [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
  11910. [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
  11911. [ClassInterface(ClassInterfaceType.None)]
  11912. public class BaseFileWriterFilter : BaseMuxer, IFileSinkFilter2
  11913. {
  11914. #region Constructor
  11915. protected BaseFileWriterFilter(string _name, FileWriter _writer)
  11916. : base(_name, _writer)
  11917. {
  11918. }
  11919. #endregion
  11920. }
  11921. #endregion
  11922. #region Generic Templates
  11923. [ComVisible(false)]
  11924. [ClassInterface(ClassInterfaceType.None)]
  11925. public class BaseMuxerFilterTemplate<Writer> : BaseMuxerFilter where Writer : FileWriter, new()
  11926. {
  11927. public BaseMuxerFilterTemplate(string _name)
  11928. : base(_name, new Writer())
  11929. {
  11930. }
  11931. }
  11932. [ComVisible(false)]
  11933. [ClassInterface(ClassInterfaceType.None)]
  11934. public class BaseFileWriterFilterTemplate<Writer> : BaseFileWriterFilter where Writer : FileWriter, new()
  11935. {
  11936. public BaseFileWriterFilterTemplate(string _name)
  11937. : base(_name, new Writer())
  11938. {
  11939. }
  11940. }
  11941. #endregion
  11942. #endregion
  11943. }