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

Post date: Aug 7, 2012 2:57:04 AM

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
ZM Config Dialog - Source 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