my notes of FFMpeg

                                                FFMPEG

My notes about ffmpeg.
This is an excerpt from following website.(http://www.didier-breedt.co.za/2010/09/installing-ffmpeg-from-command-line-with-h264-avc-and-mp3/) And the reason of placing a copy here is purely for personal purpose.

Installing ffmpeg from command line with h264 (AVC) and mp3

Posted on by Breedt Didier

Step by step guide on installing the following ffmpeg installation:

configuration: 每enable-libmp3lame
每enable-libvorbis 每enable-libxvid 每enable-gpl 每enable-shared 每enable-version3 每enable-nonfree 每enable-pthreads 每enable-libfaac 每enable-libfaad 每enable-libopencore-amrnb 每enable-libopencore-amrwb 每enable-libtheora 每enable-libx264 每enable-libxvid 每enable-x11grab

I would advise you to fetch all the following files inside a single directory. What I usually do, which has been working for me quite well, is I would start with fetching the ffmpeg installation and immediately start the above configure command, then as it fails due to dependiencies, I just install them one by one. I will now log the entire install here for you to grab a read and perhaps try yourself.


./configure --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-gpl --enable-shared --enable-version3 --enable-nonfree --enable-pthreads --enable-libfaac
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab

ERROR yasm not found

wget http://www.tortall.net/projects/yasm/releases/yasm-1.1.0.tar.gz

ERROR: libfaac not found

wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz


ERROR: libmp3lame >= 3.98.3 not found

wget http://downloads.sourceforge.net/project/lame/lame/3.98.4/lame-3.98.4.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Flame%2Ffiles%2Flame%2F&ts=1285256527&use_mirror=ufpr

ERROR: libopencore_amrnb not found

wget http://downloads.sourceforge.net/project/opencore-amr/opencore-amr/0.1.2/opencore-amr-0.1.2.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fopencore-amr%2F&ts=1285256783&use_mirror=ufpr



(libtheora depends on libogg, libvorbis)
wget http://downloads.xiph.org/releases/ogg/libogg-1.2.2.tar.gz
wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.2.tar.gz

ERROR: libtheora not found

wget http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2


ERROR: libx264 not found

This one doesn't work!!! wget ftp://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20100922-2245.tar.bz2

use this one:
(in case you don't have git: sudo apt-get install git-core)
git clone git://git.videolan.org/x264.git



ERROR: libxvid not found

wget http://downloads.xvid.org/downloads/xvidcore-1.2.2.tar.gz

Depending on your system, you may need to update your GNU make as well if you get this error:
common.mak:28: *** unterminated call to function `foreach': missing `)'.  Stop.

cd ..
wget http://ftp.gnu.org/gnu/make/make-3.82.tar.gz

ldconfig
bash -l

In order to compile ffplay, you may need to --enable-ffplay
And you need to install sdl:


ipad conpatible video format:
ffmpeg -y -i input.avi -acodec libfaac -ar 48000 -ab 128k -ac 2 -s 720x480 -vcodec libx264 -b 1200k -flags +loop+mv4 -cmp 256 -partitions +parti4x4+partp8x8+partb8x8 -subq 7 -trellis 1 -refs 5 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 1200k -maxrate 1200k -bufsize 1200k -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 16:9 -r 30 -g 90 -async 2 output.mp4

================================================================================================================================================
To compile in Code:Block, the simplest way is to point the original "MakeFile" as its makefile. However, you need to modify some parameter in code:block so that when you make it call "all" or "clean". Also, you will
notice the debugger is not working properly. i.e. some breakpoint is not what it expects to be. This happens from time to time when I was working in mobile-phone manufacturor. Of course anybody with basic
understanding of compiler will understand it is because "-O3" or something is switched on, so, search for makefile.(You will not find "cflag" there! Where is it? It is in "config.mak".) Remove the -O3.
Also, at very beginning, I cannot even debug! Why? Of course it is because .o and executable donot contain "debug" info. But double checking shows "-g" switch is on. Then I found the "strip" command which "strip"
debug info after compilation so that you don't have to give two sets of compilation flag. (Actually the "optimasation flag forces you to give two sets of flag which means you have to "rebuild" if you want to "distribute".)
================================================================================================================================================
I have a "av_assert0(ost->audio_resample);" failure and it only happens around some frames. Gee! Code:Block doesn't have a conditional break like VC6!
===================
Don't use svn trunk version. Download the 0.6 version!!!
===============================
So, you need to remember how to compile the project!
1. just ./configure 每enable-libmp3lame 每enable-libvorbis 每enable-libxvid 每enable-gpl 每enable-shared 每enable-version3 每enable-nonfree 每enable-pthreads 每enable-libfaac 每enable-libfaad 每enable-libopencore-amrnb 每enable-libopencore-amrwb 每enable-libtheora 每enable-libx264 每enable-libxvid 每enable-x11grab
2. Now you need to modify the "config.mak" by removing the "-O3" from CFLAGS because its optimasition will make GDB go wild.
3. Don't forget to remove "strip" from MakeFile as it will remove all debug information.
Please note, step 1 will always create config.mak and you have to do step 2 whenever you do step 1.
===============================================
Finally I think why my converted video has undesired audio stream such as Spanish instead of English because ffmpeg simply pickup the first matching audio stream. Actually this can happen to video stream, provided
your input has multiple video streams, which is unlikely for me. So does subtitle stream. The only way to solve this is by adding a new option like "ffplay" such as "-vst number", "-ast number", "-sst number".
However, my question is how can DVD player pickup the correct stream when playing? There must be some meta info somewhere in ".vob" file?? (For example, if I play ffplay for .vob, it seems it has no difficulty of
picking up correct stream. No! This is not true, ffplay is making the mistake. What I mean is my "PS3", or my DVD player. They must get information somewhere. )
BTW, I hate a function more than 1000 lines. "av_transcode" is the case!!!
===============================================
So, this is my fix for the out-of-date img_convert in swscale lib.
void img_convert(AVPicture* pDst, enum PixelFormat dstFmt, AVPicture* pSrc, enum PixelFormat srcFmt, int srcW, int srcH)
{
    struct SwsContext* context = NULL; // =
    context = sws_getContext(srcW, srcH, srcFmt, srcW, srcH, dstFmt, SWS_BILINEAR, NULL, NULL, NULL);
    //context = sws_alloc_context();
    //sws_init_context(context, NULL, NULL);
    sws_scale(context, pSrc->data, pSrc->linesize, 0, srcH, pDst->data, pDst->linesize);
    //sws_freeContext(context);
}
And here is the code of tutorial from this website: (http://dranger.com/ffmpeg/tutorial01.html) And of course, I made a little change.
1. ffmpeg project decide not to support C++ header. So, you need a macro "__STDC_CONSTANT_MACROS". In command line, it is -D__STDC_CONSTANT_MACROS.
2. It took me almost more than one hour to realize the similar issue of c/c++ compilation of ffmpeg. Since my "code:blocks" by default creates .cpp file and gcc assume it is a c++ code and therefore the exported
function from libavcodec/libavformat won't work. So, I replace the .cpp as .c. Or other people suggests to add
extern "C" {
#include <some_ffmpeg_header.h>
}
ˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊˊ
Quite often you may run into compilation error such as "libavcodec/x86/dsputil_mmx.c:727: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm' etc. And this is a known bug(I guess) for gcc and there is a solution patch here. How does it work? I guess it has something to do with manipulating registers. (Do I know what I am talking?) You have to do: patch ./ffmpeg-0.6.1/libavcodec/x86/dsputil_mmx.c ./ffmpeg-0.6-PIC_fix.patch
even though I can guess how to do it manually. (crazy! do you want to apply diff file manually? What an idiot! I don't even know how to use patch.)
===================================================================
Did I forget to mention my little hack of ffmpeg with my own menu of designated "audio stream" and "subtitle stream"? Just search for "added by nick" and
you will see it is fairly straight-forward. However, now "-scodec copy" has "av_interleaveXXX.c" non-monotone pst error. I have been struggling for days...
===================================================================
I guess this is really educational for me who is not an expert in Linux programming environment setup at all. It happens when my little testing program always crashes at "av_free_packet" call, which in some version switched from "static" to "dynamic" or exported in ffmpeg project. It is in libavformat.so.
After I eliminate the issue of compilation of my ffmpeg project, I search libavformat.so by "locate" and it shows /usr/lib/... has very old version. And also my compiled version only "install" to default path like "/usr/local/lib". In code:blocks' debugger, the error is like "ld" error. This implies something like windows dynamic loaded dll error, in linux it is .so. (Actually there is error message like cannot find symbol.) So, this almost confirms the wrong .so.
How to solve it?
Search google, you will understand it is not only the debugger search path, it is actually the linking path search issue for running. So, I modify .bashrc by adding "export LD_LIBRARY_PATH=/usr/local/lib", then dot it or source it. Restart "code:block", as I suspect it needs restart. Now it works!
(Actually I forget to mention that I delete those "/usr/lib/libavformat.so" soft links before I made above changes. )
So, this is my guess. In code:block or command line, you setup linking parameter as -lavformat which actually asks linker to search for "libavformat.so". However, the true SONAME is "libavformat.so.52". 
nick@nick-desktop:~/downloaded/ffmpeg-0.6.1/libavformat$ objdump -p libavformat.so | grep SONAME
  SONAME               libavformat.so.52

So, it all depends how you setup the soft link to pointing to correct version. (except in each .so it has its own depending info.)
Also, I add the same export LD_LIBRARY_PATH=/usr/local/lib in code:block debugger/link command line.
=====================================================
I guess it is very educational for me as I originally thought there was something meaningless in this tutorial. Later as I tried to modify and come to understand why. However, there is only one thing I think necessary. It is the "pointer-alignment" of input buffer. The following is from original "ffmpeg" comment in source file "avcodec.h".
 * @note You might have to align the input buffer avpkt->data and output buffer
 * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
 * necessary at all, on others it won't work at all if not aligned and on others
 * it will work but it will have an impact on performance.
 *
 * In practice, avpkt->data should have 4 byte alignment at minimum and
 * samples should be 16 byte aligned unless the CPU doesn't need it
 * (AltiVec and SSE do).
So, this is why I create a second temporary uint16_t buffer instead of using uint8_t buffer.(Search for function "audio_decode_frame" and see a "static int16_t data_buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];") You can compare with the original code tutorial here.
====================================================
Another issue is with avcodec_decode_audio2/3. Naturally you want to migrate from 2 to 3 since 2 is declared to be deprecated. However, the following comment originally from "avcodec.h" might disencourage you to
to so since "2" is now simply a wrapper of "3".
 * Some decoders may support multiple frames in a single AVPacket, such
 * decoders would then just decode the first frame. In this case,
 * avcodec_decode_audio3 has to be called again with an AVPacket that contains
 * the remaining data in order to decode the second frame etc.

So, what it says that you have to monitor the return value and compare with the original "packet data size" to see if decoder consumes all input data. In this case, you even want to just use "2" as "3" does almost no help for this.
====================================================
So, I spent several days debugging/tracing ffmpeg/ffplay to see why subtitle is not correctly encoded in .avi from .vob. In ffplay it shows the stream as "data" instead of "subtitle". Then I realize that ffplay is searching
for tag of "subp" and ffmpeg encoded as "text". In this super-simplified document, there is no mention of chunk name.
====================================================
Do you believe that AVI write its stream info at end of file? This is what I found and I cannot figure out why!?! And here is my little hack for ffplay to force it to show subtitle. Of course in ffmpeg I also hack to force
it output subtitle. However, still the transcoding of vob to avi has the previous "pst" non-monotone error in av-interleave-write. FFMpeg is simply buggy, if I may say so.
It is midnight and I am hungry now.





                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)