Saturday, May 31, 2014

About ffmpeg tutorial

If you want to work with ffmpeg from your code, you may want to build it from source. How to build it on your Linux distro, or possibly some other operating system, is described in Compilation Guide at ffmpeg wiki. For updated tutorial code one will also want to install git. I was working on LinuxMint, so commands used in this article are Debian-centric.
Latest ffmpeg tutorial is written by Dranger and it is severely outdated. If you visit his website you will see that his tutorial is remake of older tutorial written by Martin Bohme. Few programmers have made attempts to keep code for this tutorial in sync with current ffmpeg API. One can find updated code in git repository git@github.com:chelyaev/ffmpeg-tutorial.git. So, open terminal, cd where you want to clone repo and execute

git clone git@github.com:chelyaev/ffmpeg-tutorial.git
cd ffmpeg-tutorial
git log


Last line will print log and it will start from freshest commits, to advance towards oldest ones we press space. In order to see what changes have been made on tutorial01.c between initial import and working version we execute in terminal:

git log -u 3e1426115418ae50cb9a4357d57afbcec69342fe..69b7f32f5edb38cc4e9c47711f100998404485d1 tutorial01.c

Those hashes separated by double dot we got from previously executed git log and what set of changes is hash for we know from comment bellow hash. This one I used to see what was changed in tutorial01.c to make it work.
If we go through commits we will find in few comments that sound is not being decoded as expected, that is actually main reason why I am fiddling with this tutorials. You go through only available tutorial for ffmpeg and end up debugging sound problems, not very encouraging.

SDL

Original Dranger tutorial is called An ffmpeg and SDL Tutorial, so let us take a look at SDL. We will output our video to SDL and I prefer to familiarize with SDL before I use it.
If we have done what Compilation Guide for ffmpeg says, we already have SDL 1.2 installed. In order to find header files, man pages and similar we use:

dpkg -L libsdl1.2-dev

That will list installed files and help with includes for our hello world code.


There is uninitialized SDL_Surface pointer, why I didn’t set it to NULL? Because SDL_SetVideoMode will set it to NULL if it fails. Path to include file is sorted out within code, linker instructions are added and we can build it and run it.

gcc helloSDL.c -lSDL -o helloSDL
./helloSDL


And half painted window should show up. Simple use API program where SDL is initialized, later surfice created and quit event handler resource cleanup is done. To better understand what code does please execute in terminal man followed by function name.

Building ffplay

Tutorial relies on ffplay.c which is part of ffmpeg source and currently only (partly) working example how to use ffmpeg to create simple video player. That is very simple but there may be some of us who are not very familiar with GNU make. We follow Compilation Guide and set environment variables, cd to ffmpeg source directory and in terminal execute:

PKG_CONFIG_PATH="$HOME/work/ffmpeg_build/lib/pkgconfig"
export PKG_CONFIG_PATH
./configure --prefix="$HOME/work/ffmpeg_build" --extra-cflags="-I$HOME/work/ffmpeg_build/include" \
   --extra-ldflags="-L$HOME/work/ffmpeg_build/lib" --bindir="$HOME/work/bin" --extra-libs="-ldl" --enable-gpl \
   --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus \
   --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab


Config will take a while and doesn’t provide feedback about progress, so be patient. I decided to build it and install it in ~/work folder instead in suggested $HOME, if you like to follow original just grep and remove work/. Now to get commands required to compile and link cmdutils.c and ffplay.c execute in terminal:

make -n > ~/dry_run

I outputed it to file since it produces quite large output and it may be interesting to look at it again. Simple grep for cmdutils.c and ffplay.c will return required instructions. Skip start of the line:

printf "CC\t%s\n" cmdutils.o;
printf "CC\t%s\n" ffplay.o;
printf "LD\t%s\n" ffplay_g;


and use compile commands from gcc -I. -I./ ... and link command from gcc -Llibavcodec -Llibavdevice ...
Link command will produce executable ffplay_g and it is located right under compile command for ffplay.o. Now you can nicely modify, build and debug ffplay.