2013/03/19

[工作點滴] process to generate makefile by autotools with Makefile.am

I've search on internet and get quick steps for whole process to generate Makefile by Autotools.

# autoscan .                      // scan the folder
# cp configure.scan configure.ac  // copy the configure.scan to configure.ac
# vi configure.ac                 // edit the configure.ac
                                  // add AM_INIT_AUTOMAKE(hello,1.0) in configure.ac

                                  // this is required marco for automake
# aclocal                         // execute aclocal to generate aclocal.m4
# autoconf                        // execute autoconf to generate configure
# autoheader
# automake --add-missing          // run automake
# touch NEWS; touch README; touch AUTHORS; touch ChangeLog
  // create related documents
# automake --add-missing          // run automake again
# ./configure                     // execute the configure to generate Makefile
# make                            // execute make

According to the steps, I get more hint to modify the related files for my target.

2013/03/18

[工作點滴] gstreamer from 0.10.x to 1.0.x in openwrt

I start to move the gstreamer version from 0.10.x to 1.0.x in openwrt. Two purpose, one is to get much more familiar with the gstreamer applications and plugins development, another one is to assist my colleagues for next schedule. Just make a quick note here.


Official gstreamer packages version I use is 1.0.5:
gstreamer core -> Modify Makefile and patch, compile ok.
- gst-plugins-base -> Modify Makefile and patch, compile ok.
- gst-plugins-good -> Modify Makefile and patch, compile ok.
- gst-plugins-ugly -> To be check if required.
- gst-plugins-bad -> Modify Makefile and patch, compile ok.
- gst-libav -> To be check if required.

Proprietary plugins
- package folder -> Modify the Makefile.
- gst-plugin foler -> Modify the configure.ac
- gst-plugin/src folder -> Modify the Makefile.am
- plugin source
  * GST_BOILERPLATE_FULL is gone, replace by G_DEFINE_TYPE_WITH_CODE
  * add the parent_class definition.
    #if 0
      GST_BOILERPLATE_FULL (GstA5sSrc, gst_a5s_src, GstBaseSrc, GST_TYPE_BASE_SRC, gst_a5s_src_init_interfaces);
    #else
      #define gst_a5s_src_parent_iclass parent_class
      G_DEFINE_TYPE_WITH_CODE (GstA5sSrc, gst_a5s_src, GST_TYPE_BASE_SRC, gst_a5s_src_init_interfaces);
    #endif
  * init funtion parameters is change.
    #if 0
      static void gst_a5s_src_init (GstA5sSrc * a5ssrc, GstA5sSrcClass * a5ssrc_class)
    #else
      static void gst_a5s_src_init (GstA5sSrc * a5ssrc)
    #endif
  * remove the gone already functions.
  * audio: Need lots of works to do.
  * buffer size: replace the GST_BUFFER_SIZE() to gst_buffer_get_size().
  * buffer data: replace the GST_BUFFER_DATA() by using the gst_buffer_map to access the data.

Audio plugins:
- GstRingBufferSpec -> GstAudioRingBufferSpec
- The GstAudioRingBufferSpec has big changes. Lots parameters are re-factored in the GstAudioInfo.
- The GstAudioInfo structure is as follow. The format part is in GstAudioFormatInfo.
  /**
  * GstAudioInfo:
  * @finfo: the format info of the audio
  * @flags: additional audio flags
  * @layout: audio layout
  * @rate: the audio sample rate
  * @channels: the number of channels
  * @bpf: the number of bytes for one frame, this is the size of one
  *         sample * @channels
  * @position: the positions for each channel
  *
  * Information describing audio properties. This information can be filled
  * in from GstCaps with gst_audio_info_from_caps().
  *
  * Use the provided macros to access the info in this structure.
  */
  struct _GstAudioInfo {
    const GstAudioFormatInfo *finfo;
    GstAudioFlags             flags;
    GstAudioLayout            layout;
    gint                      rate;
    gint                      channels;
    gint                      bpf;
    GstAudioChannelPosition   position[64];

    /*< private >*/
    gpointer _gst_reserved[GST_PADDING];
  };
- GstAudioFormatInfo
  /**
  * GstAudioFormatInfo:
  * @format: #GstAudioFormat
  * @name: string representation of the format
  * @description: user readable description of the format
  * @flags: #GstAudioFormatFlags
  * @endianness: the endianness
  * @width: amount of bits used for one sample
  * @depth: amount of valid bits in @width
  * @silence: @width/8 bytes with 1 silent sample
  * @unpack_format: the format of the unpacked samples
  * @unpack_func: function to unpack samples
  * @pack_func: function to pack samples
  *
  * Information for an audio format.
  */
  struct _GstAudioFormatInfo {
    GstAudioFormat format;
    const gchar *name;
    const gchar *description;
    GstAudioFormatFlags flags;
    gint endianness;
    gint width;
    gint depth;
    guint8 silence[8];

    GstAudioFormat unpack_format;
    GstAudioFormatUnpack unpack_func;
    GstAudioFormatPack pack_func;

    /*< private >*/
    gpointer _gst_reserved[GST_PADDING];
  };
- Change the audio/x-raw-int to audio/x-raw for pad template.
- To do list:
  * Check the timestamps mechanism in new alsa plugin example.
  * Check the audio GstAudioRingBufferSpec parameters.

Applications
- gst-rtsp-server
  * execute the autogen.sh and install the required tool to generate necessary files.
  * add the AC_PROG_CXX in configure.ac because our example is cpp based.
  * create patch to make gst-libs/gst/rtsp in gst-plugins-base to be the latest master version.
  * after above patch, the gst-rtsp-server's gst/rtsp-server library could be successfully built.
  * gst_debug_add_log_function() function parameters change from 2 to 3.
    gst_debug_add_log_function(gst_log_function_syslog, NULL, NULL);
  * buffer size: replace the GST_BUFFER_SIZE() to gst_buffer_get_size().
  * buffer data: replace the GST_BUFFER_DATA() by using the gst_buffer_map to access the data.
    GstBuffer *buffer = gst_app_sink_pull_preroll(sink);
    GstMapInfo mapinfo = {0, };
    gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
    /* access the buffer by mapinfo.data and mapinfo.size */
    gst_buffer_unmap(buffer, &mapinfo);
  * g_thread_create remove, use g_thread_new -> check further.
  * gst_app_sink_set_callbacks() -> callbacks structure is change.
  * ways change to handle sink callback functions.
    #if 0
      GstBuffer *buffer = gst_app_sink_pull_preroll(sink);
    #else
      GstSample *sample = gst_app_sink_pull_preroll(sink);
      GstBuffer *buffer = gst_sampe_get_buffer(sample);
    #endif
    #if 0
      GstBuffer *buffer = gst_app_sink_pull_buffer(sink);
    #else
      GstSample *sample = gst_app_sink_pull_sample(sink);
      GstBuffer *buffer = gst_sampe_get_buffer(sample);
    #endif
  * The GstRTSPMediaMapping rename to be GstRTSPMountPoints, we can compare by the examples.
  * gst_rtsp_server_get_media_mapping() become gst_rtsp_server_get_mount_points()
  * gst_rtsp_media_mapping_add_factory() become gst_rtsp_mount_points_add_factory()
  * In configure.ac, remove the WARNING_CFLAGS because some warnings would cause errors.
    #GST_OPTION_CFLAGS="\$(WARNING_CFLAGS) \$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)"
    GST_OPTION_CFLAGS="\$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)"

2013/03/13

[工作點滴] SIP test of Freeswitch by FSClient

In previous articles, I tried to build the pjsip package, but it's hard for me to make sure the package is work correctly because of my lacking knowledge of sip. Then I try to be more familiar with how the sip works. First, prepare a PC and install the switch on it. We have two popular choices, one is Asterisk and another one is Freeswitch. I choose the Freeswitch because there is a precompiled binaries for win7 already.
After installation, remember to allow the application to pass firewall. Because it is just for testing, I execute the Freeswitch with default configuration.
When the switch is done, we could choose the softphones to test. Here are the information of the softphones.
I choose the FSClient on windows 7. 
Set the device configuration.
Add the test account and register to Freeswitch.
Then we can use the FSClient to do the test. More information in the getting started guide.
http://wiki.freeswitch.org/wiki/Getting_Started_Guide


There are some common extensions for testing
1000, 1001, ..., 1019 - Generic SIP extensions
5000 - demo IVR (requires sounds and music files to be installed)
9195 - five second delay echo test
9196 - standard echo test
9197 - milliwatt extension
9198 - tetris extension for demo TGML generation
9664 - music on hold (requires music files to be installed)

It's easy, just dial it.

2013/03/12

[工作點滴] pjsip on ubuntu

Before trying to make the pjsip work on my embedded device, I build the related libraries on PC as the reference. My environment is based Ubuntu 10.04. See the following guide.

The notes of packages building:
- ALSA and OpenSSL libraries are optional and I do not install for first.
- SDL, I download the version 2.0 and do "./configure", "make; make install" to install the package to system. If we encounter privilege problem, please add sudo.
- FFMPEG, please reference the document on FFMPEG official site. The link is as following. https://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuide
There are links for different version of the Ubuntu. We could follow the guide to build yasm, x264 and ffmpeg. The ffmpeg version(0.10.6) and building process is following pjsip guide.
- PJSIP, I follow the guide to add the "#define PJMEDIA_HAS_VIDEO 1" in config_site.h and do the "./configure". The weird thing is that the package still can be built whatever the definition is exist or not. Then "make dep", "make" and "make install"(optional).

It's not hard to build the packages but there are some uncertainty to me. Now let's quickly build an application with GNU tools.
There is an error occur when make.
cc -o myapp myapp.cpp `pkg-config --cflags --libs libpjproject`
/tmp/cczRrbTp.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
make: *** [myapp] Error 1

There are two ways to solve this. One is change the myapp.cpp to be myapp.c and another way is to add -lstdc++ in the Makefile.
# Makefile
all: myapp
myapp: myapp.cpp
    $(CC) -o $@ $< `pkg-config --cflags --libs libpjproject` -lstdc++
clean:
    rm -f myapp.o myapp

The myapp.cpp code.
/* pjsip applicaiton */
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#include <pjsip.h>
#include <pjsip_simple.h>
#include <pjsip_ua.h>
#include <pjsua-lib/pjsua.h>
int main()
{
    printf("hello pjsip\n");
    return 0;
}

Okay, that's all and we could start our application.

[工作點滴] pjsip package build in openwrt

There is a default pjsip package in the openwrt but it link to the extension package of ltq-tapi and oss. But what I need first is the package without extra packages. So I try to create the libraries by using the latest version 2.1 for the experiment.
First, the Makefile of the package as following.

# Makefile of the package.
include $(TOPDIR)/rules.mk

PKG_NAME:=pjsip2
PKG_VERSION:=2.1
PKG_RELEASE:=0

PKG_SOURCE:=pjproject-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://www.pjsip.org/release/$(PKG_VERSION)/
PKG_MD5SUM:=310eb63638dac93095f6a1fc8ee1f578

PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1

PKG_BUILD_DIR:=$(BUILD_DIR)/pjproject-$(PKG_VERSION).$(PKG_RELEASE)

include $(INCLUDE_DIR)/package.mk

define Package/pjsip2
  SECTION:=lib
  CATEGORY:=Libraries
  URL:=http://www.pjsip.org/
  MAINTAINER:=John Crispin <blogic@openwrt.org>
  TITLE:=pjsip2
  DEPENDS:=+libuuid
endef

CONFIGURE_ARGS += \
--disable-floating-point \
--disable-g711-codec \
--disable-l16-codec \
--disable-g722-codec \
--disable-g7221-codec \
--disable-gsm-codec \
--disable-ilbc-coder \
--disable-libsamplerate \
--disable-ipp \
--disable-ssl \
--disable-oss \
--disable-sound

define Build/Configure
(cd $(PKG_BUILD_DIR); autoconf aconfigure.ac > aconfigure)
$(call Build/Configure/Default)
endef

define Build/Compile
CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS) -lc $(LIBGCC_S) -lm" \
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
endef

define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/pjsip2
$(CP) $(PKG_INSTALL_DIR)/usr $(1)/usr/pjsip2
endef

$(eval $(call BuildPackage,pjsip2))


Here we will encounter the problem as follow. 

--target=BFDNAME - specify the target object format as BFDNAMEemulation options: 
No emulation specific options
arm-openwrt-linux-uclibcgnueabi-ar: supported targets: elf32-littlearm elf32-bigarm elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex
make[5]: *** [../lib/libpj-arm-openwrt-linux-gnu.a] Error 1
make[5]: Leaving directory `/home/ubnt/aircam_temp/openwrt/build_dir/target-arm_v6k_uClibc-0.9.33.2_eabi/pjproject-2.1.0/pjlib/build'
make[4]: *** [pjlib] Error 2
make[4]: Leaving directory `/home/ubnt/aircam_temp/openwrt/build_dir/target-arm_v6k_uClibc-0.9.33.2_eabi/pjproject-2.1.0/pjlib/build'
make[3]: *** [all] Error 1



Then we need to patch the aconfigure.ac as follow, this is reference to original content in pjsip patches.

--- pjproject-2.1.0.orig/aconfigure.ac 2013-01-23 14:18:18.000000000 +0800
+++ pjproject-2.1.0/aconfigure.ac 2013-03-11 18:26:43.705804028 +0800
@@ -48,9 +48,8 @@
    CROSS_COMPILE=`echo ${CC} | sed 's/gcc//'`
 fi
-if test "$AR" = ""; then AR="${CROSS_COMPILE}ar rv"; fi
+AR="${AR} rv"
 AC_SUBST(AR)
-if test "$LD" = ""; then LD="$CC"; fi
 AC_SUBST(LD)
 if test "$LDOUT" = ""; then LDOUT="-o "; fi
 AC_SUBST(LDOUT)




New error occur that cannot find libgcc.a. This is quite weird.

arm-openwrt-linux-uclibcgnueabi-ld: cannot find libgcc.a
make[5]: *** [../bin/pjlib-test-arm-openwrt-linux-gnu] Error 1
make[5]: Leaving directory `/home/ubnt/aircam_temp/openwrt/build_dir/target-arm_v6k_uClibc-0.9.33.2_eabi/pjproject-2.1.0/pjlib/build'
make[4]: *** [pjlib-test] Error 2
make[4]: Leaving directory `/home/ubnt/aircam_temp/openwrt/build_dir/target-arm_v6k_uClibc-0.9.33.2_eabi/pjproject-2.1.0/pjlib/build'
make[3]: *** [all] Error 1



I check the toolchain build_dir in openwrt and copy the libgcc.a in staging_dir toolchain/lib. The error solved and the package could successfully be built.
There are tasks to be done if we want to integrate with private audio and video modules.

2013/03/07

[產業觀察] Evernote was hacked

I've already change my tool from the notepad++ or Microsoft's word to Evernote to make a quick note for several months. It's quite simple to use and the data can be synchronize to cloud and I could access my notes through network everywhere anytime. There is a news that Samsung's refrigerator built in Evernote for food management and Samsung show this device in the CES show. The story at this moment, I think Evernote make his products go into a new era. However, the morning sun never lasts a day. Evernote was hacked and the customers information were possibly stolen last week.
This news remind me again about the security and reliability of the cloud service. Evernote build his own cloud service server but the security problem is still happen. However, I do not worry about it because when everyone notice, it will be fixed in near future. But it makes me feel that it may not worth to invest on building own cloud service server on public place especially when we do not have enough security people to maintain it. I've ever attended the CSSLP class and I learned that the security question is very complicated. Maybe it is much better for us to host our cloud service on famous 3rd party provider like AWS.



2013/03/03

[產業觀察] Smartvue cloud architecture

There is a company that we discuss recently because of their elegant embedded NVR device.
I just talk about the private cloud and public cloud roles in the surveillance system in previous article.
Smartvue's product architecture is a case of the hybrid cloud. Let's see the whole system they define.
We can take S9 server as the private cloud server for local storage and playback. If we remove this part, the total system become a pure public cloud type. Although the pure cloud system is simpler, there are still some limitations at this moment. Smatrvue let the high resolution video to be stored on the local server and high or low resolution video can optionally be put on the secure cloud. The reason is obvious that the network environment of LAN is still much clean and fast than WAN and all high resolution video can be saved totally  without any loss.
Someday, we do not need this kind of device when the public network become solid on bandwidth, however, it's not now.


2013/03/01

[科技新知] Firefox OS - liberate the app stores

I saw a news on TV today that about Firefox OS for mobile phone and it got my curiosity. So I go Mozilla's web site to see what's that about. See the link: http://www.mozilla.org/en-US/firefox/partners/#
The first page have the overview of the Firefox OS. The point to me is following picture. Some of telecommunication operators and device manufacturer get involved in the Firefox OS. It shows that the operators and manufacturer want to liberate the apps stores from the providers like Apple, Google.

Here is a picture that from the Mozilla Taiwan site. It describe the difference the operation mode between original and new Open Web App operation mode.
I think the telecommunication operators would be very interesting with it. Because when more requirements are created for consumers to access the web, the operators can earn more. Developers could have one more option to provide their apps and could dealing with customers directly. For manufacturer, I do not see what they can get except the ODM from operators but they still play an important roles here because variety of devices are required. Would Apple and Google agree this?