Home‎ > ‎Tom's Ideas And Notes‎ > ‎

Building ZoneMinder and required FFMPEG and x264 from source on Fedora 15 x86_64

posted Aug 6, 2012, 7:57 PM by Tom Gutwin   [ updated Nov 12, 2012, 8:30 PM ]
ZoneMinder Image
This post documents my steps to build ZoneMinder 1.25, ffmpeg 0.11.1, and x264 latest 20120803-2245 snapshot on or about August 2012.

Success Update - Now all problems fixed

This is now a 100% success. 
A few 'showstoppers' remain unresolved and are forcing me to re-install (either back or forward in  Fedora distribution versions).
  • FIXED Live View not working due to php socket_sendto permission errors
    • It was the http ScriptAlias. see the end of this post
  • filters to delete old events not working (yet to be fully investigated)
    • cgi-bin ScriptAlias problem
My system is working and recording events, however, it is not the required 100%.
I even got my new IP camera working through ffmpeg in Zoneminder.
My existing install was a Default Fedora ZM package for 1.24.1.

I recently bought an IP camera that streams its feed in x264 via RTSP with intent of using it in my Fedora 15 x86_64 (F15) ZoneMinder installation.  I found that the default ZM RPM requires ffmpeg to handle the receiving of the RTSP video feed.  Updating ffmpeg RPM to get the libavformat needed did not work. So, I have to go down the build from source path which leads to installing all kinds of library dependencies. 
I have done this before about, 7 years ago, and I know what it takes... a lot of work. 

Trying to add IP Camera to ZoneMinder

I tried adding my new IP camera (model CAM-IP9032) from www.aartech.ca as shown
ZM Config Dialog - General Tab

When I tried to add my RTSP based camera to ZM I found the following error in the ZM logs...
zm_monitor.cpp/2428 [You must have ffmpeg libraries installed to use remote camera protocol 'rtsp' for monitor 1]
 

ZM needs ffmpeg which needs x264 which needs needs labavformat and libavutil and many others.
Many of the development packages (-devel rpms for Fedora) are new enough to meet the dependency requirement.
Others are NOT. so I have to build them from source.
Sources are ffmpeg and x264.

So here are the details of how I got it built.  I'll start backwards with the dependencies 1st.

UPDATE: IP Camera Success

I did eventually get this camera working, but not as a 'remote' source type.
I got it working using the 'ffmpeg' source type.
I used the following url
  rtsp://username:password@ipc:554/cam/realmonitor?channel=1&subtype=0
where 'ipc' is my camera hostName.



Library dependencies

Here is a dump from my yum.log that lists all the devel packages I installed
from /var/log/yum.log
ffmpeg-devel-0.7.13-1.fc15.x86_64
libstdc++-devel-4.6.3-2.fc15.x86_64
glibc-devel-2.14.1-6.x86_64
libogg-devel-1.2.2-3.fc15.x86_64
libtheora-devel-1.1.1-1.fc15.x86_64
libvorbis-devel-1.3.2-1.fc15.x86_64
x264-devel-0.0.0-0.30.20110620.fc15.x86_64
xvidcore-devel-1.3.2-2.fc15.x86_64
lame-devel-3.98.4-1.fc14.x86_64
dirac-devel-1.0.2-6.fc15.x86_64
libtasn1-devel-2.12-1.fc15.x86_64
libgpg-error-devel-1.9-2.fc15.x86_64
libgcrypt-devel-1.4.6-1.fc15.x86_64
gnutls-devel-2.10.5-3.fc15.x86_64
librtmp-devel-2.4-0.1.20110811gitc58cfb3e.fc15.x86_64
freetype-devel-2.4.4-8.fc15.x86_64
speex-devel-1.2-0.13.rc1.fc15.x86_64
openjpeg-devel-1.4-12.fc15.x86_64
libjpeg-turbo-devel-1.1.1-3.fc15.x86_64
pcre-devel-8.12-8.fc15.x86_64
bzip2-devel-1.0.6-3.fc15.x86_64
systemtap-sdt-devel-1.8-1.fc15.x86_64
perl-devel-5.12.4-166.fc15.x86_64
yasm-devel-1.1.0-2.fc15.x86_64
faac-devel-1.28-2.fc12.x86_64
gsm-devel-1.0.13-2.fc12.x86_64
v4l-utils-devel-tools-0.8.7-1.fc15.x86_64
libv4l-devel-0.8.7-1.fc15.x86_64
glib2-devel-2.28.8-1.fc15.x86_64
pulseaudio-libs-devel-0.9.22-5.fc15.x86_64
libvpx-devel-1.0.0-1.fc15.x86_64
xorg-x11-proto-devel-7.6-12.fc15.noarch
libXau-devel-1.0.6-2.fc15.x86_64
libxcb-devel-1.7-2.fc15.x86_64
libpciaccess-devel-0.12.1-1.fc15.x86_64
pixman-devel-0.20.2-2.fc15.x86_64
xorg-x11-server-devel-1.10.4-2.fc15.x86_64
libX11-devel-1.4.3-1.fc15.x86_64
libXext-devel-1.2.0-2.fc15.x86_64
libXfixes-devel-5.0-1.fc15.x86_64
libcdio-devel-0.82-4.fc15.x86_64
perl-Error-0.17016-5.fc15.noarch
perl-Git-1.7.6.5-1.fc15.noarch
git-1.7.6.5-1.fc15.x86_64


I tried to build x264 first because if I want to enable libx264 on the ffmpeg configure command line - it needs a new version of libx264 but I ran into an error. It stated that swscale was not enabled because PIX_FMT_RGB was not set in avutil and therefore was not going to enable libavformat.
  • ffmpeg needs x264
  •    which needs a re-build of avformat and avutil
  •      which are built from within ffmpeg
Looks like a circular need ! 
Hmmm now what?
  1. build ffmpeg 1st without libx264
  2. then build x264
  3. then rebuild ffmpeg with libx264
  4. then build ZoneMinder

Build ffmpeg without libx264

Get the latest source.
sudo yum remove ffmpeg-devel ffmpeg-libs ffmpeg

I built it with the following configure command line
./configure --prefix=/usr --enable-gpl --enable-postproc --enable-swscale --enable-pthreads --enable-x11grab --enable-libfaac --enable-libgsm --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libxvid --enable-nonfree --enable-version3 --enable-libvpx --enable-nonfree --enable-libopenjpeg --enable-libspeex --enable-libv4l2 --enable-libxvid --enable-libspeex --enable-libpulse

make
sudo make install

notice there is no   --enable-libx264
I will build again later after I build x264

Build x264

Get the 0.11.1 source.

Make sure no other RPM packages are installed. They will lead to problems in the ffmpeg build.
sudo yum remove x264*

I built it with the following configure command line
./configure --prefix=/usr
make

For some reason x264 could not find libavformat/libavformat.h   ???
x264 goes looking for these headers /usr/include/ffmpeg/libavformat dir but there was no ffmpeg/libavformat  there ???
I Just installed ffmpeg... whats going on???

I found that the ffmpeg makefile uses config.mak to setup the install dirs and it was not putting things in the ffmpeg dir within include dir
Line 8 in the ffmpeg config.mak looked like this
INCDIR=$(DESTDIR)${prefix}/include
I changed it to
INCDIR=$(DESTDIR)${prefix}/include/ffmpeg
re-did the ffmpeg make install

The back to the x264 build dir and re-did the
make
This went well without problems except the make install only install the executable, so i specifically called the other makefile targets:
sudo make install install-lib-dev install-lib-static install-lib-shared

Now onto ffmpeg with libx264...

Build ffmpeg with libx264

I built it with the following configure command line
./configure --prefix=/usr --enable-gpl --enable-postproc --enable-swscale --enable-pthreads --enable-x11grab --enable-libfaac --enable-libgsm --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libxvid --enable-nonfree --enable-version3 --enable-libvpx --enable-nonfree --enable-libopenjpeg --enable-libspeex --enable-libv4l2 --enable-libxvid --enable-libspeex --enable-libpulse --enable-libx264 --arch=x86_64 --enable-runtime-cpudetect
I had trouble with  cdio and 1394 so I did not build them.

when I did the make
I ran into an error about  x264_encoder_open_125 not being defined but that was because I had the OLD Fedora ffmpeg-devel ffmpeg-libs installed. As soon as I removed the old x264 packages
sudo yum remove ffmpeg-devel ffmpeg-libs ffmpeg
went back to the x264 build dir and re-did the x264
sudo make install install-lib-dev install-lib-static install-lib-shared

Now back to ffmpeg to re-do the
make
sudo make install
Worked without error!

Build ZoneMinder

Get the latest source.
I built it with the following configure command line
./configure --with-libarch=lib64 --with-mysql=/usr --with-ffmpeg=/usr --with-webdir=/usr/share/zoneminder/www --with-webhost=zm.webarts.bc.ca --with-cgidir=/usr/libexec/zoneminder/cgi-bin --with-extralibs="-lfreetype -lmp3lame -lopenjpeg -lrtmp  -lspeex -ltheora -lvorbis -lvorbisenc -lx264 -lfaac -lgsm -lopenjpeg -lv4l2"

Another error abount not being able to build libavformat
When I checked the config.log I found
common.h:154: error: ‘UINT64_C’ was not declared in this scope
Google has seen this many times. I found the solution at Sirivy's Weblog
or define CXXFLAGS=-D__STDC_CONSTANT_MACROS before you configure.

export CXXFLAGS=-D__STDC_CONSTANT_MACROS;./configure --with-libarch=lib64 --with-mysql=/usr --with-ffmpeg=/usr --with-webdir=/usr/share/zoneminder/www --with-webhost=zm.webarts.bc.ca --with-cgidir=/usr/libexec/zoneminder/cgi-bin --with-extralibs="-lfreetype -lmp3lame -lopenjpeg -lrtmp  -lspeex -ltheora -lvorbis -lvorbisenc -lx264 -lfaac -lgsm -lopenjpeg -lv4l2 -lpulse -lxvidcore -L/usr/lib "

Another error in the config.log
fatal error: pcre/pcre.h: No such file or directory
Easy to fix.
Make sure you have the pcre-devel package installed ( sudo yum install pcre*) then
because the latest pcre packkage installs the *.h files right into /usr/include while ZM is looking in /usr/include/pcre
cd /usr/include;sudo mkdir pcre; cd pcre; sudo ln -s ../pcre.h; sudo ln -s ../pcrecpp.h; sudo ln -s ../pcrecpparg.h; sudo ln -s ../pcreposix.h; sudo ln -s ../pcre_stringpiece.h; sudo ln -s ../pcre_scanner.h

now the build...

More errors:
error: ‘sws_freeContext’ was not declared in this scope
error: ‘av_open_input_file’ was not declared in this scope
I suspect that these are macro defines in ffmpeg somewhere so I did a search in the ffmpeg source and confirmed.
So... This is telling me that ZM is not finding the libavfomat and other libav* headers.
Maybe because ZM did not get configured correctly to set the right DEFINEs for
  • HAVE_LIBAVCODEC,
  • HAVE_LIBAVUTIL_AVUTIL_H,
  • HAVE_LIBAVCODEC_AVCODEC_H,
  • HAVE_LIBAVFORMAT_AVFORMAT_H,
  • HAVE_LIBSWSCALE,
  • HAVE_LIBSWSCALE_SWSCALE_H
See zm_ffmpeg.h included from zm_ffmpeg_camera.h

In zm_ffmeg.h in addition to the checks for the above flags
I added
#include <ffmpeg/libavutil/avutil.h>
#include <ffmpeg/libavcodec/avcodec.h>
#include <ffmpeg/libavformat/avformat.h>
#include <libswscale/swscale.h>

Now to find out why?? back to the config.log

I see I had not set the --prefix=/usr on the configure command-line
So try again with:

export CXXFLAGS=-D__STDC_CONSTANT_MACROS;./configure --prefix=/usr --with-extralibs=-L/usr/lib --with-libarch=lib64 --with-mysql=/usr --with-ffmpeg=/usr --with-webdir=/usr/share/zoneminder/www --with-webhost=zm.webarts.bc.ca --with-cgidir=/usr/libexec/zoneminder/cgi-bin --with-extralibs="-lfreetype -lmp3lame -lopenjpeg -lrtmp  -lspeex -ltheora -lvorbis -lvorbisenc -lx264 -lfaac -lgsm -lopenjpeg -lv4l2 -lpulse"

now only this error
error: ‘av_open_input_file’ was not declared in this scope
search ffmpeg source again to find out whats up...
av_open_input_file WAS defined in ffmpeg avformat.h and deprecated in 2011-06-16
See http://ffmpeg.org/doxygen/trunk/deprecated.html

It is now removed in the latest version of ffmpeg
so this is a bit more trouble

The ffmpeg docs for that say it's deprecated and you should use avformat_open_input instead.

so I changed line 94 of zm_ffmpeg_camera.cpp
  from
if ( av_open_input_file( &mFormatContext, mPath.c_str(), NULL, 0, NULL ) !=0 )
  to
if ( avformat_open_input( &mFormatContext, mPath.c_str(), NULL, NULL ) !=0 )

make now gets through to zm_mpeg.cpp
and gives me these errors
In member function ‘void VideoStream::SetParameters()’:
zm_mpeg.cpp:133:34: error: ‘av_set_parameters’ was not declared in this scope
zm_mpeg.cpp: In member function ‘void VideoStream::OpenStream()’:
zm_mpeg.cpp:179:8: warning: ‘int avcodec_open(AVCodecContext*, AVCodec*)’ is deprecated (declared at /usr/include/ffmpeg/libavcodec/avcodec.h:3380) [-Wdeprecated-declarations]
zm_mpeg.cpp:179:29: warning: ‘int avcodec_open(AVCodecContext*, AVCodec*)’ is deprecated (declared at /usr/include/ffmpeg/libavcodec/avcodec.h:3380) [-Wdeprecated-declarations]
zm_mpeg.cpp:225:38: error: ‘URL_WRONLY’ was not declared in this scope
zm_mpeg.cpp:244:21: error: ‘av_write_header’ was not declared in this scope
zm_mpeg.cpp: In member function ‘double VideoStream::EncodeFrame(uint8_t*, int, bool, unsigned int)’:
zm_mpeg.cpp:340:102: error: ‘img_convert’ was not declared in this scope

Maybe
replace it with...
ffmpeg changelog states...
+#if FF_API_FORMAT_PARAMETERS
+/**
+ * @deprecated pass the options to avformat_write_header directly.
+ */
+attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
+#endif
So I did a like-for-like replacement of
av_set_parameters
with
avformat_write_header
in zm_mpeg.cpp

Now an error about URL_WRONLY
it has been replaced with AVIO_FLAG_WRITE


Now ffmpeg  img_convert has been replaced with sws_scale as described in http://dranger.com/ffmpeg/tutorial08.html

Compile now succeeds!

Onto the linking...
error:  can't find avcore
 the ffmpeg library libavcore got merged into libavutil  so the '-lavcore' can be removed from the LIBS in a;l the Makefiles
It should be removed during the configure step.

Now
undefined reference to symbol 'vorbis_encode_setup_managed'
/usr/lib64/libvorbisenc.so.2: could not read symbols: Invalid operation

I had NOT included all the libavformat required libraries on the zm extralibs option
go to where you built ffmpeg and look into the config.mak
 
more ../ffmpeg-0.11.1/config.mak
and look for the line that has
EXTRALIBS=-ldl -lXfixes -lXext -lX11 -lxvidcore -lx264 -lvpx -lvpx -lvorbisenc -lvorbis -logg -lv4l2 -ltheoraenc -ltheoradec -logg -lspeex -lpulse-simple -lpulse -lopenjpeg -lmp3lame -lgsm -lfaac -lm -pthread -lbz2 -lz -lrt
copy that to your zm configure --with-extralibs option

So my final configure command is:
export CXXFLAGS=-D__STDC_CONSTANT_MACROS;./configure --prefix=/usr --with-libarch=lib64 --with-mysql=/usr --with-ffmpeg=/usr --with-webdir=/usr/share/zoneminder/www --with-webhost=zm.webarts.bc.ca --with-cgidir=/usr/libexec/zoneminder/cgi-bin  --with-extralibs="-lfreetype -lmp3lame -lopenjpeg -lrtmp  -lspeex -ltheora -ltheoraenc -ltheoradec   -lvorbis -lx264 -lfaac -lgsm -lopenjpeg -lv4l2 -lpulse -lvorbisenc -lxvidcore -logg -lvpx -lX11 -lXfixes -lpulse-simple -lm -ldl -lbz2 -lz -lrt"

Success
!

Back some things up.
  • sudo cp /etc/zm.conf /etc/zm-1.24.4.conf
  • backed up my mySql  zm db using MySQL  Workbench

Now on to installing and testing

Stop zoneminder

/etc/init.d/zoneminder stop

install 1.25.0

sudo make install

sudo /usr/bin/zmupdate.pl --user=yourMySqlUserForZm --pass=yourMySqlZmPassword --version=1.24.4
this saves a new zm.conf into the current dir, so I updated its contents with my specifics for path dirs and user/passwords
I put it into /etc/zm.conf

Start it up!
 /etc/init.d/zoneminder start

Some things like the logging is new with a few new options.

FC15 has a version of php that causes issues.
I had to put this in my /etc/httpd/conf.d/zoneminder
Note lines 5 and 6
    Alias /zm "/usr/share/zoneminder/www"
    <Directory "/usr/share/zoneminder/www">
        Options FollowSymLinks
        AllowOverride All
        # The code unfortunately uses short tags in many places
        php_value short_open_tag 1

    </Directory>

        # My original had /cgi-bin/  with an erroneous trailing '/'  that caused many hours of searching.
    ScriptAlias /cgi-bin "/usr/libexec/zoneminder/cgi-bin"
    <Directory "/usr/libexec/zoneminder/cgi-bin">
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        AllowOverride All
    </Directory>

    # Use the first option to have Apache logs written to the general log
    # directory, or the second to have them written to the regular Apache
    # directory (you may have to change the path to that used on your system)
    ErrorLog /var/log/zm/apache-error.log
#    ErrorLog /var/log/httpd/zm-error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    # Use the first option to have Apache logs written to the general log
    # directory, or the second to have them written to the regular Apache
    # directory (you may have to change the path to that used on your system)
    CustomLog /var/log/zm/apache-access.log combined


socket_sendto error

The Existing cameras seem to work and record events BUT no streaming of the video view in my browser?
Error is
socket_sendto( /tmp/zm/zms-515613s.sock ) failed: No such file or directory
/tmp/zm owner is apache:apache
I changed rwx for guo
still fail

I confirmed httpd is running as apache and my /etc/zm.conf has apache/apache set as user

All dirs in /usr/share/zoneminder/www are owned by apache:apache
Hmmm what else??
I think this is a php issue.

NOPE, I Fixed it!
It was my ScriptAlias for the cgi-bin directory
I had an extra / .

Here is the working copy of /etc/http/conf.d/zoneminder.conf

Alias /zm "/usr/share/zoneminder/www"
    <Directory "/usr/share/zoneminder/www">
        Options FollowSymLinks
        AllowOverride All
        # The code unfortunately uses short tags in many places
        php_value short_open_tag 1
    </Directory>

    ScriptAlias /cgi-bin "/usr/libexec/zoneminder/cgi-bin"
    <Directory "/usr/libexec/zoneminder/cgi-bin">
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        AllowOverride All
        # The code unfortunately uses short tags in many places
        php_value short_open_tag 1
    </Directory>

    # Use the first option to have Apache logs written to the general log
    # directory, or the second to have them written to the regular Apache
    # directory (you may have to change the path to that used on your system)
    ErrorLog /var/log/zm/apache-error.log
#    ErrorLog /var/log/httpd/zm-error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    # Use the first option to have Apache logs written to the general log
    # directory, or the second to have them written to the regular Apache
    # directory (you may have to change the path to that used on your system)
    CustomLog /var/log/zm/apache-access.log combined




Comments