Compiling PJSIP with Video and Audio on the Raspberry Pi 3 RPI Camera Module - acrossi/raspberry-pi-stuff GitHub Wiki

These are the steps I used to get PJSIP running on a Raspberry Pi 3 with audio and video. Strap in.

Flash an SD Card with Raspian Stretch. I used the latest at the time of this writing (2018-03-13-raspian-stretch): Download Raspian Stretch

  • Log in as user pi and update:
$ sudo apt-get update
$ sudo apt-get dist-upgrade
  • Run the raspi-config utility and set timezone, local, keyboard, ssh, expand filesystem, etc. Most importantly, enable the camera.

  • Reboot

  • Test the camera:

$ sudo modprobe bcm2835-v4l2
$ v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=3
$ v4l2-ctl --stream-mmap=3 --stream-count=1 --stream-to=test1.jpg
  • Build and install SDL. I used 2-2.0.8 (latest at time of writing)
$ sudo apt-get install libasound2-dev
$ sudo apt-get install libasound2-doc
$ sudo apt-get update
$ sudo apt-get install libssl-dev
$ wget https://www.libsdl.org/release/SDL2-2.0.8.tar.gz
$ tar xvfz SDL2-2.0.8.tar.gz
$ cd SDL2-2.0.8/
$ ./configure
$ make
$ sudo make install
  • Build and Install OpenH264
$ git clone https://github.com/cisco/openh264.git
$ cd openh264
$ make
$ sudo make install
  • Install libfaac, libmp3lame, libvorbis, other (non-free) codecs:

Add the following line to the /etc/apt/sources.list file:

deb http://www.deb-multimedia.org/ stretch main non-free rpi

Now install the packages:

$ sudo apt-get update -oAquire::AllowInsecureRepositories=true
$ sudo apt-get install deb-multimedia-keyring -oAquire::AllowInsecureRepositories=true
$ sudo apt-get update
$ sudo apt-get install lame libfaac-dev libmp3lame-dev libvorbis-dev libopencore-amrwb-dev libtheora-dev libx11-dev libfdk-aac-dev libopencore-amrnb-dev
  • Build and Install FFMPEG (3.4.2 at the time of this writing). You are going to want to go out and climb a tree, read a book, or drink a few cups of coffee at this point.
$ wget https://ffmpeg.org/releases/ffmpeg-3.4.2.tar.bz2
$ tar xvfj ffmpeg-3.4.2.tar.bz2
$ cd ffmpeg-3.4.2/
$ ./configure --enable-shared --disable-static --enable-gpl --enable-libx264 --enable-nonfree --enable-libmp3lame --enable-libfdk-aac --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-version3 --enable-libxcb --enable-libopenh264 --arch=armv8 --cpu=cortex-a53
$ make
$ sudo make install
  • Build and install PJSIP (2.7.2 release at the time of this writing)
$ sudo apt-get install automake autoconf libtool libsamplerate0-dev libspeexdsp-dev libspeex-dev libcelt-dev libzrtpcpp-dev libccrtp-dev libasound2-dev libdbus-c++-dev libgsm1-dev opus-tools libopus-dev libpcre3-dev libcommoncpp2-dev libdbus-1-dev libyaml-dev libv4l-dev libvo-amrwbenc-dev

$ wget http://www.pjsip.org/release/2.7.2/pjproject-2.7.2.tar.bz2
$ tar xvfj pjproject-2.7.2.tar.bz2 
$ cd pjproject-2.7.2/

Create a new file called pjlib/include/pj/config_site.h

$ vi pjlib/include/pj/config_site.h

with the following contents:

#define PJMEDIA_AUDIO_DEV_HAS_ALSA      1
#define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
#define PJMEDIA_HAS_VIDEO       1

Create a file called 'user.mak' in the root of the pjsip source directory:

$ vi user.mak

with the following contents (note: these are specific to the RPI3)

export CFLAGS += -march=armv8-a -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mlittle-endian -munaligned-access -ffast-math
export LDFLGS +=

There is a bug in the build script that you must correct, as the system tries to compile sse2 support which is not available on the RPI. Edit the 'third-party/build/os-auto.mak.in':

$ vi third_party/build/os-auto.mak.in

Copy over the following block (note the comments, which force the build system to skip sse2):

ifneq (@ac_no_webrtc@,1)
ifeq (@ac_external_webrtc@,1)
# External webrtc
else
DIRS += webrtc
WEBRTC_OTHER_CFLAGS = -fexceptions -DWEBRTC_POSIX=1 @ac_webrtc_cflags@
#ifneq ($(findstring sse2,@ac_webrtc_instset@),)
#    WEBRTC_SRC = \
#             modules/audio_processing/aec/aec_core_sse2.o               \
#             modules/audio_processing/aec/aec_rdft_sse2.o               \
#             modules/audio_processing/aecm/aecm_core_c.o                \
#             modules/audio_processing/ns/nsx_core_c.o                   \
#             system_wrappers/source/cpu_features.o
#else ifneq ($(findstring neon,@ac_webrtc_instset@),)
    WEBRTC_SRC = \
              modules/audio_processing/aec/aec_core_neon.o               \
              modules/audio_processing/aec/aec_rdft_neon.o               \
              modules/audio_processing/aecm/aecm_core_c.o                \
              modules/audio_processing/aecm/aecm_core_neon.o             \
              modules/audio_processing/ns/nsx_core_c.o                   \
              modules/audio_processing/ns/nsx_core_neon.o                \
              common_audio/signal_processing/cross_correlation_neon.o    \
              common_audio/signal_processing/downsample_fast_neon.o      \
              common_audio/signal_processing/min_max_operations_neon.o
    WEBRTC_OTHER_CFLAGS += -DWEBRTC_HAS_NEON
#else ifneq ($(findstring mips,@ac_webrtc_instset@),)
#    WEBRTC_SRC = \
#              modules/audio_processing/aec/aec_core_mips.o               \
#             modules/audio_processing/aec/aec_rdft_mips.o               \
#             modules/audio_processing/aecm/aecm_core_mips.o             \
#             modules/audio_processing/ns/nsx_core_mips.o                \
#             common_audio/signal_processing/cross_correlation_mips.o    \
#             common_audio/signal_processing/downsample_fast_mips.o      \
#             common_audio/signal_processing/min_max_operations_mips.o
#
#    WEBRTC_OTHER_CFLAGS += -DMIPS_FPU_LE
#else # Generic fixed point
#    WEBRTC_SRC = \
#             modules/audio_processing/aecm/aecm_core_c.o                \
#             modules/audio_processing/ns/nsx_core_c.o                   \
#             common_audio/signal_processing/complex_fft.o
#endif
endif
endif

Now make PJSIP:

$ ./configure
$ make dep
$ make

Note: I had a compile error during make dep, probably due to the fact that I was missing dependencies and went back and added some additional packages. If you are following these instructions, you should be ok. However, if you have errors, try the following:

$ make clean
$ make distclean
$ make realclean
$ find . -name "*.depend" -exec rm {} \;
$ ./configure
$ make dep
$ make

Now you can find the index of your audio and video devices by executing some sample apps. Find the index of your audio out and in devices

$ cd pjproject-2.7.2/pjsip-apps/bin/samples/armv7l-unknown-linux-gnueabihf
$ ./auddemo

Test your video codecs:

$ ./vid_codec_test

Create a configuration file to specify params for the pjsua cli application

$ cd ~/pjproject-2.7.2/pjsip-apps/bin/
$ vi .pjsua-conf

Contents of file:

--stereo
--auto-answer=200
#--duration=60
--color
--capture-dev=8
--playback-dev=8
--local-port=5060
--video
--no-vad
--ec-tail=0
--log-file=pjsualog.log
--log-level=6

Note: I have a USB soundcard device, which shows up as pjsip index 8 in the auddemo app mentioned above. This is the soundcard I am using to interface with a set of speakers and a microphone:

Ugreen USB Soundcard

Thats it! You should be able to make audio calls as well as video calls. Enjoy!