MT

Přehled

autor: tsp
verze: 0.7
stáhnout: http://www.avisynth.org/tsp/, http://www.avisynth.org/warpenterprises/
kategorie: Různé pluginy
požadavky: 

licence: GPL


Obsah

MT 0.7

MT(clip clip,string filter,int threads,int overlap,bool splitvertical)

MTi(clip clip,string filter)

MTsource(string filter,int delta,int threads)

Úvod

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

Technické info

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.

Omezení

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.

Instalace

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í.

Syntaxe

MT

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

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

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.

Příklady

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))


Seznam změn

   * 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


Modifikovaný avisynth MT 2.5.7.5

Úvod

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

Technické info

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í.

Syntaxe

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.

Příklad:

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

Jak vyvíjet vláknově bezpečné (threadsafe) filtry

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
 }
}

Odkazy

stránky filtrů od tsp

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.

MT stránka podpory

Získáno z"http://avisynth.org/mediawiki/MT"

Český překlad:2.7.2009