Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth
Register FAQ Calendar Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old 28th March 2020, 15:26   #1  |  Link
josemaria.alkala
Registered User
 
Join Date: Apr 2010
Posts: 16
Presenting VapourSynth.nim

I have wrapped VapourSynth in Nim programming language. Nim is to C like CoffeScript is to JavaScript.

The main advantages I see are:

1. Writting a pipeline is very easy. It feels even easier than python. For instance, reading the first 100 frames, transposing and piping to stdout:
Code:
import vapoursynth
Source("video.mkv")[0..100].Transpose.Pipey4m
2. The code is compiled, so you end up with a binary file.
3. It should be as fast as C. (But I haven't performed any serious benchmark yet)
4. You can even perform filters like in C. mycrop.nim is an implementation similar (not complete) to vapoursynth's simplefilter.c version.
5. Nim has metaprogramming superpowers. I have created a macro to make easier the development of filters. This way, the creation of a filter becomes:
Code:
import ../vapoursynth
import mymacro
import options
import strformat

newFilter("MyCropRel"):
  parameters:  
    inClip   clip           # Input video (mandatory)
    optional:
      left   Natural  
      right  Natural  
      top    Natural  
      bottom Natural  

  validation:
    # We assign the destination's frame size
    data.width  = data.vi.width.Natural - data.left - data.right
    data.height = data.vi.height.Natural - data.top - data.bottom

    # Avoid too much cropping
    assert( (data.top + data.bottom) < data.vi.height, "vertical cropping too big" )  
    assert( (data.left + data.right) < data.vi.width, "horizontal cropping too big" )

    # make sure the given values will work with subSampling
    assert( (data.left mod divHorizontal) == 0,  &"subSampling: \"left\"={data.left} not divisible by {divHorizontal}" )
    assert( (data.top mod divVertical) == 0,     &"subSampling: \"top\"={data.top} not divisible by {divVertical}"  )
    assert( (data.width mod divHorizontal) == 0, &"subSampling: new \"width\"={data.width} not divisible by {divHorizontal}" )
    assert( (data.height mod divVertical) == 0,  &"subSampling: new \"height\"={data.height} not divisible by {divVertical}")

    if (data.left == 0 and data.right == 0 and data.top == 0 and data.bottom == 0):
      passTrough()

  processing:
    let dst = src.newVideoFrame(data.width, data.height)
    #echo "Frame: ", n
    for i in 0..<srcNumPlanes:
      var srcPlane = src.getPlane(i)
      var dstPlane = dst.getPlane(i)     
      srcPlane.goto(row=data.top, col=data.left) 

      if data.height > 0:      
        srcPlane.copy(dstPlane, rows=data.height, cols=data.width)
As you can see it has three areas:
- parameters: The function parameters, where left, right, top, bottom has Natural type (>=0)
- validation: contains all the checks needed for the inputs
- processing: which is pretty human friendly code. Creates a new frame, iterates over the planes, goes to a position in the plane and copiesss a number of rows up to certain column. It does so bearing in mind the subsampling.

This is about 40 lines for a working filter. You can find it here.

In order to use this filter you would do:
Code:
import ../vapoursynth
import options
import croprel

# Reads the file, applies the Simple filter and saves the result in a file
Source("../../test/2sec.mkv").MyCropRel(top=some(150.Natural),bottom=some(150.Natural)).Savey4m("original.y4m")
How much time does it take to compile above's code? Less than two seconds
Code:
$ time nim c modifyframe
real	0m1,284s
user	0m1,361s
sys	0m0,136s
How much time does it take to perform the cropping to the two seconds video?
Code:
$ time ./modifyframe
real	0m0,176s
user	0m0,141s
sys	0m0,038s
How much time does it take the original filter in pure C?
Code:
$ time ./modifyframe2
real	0m0,186s
user	0m0,148s
sys	0m0,037s
So pretty similar.

I hope you find it useful. There is lot of work to do ahead nonetheless. I am not a pro-developer, so my code is pretty ugly. Bear in mind that this has been my toy project to learn Nim.
josemaria.alkala is offline   Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:23.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.