licence: GPL
MT
(clip clip,string filter,int threads,int overlap,bool splitvertical)
MTi
(clip clip,string filter)
MTsource
(string filter,int delta,int threads)
MT je filtr, který umožňuje jiným filtrům běžet na více vláknech. To by mělo urychlit zpracování na hyperthreaded/vícejádrových procesorech nebo víceprocesorových systémech.
Důležité: Nikdy nezapomeňte posoudit výsledek pohledem na zvýšení rychlosti a ne jen využití cpu.
Také se podívejte na MT support page pro více informací než požádáte o pomoc
MT je filtr, který rozděluje snímek na malé fragmenty, které jsou zpracovány v jednotlivých vláknech a tím umožní plné využití víceprocesorových nebo hyperřetězených (hyperthread) počítačů. Testoval jsem ho na mém starém abit bp6 s 2x celeron 400 MHz a zvýšil rychlost o 40%. Všimněte si, že pokud už máte 100% zatížení cpu při zpracování avs skriptů bez MT (t.j pokud enkódujete do DivX/XviD) nemusíte použít tento filtr.
Tento filtr pracuje jako tato avs funkce:
function PseudoMT(clip c,string filter) { a=eval("c.crop(0,0,src.width/2,src.height)."+filter) b=eval("c.crop(src.width/2,0,src.width/2,src.height)."+filter) stackhorizontal(a,b) }
Jediný rozdíl je, že a i b jsou vykonány paralelně a je možné
rozdělit snímek do více než 2 kusů. Pokud filtr pracuje s výše uvedeným
skriptem měl by pracovat s MT , pokud je filtr vláknově bezpečný (thread safe). Dust nepracuje
se skriptem výše, takže jestliže chcete použít iip , použijte jiný odšumovač nebo donuťte
Steadyho opravit chybu.
Aby filtr běžel, musí přijímat jen jeden vstupní klip a tím je last. Filtr by také neměl počítat s obsahem celého snímku (jako smart deinterlacery) jinak je zde riziko, že bude zpracována jen část snímku. Filtr by měl být také vláknově bezpečný. Většina filtrů je vláknově bezpečná, ale některé budou vytvářet chybné výsledky nebo budou padat.
Zkopírujte mt.dll do složky avisynth pluginů a zkopírujte zahrnutý soubor avisynth.dll do vaší složky windows\system32 nebo tam, kde je umístěn váš původní avisynth.dll a nezapomeňte si tento starý soubor avisynth.dll (přejmenovat) pokud nemáte nainstalovanou verzi 2.6 .
Od verze 0.7 jsou zahrnuty také další dva filtry:
function PseudoMTi(clip c,string filter) { a=eval("c.AssumeFieldBased().SeparateFields.selecteven()."+filter) b=eval("c.AssumeFieldBased().SeparateFields.selectodd()."+filter) interleave(a,b).weave() }
Jako další pseudoskript a i b jsou vykonány paralelně. Všimněte si, že jsou vytvořena jen dvě vlákna, takže využije jen dvě (virtuální) jádra.
function PseudoMTsource(string filter) { SetMTmode(2) eval(filter) SetMtmode(0) }
Tedy na rozdíl od dvou ostatních filtrů je to časový (temporal) filtr který přenáší snímky vpřed v čase a ukládá je do vyrovnávací paměti (cache) pro rychlé znovuzískání.
MT
(clip clip,string filter,int threads,int overlap,bool splitvertical)
Všechny parametry jsou jmenné. Parametry jsou:
clip clip = last
Vstupní klip.
filter string = nemá výchozí hodnotu
Filtr, který má běžet na více vláknech. Všimněte si, že filtr nesmí měnit jak
výšku tak ani šířku snímku (ale barevné prostředí je okay) a je povolen jen 1 vstupní klip.
Může to být jakýkoli vestavěný filtr, avs skriptem definovaný filtr nebo externí plugin
filtr dokud jsou dodržena omezení.
threads int = 2
Počet pracovních vláken. Nastavte ho na počet vláken která mohou
na vašem počítači běžet současně.
overlap int = 0
- počet pixelů pro přidání na horní a spodní okraj nebo levý a pravý okraj.
Zvyšte ho pokud vidíte artefakty v místě kde je snímek rozdělen.
splitvertical bool = false
- pokud je true , snímky jsou rozříznuty vertikálně(a filtru je umožněno změnit
výšku) jinak je rozříznut horizontálně (a filtru je umožněno změnit
šířku).
MTi
(clip clip,string filter)
Všechny parametry jsou jmenné. Parametry jsou:
clip clip = last
Vstupní klip. Musí mít výšku dělitelnou 2 pro RGB a YUY2 barevná prostředí a výšku dělitelnou 4 pro
YV12 barevné prostředí
filter string = nemá výchozí hodnotu
Filtr, který má běžet na více vláknech. Všimněte si, že filtr může měnit jak
výšku tak i šířku snímku ve stejném čase, ale je povolen jen 1 vstupní klip.
Může to být jakýkoli vestavěný filtr, avs skriptem definovaný filtr nebo externí plugin
filtr dokud jsou dodržena omezení.
MTsource
(string filter,int delta,int threads,int max_fetch)
Všechny parametry jsou jmenné. Parametry jsou:
filter string = nemá výchozí hodnotu
Zdrojový filtr, který má běžet na více vláknech. V současnosti jsou podporovány pouze vnitřní a externí
zdrojové filtry (jako DirectShowSource, Avisource, MPEG2Source) . Můžete použít
avs skriptem definovaný filtr nebo ne-zdrojový filtr, ale to může spadnout nebo vytvářet
poškozené snímky.
delta int = 1
Toto je kolik snímků je mezi každým požadavkem o snímek, takže pokud hodláte
číst jen každý druhý snímek nastavte ho na 2 nebo pokud čtete snímky
zpětně, nastavte ho na -1. Komplexnější modely přístupu ke snímku jako
SelectEvery(10,3,6,7) nejsou podporovány (ale mohly by ostatně pracovat, protože žádané
snímky jsou ve vyrovnávací paměti (cache), kde bude prostor v paměti od nevyžadovaných
snímků v cache)
threads int = 2
Počet pracovních vláken. Nastavte ho na počet vláken, která mohou
na vašem počítači běžet současně.
max_fetch int = 30
Toto je maximální počet snímků vpřed od aktuálně žádaného snímku,
který MTsource přenese. Jeho nízké nastavení nechá vlákna nečinná po
času a příliš vysoké nastavení zabere příliš mnoho paměti.
obyčejné rozmazání:
MT("blur(1)",2,2)
také uživatelem definovaná funkce (používá variableblur):
MT("unsharp(2,0.7)",2,2) function unsharpen(clip c,float variance,float k) { blr=binomialBlur(c,vary=variance,varc=2,Y=3,U=2,V=2) return yv12lutxy(blr,c,"y x - "+string(k)+" * y +",y=3,u=2,v=2) }
Toto sice nevytvoří zamýšlený výsledek - urychlení, ale ukáže kdy použít trojité uvozovky - když už jsou nějaké použité v parametru:
MT(""" subtitle("Doh") """,4,0)
Příklad MTi
MTi("fft3dfilter()")
vytváří téměř stejný výsledek jako
MT("fft3dfilter(interlaced=true)",threads=2)
ale pro filtry, které nativně nepodporují prokládaný obsah může být jednodušší použít MTi()
Příklad pro MTsource()
ir=MTSource(""" imagereader("c:\test.png") """,delta=1,threads=2,max_fetch=10) as=MTSource(""" avisource("c:\test.avi") """,delta=-1) #delta záporné kvůli reverse() ms=MTSource(""" MPEG2Source("c:\test.d2v") """,delta=9) #delta je 9 kvůli selectevery(9,1) stackhorizontal(ir.trim(0,100),as.reverse().trim(0,100),ms.selectevery(9,1).trim(0,100))
* 0.1 first release. * 0.2 Should be more thread safe. * 0.21 forgot to comment out a Sleep(0) * 0.25 Added the splitvertical option * 0.3 More stable(and slower) * 0.4 Includes a custom version of avisynth 2.56 beta that should speed things up * 0.41 Minor speed increase * 0.5 Requires the included modified avisynth 2.5.6 or avisynth 2.6 * 0.6 Bugfix: height can be changed with splitvertical=true without crashing. Also includes modified avisynth MT 2.5.7.3 * 0.7 two new filters: MTi(), MTsource() and Avisynth MT 2.5.7.5
Obsahuje dvě nové funkce SetMTMode()
a GetMTMode()
a
je potřeba MT.dll. Nainstalujte ho nahrazením avisynth.dll ve vaší složce
c:\windows\system32 (a pamatujte nejdříve na zazálohování starého souboru).
Poznámka: Ani oficiální verze Avisynthu 2.5.8 nepodporuje multhreading a tak vznikají pobočné pokusy o jeho vytvoření. Najdete je zde http://forum.doom9.org/showthread.php?t=144852 a nebo zde http://forum.doom9.org/showthread.php?t=148117
Tyto funkce umožňují avisynthu použít více než jedno vlákno při zpracování filtry. To je užitečné, když máte více než jedno cpu/jádro nebo hyperthreading. Tato funkce je stále experimentální.
GetMTMode
(bool threads)
threads bool = false
Když je true GetMTMode
vrací počet využitých vláken, jinak je
vrácen režim mode (viz níže).
SetMTmode
(int mode,int threads)
Umístěte toto na první řádek v avs souboru, aby jste zapnuli časový - temporal (to je, že je zpracováno více než jeden snímek ve stejném čase) multithreading. Použijte ho později ve skriptu pro změnu režimu mode u filtrů níže.
mode int (2, výchozí 1-6)
- existuje 6 režimů 1 až 6.
* Mode 1 je nejrychlejší, ale pracuje jen s několika filtry * Mode 2 by měl pracovat s většinou filtrů, ale využívá více paměti * Mode 3 by měl pracovat s některými z filtrů, které nepracují v režimu mode 2 ale je pomalejší * Mode 4 je kombinací mode 2 a 3 a měl by pracovat s ještě více filtry, ale je ještě pomalejší a využívá ještě více paměti * Mode 5 je nejpomalejší(Pomalejší než bez použití SetMTMode) , ale měl by pracovat se všemi filtry, které nevyžadují lineární frameserving (to je snímky přichází v pořadí snímek 0,1,2 ... poslední) * Mode 6 je upravený mode 5 , který by mohl být mírně rychlejší
Podrobnější vysvětlení různých režimů si můžete přečíst zde: MT modes explained
threads int = 0
Počet použitých vláken. Nastavte na 0 pro jeho nastavení na počet dostupných procesorů.
Není možné měnit počet vláken jinak než v
prvním SetMTMode.
SetMTMode(2,0) #zapne multihreading použitím thread = na počet dostupných procesorů a mode 2 LoadPlugin("...\LoadPluginEX.dll") #potřebný pro načtení avisynth 2.0 pluginů LoadPlugin("...\DustV5.dll") #Načte Pixiedust import("limitedsharpen.avs") src=AVIsource("test.avi") SetMTMode(5) #mění mode na 5 pro řádky níže src=src.converttoyuy2().PixieDust()#Pixiedust potřebuje mode 5 aby fungoval. SetMTMode(2) #mění mode zpět na 2 src.LimitedSharpen() #protože LimitedSharpen pracuje s mode 2 dobře subtitle("Pocet pouzitych vlaken: "+string(GetMTMode(true))+" Aktualni MT Mode: "+string(GetMTMode())) #Zobrazí mode a počet použitých vláken
Není zaručeno žádné lineární pořadí snímků (kromě případu kdy je použito MT místo setmtmode) a pro každý režim mode existují různá omezení:
PVideoFrame __stdcall AdjustFocusV::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame frame = child->GetFrame(n, env); //Assigned to a local variable so this will work in mode 3 env->MakeWritable(&frame); if (!line) line = new uc[frame->GetRowSize()+32]; uc* linea = (uc*)(((int)line+15) & -16);// Align 16 uc* buf = frame->GetWritePtr(); int pitch = frame->GetPitch(); int row_size = vi.RowSize(); int height = vi.height; memcpy(linea, buf, row_size); // First row - map centre as upper if ((pitch >= ((row_size+7) & -8)) && (env->GetCPUFlags() & CPUF_MMX)) { AFV_MMX(linea, buf, height, pitch, row_size, amount); } else { AFV_C(linea, buf, height, pitch, row_size, amount); } return frame; }
Ale ne jako toto:
PVideoFrame TemporalSoften::GetFrame(int n,IScriptEnvironment* env) { __int64 i64_thresholds = 0x1000010000100001i64; int radius = (kernel-1) / 2 ; int c= 0; // Just skip if silly settings if((!luma_threshold)&& (!chroma_threshold) || (!radius)) return child->GetFrame(n,env); for(int p= 0;p<16;p++) planeDisabled[p]=false; for(p= n-radius;p<=n+radius;p++) { frames[p+radius-n] = child->GetFrame(min(vi.num_frames-1,max(p,0)), env); //GetFrame assigned to class variable frames. This wouldn't work with Mode 3 //because the next thread that enters this getframe will overwrite the result // from the last thread } //do stuff }
Ale při použití mode 3 není žádná potřeba pro vláknově bezpečný přístup do třídy proměnných. A protože je jen 1 instance třídy, která zpracuje všechny snímky, internal caches bude pracovat mnohem lépe. Horší věc je, že vykonat filtr v čase může jen 1 vlákno, takže pokud je to jen pomalý filtr ve skriptu, urychlení by nebylo tak velké.
PClipLocalStorage
Zde je příklad jak může být použit PClipLocalStorage pro sdílení cache mezi více instancemi (které jsou vytvořeny pomocí mode=2,4):
class Cache { public: //These function should be threadsafe. The most simple way is to use a //critical section like this PVideoFrame GetCachedFrame(int framenumber) { EnterCriticalSection(&cs); //Code //... LeaveCriticalSection(&cs); return retval; } SetCachedFrame(PVideoFrame frame); private: CRITICAL_SECTION cs; } class Sample : public GenericVideoFilter{ public: Sample(PClip _child, IScriptEnvironment* env); ~Sample(); PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env); protected: PClipLocalStorage cls; Cache* FrameCache; } Sample::Sample(PClip _child, IScriptEnvironment* env) : GenericVideoFilter(_child),cls(env) { //if the cache has not been created yet GetValue will return 0 if(cls->GetValue()==0) { //create the cache and save the address in the PClipLocalStorage FrameCache = new Cache();cls->SetValue(static_cast(FrameCache)); } // The cache has been created so assign the address to FrameCache else { FrameCache=static_cast(cls->GetValue()); } } Sample::~Sample() { //only delete FrameCache if it is not delete yet. if(cls->GetValue()!=0) { delete FrameCache; cls->SetValue(0);//Signal that the cache is deleted } }
oficiální vlákno na doom9.org forum Čtěte prosím tuto stránku a stránku podpory níže před tím než se budete ptát na pomoc - díky.
Získáno z"http://avisynth.org/mediawiki/MT"
Český překlad:2.7.2009