Module: CSD::Application::Minisip::Component::Core

Extended by:
Packaging
Defined in:
lib/csd/application/minisip/component/core.rb,
lib/csd/application/minisip/component/core_packaging.rb

Overview

This MiniSIP component is the very minisip source code itself.

Defined Under Namespace

Modules: Packaging

Constant Summary collapse

LIBRARIES =

This is an Array containing the names of the internal MiniSIP libraries. Note that they are sorted according to the sequence in which they need to be compiled (because they depend on each other).

%w{ libmutil libmnetutil libmcrypto libmikey libmsip libmstun libminisip minisip mloggingutil }

Class Method Summary collapse

Methods included from Packaging

build_package, extract_tar_file, make_dist, package, package!, packing_introduction

Class Method Details

.bootstrapObject

This method runs the ‘bootstrap´ command in the current directory unless –no-bootstrap was given. It is only used for the internal MiniSIP libraries.



259
260
261
# File 'lib/csd/application/minisip/component/core.rb', line 259

def bootstrap
  bootstrap! if Options.bootstrap
end

.bootstrap!Object

This method forces running the ‘bootstrap´ command in the current directory. It is only used for the internal MiniSIP libraries.



266
267
268
269
270
271
272
# File 'lib/csd/application/minisip/component/core.rb', line 266

def bootstrap!
  if Options.this_user
    Cmd.run(%Q{./bootstrap -I "#{Path.build_share_aclocal}"})
  else
    Cmd.run("./bootstrap")
  end
end

.checkoutObject

This method downloads the minisip source code in the right version. If the Options.branch parameter is set to a branchname of the source code repository, that branch will be downloaded. Currently this function uses the intermediary Github repository to make sure that

  • the downloaded version is not a risky cutting-edge trunk

  • the download works even if the vendor’s repository is down (again)

That means that the Github repository (or any other intermediary repository) should be manually updated by an TTA AI developer, after having made sure that that source code version is working properly.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/csd/application/minisip/component/core.rb', line 106

def checkout
  # The untested version from the vendor was requested
  return checkout_from_vendor if Options.vendor
  Cmd.git_clone 'MiniSIP repository', 'http://github.com/csd/minisip.git', Path.repository
  # Note that the command above will checkout the master branch.
  # In that case we are not allowed to checkout the master branch again.
  if Options.branch and Options.branch != 'master'
    Cmd.cd Path.repository, :internal => true
    Cmd.run "git checkout -b #{Options.branch} origin/#{Options.branch}"
  end
  UI.info "Initializing any optional git submodules".green.bold
  Cmd.cd Path.repository, :internal => true
  Cmd.run 'git submodule init'
  Cmd.run 'git submodule update'
end

.checkout_from_vendorObject

The method downloads MiniSIP source code from official SVN repository. If the Options.vendor parameter is set, AI will not use the default git repository and use SVN to download the source code of MiniSIP.



126
127
128
129
# File 'lib/csd/application/minisip/component/core.rb', line 126

def checkout_from_vendor
  Cmd.cd Path.work, :internal => true
  Cmd.run "svn checkout svn://svn.minisip.org/minisip/trunk minisip"
end

.compileObject

This method processes the MiniSIP Core component and does everything needed for compiling it. Note that it is not responsible for checking depenencies here. It will just focus on compiling the internal MiniSIP libraries.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/csd/application/minisip/component/core.rb', line 28

def compile
  UI.debug "#{self}.compile was called"
  UI.debug "The current Options are: #{::CSD.options.inspect_for_debug}"
  remove_ffmpeg
  if Path.repository.directory? and !Options.reveal
    UI.warn "The MiniSIP source code will not be downloaded, because the directory #{Path.repository.enquote} already exists."
  else
    checkout
    modify_source_code
  end
  modify_dirlist
  compile_libraries # We would like to re-compile MiniSIP no matter what options were given as command-line arguments.
  link_libraries
  create_address_book
  ensure_ati_vsync
  update_decklink_firmware
end

.compile_librariesObject

Iteratively processes the internal MiniSIP libraries (bootstrap, configure, make, make install).



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/csd/application/minisip/component/core.rb', line 227

def compile_libraries
  create_build_dir
  UI.debug "MILESTONE_processing_libraries"
  libraries.each do |library|
    directory = Pathname.new(File.join(Path.repository, library))
    # The mloggingutil is more or less optional because it might not be checked in as of today yet
    next if !directory.directory? and library == 'mloggingutil'
    if Cmd.cd(directory, :internal => true).success? or Options.reveal
      UI.debug "MILESTONE_processing_#{library}"
      UI.info "Processing MiniSIP -> #{library}".green.bold
      bootstrap
      configure library
      make
      make_install
    else
      UI.warn "Skipping MiniSIP library #{library} because it could not be found in #{directory.enquote}"
    end
  end
end

.configure(name = '') ⇒ Object

This method runs the ‘configure´ command in the current directory unless –no-configure was given. It is only used for the internal MiniSIP libraries.



277
278
279
# File 'lib/csd/application/minisip/component/core.rb', line 277

def configure(name='')
  configure! name if Options.configure
end

.configure!(name = '') ⇒ Object

This method forces running the ‘configure´ command in the current directory. It is only used for the internal MiniSIP libraries. If enable_debug option is set, the configuration option will include “–enable-debug”, except for the default options. If blank_minisip_configuration option is set, the configuration option will be blank. For example, this option will be used during the i2conf server setting-up procedure.



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/csd/application/minisip/component/core.rb', line 287

def configure!(name='')
  individual_options = case name
    when 'libminisip'
      %Q{--enable-video --enable-opengl --disable-mil --enable-decklink --disable-sdl #{libminisip_cpp_flags} #{libminisip_ld_flags}}
    when 'minisip'
      %Q{--enable-video --enable-opengl --enable-textui}
    else
      ''
  end
  # The --enable-debug option should only be there if specifically requested
  debug_options = '--enable-debug' if Options.enable_debug or debug_libraries.include?(name)
  # These options are used by all libraries
  common_options = %Q{--prefix="#{Path.build}" PKG_CONFIG_PATH="#{Path.build_lib_pkg_config}" ACLOCAL_FLAGS="#{Path.build_share_aclocal}" LD_LIBRARY_PATH="#{Path.build_lib}"} if Options.this_user
  # I2conf needs to compile MiniSIP without any options
  individual_options = nil if Options.blank_minisip_configuration
  # Putting it all together
  Cmd.run ['./configure', common_options, debug_options, individual_options].compact.join(' ')
end

.create_address_bookObject

The method create default MiniSIP phonebook for MiniSIP. The default phonebook is derived from carenet-se scenario, users can modify it in MiniSIP GUI after MiniSIP successfully installed.



353
354
355
356
357
358
359
# File 'lib/csd/application/minisip/component/core.rb', line 353

def create_address_book
  return unless !Path.phonebook.file? or ::CSD::Application::Minisip::OUTDATED_PHONEBOOKS.include?(File.read(Path.phonebook).hashed)
  UI.info "Creating default MiniSIP phonebook".green.bold
  Cmd.mkdir Path.phonebook_dir
  Cmd.touch_and_replace_content Path.phonebook, ::CSD::Application::Minisip::PHONEBOOK_EXAMPLE, :internal => true
  UI.info "  Phonebook successfully saved in #{Path.phonebook}".yellow
end

.create_build_dirObject

Creates all build directories such as lib, share, bin, etc.



249
250
251
252
253
254
# File 'lib/csd/application/minisip/component/core.rb', line 249

def create_build_dir
  # In sudo mode, we don't need to create these. They already exist in the OS.
  return unless Options.this_user
  UI.info "Creating target build directories".green.bold
  [Path.build, Path.build_include, Path.build_lib, Path.build_share, Path.build_share_aclocal].each { |target| Cmd.mkdir target }
end

.debug_librariesObject

Determines which libraries of MiniSIP should be configured using –enable-debug



93
94
95
96
# File 'lib/csd/application/minisip/component/core.rb', line 93

def debug_libraries
  return LIBRARIES if Options.enable_debug
  LIBRARIES.map { |lib| lib if Options.enable_debug_on.to_a.include?(lib) }.compact
end

.ensure_ati_vsyncObject

This method is agreeably a little bit out of place. Because this technically should happen whenever the graphic card drivers are installed and not when MiniSIP is installed. However, the AI is not present when the graphic card drivers are installed (because then X11 is booted down and the AI process is replaced by the proprietary ATI or nVidia installation process). So we better make sure at this point, that the vertical synching for ATI graphic cards is switched on.

The reason why we want this is because otherwise we will have vertical lines in the video. It is commonly referred to as “teared images” and is caused by the monitor having a Hertz rate of 60Hz, while OpenGL has a rate of about 400Hz. So the screen picture might be refreshed by OpenGL while the monitor is doing his own refresh. This will result in a horizontal line on the screen. When they are synchronized, OpenGL will be reduced to about 59Hz and the video will be clear. This information was obtained by Erik, the vendor of MiniSIP.



374
375
376
377
378
379
# File 'lib/csd/application/minisip/component/core.rb', line 374

def ensure_ati_vsync
  # Return if no ATI drivers are installed
  return unless Path.catalyst_config.file?
  UI.info "Ensuring AMD vertical synchronization between OpenGL and Monitor".green.bold
  Cmd.run "sudo aticonfig --set-pcs-u32=BUSID-2:0:0-0/OpenGL,VSyncControl,2", :announce_pwd => false
end

.introductionObject

This method provides upfront information to the user about how the MiniSIP Core component will be processed.



74
75
76
77
78
79
80
81
82
# File 'lib/csd/application/minisip/component/core.rb', line 74

def introduction
  UI.info " MiniSIP".green.bold
  # If the repository directory already exists, we indicate that here
  download_text = Path.repository.directory? ? "  - located at:           " : "  - downloading to:       "
  UI.info download_text.green + Path.repository.to_s.yellow
  # Now let's present which libraries will be compiled with which commands
  UI.info "  - libraries to process: ".green + libraries.join(', ').yellow
  UI.info "  - with these commands:  ".green + [('bootstrap' if Options.bootstrap), ('configure' if Options.configure), ('make' if Options.make), ('make install' if Options.make_install)].compact.join(', ').yellow
end

.libminisip_cpp_flagsObject

The method holds the CPPFLAGS value, where MiniSIP make process is needed. CPPFLAGS is for compiler to find the libraries and their header files. When force_ffmpeg option is set, the value of CPPFLAGS will also includes the path to related FFmpeg libraries.



210
211
212
213
214
215
216
# File 'lib/csd/application/minisip/component/core.rb', line 210

def libminisip_cpp_flags
  if Options.ffmpeg_first
    %{CPPFLAGS="-I#{Path.hdviper_x264} -I#{Path.hdviper_x264_test_x264api} -I#{Path.ffmpeg_libavutil} -I#{Path.ffmpeg_libavcodec} -I#{Path.ffmpeg_libswscale} -I#{Path.repository_grabber} -I#{Path.repository_decklinksdk}"}
  else
    %{CPPFLAGS="-I#{Path.hdviper_x264} -I#{Path.hdviper_x264_test_x264api} -I#{Path.repository_grabber} -I#{Path.repository_decklinksdk}"}
  end
end

.libminisip_ld_flagsObject

The method holds the LDFLAGS value, where MiniSIP make process is needed. CPPFLAGS is for linker to find the libraries and their header files.



221
222
223
# File 'lib/csd/application/minisip/component/core.rb', line 221

def libminisip_ld_flags
  %{LDFLAGS="#{Path.hdviper_libx264api} #{Path.hdviper_libtidx264} -lpthread -lrt"}
end

.librariesObject

Determines which libraries of MiniSIP should be processed, because the –only parameter might be set by the user, requesting for only a subset of the libraries.



87
88
89
# File 'lib/csd/application/minisip/component/core.rb', line 87

def libraries
  Options.only ? LIBRARIES.map { |lib| lib if Options.only.to_a.include?(lib) }.compact : LIBRARIES
end

The method links shared MiniSIP libraries by ldconfig command. ldconfig determines run-time linkbindings between ld.so and shared libraries. It scans a running system and sets up the symbolic links that are used to load shared libraries properly.



200
201
202
203
204
# File 'lib/csd/application/minisip/component/core.rb', line 200

def link_libraries
  return if Options.this_user
  UI.info "Linking shared MiniSIP libraries".green.bold
  Cmd.run "sudo ldconfig #{Path.build_lib_libminisip_so}", :announce_pwd => false
end

.makeObject

This method runs the ‘make´ command in the current directory unless –no-make was given. It is only used for the internal MiniSIP libraries.



309
310
311
# File 'lib/csd/application/minisip/component/core.rb', line 309

def make
  make! if Options.make
end

.make!Object

This method forces running the ‘make´ command in the current directory. It is only used for the internal MiniSIP libraries. AI uses “-j 15” option of make command to speed up the make process.



317
318
319
# File 'lib/csd/application/minisip/component/core.rb', line 317

def make!
  Cmd.run "make -j #{Options.threads}"
end

.make_installObject

This method runs the ‘make install´ command in the current directory unless –no-make-install was given. It is only used for the internal MiniSIP libraries.



324
325
326
# File 'lib/csd/application/minisip/component/core.rb', line 324

def make_install
  make_install! if Options.make_install
end

.make_install!Object

This method forces running the ‘make install´ command in the current directory. It is only used for the internal MiniSIP libraries.



331
332
333
334
335
336
337
# File 'lib/csd/application/minisip/component/core.rb', line 331

def make_install!
  if Options.this_user
    Cmd.run("make install")
  else
    Cmd.run("sudo make install")
  end
end

.modify_dirlistObject

Usually, Ubuntu ignores /usr/local/share/aclocal. So we need to create a file called dirlist in /usr/share/aclocal which contains the path to the other directory.



186
187
188
189
190
191
192
193
194
# File 'lib/csd/application/minisip/component/core.rb', line 186

def modify_dirlist
  Path.dirlist = Pathname.new File.join('/', 'usr', 'share', 'aclocal', 'dirlist')
  if !Path.dirlist.file? and Gem::Platform.local.debian? or Options.reveal
    UI.info "Fixing broken Debian aclocal path".green.bold
    Path.new_dirlist = Pathname.new File.join(Path.work, 'dirlist')
    Cmd.touch_and_replace_content Path.new_dirlist, '/usr/local/share/aclocal'
    Cmd.run "sudo mv #{Path.new_dirlist} #{Path.dirlist}", :announce_pwd => false
  end
end

.modify_libminisip_rulesObject

The method fixes libminisip Debian rules file.



174
175
176
177
178
179
180
181
# File 'lib/csd/application/minisip/component/core.rb', line 174

def modify_libminisip_rules
  if Path.repository_libminisip_rules_backup.file?
    UI.warn "The libminisip rules seem to be fixed already, I won't touch them now. Delete #{Path.repository_libminisip_rules_backup.enquote} to enforce it."
  else
    Cmd.copy Path.repository_libminisip_rules, Path.repository_libminisip_rules_backup
    Cmd.replace Path.repository_libminisip_rules, 'AUTOMATED_INSTALLER_PLACEHOLDER=""', [libminisip_cpp_flags, libminisip_ld_flags].join(' ')
  end
end

.modify_source_codeObject

Some places in the MiniSIP source code have to be modified before MiniSIP can be compiled.

  • An absolute path must be replaced with the current absolute prefix path in libminisip/source/subsystem_media/video/display/OpenGLDisplay.cxx

  • The .minisip.conf configuration file generated by MiniSIP has a SIP proxy server by default. The configuration key is $proxy_addr$ and the value is $sip.domain.example$. We modify the source code file responsible for generating the default configuration file, so that it will not fill in a SIP proxy server by default. The reason is that during compilation there is no .minisip.conf file that we could edit! So we go for the source.

  • Modifications of some constants will be done, because this is more compatible with the most recent FFmpeg version. In fact, MiniSIP won’t compile if FFmpeg is present and this has not been modified. See www.howgeek.com/2010/03/01/ffmpeg-php-error-‘pix_fmt_rgba32’-undeclared-first-use-in-this-function and ffmpeg.org/doxygen/0.5/pixfmt_8h.html#33d341c4f443d24492a95fb7641d0986 for more information about the FFmpeg pixel format constants.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/csd/application/minisip/component/core.rb', line 145

def modify_source_code
  UI.info "Fixing MiniSIP OpenGL GUI source code".green.bold
  # Replacing the hardcoded path in the OpenGLDisplay.cxx
  Cmd.replace Path.repository_open_gl_display, /\tstring path = "(.+)"\+/, %{\tstring path = "#{Path.build}"+}
  UI.info "Modifying default MiniSIP configuration parameters".green.bold
  # Removing the default SIP proxy server from the Configuration generator
  Cmd.replace Path.repository_sip_conf, 'sip.domain.example', ''
  # We would like decklink to be the default video device
  Cmd.replace Path.repository_sip_conf, 'be->commit();', %{
    be->save("video_device", "decklink:0/720p50@25");
    be->save("display_frame_size", "hd720");
    be->save("display_frame_rate", "24");
    be->commit();
  }
  # Switching logging to ON as default, as opposed to OFF
  Cmd.replace Path.repository_sip_conf, 'be->saveBool("logging",false)', 'be->saveBool("logging",true)'
  if Options.ffmpeg_first
    UI.info "Fixing MiniSIP Audio/Video en/decoder source code".green.bold
    Cmd.replace Path.repository_avcoder_cxx,   'PIX_FMT_RGBA32', 'PIX_FMT_RGB32'
    Cmd.replace Path.repository_avdecoder_cxx, 'PIX_FMT_RGBA32', 'PIX_FMT_RGB32'
  end
  # Changing MiniSIP HELP Version text
  repository_name = Options.vendor ? 'SVN repository' : "Github (#{Options.branch})"
  Cmd.replace Path.repository_main_window, '(VERSION)', %{("#{repository_name} via AI #{CSD::Version.gsub("\n", '')}")}
  modify_libminisip_rules
end

.remove_ffmpegObject

The method removes FFmpeg, if FFmpeg is already installed in the system before MiniSIP compilation. This is because MiniSIP use HDViper as its H.264 encoder, while HDviper use modified FFmpeg library within it. This may cause conflict with original FFmpeg library. The solution to that is to remove FFmpeg before MiniSIP compilation and install it again after completion of MiniSIP compilation process. However,if the user set the option “–force-ffmpeg”, AI will skip the process, even though FFmpeg may have been installed in the system. Currently, FFmpeg must have been installed via apt-get or via the AI in order for this to work, because manual compilations of FFmpeg cannot be removed automatically.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/csd/application/minisip/component/core.rb', line 55

def remove_ffmpeg
  ffmpeg_available = Cmd.run('ffmpeg -h', :internal => true, :die_on_failure => false).success?
  return if Options.ffmpeg_first or !libraries.include?('libminisip') or !ffmpeg_available
  UI.debug "MILESTONE_removing_ffmpeg"
  if Gem::Platform.local.debian?
    # Note that FFmpeg must have been installed via apt-get or via the AI in order for this to work,
    # because manual compilations of FFmpeg cannot be removed automatically
    UI.info "Removing FFmpeg before re-compiling MiniSIP".green.bold
    UI.info "You can skip this step by giving the option --force-ffmpeg".yellow
    Cmd.run "sudo apt-get remove ffmpeg --yes", :announce_pwd => false
  else
    # On other linux distributions we don't know how to remove ffmpeg
    UI.debug "MILESTONE_cannot_remove_ffmpeg"
    raise Error::Minisip::Core::FFmpegInstalled, "Please remove ffmpeg from your system first, or run the #{CSD.executable} with --no-configure" unless Options.testmode
  end
end

.run_gtkguiObject

Execute the MiniSIP GTK GUI.



341
342
343
344
345
346
347
348
# File 'lib/csd/application/minisip/component/core.rb', line 341

def run_gtkgui
  UI.info "Executing MiniSIP".green.bold
  if Options.this_user
    Cmd.run Path.build_gtkgui, :die_on_failure => false, :announce_pwd => false
  else
    Cmd.run 'minisip_gtkgui', :die_on_failure => false, :announce_pwd => false
  end
end

The method updates Decklink Firmware (if needed).



383
384
385
386
# File 'lib/csd/application/minisip/component/core.rb', line 383

def update_decklink_firmware
  UI.info "Updating Decklink Firmware (if needed)".green.bold
  Cmd.run "BlackmagicFirmwareUpdater update", :announce_pwd => false, :die_on_failure => false
end