Log in

View Full Version : How to connect VSPipe and x264 ?


coiledCoil
12th November 2015, 08:39
Yesterday, I did some tests with VapourSynth on linux and wanted to pipe the output to x264 for encoding using 2 pass.

According http://www.vapoursynth.com/doc/gettingstarted.html , I applied the command like this:

vspipe --y4m test.script.vpy - | x264 --level 3.1 --pass 1 --bitrate 1200 ...... --output /dev/null --demuxer y4m -

vspipe --y4m test.script.vpy - | x264 --level 3.1 --pass 2 --bitrate 1200 ...... --output encode.1200kb.mkv --demuxer y4m -

The test.script.vpy contains QTGMC() and CropRel().

But after that, I was wondering, because the input file contains only 1500 frames with 25fps, but the output is 32min long with 0.781 fps.

Is it not possible to connect vspipe and x264 in that way? What I'm doing wrong here?

Any help will be welcome.


Edit: Here (https://bbs.archlinux.org/viewtopic.php?id=190192) someone created an intermediate file first. Does this solve the problem or is it not needed?

mkfifo stream.y4m

# playing in mpv (e.g., for previewing the script's result)
vspipe ~/test.vpy stream.y4m --y4m & mpv stream.y4m

# encoding
vspipe ~/test.vpy stream.y4m --y4m & x264 --crf 20 --preset fast --output test.mkv stream.y4m

Q3CPMA
12th November 2015, 11:13
You probably forgot "--fps 25". Also, why aren't you using ffmpeg directly?

splinter98
12th November 2015, 11:45
Your command looks correct, looks like vapoursynth may not be outputting at the correct frame rate.

What does the output of the following command say?


vspipe --info test.script.vpy -

coiledCoil
12th November 2015, 13:47
Also, why aren't you using ffmpeg directly?

Sorry, I'm new to this. How can I do this directly?

Your command looks correct, looks like vapoursynth may not be outputting at the correct frame rate.

What does the output of the following command say?


vspipe --info test.script.vpy -

I will post the output, when I'm back home.

jackoneill
12th November 2015, 14:29
You probably forgot "--fps 25". Also, why aren't you using ffmpeg directly?

Using ffmpeg is no more direct than using x264. They both call libx264 to do the encoding work.

coiledCoil
12th November 2015, 19:10
The first post is done with a subset of the whole video file defined with SelectEvery(). I didn't mentioned this post, because I thought it's not important. But before I went to work, I started the same script without selecting a subset. Now I see the result and it worked fine. Here is the output for both scripts. The only difference is one line, SelectEvery(....).


What does the output of the following command say?


vspipe --info test.script.vpy -



Whole video file:
Width: 694
Height: 572
Frames: 40463
FPS: 25/1 (25.000 fps)
Format Name: YUV420P8
Color Family: YUV
Bits: 8
SubSampling W: 1
SubSampling H: 1

Subset defined with SelectEvery(clip = video, cycle = 8000, offsets = range(250)):
Width: 694
Height: 572
Frames: 1500
FPS: 25/32 (0.781 fps)
Format Name: YUV420P8
Color Family: YUV
Bits: 8
SubSampling W: 1
SubSampling H: 1

Why is the fps changing from 25/1 to 25/32? I want to encode the subset as a test encode to try different x264 parameters instead of encoding the whole movie each time.

Edit: OK, after reading the documentation for SelectEvery it's clear:
The clip’s frame rate is multiplied by the number of offsets and divided by cycle. The frame durations are multiplied by cycle and divided by the number of offsets.

It seems I used the wrong function for my purpose...

jackoneill
12th November 2015, 20:11
It seems I used the wrong function for my purpose...

Not necessarily. You can add AssumeFPS after SelectEvery.

coiledCoil
12th November 2015, 20:46
Not necessarily. You can add AssumeFPS after SelectEvery.

Nice, thanks!

If someone has the same problem. Here is the correct code:
video_subset = core.std.SelectEvery(clip = video, cycle = 8000, offsets = range(250))
video_subset = core.std.AssumeFPS(clip = video_subset, src = video)

The output of --info looks good now.

FPS: 25/1 (25.000 fps)

It's time for testing :)

AzraelNewtype
12th November 2015, 21:56
For the record, you could have just edited the display fps on your muxed output to get this result without reencoding, but assumefps will ensure that you never have to poke that in the future at least.

coiledCoil
13th November 2015, 09:03
For the record, you could have just edited the display fps on your muxed output to get this result without reencoding, but assumefps will ensure that you never have to poke that in the future at least.
I think the frame rate wasn't the only difference. Because the encode with the wrong fps was ~300mb in size, but the encode with the correct fps was only ~10mb. And the smaller size is much more reasonable for movie with 60 seconds with identical encoding settings.

Here is the mediainfo of the wrong encode:
General
Complete name : encode.1200kb.mkv
Format : Matroska
Format version : Version 2
File size : 275 MiB
Duration : 32mn 0s
Overall bit rate : 1 203 Kbps
Writing application : x264 r2389 956c8d8
Writing library : Haali Matroska Writer b0

Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L3.1
Format settings, CABAC : Yes
Format settings, ReFrames : 8 frames
Codec ID : V_MPEG4/ISO/AVC
Duration : 32mn 0s
Bit rate : 1 200 Kbps
Width : 694 pixels
Height : 572 pixels
Display aspect ratio : 4:3
Original display aspect ratio : 4:3
Frame rate : 0.781 fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 3.871
Stream size : 270 MiB (98%)
Writing library : x264 core 142 r2389 956c8d8
Encoding settings : cabac=1 / ref=8 / deblock=1:-3:-3 / analyse=0x3:0x133 / me=umh / subme=10 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=32 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=0 / chroma_qp_offset=-2 / threads=3 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=0 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=16 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=60 / rc=2pass / mbtree=1 / bitrate=1200 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / cplxblur=20.0 / qblur=0.5 / vbv_maxrate=17500 / vbv_bufsize=22400 / nal_hrd=none / filler=0 / ip_ratio=1.40 / aq=1:1.00
Language : English
Default : Yes
Forced : No

I don't have the mediainfo output of the correct one at the moment. But I can post it later, if you are interested.

splinter98
13th November 2015, 12:18
For the record, you could have just edited the display fps on your muxed output to get this result without reencoding, but assumefps will ensure that you never have to poke that in the future at least.

You can but then your bitrate won't be what you set it to be. (as bitrate is a function of frame rate if you change the framerate of the video after the encoding the effective bitrate will also change) So if you're targeting a specific bitrate with a specific frame rate you will have to reencode.

If you're not worried about actual bitrate/filesize then it's not an issue (and you're probably more likely to use crf encoding anyway).

AzraelNewtype
13th November 2015, 12:24
Oh right, I always do crf (because there's basically no reason not to) so I didn't even consider that.