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 > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 20th January 2005, 21:16   #61  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
Quote:
Seems attachments are a bit of a pain, as mods don't always approve them quickly (or at all).
I didn't see it. Sorry
Wilbert is offline   Reply With Quote
Old 20th January 2005, 21:49   #62  |  Link
Valky
Registered User
 
Valky's Avatar
 
Join Date: Feb 2002
Location: Finland
Posts: 275
So what does this has to if I use avisource in my script? Should I still delete mpeg2dec.dll from plugins-folder or is it built-in avisynth nowadays?
Valky is offline   Reply With Quote
Old 20th January 2005, 22:06   #63  |  Link
Manao
Registered User
 
Join Date: Jan 2002
Location: France
Posts: 2,856
Re-read my answer : change in the script all the occurence of motionmask by masktools_motionmask

@all : you should be able to use this version of MVTools : http://manao4.free.fr/MVTools-v0.9.9.1.zip
Manao is offline   Reply With Quote
Old 21st January 2005, 04:22   #64  |  Link
dvwannab
Registered User
 
Join Date: Feb 2002
Posts: 76
sloooowwwwww!!!!!!

oh my this baby is sloooowwwwww. Anyone else experiencing the same. I used a simple script:

Import("c:\program files\avisynth 2.5 filters\mvbob.avs")

LoadPlugin("c:\program files\avisynth 2.5 filters\dgdecode.dll")
LoadPlugin("c:\program files\avisynth 2.5 filters\LeakKernelDeint.dll")
LoadPlugin("C:\Program Files\AVISynth 2.5 Filters\undot.dll")
LoadPlugin("C:\Program Files\AVISynth 2.5 Filters\tomsmocomp.dll")
LoadPlugin("C:\Program Files\AVISynth 2.5 Filters\mvtools.dll")
LoadPlugin("C:\Program Files\AVISynth 2.5 Filters\masktools.dll")

mpeg2source("c:\france.d2v")

mvbob()

Dropped the script in VDmod and encoded 10 minute clip with 1-pass DivX 5.1.2. After 5.5 hours it was at 20% complete
I used the code in balazer's last post (looks the same as scarfis_brain) and MVTools 0.9.8.5.
dvwannab is offline   Reply With Quote
Old 21st January 2005, 10:18   #65  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
@Valky,

To clarify Manao's remarks, have a look at the bottom of:

http://www.avisynth.org/AviSynthPlugins
Wilbert is offline   Reply With Quote
Old 21st January 2005, 18:33   #66  |  Link
joshbm
Registered User
 
joshbm's Avatar
 
Join Date: Jun 2003
Location: Land of the Noobs & the Home of the Brave
Posts: 349
I agree it's kind of slow, but it works great .

Keep us updated on the new mvbob() .

Regards,
-joshbm
__________________
Tired of waiting for video encodes? Get a totally new P4 Desktop Computer for FREE.
joshbm is offline   Reply With Quote
Old 21st January 2005, 19:11   #67  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
I am currently modifying mvbob() to work with the newest mvtools and its inculded corrector.

I've got it working at 3 to 4 fps on a 640x480@29.97fps NTSC video.
My machine is an athlonXP@1.5 GHz

maybe I can optimize that script further.
maybe it will loose speed again due to new features

if your mvbob() is painfully slow, just comment out the extended motion search parameters:

Code:
mvf=bobd.mvanalyse(blksize=blksize,pel=pel,isb=false,chroma=true)#,search=3,searchparam=10)
mvb=bobd.mvanalyse(blksize=blksize,pel=pel,isb=true, chroma=true)#,search=3,searchparam=10)
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 21st January 2005, 19:50   #68  |  Link
dvwannab
Registered User
 
Join Date: Feb 2002
Posts: 76
Quote:
Originally posted by scharfis_brain
I am currently modifying mvbob() to work with the newest mvtools and its inculded corrector.

I've got it working at 3 to 4 fps on a 640x480@29.97fps NTSC video.
My machine is an athlonXP@1.5 GHz

maybe I can optimize that script further.
maybe it will loose speed again due to new features

if your mvbob() is painfully slow, just comment out the extended motion search parameters:

Code:
mvf=bobd.mvanalyse(blksize=blksize,pel=pel,isb=false,chroma=true)#,search=3,searchparam=10)
mvb=bobd.mvanalyse(blksize=blksize,pel=pel,isb=true, chroma=true)#,search=3,searchparam=10)
OH NO WAY, dude!!! I just watched my marathon encode and WOOOWWWWW!!! Definitely blows away 100fps.com method and all others I have come across. Keep up the good work...... with maybe just a tad bit more speed Just kidding
dvwannab is offline   Reply With Quote
Old 3rd February 2005, 17:59   #69  |  Link
joshbm
Registered User
 
joshbm's Avatar
 
Join Date: Jun 2003
Location: Land of the Noobs & the Home of the Brave
Posts: 349
How is your new MVBob() coming along? lol... I am eager to see an update .

Regards,
joshbm
__________________
Tired of waiting for video encodes? Get a totally new P4 Desktop Computer for FREE.
joshbm is offline   Reply With Quote
Old 3rd February 2005, 19:20   #70  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
@all: I've completed the first step.
the rewrite of mvbob() is finished.
the speed is gained. at least by factor two.

@manao: I wasn't able to get your corrector() working properly.

but please take a look yourself:

Code:
setmemorymax(256)


#Helper functions:

	#stupid tmc-bobbing for better edge definition
	function tmcstupid(clip c)
	{	input=c.converttoyuy2(interlaced=true).separatefields.tomsmocomp(1,-1,0)
		a = getparity(input) ? input.selectodd : input.selecteven
		b = getparity(input) ? input.selecteven : input.selectodd
		a=stackvertical(a.crop(0,0,0,1-a.height),a.crop(0,0,0,-1))
		output = getparity(input) ? interleave(b,a) : interleave(a,b)
		output.assumeframebased().converttoyv12()
		getparity(input) ? assumetff() : assumebff()
	}



	#colorize a clip for identification in the output
	function col(clip i, int j) 
	  	{v=128
		(j==0) ? i.coloryuv(gain_u=v) : \	
		(j==1) ? i.coloryuv(gain_u=0-v) : \	
		(j==2) ? i.coloryuv(gain_v=v) : \	
		(j==3) ? i.coloryuv(gain_v=0-v) : \	
		 	 i	
		#blue 		0
		#yellow 	1
		#red 		2
		#green 		3
		#passthrough else
		}



function MVbob(clip c,int "blksize", int "pel", int "lambda", int "thy", int "thc", int "bobth", bool "predenoise", bool "showmask")
{

#disable all scene detection of mvcompensate(), because mvbob() is self-correcting due to the corrector()
	sc=255 

	showmask=default(showmask,false)

# luma and chroma thresholds for correcting false detected motion 
	thy=default(thy,20) 
	thc=default(thc,10)

# threshold of kerneldeint
	bobth=default(bobth,8)

#denoise the video for kerneldeint (better static areas for noisy video)
	predenoise=default(predenoise,false)

	blksize=default(blksize,4)
	scd=(blksize==8)? 300 : round(300/4)
	pel=default(pel,2)

#I decided lambda=0 being better, cause it stupidly trys to catch everything. errors are corrected afterwards.
	lambda=default(lambda,0)

#determine clip Fieldorder
	order=(c.getparity==true)? 1:0

# bobx 	-> deinterlaced video, used for motion search and hole filling

# mvf   -> motion vectors forward
# mvb   -> motion vectors backward

# bobd 	-> blurred bobx for error checking (correcting false compensated blocks!)
# bobdf -> forward compensated bobd
# bobdb -> backwards compensated bobd
# bobdm -> average of bobdb and bobdf

# fields-> ELA-upsized fields for motion compensated output
# mcf   -> forward compensated fields
# mcb   -> backward compensated fields
# cv    -> average of mcb and mcf

# dpf   -> forward compensated fields (global motion)
# dpb   -> backward compensated fields (global motion)
# dp    -> average of dpb and dpf

# mc    -> corrected motion compensated result

# create clip for motion analysis and hole-filling
	bobx=predenoise ? c.temporalsoften(2,5,7) : c
	#bobx=bobx.leakkernelbob(order=order,threshold=bobth)
	bobx=bobx.tdeint(mode=1,mthreshl=bobth,mthreshc=bobth,type=3,Link=0).assumetff()
	bobd=bobx.undot().verticalreduceby2()
	bobd=bobd.lanczos4resize(bobx.width,bobx.height) 
	#bobd=bobd.tomsmocomp(-1,-1,0).undot()

# create clip for motion compensation
	fields=c.tmcstupid().undot()

# create motion vectors
	mvf=bobd.mvanalyse(blksize=blksize,pel=pel,isb=false,chroma=true)#,search=3,searchparam=10)
	mvb=bobd.mvanalyse(blksize=blksize,pel=pel,isb=true, chroma=true)#,search=3,searchparam=10)

# detect mismatched areas of motion compensation
	bobdf=bobd.mvcompensate(mvf,mode=1,thscd1=scd,thSCD2=sc)
	bobdb=bobd.mvcompensate(mvb,mode=1,thscd1=scd,thSCD2=sc)
	bobdm=bobdf.mergeluma(bobdb,0.5).mergechroma(bobdb,0.5)

	bobdpf=fields.MVDepan(mvf, zoom=true, rot=true, pixaspect=1.0 ) #, float error, bool info) 
	bobdpb=fields.MVDepan(mvb, zoom=true, rot=true, pixaspect=1.0 ) #, float error, bool info) 
	bobdpm=bobdpf.mergeluma(bobdpb,0.5).mergechroma(bobdpb,0.5)

# do the deinterlacing
	original_even=c.separatefields().selecteven()
	original_odd =c.separatefields().selectodd()

	mcf=fields.mvcompensate(mvf,mode=1,thscd1=scd,thSCD2=sc).deblock()
	mcb=fields.mvcompensate(mvb,mode=1,thscd1=scd,thSCD2=sc).deblock()
	dpf=fields.MVDepan(vectors=mvf, zoom=false, rot=false, pixaspect=1.0,thscd1=scd,thSCD2=sc,info=true,error=255 ) #, float error, bool info) 
	dpb=fields.MVDepan(vectors=mvb, zoom=true, rot=true, pixaspect=1.0,thscd1=scd,thSCD2=sc, info=true,error=255 ) #, float error, bool info) 

	dp=dpf.mergechroma(dpb,0.5).mergeluma(dpb,0.5)
	cv=mcf.mergechroma(mcb,0.5).mergeluma(mcb,0.5)

#	--------------------------------------
#	here, I want to insert the correction
#	but corrector seems to deliver bobd, bobdf and/or bodb to the output,
#	while only bobx, mcf and mcb should be delivered!
#	col(x) is just a chroma adjuster to visualize the outputted clips
#	so manao, can you confirm this misbehaviour of corrector? or am I using it in the wrong way?

	mc=corrector(bobd,bobx.col(1),bobdf,mcf.col(2),bobdb,mcb.col(3),mode=0,th=11)
	

#
#	-----------------------------------
#
	compensated_even=(order==0) ? mc.selecteven().separatefields().selecteven() : mc.selecteven().separatefields().selectodd()
	compensated_odd =(order==0) ? mc.selectodd().separatefields().selectodd()   : mc.selectodd().separatefields().selecteven()

	even=interleave(original_even, compensated_even).weave()
	odd =interleave(original_odd , compensated_odd ).weave()

# output
	interleave(even,odd)
	stackhorizontal(last,bobx)
#stackhorizontal(bobdf,bobd,bobdb).bicubicresize(1264,480)
stackhorizontal(mc,bobx)

}


# use older mvtools to do framerate conversions.
function mvfps(clip i, float fps)
{       fwd=mvtools0962_mvanalyse(i,isb=false,lambda=1000)
	bwd=mvtools0962_mvanalyse(i,isb=true, lambda=1000)
	i.mvtools0962_mvconvertfps(bwd,fwd,fps=fps*10)
	temporalsoften(1,255,255)
	selectevery(10,0)
}

loadplugin("d:\x\tdeint.dll")
loadplugin("d:\x\masktools.dll")
loadplugin("d:\x\MVTools0962.dll")
loadplugin("d:\x\MVtools0991.dll")
LoadPlugin("d:\x\dgdecode.dll")
LoadPlugin("d:\x\undot.dll")
loadplugin("d:\x\tomsmocomp.dll")
loadplugin("d:\x\leakkerneldeint.dll") 

loadplugin("d:\x\loadpluginex.dll")
loadplugin("d:\x\warpsharp.dll")


avisource("doom9.avi")

assumetff()

converttoyv12(interlaced=true)

mvbob(predenoise=false,bobth=9,thy=255,thc=255,showmask=false,lambda=400,blksize=8)

if I do just

mc=cv

instead of

mc=corrector(blah blah)

the output is very fine. expept of the mv-mismatches.

but when I am using corrector somehow the analysis clips are passed to the output.

I really appreciate if you could have a look into it.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 3rd February 2005, 19:59   #71  |  Link
Manao
Registered User
 
Join Date: Jan 2002
Location: France
Posts: 2,856
That's what i thought, you interleaved analysis and output clips. Clips have to be given in that order :

analysis_0, output_0, analysis_1, analysis_2, ... analysis_n, output_1, output_2, ... output_n.

I chose that order because analysis_0 and output_0 work differently from the other. But i recon, reading again the documentation, that how clips should be given was slightly ambiguous.
Manao is offline   Reply With Quote
Old 3rd February 2005, 20:29   #72  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
wow!

now it works!

you should really update the documentation regaring this issue. it was very confusing....


hm.. but I think mvbob it still needs a lot of work.

I'll implement a function that really really makes static logos/texts/objects static.
(they are un-corrected by the corrector, but that is by nature)
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 6th February 2005, 03:25   #73  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
I've managed to implement nearly everything I wanted to into mvbob.

download a package here:
http://home.arcor.de/scharfis_brain/mvbob/mvbob.rar

it contains all needed plugins, which are automatically loaded when importing the mvbob.avs into your personal script.
do NOT remove the plugin-dlls from the folder that contains mvbob.avs

mvbob.avs contains three functions:

mvbob(clip c, int "blksize", int "pel", int "lambda", int "th", int "ths", int "bobth", bool "predenoise")

blksize(4,8,16) -> defines the final size of the motion-blocks.
the smaller, the slower and the more accurrate the motioncompensation, but more instable, too.
so use 16 if your video is not stable enough
default = 8

pel (1,2) -> subpixel accuracy of mvtools.
default(2)

lamda(0...?)
see mvtools-documentation
default(1000)

bobth(0...255)
deinterlacing threshold for the internal motion adaptive deinterlacers (leakkernelbob/tdeint)
do not go much over 10
default(8)

th(0...255)
the threshold for correcting false compensated motion
0 -> there will be no motioncompensation in your output (everything gets 'corrected')
255-> no correction
default(8)

ths(0...255)
threshold of static area correction (bobbing prevention)
0-> no correction
255-> full 'correction' motion compensation misses will show up again
(works against th! so be careful)
default(4)

predenoise(true/false) (experimental)
is a stupid temporalsoften with fixed parameters to help the deinterlacer
show no be used, cause it fools motion estimation.
default(false)

mvfps(clip i, float fps, int "blur")

motion compensated framerate changer

fps -> target framerate

int blur-> factor of internal oversampling
blur=10 will internally sample 10 times the framerate and will blend
3 of those 10 frames together to hide motion artifacts
default(1) (no blurring)


reYV12(clip i)

reverts PAL-DV to its nature: YV12
without quality loss
speeds up things significantly in the processing chain!

report any problems and quality issues immediately, please.


EDIT:

this tool is able to do a fully motion compensated standards conversion for you!

example:

NTSC-DV to PAL:

Code:
avisource("ntsc-file.avi")
reinterpolate411() #if you wish to....
mvbob()
lanczos4resize(width,576)
converttoyv12()
mvfps(50)
converttoyuy2()
assumebff().separatefields().selectevery(4,0,3).weave()
PAL-DV to NTSC:

Code:
avisource("pal-file.avi")
reYV12() #if you wish to....
mvbob()
mvfps(59.94)
converttoyuy2()
lanczos4resize(width,480)
assumebff().separatefields().selectevery(4,0,3).weave()
hey! that's it!
easy, isn't it?

in future, if manao has hopefully reimplemented the motion interpoaltors to the newer versions of mvtools, the framerate conversion will be much faster, cause I can reuse the motion vectors of mvbob().
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.

Last edited by scharfis_brain; 6th February 2005 at 03:40.
scharfis_brain is offline   Reply With Quote
Old 6th February 2005, 11:24   #74  |  Link
kempfand
Registered User
 
kempfand's Avatar
 
Join Date: Oct 2001
Location: Switzerland
Posts: 225
@ scharfis: Many thanks for sharing your latest creation.

Q: Is it possible to write a variant of reYV12() which takes RGB24-input ?

I use the Canopus-DV codec through my entire chain, and usually open the DV-avi with
Quote:
AVISource("DV.avi", pixel_type="RGB24", fourCC="CDVC")
which means I have to use ConvertToYUY2() followed by reYV12().

AVISource-opening the DV with pixel_type="YUY2" kindof squeezes the colours.

Kind regards,
Andreas
kempfand is offline   Reply With Quote
Old 6th February 2005, 12:36   #75  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
which means I have to use ConvertToYUY2() followed by reYV12().

which is the correct way to use it.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 7th February 2005, 08:38   #76  |  Link
Valky
Registered User
 
Valky's Avatar
 
Join Date: Feb 2002
Location: Finland
Posts: 275
Well, I finally got this work and saw some results with it. Thanks scarfis for getting al the needed tools in a some packet.

It's awfully slow on my 1800+ machine. 1-2 frames per second.
How do you use it as just a simple deinterlacer for normal dv-pal video and is the final output always 50fps video?
Valky is offline   Reply With Quote
Old 7th February 2005, 20:49   #77  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
How do you use it as just a simple deinterlacer for normal dv-pal video and is the final output always 50fps video?

the output of mvbob() is always fullrate. (50fps / 59.94fps)


use

mvbob()
selecteven()


for halved framerate output.

it won't be much faster if I would have done a special half framerate mode into mvbob(), cause all the parameters have to be calculated. No matter whether you want full or half framerate.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 8th February 2005, 17:21   #78  |  Link
2Bdecided
Registered User
 
Join Date: Dec 2002
Location: UK
Posts: 1,673
I can't even manage to get the speeds you're reporting!

I'm using AVS2AVI -c null to go from one uncompressed AVI file to another, and I'm getting about 0.02FPS(!!!!) converting PAL to NTSC. That's 21 hours to convert 40 seconds! This is on a P4 2.8GHz.

I'm using...

Code:
import("C:\Program Files\AviSynth 2.5\plugins\mvbob.avs")
avisource("all no grey.avi")
#reYV12() #if you wish to....
assumetff()
convertToYV12
mvbob()
mvfps(59.94)
converttoyuy2()
lanczos4resize(width,480)
assumebff().separatefields().selectevery(4,0,3).weave()
There are a couple of reasons why this code might not work or might not be optimal - I'm not sure if assumetff() is the right way to pass TFF material to mvbob()*, I know convertToYV12 without interlace-true is wrong, and the source material has already gone from YUV2 to RGB24 before it even gets into the script.**

However, all this asside(!!!), why is it _so_ slow?

Cheers,
David.

* - but I'll find out when I actually get to watch the result in 21 hours!!!

** - anyone know a way to pass raw YUV files like these (good test sequences there btw) straight into AVISynth?
2Bdecided is offline   Reply With Quote
Old 8th February 2005, 17:53   #79  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
UHM? 0.02fps?

this means that you are getting ONE new frame every 50 seconds ????

This cannot be the case.

I get about 0.5 to 1.5fps using this script with my AthlonXP1600+ @ 1.5 GHz (768MB DDR-266 RAM)

a plain converttoyv12 is definately WRONG!
either use converttoyv12(interlaced-true) (use this with TV-Cards captures)
or reYV12() (for PAL=DV stuff, this is the best choice!)

assumetff() and assumebff()
are used to set up the correct fieldorder.

PAL-DV is always BFF, while TV-Cards captures are more common to be TFF.

ensure that both assume?ff() calls are setting the SAME fieldorder.

is the fieldorder was set incorrectly, the output will show heavy motion jitter.

To open YUV-files directly in AVISynth, you will need the plugin rawsource.dll
get it (and other plugins, too!) here:
http://www.avisynth.org/warpenterprises/
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 8th February 2005, 18:09   #80  |  Link
2Bdecided
Registered User
 
Join Date: Dec 2002
Location: UK
Posts: 1,673
Thanks for the reply scharfis_brain.

Quote:
Originally posted by scharfis_brain
UHM? 0.02fps?

this means that you are getting ONE new frame every 50 seconds ????

This cannot be the case.
Yes, it really is! It's been running since I last posted, and we're up to 55 frames now, ETA of about 13 hours. I've only been browsing the net. It's obvious there's something wrong, but I don't know what. It's probably a general AVIsynth problem on my system (it's just as slow in VDub), so maybe I should address it in another thread.

Quote:
a plain converttoyv12 is definately WRONG!
either use converttoyv12(interlaced-true) (use this with TV-Cards captures)
or reYV12() (for PAL=DV stuff, this is the best choice!)
This isn't PAL DV, so I was going to use convertoyv12(interlaced=true). I litterally just threw this script together to see if assumetff() would work, and then was amazed at how slow it was!

Quote:
ensure that both assume?ff() calls are setting the SAME fieldorder.
I'll check. I'd swear on previous conversions I had opposite for PAL and NTSC (not DV) to avoid judder.

EDIT: I Ctrl-C'd it. The field order seems fine - TFF on the way in, BFF on the way out with no judder (checked field-by-field in TMPGEnc deinterlace filter, even-odd). So far, the quality looks great!

Quote:
To open YUV-files directly in AVISynth, you will need the plugin rawsource.dll
get it (and other plugins, too!) here:
http://www.avisynth.org/warpenterprises/ [/B]
I'd been there, but not realised what that one would do - I'll try it tomorrow.

Thanks for your help.

Cheers,
David.

Last edited by 2Bdecided; 8th February 2005 at 18:14.
2Bdecided is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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 02:23.


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