VMware Workstation 7 Released

VMware just released version 7 of their well known Workstation application. Here’s an interesting new feature many have been waiting for:

Aero Glass — A new Windows Display Driver Model (WDDM) graphics driver has been developed for Windows Vista and Windows 7 virtual machines. The WDDM driver can display the Windows Aero user interface, OpenGL 1.4, and Shader Model 3.0. For more information on the VMware recommended graphics hardware, see the VMware Workstation User’s Manual.

Full release notes can be found here.
Downloads are here.

Windows 7 x64 - VMware Workstation

Statically Linked Qt On Win32 Using MSVC

I have been trying to compile a statically linked version of Qt on Windows using MSVC for some time now but never found my way through until recently. There is a lot of information on the web about how to do this however I haven’t found one that actually worked for me (some information can be found on Trolltech’s website). So here’s yet another howto for using a static version of Qt with Visual Studio 2008!

What you need:

What you do (assuming VS2008 is already installed):

  1. Unpack the Qt sources. I used C:\Qt\4.5.3-win32-msvc2008 as target (%QTDIR%)
  2. If you have a multicore CPU you might want to speedup things by modifying %QTDIR%\mkspecs\win32-msvc2008\qmake.conf and adding those two lines (change 2 for the no. of CPUs you have):
    QMAKE_CXXFLAGS_RELEASE += -MP2
    QMAKE_CXXFLAGS_DEBUG += -MP2
  3. Next, open a Visual Studio 2008 Command Prompt (under the Start menu), go to %QTDIR% and run configure.exe with at least -static as option. I used the following (minimal build):
  4. configure.exe -debug-and-release -opensource -static -no-exceptions -no-accessibility -no-stl -no-qt3support -no-opengl -platform win32-msvc2008 -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libtiff -qt-libjpeg -no-openssl -no-dbus -no-phonon -no-webkit -no-scripttools

  5. Once configured, start the build:
    nmake sub-src
  6. Install the Qt Visual Studio Addin
  7. In Visual Studio, under the Qt menu choose Qt Options. Under the Qt Versions tab click Add and type 4.5.3_win32-msvc2008 (or whatever you want) and fill in the path where you extracted the Qt sources
  8. Optionally you can test your installation by creating a new Qt Project, compiling it and running it.

Easy enough?! Happy Qt’ing!

UPDATE 15/10/2009: This also works with MS Visual Studio C++ Express Edition!

Organizing Your Files

I don’t know about you but I have files spread over multiple PCs since I use multiple PCs. Sometimes you simply don’t have time to transfer them over and find yourself missing a file and looking all over the place to find it.

Welcome Dropbox!  A very neat simple software that allows to automatically sync your files between multiple PCs. It also provides a website repository so you can share files with other people. I’ve been using it for some time now and find it very useful!

Check it out.

If you wish to join and don’t mind giving me credits for the referral, send me your email address and I’ll send you an invite. Referrals can help you gain more disk space online.

HD-PVR Post-production

As already posted, last year I bought the Hauppauge HD-PVR. Since I’m a geek (am I?!) and I like doing things my way, using all the software provided with the device wasn’t an option I was going to choose. Also, since I always want maximum picture quality I always set the HD-PVR to record at full bitrate (13.5Mpbs CBR).

As you can imagine recording at 13.5Mpbs will produce some quite big files, but thats all good as I have plenty of disk space to waste (temporarily). For example, a 1 1/2 hour recording will take approx. 9.7GB. That’s big, even with lots of disk space to waste. So, I convert the recording to at least an MKV (AVC/AAC) as an archive/computer playable version and sometimes a DVD (to watch on the TV set, which only has a DVD player, for now).

Now since I’m a command line freak (did I say I was a geek?!), here’s how I do it. In order to do the same you will need at least the following software (all free):

1. The first step is is to load the .TS (or M2TS) file in DGAVCIndex:

DGAVCDec

And save the whole stream into a DGA project (File -> Save Project or F4). This will also demux the audio and create a [filename] PID 1100 DELAY [delay]ms.aac file.

2. Then I create an Avisynth script to load the DGA project in VirtualDub to make a stream selection (strip the beginning/end and commercials). The script looks like this:

LoadPlugin("DGAVCDecode.dll")
V=AVCSource("Project.dga")
A=DirectShowSource("Project PID 1100 DELAY -180ms.aac", video=false, seek=false)
AudioDub(V, A)
DelayAudio(-0.180)

[UPDATE 1/3/2010: You may want to use seekzero=true instead of seek=false as some seeking may be required depending on the context.]

Make sure to match the DelayAudio() with the delay from the AAC file then load the AVS into VirtualDub. This part can be time consuming as this is where I seek through the whole stream to find commercials and other parts I want to strip. For every part to strip I write down the first frame and last frame numbers to insert into the AVS. Once this is done you simply trim all the frames you want to keep like this:

Trim(29, 13187)+Trim(19031, 57183)+Trim(60138, 62091)

This strips the following frame ranges: 0-28, 13188-19030, 57184-60137 and 62092 to the end. Basically, Trim tells Avisynth to keep the specified frame range.

3. Now is the time to start encoding. First you will need to calculate your bitrate to make sure the newly encoded stream will fit your target media. Open the Bitrate Calculator and input your stream length and audio bitrate (I use 128Kpbs) and select your target media. Keep in mind the target bitrate is an average bitrate therefore you may want to bring it down by 1-2% to make sure you won’t have to re-encode the stream a second time.

For encoding the video, I use the following 2-pass encode:

x264.exe --profile high --pass 1 --bitrate 16000 --threads auto --thread-input --output Project.ts.avs.264 Project.ts.avs
x264.exe --profile high --pass 2 --bitrate 16000 --threads auto --thread-input --output Project.ts.avs.264 Project.ts.avs

For the audio, I use the following 1-pass encode:

wavi Project.ts.avs - | faac.exe -b 128 -o Project.ts.avs.aac -

Then I end up with 2 files, Project.ts.avs.264 and Project.ts.avs.aac which I multiplex in MKVToolnix to produce an MKV file. Make sure to select your video framerate in mmg.exe as .264 files do not store that information (you should get a warning after adding the .264 into mmg). Optionally, you can also select the language for both streams. That’s it for the high quality archive copy!

4. To create a DVD compliant structure, I use mencoder (lavcodec) for encoding both the video and audio. Here’s the command line I use for a high quality encode:

mencoder.exe -mc 0 -noskip -ovc lavc -nosound -lavcopts threads=2:vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=9668:keyint=15:vpass=1:trell:mbd=2:precmp=2:subcmp=2:cmp=2:dia=-10:predia=-10:cbp:mv0:vqmin=1:lmin=1:dc=10:vstrict=0:aspect=16/9 Project.ts.avs -o Project.ts.avs.mpg -ofps 30000/1001 -of mpeg -mpegopts format=dvd:tsaf
mencoder.exe -mc 0 -noskip -ovc lavc -nosound -lavcopts threads=2:vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=9668:keyint=15:vpass=3:trell:mbd=2:precmp=2:subcmp=2:cmp=2:dia=-10:predia=-10:cbp:mv0:vqmin=1:lmin=1:dc=10:vstrict=0:aspect=16/9 Project.ts.avs -o Project.ts.avs.mpg -ofps 30000/1001 -of mpeg -mpegopts format=dvd:tsaf
mencoder.exe -mc 0 -noskip -ovc lavc -oac lavc -lavcopts acodec=ac3:abitrate=128:threads=2:vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=9668:keyint=15:vpass=3:trell:mbd=2:precmp=2:subcmp=2:cmp=2:dia=-10:predia=-10:cbp:mv0:vqmin=1:lmin=1:dc=10:vstrict=0:aspect=16/9 -srate 48000 -af lavcresample=48000 Project.ts.avs -o Project.ts.avs.mpg -ofps 30000/1001 -of mpeg -mpegopts format=dvd:tsaf

Here you could tweak the first and 2nd pass for better performance (remove CPU intensive switches). Also, vpass=3 isn’t a mistake for pass no. 2 (you can read mencoder’s manpage for more details). Now at this point if everything went fine with the encode you should end up with a Project.ts.avs.mpg file.

5. Time to create the DVD structure with DVDAuthor. This is as simple as this:

dvdauthor.exe -t -o PROJECT Project.ts.avs.mpg
dvdauthor.exe -T -o PROJECT

Here, PROJECT is an output folder containing the DVD structure (AUDIO_TS and VIDEO_TS folders). The -t switch creates the titleset and the -T switch creates the table of content (which contains only the single titleset created from -t).

6. The last step to create the DVD is to burn the disc. Just fire up ImgBurn and select Create image file from files/folders and under the Output menu select Device to burn the result to disc.

Et voilà. Of course there is always a thousand ways of re-encoding a stream so keep in mind this is only one way of doing it… 🙂

PPA Update

Yes, I have found some time (sorry, I meant “took some time”) to update my PPA. I’ve updated my x264 package to core 76 for now. You’ll find my PPA on launchpad.

I also want to update my other packages but first I need to better understand the process of updating an existing source package with a new upstream version using version control (git). Launchpad has lots of good resources on packaging software for Ubuntu (or any Debian based distro).

I found interesting links on packaging for Debian. However they all seem to be using their “own” way and there seems to be no “standard/official” way of doing it. There is also the vcs-pkg project that aims to further investigate the use of version control for packaging. Interesting.

Any good links aside those ones you would like to suggest?

Reference Counting Garbage Collection

One nice feature from the .NET world is garbage collection. You simply don’t need to worry (99% of the time) about memory allocation resulting from creating new objects. The .NET garbage collector detects when an object is no longer needed based on a few heuristics but mainly based on reference count.

Using the same technique while using C++ is possible, and even easy. Since programming is about reuse I opted to create a class that wraps existing objects to add the wanted feature. It looks like this:

CRefObject<TExisting>* p = CRefObject<TExisting>::CreateInstance(/* TExisting ctor args */);

CRefObject basically derives from TExisting to keep all the same functionality:

template<typename TBase, typename TActivator = CRefActivatorTraits<TBase>>
class CRefObject : public TBase
{

...

};

Keeping the reference count within the object itself is important as one objective is to pass objects between threads without having to worry about memory allocation. There are many smart pointers out there and many implement reference counting however I haven’t found one that keeps the reference count as an part of an object identity.

Implementing CRefObject<T> is quite straightforward: manage reference counting.

	ULONG AddRef()
	{
		return ::InterlockedIncrement(&m_lRefCount);
	}

	ULONG Release()
	{
		LONG lCount = ::InterlockedDecrement(&m_lRefCount);
		ATLASSERT(lCount >= 0);
		if (lCount == 0)
			TActivator::Destroy(this);

		return lCount;
	}

Now that we have reference counting we can upgrade existing objects and manage reference counting like this:

CRefObject<TExisting>* p = CRefObject<TExisting>::CreateInstance(/* TExisting ctor args */);
...
// When done with the object, release it
p->Release();

That looks like COM doesn’t it? Yes it does. And there is one more feature we can add to make it look even more like COM using ATL: using smart pointers. This makes it much easier to track the reference count. Welcome CRefAutoPtr<T>:

template<typename T>
class CRefAutoPtr
{
public:
	CRefAutoPtr() throw() :
		m_pT(NULL)
	{ }

	CRefAutoPtr(const CRefAutoPtr& sp) throw() :
		m_pT(sp.m_pT)
	{
		_AddRef();
	}

	explicit CRefAutoPtr(CRefObject* pT) throw() :
		m_pT(NULL)
	{
		_Attach(pT);
	}

	virtual ~CRefAutoPtr() throw()
	{
		_Release();
	}

	CRefAutoPtr& operator =(const CRefAutoPtr& sp) throw()
	{
		_Release();
		m_pT = sp.m_pT;
		_AddRef();
		return *this;
	}

	CRefObject* operator &() throw()
	{
		_AddRef();
		return m_pT;
	}

	operator CRefObject*() throw()
	{
		return operator&();
	}

	CRefObject* operator ->() const throw()
	{
		return m_pT;
	}

	bool operator !=(const CRefAutoPtr& sp) const throw()
	{
		return !operator==(sp);
	}

	bool operator ==(const CRefAutoPtr& sp) const throw()
	{
		return m_pT == sp.m_pT;
	}

	CRefObject* Detach() throw()
	{
		CRefObject* pT = m_pT;
		m_pT = NULL;
		return pT;
	}

protected:
	VOID _Attach(CRefObject* pT) throw()
	{
		_Release();
		m_pT = pT;
	}

	VOID _AddRef() throw()
	{
		CRefObject* pT = m_pT;
		if (pT)
			pT->AddRef();
	}

	VOID _Release() throw()
	{
		CRefObject* pT = m_pT;
		if (pT)
		{
			m_pT = NULL;
			pT->Release();
		}
	}

public:
	CRefObject* m_pT;
};

The whole implementation isn’t 100% complete, but its quite a good start.