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 phpsocket_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
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.
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?
- build ffmpeg 1st without libx264
- then build x264
- then rebuild ffmpeg with libx264
- 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