Compile ffmpeg 64 bit on Windows with MSYS/MinGW-w64

January 8th, 2014

Set up the MSYS environment

Download MSYS from MinGW-builds. Extract it to a path with no spaces, to which you have write permissions. For example, D:\msys. This already includes useful features like pkg-config, Autotools and Git.

Download a pre-built MinGW-w64 from and extract it inside the MSYS directory. This already includes useful features like Yasm.

Start MSYS with msys.bat

In MSYS, run:

echo 'export PATH=.:/local/bin:/bin:/mingw64/bin' > .profile
source .profile

Check that it has worked with gcc -v

Compile ffmpeg and libraries

These steps are similar to the Linux/BSD version of this guide.

git config --global core.autocrlf false
git clone git:// x264
cd x264
./configure --host=x86_64-w64-mingw32 --enable-static --enable-shared && make && make install
cd ..
git clone git:// fdk-aac
cd fdk-aac
./configure --host=x86_64-w64-mingw32 --enable-static --enable-shared && make && make install
cd ..
git clone git:// ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-nonfree --enable-libx264 --enable-libfdk_aac --enable-static --disable-shared --extra-cflags=-I/local/include --extra-ldflags='-L/local/lib -static' && make && make install

NOTE: configure on ffmpeg in mingw is slow. Be patient. You should also check for success after each library has compiled.

This should build ffmpeg.exe as a 64 bit static executable that can be run directly in Windows x64, with H.264 and AAC support. It does not need to be run from MSYS. In my testing, the 64 bit version is approx. 10% faster than the 32 bit version.

If you want it to use DLLs instead of creating a static executable, change --disable-shared to --enable-shared and remove the -static from the ldflags in the ffmpeg configure.

Free alternative to .NET Reflector

December 18th, 2013

ILSpy is free and open source.

Park or Unpark your CPU cores the easy way.

September 18th, 2013

CPU cores that are not under heavy load get parked to save on power, reduce heat, etc.

Some users (not me) may get a performance benefit out of disabling this parking and keeping their cores unparked.

There is a commonly used tool to do this, but it is slow and somewhat convoluted. All this tool does is modify a few values in the registry.

The different keys it modifies are actually different control sets. As CurrentControlSet is a pointer, it is the only one you need to modify. In fact, as the numbered control sets store the “last known good configuration” that you may see when you recover from a crash, you probably shouldn’t change them directly.

This means that all you need to do is:

Step 1:

Run regedit as Administrator
(type regedit in start menu, right click, Run as Administrator).

Step 2:

Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\

(you can just go to “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet”, right click, find, search for 0cc5b647-c1df-4637-891a-dec35c318583)

Step 3:

To park, set ValueMax to 100 as decimal (or 64 as hex).
To unpark, set ValueMax to 0.

Alternatively, set Attributes to 0 and you will be able to change the setting easily from Power Options in the Control Panel.

Step 4:


Core parking tool

Alternatively, I made a very simple tool to do it in one click. admin rights and .net 2.0 required to run, reboot is required for setting to take effect. Source code is in the archive.

See also: BitSum ParkControl.

You can also use the PowerCfg command line.

YouTube My Subscriptions grid view

August 16th, 2013

YouTube has finally removed the old grid view my_subscriptions page. If you don’t like the frankly broken and unusable /feed/subscriptions page, there is a Chrome extension that will fix it for you.

Better Youtube Subscriptions Page
“Transforms Youtube’s broken feed subscription page and restore it to it’s former grid glory.”

In fact, I actually prefer it over the old grid page because it fills the grid to the width of the page, showing more on wider resolutions. It doesn’t seem to hide watched videos, but I didn’t like the grid page doing that anyway because it also hid partially watched videos (anything viewed for more than a couple of seconds).

This app does not require strange permissions that it shouldn’t need or an OAuth login (as YouTube Video Deck does) or anything like that, it just alters your subscription feed to appear as a grid.

As a side note, the YouTube API actually doesn’t need authentication to get channel or video information. You should only need to give login auth if it tracks what you have watched, automatically gets your subscriptions from your YouTube account or anything else that involves your account directly. Although it’s better than a 3rd party website saving your password, you should still be very careful who you give your OAuth authentication to, as it essentially logs them into your Google account for you.

It’s also compatible with the YouTube Ratings Preview extension, which shows the green/red rating bar on the thumbnail before you view the video, although this seems to only show ratings previews on the first 30 or so videos on each page.

Introduction to MFC

February 7th, 2013

The Microsoft Foundation Class library is a framework for Windows GUIs in C++, based on the Win32 API C library.

To create a simple window, you need to create an app and a window.

The app class handles most of the behind the scenes stuff, including program entry. There must be one globally defined instance of the app for the program to run.

Here is a very basic MFC application. It just shows a blank window.

#include <afxwin.h>
class CHelloWorldFrame : public CFrameWnd
BEGIN_MESSAGE_MAP(CHelloWorldFrame, CFrameWnd)
class CHelloWorldApp : public CWinApp
	CHelloWorldApp() : CWinApp(_T("App Name")) {}
	BOOL InitInstance()
		CFrameWnd* frame = new CHelloWorldFrame();
		m_pMainWnd = frame;
		frame->Create(NULL, _T("Window Caption"));
		return TRUE;
CHelloWorldApp theApp;

If you want to create a form with buttons, text boxes etc, you should probably look at CFormView. Alternatively, create a dialog-based application in Visual Studio rather than single document (SDI).

The solution to most of the US’ political problems

February 1st, 2013

In a US election, most states are pretty much guaranteed to vote a certain way. Amazingly, these political parties are actually distinguishable from one another (this is not the case in my country, in which all politicians are equally corrupt, greedy liars that may as well be in a single political party). These parties have been arguing over the same points for decades.

The solution is obvious. Split the republican states and the democrat states into two separate countries. Swing states can either pick and choose, redefine their borders or emigrate. A couple of suggestions for the name of the resulting republican country are Acirema and ‘merica.

This way, the democratic country can have free healthcare, while the republican country can have all the guns they want and so on.

P.S. This post is tongue in cheek. Don’t take it too seriously (unless you’re a US president and think it’s a good idea!)

SQL Server random unique identifiers

May 4th, 2012

A common method of producing random unique identifiers in SQL server is by using a GUID field, calling newid() to generate the data. For the most part, this works because it’s 128 bits worth of random data, which means there is a very low probability of duplicate records for most databases.

However, it is also common to combine this with the checksum() function to reduce it to a 32 bit integer. This makes collisions much more likely, even in relatively small databases. For example, the GUIDs 28258F69-6536-4198-BE37-94960ABF054F and 49B60D4B-DC4A-4E18-825E-B4C99713D011 both checksum to 0xC3AD13D3. With a table of about 100,000 rows collisions will start to occur more frequently by the birthday paradox.

def P(x, n):
  return 1 - ((x-1)/x)**(n * (n-1)/2)
>>> P(2**32,77500)
>>> P(2**32,200000)
>>> P(2**53,10000000)
>>> P(2**53,100000000)

Using this maths, we can see that using a 32 bit random number, the probability of getting at least one collision is 50% at around 77,500 rows and 99% at 200,000 rows. We can also see that if we increase this to a 53 bit number, 10 million rows gives a 0.55% chance of getting at least collision and 100 million rows gives a 42.5% chance of getting at least one collision, so 64 bit should be plenty.

For higher precision numbers, we can use mpmath

from mpmath import *
def P(x, n):
  return 1 - ((x-1)/x)**(n * (n-1)/2)
>>> print( P(mpf(2)**mpf(64), mpf(1000000000)) )
>>> print( P(mpf(2)**mpf(64), mpf(10000000000)) )

From here you can see that a 64 bit number has a 2.6% chance of getting a single collision in a 1 billion row table, and a 93% chance in a 10 billion row table.

A compromise of both is to simply truncate the GUID at 64 bits and optionally convert to a bigint.


If you leave it as binary and don’t need to convert to an integer type, this does not have to be 8 bytes. For example, you could have a 5 or a 10 byte code.

None of these are perfect but the probability of a collision decreases with more bits. If 128 bit is too long for you (e.g. to display to users) but 32 bit generates too many collisions, try a compromise such as 64 bit.

If you are consistent enough, you may even be able to store the original GUID and just display the truncated form, which could allow you to change the length displayed later without changing the probability of collisions. This is more flexible but may lead to confusion among users and consistency is required (differing lengths could lead to bugs).


February 20th, 2012

Suggestion for YouTube:

Put the green and red like/dislike bar on the thumbnail of the video so you can see if a video is going to be any good before you visit it and to reduce mindless spam from misleading video names and thumbnails.

Possibly the best improvement to YouTube usability since the advent of the play button.

Update: This exists as a Google Chrome extension.

Faster than light neutrinos

December 4th, 2011

OK so this is probably going to demonstrate how bad I am at physics, and I will probably be flamed for being an idiot, but here are some of my thoughts on the faster than light neutrinos.

  1. Time slows down as you approach the speed of light. Velocity is a derivation of time (speed = distance / time). This can make it difficult to measure, and the time dilation needs to be accounted for.
  2. When measuring things close to the speed of light, the equipment itself has the same limitations. It takes time for a signal to get from one part of the equipment to another.
  3. The Earth itself is moving in the solar system, the solar system is moving in the galaxy, and the galaxy is moving in the universe. The speed of light is an absolute limit, but the measurement of something moving between two points on Earth is a relative measurement. If something was fixed in an absolute position, it would be moving very quickly relative to the Earth.
  4. The speed of light limitation applies to objects with mass. The mass of neutrinos is believed to be non-zero, but is not yet completely known, and objects with energy essentially have more mass, so the mass of it changes as it accelerates. It’s hard to do maths when you don’t have all of the starting variables.

Buyer beware: (low cost) 6 Gbps SATA III cards are a scam.

October 24th, 2011

I recently upgraded to a new SSD, the OCZ Agility 3. It gave really good speeds, but I couldn’t help but feel that I was limiting it by putting it in a motherboard which only had 3 Gbps SATA II ports.

I bought a Lycom PE115 6Gbps SATA III adapter, and put it in a PCIe 2.0 port, but when I benchmarked the drive with CrystalDiskMark, on an idle Windows 7 x64 machine (Dual Xeon E5620, 8GiB ECC-R 1333MHz) the results were very disappointing.

Not only was there no improvement over the port on the motherboard, the dedicated 6Gbps SATA III card was actually significantly slower than the 3 Gbps SATA II port (roughly 64% of the speed).

I tried without and then with the drivers for the card installed, and it made no real difference.

Fill 0

The blue bar is on the motherboard’s SATA 3Gbps.
The red bar is on the PE115′s SATA 6Gbps
The yellow bar is the PE115 with drivers manually installed.
The green bar is back on the motherboard, to confirm it.

The results show that the PE115 consistently performs significantly worse than the motherboard in both fill 0×00 (above) and fill random (below) operations.

Fill Random

All of this was done in CrystalDiskMark 3.0.1 x64.