搜索 社区服务 统计排行 帮助
  • 11740阅读
  • 31回复

[分享]利用ConditionalFilter/Reader简化avs分段处理脚本编写

楼层直达
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
发现鲜有人交流过这种偷懒技巧[/KH]

似乎很多人是利用trim来完成分段处理的,分段完成后,需要检查帧号,最后合并各段clip
当大量trim存在的情况下 如果某一句的帧号打错了 没检查出来那会很悲剧[/ku]

也有类似于FilterRange之类的avs分段脚本
http://www.avisynth.info/?FilterRange
其本质还是trim 似乎过多的trim分段+滤镜处理 很可能会导致avs脚本载入初始化失败[/KH]

这时就得靠avisynth wiki上提到的一种方法
http://avisynth.org/mediawiki/ConditionalReader#Complicated_ApplyRange
来偷懒

注意这种方法不能适用于调用一些会改变clip帧数的滤镜

脚本开始需要把要调用到的滤镜函数当作字符串赋值给变量
为了方便取名为n1,n2,n3........
例如
  1. n1="""ffpp("l5")"""
  2. n2="""daa()"""
  3. n3="""nnedi3()"""


然后需要分段处理的地方要调用到ConditionalFilter/Reader+ScriptClip+Eval
  1. ConditionalFilter(last.ScriptClip("""Eval(Eval("n"+string(filterindex)))"""),last, "filterindex", "greaterthan", "0", false)
  2. ConditionalReader("xxxxx.txt", "filterindex")


xxxxx.txt类似以下语法
  1. Type int
  2. Default 0
  3. R 0 20 1
  4. R 21 39 2
  5. R 244 266 3
  6. 3168 1
  7. 4652 2
  8. 5043 3

表示
默认情况下filterindex为0,即不处理
0-20帧filterindex为1,即调用ffpp("l5")处理
21-39帧filterindex为2,即调用daa()处理
244-266帧filterindex为3,即调用nnedi3()处理
3168单帧filterindex为1,即调用ffpp("l5")处理
4652单帧filterindex为2,即调用daa()处理
5043单帧filterindex为3,即调用nnedi3()处理


从而ConditionalReader可以从xxxxx.txt读取分段信息 赋值给filterindex
然后ConditionalFilter会检查filterindex 决定返回哪一个clip

当filterindex大于0时 返回last.ScriptClip("""Eval(Eval("n"+string(filterindex)))""")
此时ScriptClip+Eval函数 会根据之前字符串变量 替换("n"+string(filterindex))字符串,并将其当做脚本的一部分来处理 从而实现对函数的调用

以上为偷懒的全过程 小弟表达能力不好 各位大大多包涵:)


题外话:

为了能够更偷懒,小弟还编写了一个小程序

实现一边通过VirtualDub预览 一边按快捷键 便能完成分段 并生成脚本

由于是写给自己用的 程序不完善的地方有很多 再加上本人懒

所以各位大大还是不要期待比较好

http://u.115.com/file/f1b2b14865
MyVDIVTC101010.7z

简单讲解:
程序需要获取VirtualDub的Window Handle才能运作
一种方法是在程序运行初始化时会自动查找类名为VirtualDub的窗口
另一种方法是将焦点放在VD Window Handle下面的输入框里面 将鼠标指针移动到VirtualDub窗口标题上 按下回车键

然后将*.dga/*.d2v/*.*文件拖放到程序窗口里面 文件会被当作Source并在生成脚本时替换脚本编辑窗里面的 %source% 字符串

此时按下Initialize 初始化生成avs脚本 然后拖入VirtualDub预览

选中StayOnTop可以前端显示 选中HotKey可以调用快捷键 能使用快捷键的按钮后面有对应快捷键字符 全在小键盘区

其余就得各位大大自行研究或者看源代码了

Fansubbing is a waste of time.
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 31楼 发表于: 2011-05-13
因为ScriptClip是在每次GetFrame时解释运行脚本,很复杂的脚本或者初始化很慢的滤镜会有这个问题

如果改上上面那样写,那么脚本是在avs载入时初始化,如果调用滤镜太多会占用较多资源
(如果只需要使用滤镜处理个别单帧就可以考虑用ScriptClip,如果你需要处理大量连续帧就别使用ScriptClip

当然还可以自己写个滤镜解决这问题,当需要处理大量连续帧时初始化滤镜,处理完毕再进行释放

还有个办法是将分段写成多个avs脚本,通过pipe依次输出给编码器
[ 此帖被linuxyouxia在2011-05-13 20:44重新编辑 ]

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2009-01-02
在线时间:
8小时
发帖:
32
只看该作者 30楼 发表于: 2011-05-13
似乎scriptclip的调用效率有问题,尤其是调用一些比较大的滤镜的时候?
比如mctd 基本default在我的机器和朋友机器上用scriptclip调用只有1/10或者更慢的速度。
另外前几天在搞另一个片子时调用eedi2的aa滤镜也很慢
似乎改成
ConditionalFilter(last.function1,last, "filterindex", "==", "1", false)
ConditionalFilter(last.function2,last, "filterindex", "==", "2", false)
ConditionalReader("xxxxx.txt", "filterindex")
能避免此问题
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 29楼 发表于: 2011-04-27
无聊改了下tivtc中的tfm,当display=true时通过消息列队把场景切换帧帧号和交错帧帧号 发送给MyVDIVTC
MyVDIVTC CheckListBox中双击帧号,通过发送消息方式操作VD界面跳转到该帧

tfm函数初始化时,通过FindWindowEx搜索标题为 MyVDIVTC 的窗口 获取MyVDIVTC的窗口句柄

代码尚未整理,凑合着用似乎没问题

http://dl.dbank.com/c08u5ftvot

  1. diff -C 3 B/TFM.cpp A/TFM.cpp
  2. *** B/TFM.cpp    2008-01-17 13:01:06.000000000 +0800
  3. --- A/TFM.cpp    2011-04-27 14:12:56.000000000 +0800
  4. ***************
  5. *** 537,542 ****
  6. --- 537,543 ----
  7.           int blockN, int xblocks, bool d2vmatch, int *mics, PVideoFrame &prv,
  8.           PVideoFrame &src, PVideoFrame &nxt, IScriptEnvironment *env)
  9.   {
  10. +     bool isSC;
  11.       if (combed > 1 && PP > 1) return;
  12.       if (combed > 1 && PP == 1 && blockN != -20)
  13.       {
  14. ***************
  15. *** 552,563 ****
  16.           sprintf(buf, "order = %d  field = %d  mode = %d ", order, field, mode);
  17.       if (np == 3) DrawYV12(dst, 0, 1, buf);
  18.       else DrawYUY2(dst, 0, 1, buf);
  19.       if (!over && !d2vmatch) sprintf(buf, "frame: %d  match = %c %s", n, MTC(fmatch),
  20. !         ((ubsco || mmsco || flags == 5) && checkSceneChange(prv, src, nxt, env, n)) ? " (SC) " : "");
  21.       else if (d2vmatch) sprintf(buf, "frame: %d  match = %c (D2V) %s", n, MTC(fmatch),
  22. !         ((ubsco || mmsco || flags == 5) && checkSceneChange(prv, src, nxt, env, n)) ? " (SC) " : "");
  23.       else sprintf(buf, "frame: %d  match = %c (OVR) %s", n, MTC(fmatch),
  24. !         ((ubsco || mmsco || flags == 5) && checkSceneChange(prv, src, nxt, env, n)) ? " (SC) " : "");
  25.       if (np == 3) DrawYV12(dst, 0, 2, buf);
  26.       else DrawYUY2(dst, 0, 2, buf);
  27.       int i = 3;
  28. --- 553,565 ----
  29.           sprintf(buf, "order = %d  field = %d  mode = %d ", order, field, mode);
  30.       if (np == 3) DrawYV12(dst, 0, 1, buf);
  31.       else DrawYUY2(dst, 0, 1, buf);
  32. +     isSC = checkSceneChange(prv, src, nxt, env, n);
  33.       if (!over && !d2vmatch) sprintf(buf, "frame: %d  match = %c %s", n, MTC(fmatch),
  34. !         ((ubsco || mmsco || flags == 5) && isSC) ? " (SC) " : "");
  35.       else if (d2vmatch) sprintf(buf, "frame: %d  match = %c (D2V) %s", n, MTC(fmatch),
  36. !         ((ubsco || mmsco || flags == 5) && isSC) ? " (SC) " : "");
  37.       else sprintf(buf, "frame: %d  match = %c (OVR) %s", n, MTC(fmatch),
  38. !         ((ubsco || mmsco || flags == 5) && isSC) ? " (SC) " : "");
  39.       if (np == 3) DrawYV12(dst, 0, 2, buf);
  40.       else DrawYUY2(dst, 0, 2, buf);
  41.       int i = 3;
  42. ***************
  43. *** 606,611 ****
  44. --- 608,633 ----
  45.           if (np == 3) DrawYV12(dst, 0, i, buf);
  46.           else DrawYUY2(dst, 0, i, buf);
  47.       }
  48. +
  49. +     if ((MyVDIVTC == NULL) || ((!isSC) && (combed == 0)))
  50. +     {
  51. +         return;
  52. +     } else
  53. +     if ((combed != 0) && isSC)
  54. +     {
  55. +         SendMessage(MyVDIVTC, WM_USER+100, n, 0);
  56. +     } else
  57. +     if ((combed != 0) && (!isSC))
  58. +     {
  59. +         SendMessage(MyVDIVTC, WM_USER+100, n, 1);
  60. +     } else
  61. +     if ((combed == 0) && isSC)
  62. +     {
  63. +         SendMessage(MyVDIVTC, WM_USER+100, n, 2);
  64. +        
  65. +     }
  66. +
  67. +
  68.   }
  69.   
  70.   void TFM::getSettingOvr(int n)
  71. ***************
  72. *** 2316,2321 ****
  73. --- 2338,2347 ----
  74.           sprintf(buf, "TFM:  %s by tritical\n", VERSION);
  75.           OutputDebugString(buf);
  76.       }
  77. +     if (display)
  78. +     {
  79. +         MyVDIVTC = FindWindowEx(NULL,NULL,NULL,"MyVDIVTC");
  80. +     }
  81.       child->SetCacheHints(CACHE_RANGE, 3); // fixed to diameter (07/30/2005)
  82.       lastMatch.frame = lastMatch.field = lastMatch.combed = lastMatch.match = -20;
  83.       nfrms = vi.num_frames-1;
  84. diff -C 3 B/TFM.h A/TFM.h
  85. *** B/TFM.h    2008-01-17 13:01:28.000000000 +0800
  86. --- A/TFM.h    2011-04-26 12:38:22.000000000 +0800
  87. ***************
  88. *** 92,97 ****
  89. --- 92,98 ----
  90.       int tpitchy, tpitchuv, *moutArray, *moutArrayE;
  91.       MTRACK lastMatch;
  92.       SCTRACK sclast;
  93. +     HWND MyVDIVTC;
  94.       double scthresh;
  95.       char buf[4096], outputFull[270], outputCFull[270];
  96.       PlanarFrame *map, *cmask;

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2009-11-20
在线时间:
7小时
发帖:
61
只看该作者 28楼 发表于: 2010-11-15
EP就是中文直译过来的egg pain饿(捂脸

于是路过学习了。
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 27楼 发表于: 2010-11-14
引用
最初由 Yuricon 发布
这方法也不错,其实你还可以加个ShowFrameNumber

这个主意真好:) 谢大大指点

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2002-07-21
在线时间:
35小时
发帖:
79
只看该作者 26楼 发表于: 2010-11-14
引用
最初由 upyzl 发布
其实以前一直想问了
EP的全称是啥?
Extreme P????


蛋+疼
http://popgo.net/wiki/%E6%89%80%E8%B0%93EP
级别: 风云使者
注册时间:
2004-01-20
在线时间:
633小时
发帖:
549
只看该作者 25楼 发表于: 2010-11-14
其实以前一直想问了
EP的全称是啥?
Extreme P????

求资源,欢迎PM告知:
Xbox360 Clannad OP原版(WMV格式)
PS3 圣恩传说F / Tales of Graces F OP原版(BIK格式)


CLANNAD游戏OP/ED + TOMOYO after OP 无二次Credits内嵌字幕清晰版
BiliBili站点     AcFun站点

--- Direct264 自编译版 ---

碧之轨迹Nightmare VS风之剑圣 第1战(均无水印):6cn(六间房)   56(我乐)
BGM: Inevitable Struggle (Super Arrange Ver.)

Rockman 9 Rock Medley
级别: 新手上路
注册时间:
2010-11-13
在线时间:
0小时
发帖:
28
只看该作者 24楼 发表于: 2010-11-14
这方法也不错,其实你还可以加个ShowFrameNumber
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 23楼 发表于: 2010-11-14
其实之前对比都是用Interleave(clip1.Subtitle("clip1"),clip2.Subtitle("clip2"))

这样VD预览时 按方向键在前后帧来回切换就能方便得看出不同了

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2010-11-13
在线时间:
0小时
发帖:
28
只看该作者 22楼 发表于: 2010-11-14
MME重点在于双屏显示来更直观的进行视觉对比,这点上已经和Subtract之类的不同了
其实也就是利用overlay罢了,都这么久了,我自己也没怎么用过(拖
EP乃罪过啊....
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 21楼 发表于: 2010-11-14
引用
最初由 Yuricon 发布
这和MME性质不一样吧...

是不一样 但是也是一种对比的选择

实现同一目的或类似目的 可以有不同的选择

所以如果俺的方法行不通的时候 俺也会用大大的脚本 因为俺懒嘛 有现成的就用现成的
比如某一段需要对画中画处理 那么直接在俺自己的方法上加一行 调用大大编写的脚本

大大完全可以另开一帖在POPGO推广EP脚本 让POPGO一些不去NMM的群众不需要进俺的主题 就能了解大大写的脚本的优点 小弟一定捧场

小弟没有任何贬低大大写的脚本的意思 如果先前说的话有所冒犯 还请多多包涵:)

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2010-11-13
在线时间:
0小时
发帖:
28
只看该作者 20楼 发表于: 2010-11-14
这和MME性质不一样吧...
级别: 圣骑士
注册时间:
2006-08-17
在线时间:
146小时
发帖:
215
只看该作者 19楼 发表于: 2010-11-14
引用
最初由 Yuricon 发布

他们需要MYEPTools里的MoMoE

其实avs本身也提供了一个对比函数

Compare(clip_filtered clip, clip_original clip, string channels, string logfile, bool show_graph)

还有个
Subtract(clip1 clip, clip2 clip)

Subtract produces an output clip in which every pixel is set according to the difference between the corresponding pixels in clip1 and clip2. More specifically, it sets each pixel to (50% grey) + (clip1 pixel) - (clip2 pixel). You can use Levels afterwards if you want to increase the contrast.

嘛 EP无止境 话说破沟有EP交流群吗:D

Fansubbing is a waste of time.
级别: 新手上路
注册时间:
2010-11-13
在线时间:
0小时
发帖:
28
只看该作者 18楼 发表于: 2010-11-14
引用
最初由 linuxyouxia 发布
不EP不行啊 有些观众可是会EP到下多个Raw到逐帧对比的啊

以上说笑 勿当真

他们需要MYEPTools里的MoMoE
快速回复

限150 字节
上一个 下一个