(JEEB) そういや、うちのAvs2.6ビルドってChikuzen氏がテストした奴と性能がどんな感じ?
(Chikuzen) 若干スピードが上がってるみたいよ
(Chikuzen) ちょっとベンチマーク回してみるか
official 2.6.0α2 JEEB's 2.6.0(20110125) 1st 00:01:11.003(14.08fps) 00:01:07.254(14.87fps) 2nd 00:01:11.010(14.08fps) 00:01:07.003(14.92fps) 3rd 00:01:10.753(14.13fps) 00:01:07.003(14.92fps) (スクリプト等は前回と同じ)(JEEB) interesting
たしかに興味深い。
どうやら最適化はα2配布後にさらに進んでいたようである。
さて、前回、自分はマルチスレッドによる高速化ではなく、マルチプロセスによる高速化を選んだことを書いた。
ここで問題となるのが、同時にエンコードするための複数のソースがない場合である。
そもそも自分は放送ソースの保存用エンコなんてまったくしない。そんなことには興味がない。
いろいろなフィルタやエンコーダーを試して遊ぶのが好きなのである。
当然、エンコードするべきソースは大抵1本しかなく、3本同時にエンコードなんていままでに数えるほどしかやったことがない。
では、どうすればいいのか?
エンコード対象がひとつしかないのであれば、ひとつを複数に分割してやればいいだけだ。
3本同時にエンコードできる余裕があるなら、1本を3分割してそれぞれ中間出力し、ふたたびくっつけてやればよい。
それが簡単にできるのがAviSynthである。
中間出力用のファイルサイズを気にするような時代でもないしね。
てことで、自動で分割->中間出力->結合->エンコードを行うAvsPマクロを書いた。
#multiprocess intermediate file generator.py
#dividing source script into X -> generate intermediate files at same time -> final encode
#requiaments : VirtualDub.exe, vcf file, ffmpeg or x264 (optional)
import sys
import os.path
import subprocess
vdub = r'C:\VirtualDub-1.9.11\VirtualDub.exe'
vcf  = r'C:\VirtualDub-1.9.11\fastrecomp_uly0_noaudio.vcf'
entries = avsp.GetTextEntry(['Number of dividing', 'SetMemoryMax(?)'], ['3', '1024'])
dnum, mmax = [int(i) for i in entries]
imf_outdir = avsp.GetDirectory('Select a directory to output intermediate files.')
encbin  = avsp.GetFilename('Set Path to Encoder(ffmpeg or x264)')
#encbin = r'G:\Enctools\ffmpeg.exe'
#encbin = r'G:\Enctools\x264_x64.exe'
encout  = avsp.GetSaveFilename('Set final output file name')
encopts = avsp.GetTextEntry('Input commandline options').split(' ')
source = avsp.SaveScript()
frames = avsp.GetVideoFramecount()
if dnum > 1 and mmax > 0 and imf_outdir and frames and os.path.isfile(vdub) and os.path.isfile(vcf):
    start = 0
    vdubprocess = []
    catfilename = os.path.splitext(source)[0] + '_imf.avs'
    catfile = open(catfilename, 'w')
    for i in range(dnum):
        end = frames / dnum * (i + 1)
        if i < dnum - 1:
            trimline = 'trim(%i, %i)' % (start, end)
        else:
            trimline = 'trim(%i, 0)' % start
        lines = 'SetMemoryMax(%i)\nImport("%s")\n%s\n' % (mmax, source, trimline)
        start = end + 1
        imf_avsname = os.path.join(imf_outdir, os.path.basename(source)).rstrip('avs') + 'imf_%02i.avs' % i
        file = open(imf_avsname, 'w')
        file.write(lines)
        file.close()
        imf_aviname = os.path.splitext(imf_avsname)[0] + '.avi'
        vdubargs = [vdub, '/s', vcf, '/p', imf_avsname, imf_aviname, '/r', '/c', '/x']
        p = subprocess.Popen(vdubargs)
        vdubprocess.append(p)
        if i < dnum - 1:
            catfile.write('AVISource("%s") + \\\n' % imf_aviname)
        else:
            catfile.write('AVISource("%s")\n' % imf_aviname)
    catfile.close()
    if encbin and encout:
        for p in vdubprocess:
            p.wait()
        if os.path.basename(encbin).count('ffmpeg'):
            encargs = [encbin, '-i', catfilename] + encopts + ['-y', encout]
        elif os.path.basename(encbin).count('x264'):
            encargs = [encbin, catfilename, '-o', encout] + encopts
        else:
            sys.exit()
        subprocess.Popen(encargs)
