Compiling FFmpeg with libx264 and libfdk_aac under Cygwin without Mingw32

After many days and nights – I have been through many battles. One battle involved my scratching of my head many times. This battle is me trying to build FFmpeg with Cygwin. A new post and about computer stuff? Yay!

If you just happen to stumble upon this mostly irrelevant post to the world, and you know absolutely nothing about programs and have no interest on these kind of things, you can opt out and stop reading right now, or better yet read some of my other post, as if there’s many worthwhile one, or just go outside and do some “real world” stuff instead of being in front of your computer lazily glazing your eyes with artificial radiation. What the feck is an artificial radiation anyway. If someone referred you to this page, like a search engine, then I’m fluttered.

Continuing with the topic. This is about making the latest source snapshot at least compile within Cygwin under Windows. If you didn’t know about Cygwin, it’s an excellent (at least for me) unix shell layer for Windows. This can entice you if you miss bashing (sorry) and you want to experience it under Windows or if you want to use practical UNIX tools under Windows.

The problem with Cygwin (a system always have a problem; it’s the charm of engineering) is because it’s practically an emulation of the Unix shell (even though technically it’s not an emulation; it’s more of an application layer, like Wine on Linux), and you are guaranteed to encounter a slew of problems here and there, especially if it pertains to libraries and dependencies.

You can think you can get away with the base installation of Cygwin and just compile those dependencies yourself, but you’ll just waste your time. Because of the low-levelness of these things, they are specially pre-built by the Cygwin team and are available over the repositories, and can be fetch by the setup program. So we will use the pre-built version of these little ones. However, some are missing on the repositories; most likely due to licensing issues. So to get around this, we can try to build it ourselves and cross your finger, or find a third-party repository. We will go on the harder route, and we’ll build them ourselves coz we’re masochists Fortunately, there’s one available. We will come to that later.

And you might have thought, what the ♥♥♥♥ is FFmpeg? FFmpeg is the most powerful, open-source command-line media factory for all your media handling needs. Hands down. You can use it to efficiently convert, repack, encode, re-encode, etc. almost all various image, video, and audio formats. It is the back-end that powers most powerful, often free, encoders, decoders, and players out in the wild, like MPlayer. Later versions also includes a player and a server, ffplayer and ffserver, respectively, but mainly it is used for repackaging and encoding purposes. We will only focus on the ffmpeg binary on this page.

For this guide, we will use another guide (so much for a guide). Head over to https://www.ffmpeg.org/platform.html and read the specifications “Compilation under Cygwin”, or you can read them all and have an idea of how these things work across platforms, or just ignore the link and continue below (trust me, the above link is completely optional). It mutters these names:

binutils, gcc4-core, make, git, mingw-runtime, texinfo
bc, diffutils
libogg-devel, libvorbis-devel
yasm, libSDL-devel, libfaac-devel, libaacplus-devel, libgsm-devel, libmp3lame-devel,
libschroedinger1.0-devel, speex-devel, libtheora-devel, libxvidcore-devel

Install them through the Cygwin setup, together with the entire “Base” packages. gcc4-core is gcc-core. git will not be used but install it anyway (for the future). bc and diffutils are still important even if you don’t do FATE so get them anyway. mingw-runtime is required even though we will not use Mingw32 for building. The 4th row is the most important, but all of these are not available in the official repos (you know the reason). In order to get them, follow the guide there and use Cygport repositories. Make sure you get yasm and libtheora, as those others provides the codecs, albeit popular codecs, so you might get them as well. Since we will build libfdk_aac and libx264 ourselves, we can ignore libfaac, libaacplus, and libvorbis (they’re missing in the repositories anyway). You can also ignore libschroedinger, since we will ideally use x264 for h.264 codec.

Additionally, install the packages:

wget, unzip, texi2html, curl, dos2unix, autotools (autobuild, autoconf, automake, autotoolset, all versions, for insurance), pthreads, cygport

dos2unix is required for conversions of formatting characters (e.g. newline character) from dos unto Unix format. Make sure you get cygport, it provides the proper lib-utils to build under windows. Without it, all of your attempts to build will throw you an error. autotools is required for one particular build process. pthread is required to build ffmpeg with pthreads, as it’s supposed to provide multithreading support. You can build without one; in fact, it’s not required if you’ll only use x264 codings, as libx264 provides this functionality for itself.

After you managed to get and install those packages, we will use another guide, again. We will use https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu. You can read that entire page, or just ignore the link and open your Cygwin Terminal. For the purpose of uniformity, we will follow the guide (or you can just do some liberties in the process, as long as it sounds logically). On the terminal, run:

mkdir bin && mkdir ffmpeg_sources && mkdir ffmpeg_build

Those will setup the working directories. After that, copy and paste to terminal:

cd ~/ffmpeg_sources
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
PATH="$HOME/bin:$PATH" make
make install
make distclean

Make sure to press enter on the last command. This will build libx264 for us. If all required packages were installed, the build process will be successful. You can find libx264.exe inside ~bin on your cygwin home folder.

This builds the 8-bit variant. If you happen to want to encode 10-bit videos, you have to use --bit-depth=10 argument when running configure. So thus the command:

./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --bit-depth=10

If you’ve come across --enable-win32thread, you’ll know the name is sweet but don’t ever use it!! (Not that you care.) You’ll lose multi-threading capability since we are not cross-compiling for windows; we are compiling for Cygwin.

All done with libx264, run:

cd ~/ffmpeg_sources
wget -O fdk-aac.zip https://github.com/mstorsjo/fdk-aac/zipball/master
unzip fdk-aac.zip
cd mstorsjo-fdk-aac*
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

This will build libfdk_aac. The “F” stands for Fraugher, something like that (it was German, ha ha). Again, if all packages mentioned in this post were installed, this will build successfully. It doesn’t come with an executable binary so it doesn’t produce an output inside ~bin. Now, we will have a library that will enable us to encode High Efficiency Advanced Audio Codec (HE-AAC). Quality audio for lower bitrates. That’s German engineering for you. Yay!

Now, finally, the ffmpeg itself. Run:

cd ~/ffmpeg_sources
wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjvf ffmpeg-snapshot.tar.bz2
cd ffmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --bindir="$HOME/bin" \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-ffserver \
  --enable-gpl \
  --enable-libfdk-aac \
  --enable-libmp3lame \
  --enable-libtheora \
  --enable-libvorbis \
  --enable-libx264 \
  --enable-pthreads \
  --enable-nonfree
PATH="$HOME/bin:$PATH" make
make install
make distclean
hash -r

This is my configuration. Be ready for a loooong time of compilation. If you didn’t install libvorbis, you can remove its line. The same with other codecs that you didn’t install. We disabled ffplay, ffprobe and ffserver for this setup since we didn’t install some of their dependencies. If you want them, you can always head to the official FFmpeg documentations and wiki for more information on them and their dependencies.

Now, unless you find watching progress and numbers appearing entertaining (like me), that’s a boring compilation! You will find ffmpeg.exe inside ~bin. If you care about bits, we used x86 toolchains, so the binary is 32-bit. You’ll notice that it’s pretty big compared to other ffmpeg builds out there in the jungle, but don’t fret. It was built statically which means that included libraries are all packed in that one binary, and under Cygwin. It would be different if you built it using mingw32. But if you wanted to cross-compile it, you could have better compiled it under other sane platforms (like Linux), or better, under Windows (if you know to setup Visual Studios or Mingw32 for ffmpeg, that is).

But why Cygwin? Because sometimes these kinds of work and process are easier here, evident by this one post alone.

When you’re ready to use your newly built program, you can copy the binary unto anywhere and run it through cmd there or whatever method of applications you can use it with, or put it on a directory included with your SYSTEM PATH (e.g. WINDOWS\system32). You can even use it for scripting purposes (that’s part of FFmpeg’s charm, or any other cmd-line programs). Just remember that you need external Cygwin libraries either on the same folder or in the system path to run this little shiny, since you technically compiled it under/for a UNIX environment. Depending on what packages you included during configuration, these includes:

cyggcc_s-1.dll
cygiconv-2.dll
cygmp3lame-0.dll
cygogg-0.dll
cygSDL-1-2-0.dll
cygtheoradec-1.dll
cygtheoraenc-1.dll
cygvorbis-0.dll
cygvorbisenc-2.dll
cygwin1.dll
cygz.dll

If you don’t want these extra dll’s lying around, you can always cross-compile it or natively compile it in Windows. That will be another story.

To know the command parameters, run ffmpeg -h.

Some example command:

ffmpeg -i "!filepath!" -c:v libx264 -preset:v veryslow -crf 27 -c:a libfdk_aac -profile:a aac_he_v2 -strict experimental -b:a 32k -movflags +faststart -vf "scale=-2:480" -r 24 "!outfile!"

“!filepath!” is your input file, while “!outfile!” would be your output file. For more information how to use ffmpeg, FFmpeg has an excellent documentation for all its flexibility and possible use.

Happy Compiling!

Automatic Remote Connection through Deluge WebUI in Debian/Ubuntu-based Systems

In search for good bittorrent clients on ‘Nixes, one name could come up on your mind if you ever knew about these things:
Deluge.

Deluge is one of the most customizable and feature-rich torrent clients out in the woods. Mostly used in the most popular platform which is Windows Linux, most servers/torrent boxes used it for daily business. You can use remote shell and clients to shape and manipulate your Deluge remotely, to suit your carnal needs.

To enable remote connections to deluge through clients, there are two separate components at the backside of the program that handles this task.

These components are the daemon and web interface, called deluged and deluge-web, respectively.

There are clients that connect directly through the daemon, a prominent example of this is deluge (the client) itself, with classic interface option off. There are also clients that connect through the web interface deluge-web instead, which in turn connects to the daemon deluged. This approach might have been prefered to enable usage of web security technologies, SSH for example. Clients using this approach must have required the web interface to be configured before communication is possible through the daemon.

Deluge can be run and configured easily and out of the box on ‘nix systems after installation. But to configure telekinesis, normally you need to download and install two separate packages. You might not be able to guess the package names because you have low IQ. After somehow figuring it out, you can enable them on your deluge client, and set things ready for remote hook-up.

Now, suppose you want to connect remotely to deluge in your LAN network using other devices for lulz. You need clients that supports this feature.

But luckily, you have an android because iPhone sucks. You used Transdroid. It connects to deluge through the web interface. So, the web interface needs to be connected to the daemon. So, in every instance you start your deluge, you need to login through your web interface to connect it to the daemon. This is fine in the first run. But when your box that serves deluge is not an everlasting server, that is turned off regularly, you need to set things up again! Why can’t they just meet automatically in the usual place and hook-up already?

The solution is simple.

Assuming you have set up deluged and deluge-web on the local machine, your deluge is running, disabled classic interface and enabled WebUI plugin.
You’ll connect to the web interface for the first time. With default settings, you’d use the Port 8112. So, in your web browser you type:
 

localhost:8112

 
Enter the default password, which is deluge,and connect to the local
daemon (or a remote daemon, if you have, for whatever reasons, like illegal ones).

Now, close your deluge client and daemon.

Open up your favorite text editor, in my case nano, and open web.conf:
 

nano ~/.config/deluge/web.conf

 
find the line that says “default_daemon”, and edit it accordingly. Assuming default port and localhost:
 

~/.config/deluge/web.conf

"default_daemon": "127.0.0.1:58846",

 
Save the file. Start deluge and deluged, and that’s the solution. Everytime deluge starts, so does deluge-web, which now automatically connects to the daemon, so when you open the WebUI, you don’t need to connect to the daemon manually. So does your remote client. Short, sweet and simple.

Thoughts: Lollipop Madness

Just last week if I remember correctly, Google announced the next version of the Android Operating System, Android 5.0 Lollipop. It follows last years’ KitKat, which is somewhat like Windows 8 in Microsoft analogy. Lollipop, is the next major overhaul change since Ice Cream Sandwich, boasting more flatter design called Material design (this trend must have started 2-3 years ago… so familiar…), performance and stability boost, better notification handling, “better” multitasking (which is just, you know, a visual upgrade), and other small, under-the-hood improvements. This update can be like Windows 10 in Microsoft analogy.

Now, let me talk about a couple of things concerning this news.

The name. I was kinda bummed here. They obviously chose the most obvious of all sweet things! I thought Key Lime Pie was already great, which turned out to be version 4.4 KitKat. They should have continued the trend that starts with Gingerbread, Honeycomb, Ice Cream Sandwich and Jellybean. Not only those are not that remotely popular (for all around the world; reality check), they are also unique, so Lollipop broke that sacred naming convention. About KitKat, don’t ask why.

This part is terrible. Why the heck is it that when it comes to its design, the irony is that it doesn’t even come to the low-end devices, and more importantly, those old flagship devices, where it is needed the most? It was designed to be more optimized in lesser memory, have a more efficient, faster binary runtime that requires lesser memory (in the form of ART), better battery optimization in the form of baked-in greenify-like feature in the system, and for ART that’s supposed to lessen processing load.

So, clearly it carried the banner that started with KitKat that said lesser fragmentation and uniformity across devices. Wait, that is the supposed intention? Then why is my Galaxy Nexus isn’t supported? They missed a great chance to explore the power and possibilities of these new operating systems by making them available to those not-so-old, capable devices.

Now, reasons for these are apparently obvious – Galaxy Nexus having no updated drivers for the kernel, OEM and carriers not updating older devices, unavailability of support for third-party hardwares, low storage spaces for older devices because ART takes more space (which can be solved through external storage), money and profitability – but not taking the chance to let these perfectly capable devices, these very same devices that gets the most benefit, to get a lick and suck to the oh, so delicious Lollipop (It wasn’t made intentionally perverse in anyway), felt kinda frustrating. It could have cement more footings for android; it could have benefit Google and its partners, the developers, the whole freaking ecosystem.

Community developers had made KitKat to work with Galaxy Nexus, and I wouldn’t be surprised if they did the same thing for Lollipop.

And, some of the initial roll-up for Lollipop is the new devices that come with it (obviously) which is the Nexus 6 and Nexus 9, and coming weeks later are Nexus 5, Nexus 4, Nexus 10, Moto X, and even freaking Nexus 7. Yeah, that device from 2 years ago, earlier than Nexus 4. See the possibility?

This is a long post, actually a rant post, which is unusual for me, but this is just a side effect of my excitement on this Android release. Especially on the thought that my Galaxy Nexus could get Lollipop after it was given a new breath of life lately through community developed updated kernel and drivers. I’d continue to watch the community from the shadows and maybe I can share more information regarding these events.

cdb35f914ccb71f4e65d6903b3da98d5a76784c0