Monday, September 26, 2011

ffmpeg - qt-faststart

FFMPEG provide a good utility for you to make your mp4 file optimized for web. In general, it makes the moov atom before mdat atom so that it will be easier to find moov stom and send to remote client.

The following is assumed that you have download ffmpeg 0.8.4 source from http://ffmpeg.org/download.html and tar -xvzf ffmpeg-0.8.4.tar.gz to a folder

Build qt-faststart in Linux

1. Navigate to your ffmpeg source folder
2. Go to tools folder
3. Type make qt-faststart

Build qt-faststart in Windows

You can build qt-faststart via cygwin using Linux build step. However, it can only be run within cygwin environment as it will bind qt-faststart with cygwin libraries

Alternatively, build qt-faststart.exe from VS2010

1. Create a VS2010 project
2. Place qt-faststart.c into your source folder
3. You need to find and include 2 external header files inttypes.h and stdin.h
4. Configure your VS2010 project to use the above header files for compilation (Project Properties -> C/C++ -> General -> Additional Include Directories)
5. Open qt-faststart.c and replace __MINGW32__ with the following


#ifdef _WIN32
#    ifdef __MINGW32__
#        define fseeko fseeko64
#      define ftello ftello64
#    else
#        define fseeko _fseeki64
#        define ftello _ftelli64
#    endif
#endif


6. Build the project to get the qt-faststart.exe

Usage:

qt-faststart input.mp4 output.mp4

Windows - Command Prompt %

In Windows batch file, % can be use to get command line parameters values from input.

If you have a call a batch file with abc.exe hello world

echo %2 will return world.

There is a limitation of input parameter and the limitation is 9. That is, it can handle %0 to %9 parameters

What if you have something like this your batch file

echo hello%02world

If you call the program with abc.exe hello world, it will print

helloworldworld.

The batch program will replace %02 with the third input parameters.

You can escape % with another % parameter

So, if you batch file has


echo hello%%02world

Calling abc.exe hello world will print

hello%02world

Thursday, September 22, 2011

VS2010 - fseeko

fseeko, ftello are stdio.h function that are identical to fseek and ftell. But, they are designed for handle 64 bits file offset.

See http://www.manpagez.com/man/3/fseeko/

These function exists in Cygwin and Linux.

However, for VS2010, it does not have fseeko and ftello.

To make your program compilation with fseeko in VS2010, you can do the following



#ifdef _WIN32
#    ifdef __MINGW32__
#        define fseeko fseeko64
#      define ftello ftello64
#    else
#        define fseeko _fseeki64
#        define ftello _ftelli64
#    endif
#endif

This will make fseeko to use VS2010 _fseeki64. It is a 64 bit equivalent in VC++.

Tuesday, September 20, 2011

Python - OpenCV cvseq

Function like FindContours in OpenCV returns a list of cvseq. To access the list object, it provides h_next(), h_prev(), v_next(), v_prev() to access the next and previous object.

h_next() and h_prev() allows you to access sibling items

 v_next() and v_prev() allows you to access child/parent items

If there is no sibling or child, it will return None

To print the length of the sibling

print len(seq.h_next())

To print the list of item in sibling

print list(seq.h_prev())

To access individual x,y items

for (x,y) in seq:
       print (x,y)

Tuesday, September 13, 2011

C# / C++ - DLL not found error

Sometime, it is rather frustrating to work with C++. I always wish that they could feedback more useful error when there is a crash of a system.

This post is related to System.DllNotFoundException: Unable to load DLL 'xxxx.dll'. Well, this is a C# DLLImport error, but, it is kind of related to C++. DLL not found error does not really means that xxxx.dll is not found. It may means that the dll that xxxx.dll depends on is not found

Do the following check point if you encounter this error

1. Check if the xxxx.dll exist at the directory of your application or your library search path
2. If xxxx.dll exist go to ----- to download Dependency Walker. Dependency Walker is a nice program to tell you which dependency is missing/linked/needed
3. Drop xxxx.dll to Dependency Walker. Dependency Walker will load the DLL and search for missing dll
4. If you have a missing DLL dependency. It will prompt you as an error.
5. Try to locate the missing library and place it on your application or library search path.


Monday, September 12, 2011

FFMPEG - av_interleaved_write_frame return error code -22 when passing in a H.264 frame

Actually, until now, I don't know what is error -22 means when av_interleaved_write_frame return me this error code. But, I am sure it is related to PTS value in your AVPacket that is going to pass into av_interleaved_write_frame.


AVPacket pkt;
av_init_packet(&pkt);
......
ret = av_interleaved_write_frame(oc, &pkt);


The above will return -22 if pkt is a H.264 encoded frame from avcodec_encode_video

Now, you need to figure out where to set this PTS value. If you are encoding raw image frame (YUV, RGB, etc...) into H.264, you have to set the PTS at the input frame for avcodec_encode_video.


AVFrame * picture;
picture = avcodec_alloc_frame();
picture->pts = video_pts;
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);

The line picture->pts = video_pts; is very important. It will solve not onlyyour error -22 issue but also non-strictly-monotonic pts generate when you call avcodec_encode_video.

Now, you will wonder how to compute PTS.

For H.264 frame, it will be 90000Hz for sample ratewith 30FPS. Therefore, the sequence for H.264 PTS will be

frame 0 ->  (1 / 30) * 90000 * 0 = 0
frame 1 ->  (1 / 30) * 90000 * 1 = 3000
frame 2 ->  (1 / 30) * 90000 * 2 = 6000
frame 3 ->  (1 / 30) * 90000 * 3 = 9000

So, the general formula is

(1 / FPS) * sample rate * frame number

Putting all the above together, it should solve all the issue.

If you want more concrete example, just give me a ping

Wednesday, September 7, 2011

Android - MediaRecorder SetAudioSource Failed

If you encounter this issue, please check your Android manifest User Permission. Record_Audio permission must be given in order for setting audio source.

Monday, September 5, 2011

Python - Install OpenCV 2.3.1 for Window

OpenCV is a Open source Computer Vision library.

This is provide some guide on installing OpenCV 2.3.1 for Window

1. Download and install Python 2.7
2. Download and install NumPy and SciPy. Installing them is as simple as double clicking the downloaded installer. It will install the extension to your Python site-package folder
3. Download OpenCV 2.3.1 for Window Pre-build version
4. Double click on the OpenCV installer. It will extract OpenCV to your selected folder. For me, I extract it to C:\opencv and I will use that path for the rest of this blog
5. OpenCV 2.3.1 folder structure is different from OpenCV 2.2. The pre-build library and Python package are located at C:\opencv\build.
5. Add C:\opencv\build\x86\vc10\bin to PATH system environment variable for OpenCV.
6. Open Python IDLE
7. Add the following. Note: Having \\ for path is important. If not, Python interpretor may think some of the path as character encoding. For example, \b is consider as character encoding in Python

import sys
sys.path.append("C:\\opencv\\build\\python\\2.7")

8. Now, you are ready to import OpenCV with

import cv

See http://opencv.willowgarage.com/wiki/Welcome

Sunday, September 4, 2011

Python - Install Python Imaging Library

Python Imaging Library is an good open source imaging library http://www.pythonware.com/products/pil/index.htm

You require any version of Python 2.7.X in 32 bits. Get the Python Imaging Library 1.1.7 for Python 2.7and install the executable. It is rather straight forward.

For Linux, most Linux distribution comes with python-imaging package. You can perform yum install python-imaging to install it. However, the default package may be out-dated. For example, CentOS 5.5 only have python-imaging 1.1.5 package while the latest package from the web site is 1.1.7

So, if you want to install for Python Imaging 1.1.7, you will need to following my previous post http://thompsonng.blogspot.com/2011/09/python-linux-installation.html to install 2.7.X python.

Then, goes to Python Imaging Library 1.1.7 Source Kit to download the source for Python Imaging 1.1.7.

After that, at your Linux machine, do the following

1. tar -xzvf Imaging-1.1.7.tar.gz
2. python setup.py install

Note: point 2 assume that your install version of python is 2.7.X. If you have other version of python, please use the correct interpreter respectively.


If install successfully, you should be able to import Image and use their module

For example,

>>> import Image
>>> im = Image.open("your_image.jpg");





See http://gausssum.sourceforge.net/DocBook/ch01s03.html and http://www.pythonware.com/library/pil/handbook/introduction.htm


Python - Linux Installation

For Window, you can simply use the msi installer provided at http://www.python.org/download/

For Linux, you can do the following

yum install python

Usually, this way will install an older version of python. For example, CentOS will install python 2.4.3.

To install the latest version, you can use this script


# chmod +x install-python.sh
# ./install-python.sh

#!/bin/bash
# Install necessary packages
yum -y install gcc gdbm-devel readline-devel ncurses-devel zlib-devel bzip2-develsqlite-devel db4-devel openssl-devel tk-devel bluez-libs-devel make

cd /var/tmp
wget http://sqlite.org/sqlite-amalgamation-3.7.3.tar.gz
tar xfz sqlite-amalgamation-3.7.3.tar.gz
cd sqlite-3.7.3/
./configure
make
make install

cd /var/tmp
wget http://www.python.org/ftp/python/2.7.1/Python-2.7.1.tgz
tar xvfz Python-2.7.1.tgz
cd Python-2.7.1
./configure --prefix=/opt/python2.7.1 --with-threads --enable-shared
make
make install

touch /etc/ld.so.conf.d/opt-python2.7.1.conf
echo "/opt/python2.7.1/lib/" >> /etc/ld.so.conf.d/opt-python2.7.1.conf
ldconfig

ln -sf /opt/python2.7.1/bin/python /usr/bin/python2.7

cd /var/tmp
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
sh setuptools-0.6c11-py2.7.egg --prefix=/opt/python2.7.1

/opt/python2.7.1/bin/easy_install pip
ln -sf /opt/python2.7.1/bin/pip /usr/bin/pip

pip install virtualenv
ln -sf /opt/python2.7.1/bin/virtualenv /usr/bin/virtualenv

echo "alias python=/opt/python2.7.1/bin/python" >> ~/.bash_profile
echo "alias python2.7=/opt/python2.7.1/bin/python" >> ~/.bash_profile
echo "PATH=$PATH:/opt/python2.7/bin" >> ~/.bash_profile
source ~/.bash_profile

# Done



I reference this script from http://willsani.com/2011/03/02/centos-5-5-x86_64-install-python-2-7/ and it works for me. Just change the version number accordingly. At this time of post, python has 2.7.2

It will install python at /opt/python2.7.2

/opt/python2.7.2/bin/python2.7 will trigger the interpreter


Linux - Setting Static IP Address

Just a simple reference on how to set static IP address on Linux via command line

I using CentOS 5.6 x64 with only 1 network interface.

1. Use an editor (such as vi) to edit /etc/sysconfig/network-scripts/ifcfg-eth0
2. At ifcfg-eth0, do the following in bold. Note: IP address and net mask is only an example.

Change BOOTPROTO=dhcp ----> BOOTPROTO=static

Add IPADDR=192.168.1.250

Add NETMASK=255.255.255.0

3. Save ifcfg-eth0
4. Use an editor (such as vi) to edit /etc/sysconfig/network
5. At network, do the following in bold. Note: Gateway is only an example

Add GATEWAY=192.168.1.1

6. Save network
7. Restart the network interface by service network restart
8. Alternatively, you can restart your server to check if the changes is persistence with reboot

See http://www.cyberciti.biz/faq/linux-configure-a-static-ip-address-tutorial/

Thursday, September 1, 2011

PhoneGap - AppView Setting

PhoneGap appView is the Android WebView container. By default, many setting are off. The following are some helpful setting

//Enable Zoom
this.appView.getSettings().setSupportZoom(true);
//Display with Zoom control. Please note that Android 2.3 and below
//required this in order for zoom support to be enabled
this.appView.getSettings().setBuiltInZoomControls(true);
//Enable normal web view port (like desktop browser). If this is false, it will
//auto fit your content to mobile viewport
this.appView.getSettings().setUseWideViewPort(true);
//enable plugin. This is needed to enable flash plugin
this.appView.getSettings().setPluginState(PluginState.ON);