2012年9月12日水曜日

VapourSynth

巷で話題沸騰中?のVapourSynthを、ここ数日ちょこちょこいじっております。

VapourSynthとはffms2でお馴染みのMyrsloikことFredric Mellbin氏によって開発されているもので、
・動画を扱うためのPython3用モジュール。
・AviSynth2.5のプラグインをマルチスレッドで利用できる。
といった特徴があります。

早い話がAviSynthの開発が過去との互換性やらinline-asmやらでMT化も64bit化も一向に進まないので、新しいAviSynthを作ってしまったわけですな。

とりあえず現時点ではまだまだ試作段階ですが、MVTools2やTIVTC(mode次第では)がマルチスレッドで安定して動くあたりを見るに、かなり期待できそうです。

というわけで、試しにこんなのを書いてみました。

#!/bin/env python3
#coding: utf-8

import vapoursynth as vs
import subprocess as sp

class RawSource(object):
    def __init__(self, core, path='C:\\AviSynth2\\plugins\\rawsource_2.5x.dll'):
        self.avs = core.avs
        if core.list_functions().find('RawSource') == -1:
            self.avs.LoadPlugin(path=path)

    def rawsource(self, file):
        return self.avs.RawSource(file=file)


class MVTools(object):
    def __init__(self, core, path='C:\\AviSynth2\\plugins\\mvtools2.dll'):
        self.avs = core.avs
        if core.list_functions().find('MSuper') == -1:
            self.avs.LoadPlugin(path=path)

    def superclip(self, clip, pel=2, chroma=True, sharp=2):
        return self.avs.MSuper(c1=clip, chroma=chroma, sharp=sharp)

    def analyseclip(self, super, delta, blksize=8, overlap=4):
        return [[self.avs.MAnalyse(
            c1=super, delta=d, blksize=blksize, isb=b, overlap=overlap)
            for b in (True, False)]
            for d in range(1, delta + 1)]

    def mdegrain1(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
                  overlap=4, thSAD=400):
        super = self.superclip(clip, pel, chroma, sharp)
        vec = self.analyseclip(super, 1, blksize, overlap)
        return self.avs.MDegrain1(
            c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], thSAD=thSAD)

    def mdegrain2(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
                  overlap=4, thSAD=400):
        super = self.superclip(clip, pel, chroma, sharp)
        vec = self.analyseclip(super, 2, blksize, overlap)
        return self.avs.MDegrain2(
            c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], c5=vec[1][0],
            c6=vec[1][1], thSAD=thSAD)

    def mdegrain3(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
                  overlap=4, thSAD=400):
        super = self.superclip(clip, pel, chroma, sharp)
        vec = self.analyseclip(super, 3, blksize, overlap)
        return self.avs.MDegrain3(
            c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], c5=vec[1][0],
            c6=vec[1][1], c7=vec[2][0], c8=vec[2][1], thSAD=thSAD)

    def mflowblur(self, clip, pel=2, chroma=True, sharp=2, blksize = 8,
                   overlap=4, blur=15):
        super = self.superclip(clip, pel, chroma, sharp)
        vec = self.analyseclip(super, 1, blksize, overlap)
        return self.avs.MFlowBlur(
            c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], blur=blur)


if __name__ == '__main__':
    core = vs.Core(threads=4)
    rs = RawSource(core)
    mvt = MVTools(core)
    clip = mvt.mdegrain2(rs.rawsource("D:\\source\\derf\soccer.y4m"))
    cmd = ('D:\\tools\\x264.exe - --demuxer y4m --frames %i'
           ' --preset ultrafast -o output.mp4' % clip.num_frames)
    clip.output(sp.Popen(cmd.split(), stdin=sp.PIPE).stdin, y4m=True)

for文やif文、リスト内包表記、そして様々な他のPythonモジュール等が使えるあたり、可能性はAviSynthよりも高そうです。
それにPythonですから、avsと違って仕事や学業等にも汎用的に使えます。
憶えて損はないでしょうね。

0 件のコメント:

コメントを投稿