S3C6410 can do hardware video decode including H.264.
There's an example code from Samsung shows how to hardware decode H.264 raw data, but in the real world application this is not so useful.
Decode & Playing H.264 mp4 file is more reality. So I would like to share the implementation.
I use ffmpeg library to decode mp4 mux in order to get H.264 raw data and then send it to S3C6410 MFC to decode and finally play on the LCD panel.
Requirement
ffmpeg-0.6.1
Samsung FIMV_MFC_V1.0
Source code
https://docs.google.com/open?id=0Bx901QMLr9WlTTR1a0ZKaXVobW8
The most important part is to handle data from
av_read_frame(formatContext, &pkt);
if you pass pkt.data to decode you got fail to decode. Another filter is required.
typedef struct H264BSFContext {
uint8_t length_size;
uint8_t first_idr;
uint8_t *sps_pps_data;
uint32_t size;
} H264BSFContext;
AVBitStreamFilterContext *filterContext = (AVBitStreamFilterContext *)malloc(sizeof(AVBitStreamFilterContext));
filterContext->priv_data = (H264BSFContext *)malloc(sizeof(H264BSFContext));
memset(filterContext->priv_data, 0, sizeof(H264BSFContext));
filterContext->filter = &h264_mp4toannexb_bsf;
filterContext->parser = 0;
filterContext->next = 0;
...
r = av_read_frame(formatContext, &pkt);
...
unsigned char *lp = 0;
int len = 0;
filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY)); -->> filter here
decode_mfc(lp, len);
2012年4月10日 星期二
2012年3月6日 星期二
Ubuntu Intel I5-2500K & Z68 chipset
上次組裝電腦已經是6~7年前的事了,昨天終於下定決心把公司那台半古董桌機換下來,一方面增加工作效率也讓已經逐漸老化的硬碟退休.
之前已經在網路上研究了配備一陣子,主要還是與Ubuntu的相容性要好.最後定案的配備如下
Intel I5-2500K (有K的表示可超頻,貴幾百吧)
ASRock Z68 PRO3 GEN3 (這張Ubuntu直上,還有一個COM port,重點是便宜啊)
Kongston 4GB DDR3-1333 x 2 (共8G memory,這在十年前簡直是無法想像)
Seagate SATA3 1T ST1000DM003
CM Hyper 212 PLUS 塔型散熱器 (CPU不怕著涼的,裝大顆一點就對了)
振華400W power
裝好搬回來後直接裝Ubuntu 11.10,一路順暢都沒有什麼問題.
我最擔心的Intel HD 3000 graphic controller也能正常工作,Perfect
接著是一些監控系統資訊的方式
1.CPU 溫度
modprobe coretemp
sensors
gigijoe@gigijoe-i5-2500k:~$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Physical id 0: +31.0°C (high = +80.0°C, crit = +98.0°C)
Core 0: +25.0°C (high = +80.0°C, crit = +98.0°C)
Core 1: +29.0°C (high = +80.0°C, crit = +98.0°C)
Core 2: +26.0°C (high = +80.0°C, crit = +98.0°C)
Core 3: +30.0°C (high = +80.0°C, crit = +98.0°C)
2.硬體資訊
sudo lshw
3.CPU 超頻
現在的超頻很容易,直接在BIOS內用懶人設定選取希望的頻率即可.
3.3G -> 4.6G還蠻穩定的,CPU溫度只稍微上升.
在linux環境下cat /pro/cpuinfo會發現超頻之後的CPU clock一樣顯示是3.3G.
嗯,經過一番google後先試著用wine 跑 CPU-z這個Windows上廣泛使用的程式...失敗.
最後正解是一隻叫i7z的程式 http://code.google.com/p/i7z/
Cpu speed from cpuinfo 3292.00Mhz
cpuinfo might be wrong if cpufreq is enabled. To guess correctly try estimating
Linux's inbuilt cpu_khz code emulated now
True Frequency (without accounting Turbo) 3292 MHz
CPU Multiplier 33x || Bus clock frequency (BCLK) 99.76 MHz
Socket [0] - [physical cores=4, logical cores=4, max online cores ever=4]
TURBO ENABLED on 4 Cores, Hyper Threading OFF
True Frequency 3391.76 MHz (99.76 x [34])
Max TURBO Multiplier (if Enabled) with 1/2/3/4 Cores is 60x/60x/60x/60x
Current Frequency 1793.89 MHz [99.76 x 17.98] (Max of below)
Core [core-id] :Actual Freq (Mult.) C0% Halt(C1)% C3 % C6 %
Core 1 [0]: 1793.89 (17.98x) 38.2 38.7 9.4 31.1
Core 2 [1]: 1655.03 (16.59x) 9.69 13.6 5.07 76.5
Core 3 [2]: 1657.92 (16.62x) 2.77 2.38 1.3 94.9
Core 4 [3]: 1618.08 (16.22x) 1 0.747 0 98.9
C0 = Processor running without halting
C1 = Processor running with halts (States >C0 are power saver)
C3 = Cores running with PLL turned off and core cache turned off
C6 = Everything in C3 + core state saved to last level cache
Above values in table are in percentage over the last 1 sec
3.還有一個小問題是boot會卡在Checking Battery State.
按Ctrl+Alt+F1進 console login.
sudo apt-get install gdm
安裝過程中選lightdm
或是
sudo dpkg-reconfigure gdm
然後reboot就解決囉
之前已經在網路上研究了配備一陣子,主要還是與Ubuntu的相容性要好.最後定案的配備如下
Intel I5-2500K (有K的表示可超頻,貴幾百吧)
ASRock Z68 PRO3 GEN3 (這張Ubuntu直上,還有一個COM port,重點是便宜啊)
Kongston 4GB DDR3-1333 x 2 (共8G memory,這在十年前簡直是無法想像)
Seagate SATA3 1T ST1000DM003
CM Hyper 212 PLUS 塔型散熱器 (CPU不怕著涼的,裝大顆一點就對了)
振華400W power
裝好搬回來後直接裝Ubuntu 11.10,一路順暢都沒有什麼問題.
我最擔心的Intel HD 3000 graphic controller也能正常工作,Perfect
接著是一些監控系統資訊的方式
1.CPU 溫度
modprobe coretemp
sensors
gigijoe@gigijoe-i5-2500k:~$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Physical id 0: +31.0°C (high = +80.0°C, crit = +98.0°C)
Core 0: +25.0°C (high = +80.0°C, crit = +98.0°C)
Core 1: +29.0°C (high = +80.0°C, crit = +98.0°C)
Core 2: +26.0°C (high = +80.0°C, crit = +98.0°C)
Core 3: +30.0°C (high = +80.0°C, crit = +98.0°C)
2.硬體資訊
sudo lshw
3.CPU 超頻
現在的超頻很容易,直接在BIOS內用懶人設定選取希望的頻率即可.
3.3G -> 4.6G還蠻穩定的,CPU溫度只稍微上升.
在linux環境下cat /pro/cpuinfo會發現超頻之後的CPU clock一樣顯示是3.3G.
嗯,經過一番google後先試著用wine 跑 CPU-z這個Windows上廣泛使用的程式...失敗.
最後正解是一隻叫i7z的程式 http://code.google.com/p/i7z/
Cpu speed from cpuinfo 3292.00Mhz
cpuinfo might be wrong if cpufreq is enabled. To guess correctly try estimating
Linux's inbuilt cpu_khz code emulated now
True Frequency (without accounting Turbo) 3292 MHz
CPU Multiplier 33x || Bus clock frequency (BCLK) 99.76 MHz
Socket [0] - [physical cores=4, logical cores=4, max online cores ever=4]
TURBO ENABLED on 4 Cores, Hyper Threading OFF
True Frequency 3391.76 MHz (99.76 x [34])
Max TURBO Multiplier (if Enabled) with 1/2/3/4 Cores is 60x/60x/60x/60x
Current Frequency 1793.89 MHz [99.76 x 17.98] (Max of below)
Core [core-id] :Actual Freq (Mult.) C0% Halt(C1)% C3 % C6 %
Core 1 [0]: 1793.89 (17.98x) 38.2 38.7 9.4 31.1
Core 2 [1]: 1655.03 (16.59x) 9.69 13.6 5.07 76.5
Core 3 [2]: 1657.92 (16.62x) 2.77 2.38 1.3 94.9
Core 4 [3]: 1618.08 (16.22x) 1 0.747 0 98.9
C0 = Processor running without halting
C1 = Processor running with halts (States >C0 are power saver)
C3 = Cores running with PLL turned off and core cache turned off
C6 = Everything in C3 + core state saved to last level cache
Above values in table are in percentage over the last 1 sec
3.還有一個小問題是boot會卡在Checking Battery State.
按Ctrl+Alt+F1進 console login.
sudo apt-get install gdm
安裝過程中選lightdm
或是
sudo dpkg-reconfigure gdm
然後reboot就解決囉
2011年11月4日 星期五
2011年9月15日 星期四
Avoid zombie process
在某些應用中常會需要執行其他的程式,這時候就會需要呼叫fork產生child process並在此執行其他程式.
而當被呼叫的程式執行結束child process也就跟著結束,這時child process就成為zombie process.
if(fork() == 0) { /* Child process*/
/* Run program */
execl("/bin/ntpdate", "ntpdate", "tick.stdtime.gov.tw", "tock.stdtime.gov.tw", (char *)0);
exit(0);
/* zombie process */
}
/* Parent process or error */
wait(0);
zombie process存在的意義是等待parent process來處理child process結束後的事情,例如程式的傳回值.
有兩種方式來避免zombie process
1.明確指出parent process不需要知道child process的結束狀態
在parent process 程式碼中加上
signal(SIGCHLD, SIG_IGN); /* Do not wait for child process */
2.連續fork兩次,藉由結束first child process的方式讓second child process的parent process為pid 1 (通常是 init)
pid_t pid;
if((pid = fork()) == 0) { /*First child process*/
if((pid = fork()) > 0)
exit(0); /* Terminate first child process */
/* Second child process. Run program */
execl("/bin/ntpdate", "ntpdate", "tick.stdtime.gov.tw", "tock.stdtime.gov.tw", (char *)0);
exit(0);
}
/* Parent process or error */
而當被呼叫的程式執行結束child process也就跟著結束,這時child process就成為zombie process.
if(fork() == 0) { /* Child process*/
/* Run program */
execl("/bin/ntpdate", "ntpdate", "tick.stdtime.gov.tw", "tock.stdtime.gov.tw", (char *)0);
exit(0);
/* zombie process */
}
/* Parent process or error */
wait(0);
zombie process存在的意義是等待parent process來處理child process結束後的事情,例如程式的傳回值.
有兩種方式來避免zombie process
1.明確指出parent process不需要知道child process的結束狀態
在parent process 程式碼中加上
signal(SIGCHLD, SIG_IGN); /* Do not wait for child process */
2.連續fork兩次,藉由結束first child process的方式讓second child process的parent process為pid 1 (通常是 init)
pid_t pid;
if((pid = fork()) == 0) { /*First child process*/
if((pid = fork()) > 0)
exit(0); /* Terminate first child process */
/* Second child process. Run program */
execl("/bin/ntpdate", "ntpdate", "tick.stdtime.gov.tw", "tock.stdtime.gov.tw", (char *)0);
exit(0);
}
/* Parent process or error */
2011年8月5日 星期五
Embedded Linux IPv6 ready logo phase-2
The past month I'm working on IPv6 ready test on an embedded linux platform.
Since the kernel is really old 2.6.10 and I have to do some porting from newer kernel to get IPv6 ready test pass. Last week I finally all pass and below are some tips.
1.The test node (TN) is FreeBSD 7.4 release with v6eval-3.3.2 / v6eval-remotes-3.0 / Self_Test_5.0.0
It's very important that to disable ipv6 autoconfiguration on TN, because the testing suit needs clean ipv6 environment.
To disable ipv6 autoconfiguration, edit /etc/rc.conf and set
ipv6_enable="NO"
then after TN boot, the ipv6 link local address (fe80:X) won't be exist.
2./usr/local/v6eval/etc/tn.def
#
# tn.def
#
# Information about the Tester Node (TN)
#
#
# Remote Controal Configuration
#
RemoteDevice cuad0
RemoteDebug 0
RemoteIntDebug 0
RemoteLog 1
RemoteSpeed 0
RemoteLogout 0
RemoteMethod serial
#filter ipv6
#linkname interface BOGUS ether source address
# name of the Tester Interface
Link0 rl0 00:00:00:00:01:00
#Link1 de1 00:00:00:00:01:01
#Link2 de2 00:00:00:00:01:02
#Link3 de4 00:00:00:00:01:03
3./usr/local/v6eval/etc/nut.def
#
# nut.def
#
# Information about the Node Under Test (NUT)
#
# System type
System linux-v6
# System information
TargetName FreeBSD/i386 4.9-RELEASE + kame-20040726-freebsd49-snap
# Name
HostName HL200
# Type
# host, router, special
Type host
# Super user name and it's password
# if you select manual as "System", you don't care "User" and "Password"
#
User root
Password 1234
#linkname interface The EXACT ether source address
# name of the Interface Under Test
Link0 eth0 00:AE:45:BC:84:1E
#Link0 eth0 00:60:37:c0:ff:ee
#Link1 fxp1 00:00:92:a7:6d:f6
#Link2 de0 00:c0:f6:b0:aa:ef
#Link3 de1 00:00:92:a7:6d:f8
#Link4 de2 00:90:27:14:ce:e3
4./usr/local/lib/perl5/site_perl/5.10.1/V6evalRemote.pm
This file is really important for self test. It makes the TN to communicate NUT through serial RS232 port. TN can login / logout NUT system even more reboot NUT.
So, find key words below in this file and get it right
$Type="linux-v6";
$Device="cuad0";
$User="root";
$Password="1234";
The TN will detect message from NUT to login / logout. For example "login: " and "Password: ". Also get it right for your NUT's Behavior
# login prompt
%prompt_user = (
...
'linux-v6', 'login: ',
...
);
# password prompt
%prompt_password = (
...
'linux-v6', 'Password: ',
...
);
# command prompt
%prompt_command = (
...
'linux-v6', '(\$|#) ',
...
);
and so on
5.Test TN <-RS232-> NUT
If you can see login screen or promopt, it works
touch /var/log/aculog
chown uucp:dialer /var/log/aculog
chmod 660 /var/log/aculog
cu -l /dev/cuad0
Connected
[root@HL200 ~]$
6.Remote test
To test if TN can login then logout NUT
/usr/local/v6eval/bin/linux-v6/loginout.rmt -o1
HL200 login: root
Password:
BusyBox v1.2.2 (2011.07.20-06:33+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
[root@HL200 ~]$
[root@HL200 ~]$ exit
7.Run self test
cd Self_Test_5-0-0
make clean
make ipv6ready_p2_host
8.Run parts of self test
There are 5 test sections, you can test separated.
cd nd.p2/
make clean
make ipv6ready_p2_host
Also can test only few items, for example test items 10 to 20
make AROPT="-s 10 -e 20" ipv6ready_p2_host
9.Embedded linux setup.
There are some sysctl for ipv6 need to be set correct.
echo 0 > /proc/sys/net/ipv6/conf/default/forwarding
echo 2 > /proc/sys/net/ipv6/conf/default/dad_transmits
echo 1 > /proc/sys/net/ipv6/conf/default/use_tempaddr
echo 2 > /proc/sys/net/ipv6/conf/default/accept_dad
echo 1 > /proc/sys/net/ipv6/conf/default/optimistic_dad
echo 1 > /proc/sys/net/ipv6/conf/default/accept_redirects
Remember to set promisc and allmulti to ethernet port.
Another tip is to sleep 10 seconds after the ethernet up then go login screen
ip -6 link set lo up
#ip -6 link set eth0 up
ifconfig eth0 up promisc allmulti
echo "Wait 10 secs..."
sleep 10
10.Finally, fix /usr/local/v6eval/bin/unknown/ping6.rmt
########################################################################
use V6evalRemote;
rOpen() || goto error;
$NUTif = $rOpt_if;
$dstaddress = $rOpt_addr;
$rOpt_timeout = 5 if ! defined $rOpt_timeout;
if($rOpt_size < 1) {
$rOpt_size = 2;
}
$pingpath = "ping6";
$pingopt = "-n -c 1 -i 1 -s $rOpt_size -p 00 -w 2 -M want";
$ifopt = "-I $NUTif" if $NUTif ne "";
rLogin($rOpt_timeout) || goto error;
rCommand("$pingpath $pingopt $ifopt $dstaddress", 15) || goto error;
rLogout($rOpt_timeout) || goto error;
rClose();
exit($V6evalRemote::exitPass);
error:
rClose();
exit($V6evalRemote::exitFail);
########################################################################
Since the kernel is really old 2.6.10 and I have to do some porting from newer kernel to get IPv6 ready test pass. Last week I finally all pass and below are some tips.
1.The test node (TN) is FreeBSD 7.4 release with v6eval-3.3.2 / v6eval-remotes-3.0 / Self_Test_5.0.0
It's very important that to disable ipv6 autoconfiguration on TN, because the testing suit needs clean ipv6 environment.
To disable ipv6 autoconfiguration, edit /etc/rc.conf and set
ipv6_enable="NO"
then after TN boot, the ipv6 link local address (fe80:X) won't be exist.
2./usr/local/v6eval/etc/tn.def
#
# tn.def
#
# Information about the Tester Node (TN)
#
#
# Remote Controal Configuration
#
RemoteDevice cuad0
RemoteDebug 0
RemoteIntDebug 0
RemoteLog 1
RemoteSpeed 0
RemoteLogout 0
RemoteMethod serial
#filter ipv6
#linkname interface BOGUS ether source address
# name of the Tester Interface
Link0 rl0 00:00:00:00:01:00
#Link1 de1 00:00:00:00:01:01
#Link2 de2 00:00:00:00:01:02
#Link3 de4 00:00:00:00:01:03
3./usr/local/v6eval/etc/nut.def
#
# nut.def
#
# Information about the Node Under Test (NUT)
#
# System type
System linux-v6
# System information
TargetName FreeBSD/i386 4.9-RELEASE + kame-20040726-freebsd49-snap
# Name
HostName HL200
# Type
# host, router, special
Type host
# Super user name and it's password
# if you select manual as "System", you don't care "User" and "Password"
#
User root
Password 1234
#linkname interface The EXACT ether source address
# name of the Interface Under Test
Link0 eth0 00:AE:45:BC:84:1E
#Link0 eth0 00:60:37:c0:ff:ee
#Link1 fxp1 00:00:92:a7:6d:f6
#Link2 de0 00:c0:f6:b0:aa:ef
#Link3 de1 00:00:92:a7:6d:f8
#Link4 de2 00:90:27:14:ce:e3
4./usr/local/lib/perl5/site_perl/5.10.1/V6evalRemote.pm
This file is really important for self test. It makes the TN to communicate NUT through serial RS232 port. TN can login / logout NUT system even more reboot NUT.
So, find key words below in this file and get it right
$Type="linux-v6";
$Device="cuad0";
$User="root";
$Password="1234";
The TN will detect message from NUT to login / logout. For example "login: " and "Password: ". Also get it right for your NUT's Behavior
# login prompt
%prompt_user = (
...
'linux-v6', 'login: ',
...
);
# password prompt
%prompt_password = (
...
'linux-v6', 'Password: ',
...
);
# command prompt
%prompt_command = (
...
'linux-v6', '(\$|#) ',
...
);
and so on
5.Test TN <-RS232-> NUT
If you can see login screen or promopt, it works
touch /var/log/aculog
chown uucp:dialer /var/log/aculog
chmod 660 /var/log/aculog
cu -l /dev/cuad0
Connected
[root@HL200 ~]$
6.Remote test
To test if TN can login then logout NUT
/usr/local/v6eval/bin/linux-v6/loginout.rmt -o1
HL200 login: root
Password:
BusyBox v1.2.2 (2011.07.20-06:33+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
[root@HL200 ~]$
[root@HL200 ~]$ exit
7.Run self test
cd Self_Test_5-0-0
make clean
make ipv6ready_p2_host
8.Run parts of self test
There are 5 test sections, you can test separated.
cd nd.p2/
make clean
make ipv6ready_p2_host
Also can test only few items, for example test items 10 to 20
make AROPT="-s 10 -e 20" ipv6ready_p2_host
9.Embedded linux setup.
There are some sysctl for ipv6 need to be set correct.
echo 0 > /proc/sys/net/ipv6/conf/default/forwarding
echo 2 > /proc/sys/net/ipv6/conf/default/dad_transmits
echo 1 > /proc/sys/net/ipv6/conf/default/use_tempaddr
echo 2 > /proc/sys/net/ipv6/conf/default/accept_dad
echo 1 > /proc/sys/net/ipv6/conf/default/optimistic_dad
echo 1 > /proc/sys/net/ipv6/conf/default/accept_redirects
Remember to set promisc and allmulti to ethernet port.
Another tip is to sleep 10 seconds after the ethernet up then go login screen
ip -6 link set lo up
#ip -6 link set eth0 up
ifconfig eth0 up promisc allmulti
echo "Wait 10 secs..."
sleep 10
10.Finally, fix /usr/local/v6eval/bin/unknown/ping6.rmt
########################################################################
use V6evalRemote;
rOpen() || goto error;
$NUTif = $rOpt_if;
$dstaddress = $rOpt_addr;
$rOpt_timeout = 5 if ! defined $rOpt_timeout;
if($rOpt_size < 1) {
$rOpt_size = 2;
}
$pingpath = "ping6";
$pingopt = "-n -c 1 -i 1 -s $rOpt_size -p 00 -w 2 -M want";
$ifopt = "-I $NUTif" if $NUTif ne "";
rLogin($rOpt_timeout) || goto error;
rCommand("$pingpath $pingopt $ifopt $dstaddress", 15) || goto error;
rLogout($rOpt_timeout) || goto error;
rClose();
exit($V6evalRemote::exitPass);
error:
rClose();
exit($V6evalRemote::exitFail);
########################################################################
2011年6月20日 星期一
LeopardBoard DM368 ffmpeg
For the HD video I need libraries to support video / audio file mux. The ffmpeg is a good choice. With ffmpeg I can save H.264 raw data into mp4 file then play video on PC.
1.Download ffmpeg-0.6.1
Download ffmpeg-0.6.1 and put it in ~/LeopardBoard/DM368
2.Cross compile ffmpeg
I will install ffmpeg into the toolchain sub directory for convenience. My toolchain locate at /opt/arm-2009q1
$ cd ~/LeopardBoard/DM368/ffmpeg-0.6.1
$ mkdir build
$ cd build
$ ../configure --target-os=linux --arch=armv --cpu=armv5te --enable-cross-compile --cross-prefix=arm-none-linux-gnueabi- --prefix=/opt/arm-2009q1/arm-none-linux-gnueabi/libc/usr
$ make
$ sudo PATH=$PATH:/opt/arm-2009q1/bin make install
3.Apply patch to fix Makefile to prevent application link error and add new application video_encode_mp4.
ti-dvsdk_dm368-evm_4_02_00_06_dmai_2_20_00_15_ffmpeg.patch
There will be link error while compile application, so I did some modify to dmai_2_20_00_15/packages/ti/sdo/dmai/apps/Makefile.app
The new application is capable to record HD video and save it into mp4 file
4.Recompile DMAI
$ cd ~/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06
$ make dmai
The new application video_encode_mp4 is located at dmai_2_20_00_15/packages/ti/sdo/dmai/apps/video_encode_mp4/linux/video_encode_mp4_dm368.x470MV
5.Running
Save 720p video into SD card with file name video_encode.mp4
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_encode_mp4_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o /media/mmcblk0p2/video_encode.mp4 -e encode -b 2000000
6.Running with benchmark
$ ./video_encode_mp4_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o /media/mmcblk0p2/video_encode.mp4 -e encode -b 8000000 --benchmark
Starting application...
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
Leopard: switch to HD imager-MT9P031 video input
-----Exposure time = 2f2
-----Exposure time = 2f2
vpfe-capture vpfe-capture: width = 1280, height = 720, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1280, height = 720, bpp = 1, bytesperline = 1280, sizeimage = 1382400
vpfe-capture vpfe-capture: width = 1280, height = 720, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1280, height = 720, bpp = 1, bytesperline = 1280, sizeimage = 1382400
Output #0, mp4, to '/media/mmcblk0p2/video_encode.mp4':
Stream #0.0: Video: 0x0000, yuv420p, 1280x720, q=2-31, 8000 kb/s, 90k tbn, 15 tbc
No frame read ...
...
Frame 26: Read time: 8431us
[27] Encode: 19808us
File write time: 3915us
Total: 32414us
Frame 27: Read time: 9166us
[28] Encode: 19778us
File write time: 4592us
Total: 33793us
Frame 28: Read time: 8517us
[29] Encode: 19796us
File write time: 5055us
Total: 33621us
Frame 29: Read time: 8097us
[30] Encode: 28264us
File write time: 18042us
Total: 54664us
Frame 30: Read time: 19820us
[31] Encode: 26007us
File write time: 18879us
Total: 64968us
Frame 31: Read time: 21273us
[32] Encode: 19804us
File write time: 2930us
Total: 44265us
Frame 32: Read time: 10147us
[33] Encode: 19743us
File write time: 2517us
Total: 32662us
...
Write file time about 2 ~ 5 ms, there's no need to write file in another thread.
1.Download ffmpeg-0.6.1
Download ffmpeg-0.6.1 and put it in ~/LeopardBoard/DM368
2.Cross compile ffmpeg
I will install ffmpeg into the toolchain sub directory for convenience. My toolchain locate at /opt/arm-2009q1
$ cd ~/LeopardBoard/DM368/ffmpeg-0.6.1
$ mkdir build
$ cd build
$ ../configure --target-os=linux --arch=armv --cpu=armv5te --enable-cross-compile --cross-prefix=arm-none-linux-gnueabi- --prefix=/opt/arm-2009q1/arm-none-linux-gnueabi/libc/usr
$ make
$ sudo PATH=$PATH:/opt/arm-2009q1/bin make install
3.Apply patch to fix Makefile to prevent application link error and add new application video_encode_mp4.
ti-dvsdk_dm368-evm_4_02_00_06_dmai_2_20_00_15_ffmpeg.patch
There will be link error while compile application, so I did some modify to dmai_2_20_00_15/packages/ti/sdo/dmai/apps/Makefile.app
The new application is capable to record HD video and save it into mp4 file
4.Recompile DMAI
$ cd ~/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06
$ make dmai
The new application video_encode_mp4 is located at dmai_2_20_00_15/packages/ti/sdo/dmai/apps/video_encode_mp4/linux/video_encode_mp4_dm368.x470MV
5.Running
Save 720p video into SD card with file name video_encode.mp4
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_encode_mp4_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o /media/mmcblk0p2/video_encode.mp4 -e encode -b 2000000
6.Running with benchmark
$ ./video_encode_mp4_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o /media/mmcblk0p2/video_encode.mp4 -e encode -b 8000000 --benchmark
Starting application...
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
Leopard: switch to HD imager-MT9P031 video input
-----Exposure time = 2f2
-----Exposure time = 2f2
vpfe-capture vpfe-capture: width = 1280, height = 720, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1280, height = 720, bpp = 1, bytesperline = 1280, sizeimage = 1382400
vpfe-capture vpfe-capture: width = 1280, height = 720, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1280, height = 720, bpp = 1, bytesperline = 1280, sizeimage = 1382400
Output #0, mp4, to '/media/mmcblk0p2/video_encode.mp4':
Stream #0.0: Video: 0x0000, yuv420p, 1280x720, q=2-31, 8000 kb/s, 90k tbn, 15 tbc
No frame read ...
...
Frame 26: Read time: 8431us
[27] Encode: 19808us
File write time: 3915us
Total: 32414us
Frame 27: Read time: 9166us
[28] Encode: 19778us
File write time: 4592us
Total: 33793us
Frame 28: Read time: 8517us
[29] Encode: 19796us
File write time: 5055us
Total: 33621us
Frame 29: Read time: 8097us
[30] Encode: 28264us
File write time: 18042us
Total: 54664us
Frame 30: Read time: 19820us
[31] Encode: 26007us
File write time: 18879us
Total: 64968us
Frame 31: Read time: 21273us
[32] Encode: 19804us
File write time: 2930us
Total: 44265us
Frame 32: Read time: 10147us
[33] Encode: 19743us
File write time: 2517us
Total: 32662us
...
Write file time about 2 ~ 5 ms, there's no need to write file in another thread.
2011年6月14日 星期二
LeopardBoard DM368 HD H.264 encode
With DVSDK working on LeopardBoard DM368, Now let's trying video encode function.
1.Check kernel log to see if the dsplink related modules are loaded.
CMEMK module: built on Jun 14 2011 at 18:02:26
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
allocated heap buffer 0xc6000000 of size 0x4400000
heap fallback enabled - will try heap if pool buffer is not available
CMEM Range Overlaps Kernel Physical - allowing overlap
CMEM phys_start (0x1000) overlaps kernel (0x80000000 -> 0x83c00000)
cmemk initialized
IRQK module: built on Jun 14 2011 at 18:02:29
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/irq/src/module/irqk.c
irqk initialized
EDMAK module: built on Jun 14 2011 at 18:02:30
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/edma/src/module/edmak.c
2.If there are errors check /etc/init.d/loadmodule-rc. Below is mine
#!/bin/sh
# Default DM368 EVM Memory Map
#
# Start Addr Size Description
# -------------------------------------------
# 0x00001000 32K ARM TCM memory
# 0x80000000 48 MB Linux
# 0x83000000 12 MB Video driver memory (Linux)
# 0x83C00000 68 MB CMEM
# 0x88000000 BOTTOM ADDRESS
load () {
modprobe cmemk phys_start=0x83C00000 phys_end=0x88000000 allowOverlap=1 phys_start_1=0x00001000 phys_end_1=0x00008000 pools_1=1x28672 useHeapIfPoolUnavai
lable=1
modprobe irqk
modprobe edmak
modprobe dm365mmap
mknod /dev/dm365mmap c `awk "\\$2==\"dm365mmap\" {print \\$1}" /proc/devices` 0
}
unload () {
rmmod cmemk 2>/dev/null
rmmod irqk 2>/dev/null
rmmod edmak 2>/dev/null
rmmod dm365mmap 2>/dev/null
rm -f /dev/dm365mmap
}
case "$1" in
start)
load
;;
stop)
unload
;;
restart)
unload
load
;;
*)
echo "$0 "
;;
esac
3.Decode test to verify if DSP works.
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_decode_io2_dm368.x470MV -c h264dec -e decode -i /usr/share/ti/data/videos/davincieffect.264 -n 30 -o output.yuv
Starting application...
Loader created and primed, entering main loop..
Loaded Frame 1: frame size 401
Loaded Frame 2: frame size 36
Loaded Frame 3: frame size 804
Loaded Frame 4: frame size 844
Loaded Frame 5: frame size 863
Loaded Frame 6: frame size 933
Loaded Frame 7: frame size 1189
Loaded Frame 8: frame size 1253
Loaded Frame 9: frame size 1509
Display Frame 1: Wrote 420P frame size 1382400 (1280x720) to disk
Loaded Frame 10: frame size 1573
Display Frame 2: Wrote 420P frame size 1382400 (1280x720) to disk
Loaded Frame 11: frame size 1829
4.Now, it's time to encode video from camera. I got mt9p031 (LI-BCM5M03).
If you got kernel log below, the camera is ready
...
Leopard: switch to HD imager-MT9P031 video input
mt9p031 1-0048: Detected a MT9P031 chip ID 1801
mt9p031 1-0048: mt9p031 1-0048 decoder driver registered !!
vpfe-capture vpfe-capture: v4l2 sub device mt9p031 registered
...
5.Test if camera works
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_loopback_dm368.x470MV -O component -I camera -y5
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
Leopard: switch to HD imager-MT9P031 video input
-----Exposure time = 456
-----Exposure time = 456
vpfe-capture vpfe-capture: width = 1920, height = 1080, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1920, height = 1080, bpp = 1, bytesperline = 1920, sizeimage = 3110400
vpfe-capture vpfe-capture: width = 1920, height = 1080, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1920, height = 1080, bpp = 1, bytesperline = 1920, sizeimage = 3110400
davinci_v4l2 davinci_v4l2.1: Before finishing with S_FMT:
layer.pix_fmt.bytesperline = 1920,
layer.pix_fmt.width = 1920,
layer.pix_fmt.height = 1080,
layer.pix_fmt.sizeimage =3110400
davinci_v4l2 davinci_v4l2.1: pixfmt->width = 1920,
layer->layer_info.config.line_length= 1920
6.There's a application can do H.264 RTP which included in my dmai_2_20_00_15 patch called video_encode_rtp.
This application get frames from camera through VPFE then encoded in H.264 format packeted with H264RTP packet then send to network.
From LeopardBoard DM368
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_encode_rtp_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o 192.168.168.72 -p 1234 -e encode -b 2000000
-I camera = camera input
-y 4 = 720P,
-o 192.168.168.72 = Send to 192.168.168.72
-p 1234 = port 1234
-b 2000000 = Bit rate 2000000
I'm decoding the video stream with gstreamer on PC Ubuntu.
$ gst-launch udpsrc port=1234 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264" ! gstrtpjitterbuffer latency=100 ! rtph264depay ! ffdec_h264 ! xvimagesink
If the video frame sometimes droped, try larger gstrtpjitterbuffer latency = 200 / 300 / 500.
7.Full HD
From LeopardBoard DM368
-y 5 = 1080P
$ ./video_encode_rtp_dm368.x470MV -I camera -y 5 -c h264enc -i /dev/video0 -o 192.168.168.72 -p 1234 -e encode -b 2000000
1.Check kernel log to see if the dsplink related modules are loaded.
CMEMK module: built on Jun 14 2011 at 18:02:26
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
allocated heap buffer 0xc6000000 of size 0x4400000
heap fallback enabled - will try heap if pool buffer is not available
CMEM Range Overlaps Kernel Physical - allowing overlap
CMEM phys_start (0x1000) overlaps kernel (0x80000000 -> 0x83c00000)
cmemk initialized
IRQK module: built on Jun 14 2011 at 18:02:29
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/irq/src/module/irqk.c
irqk initialized
EDMAK module: built on Jun 14 2011 at 18:02:30
Reference Linux version 2.6.32
File /home/gigijoe/LeopardBoard/DM368/original/ti-dvsdk_dm368-evm_4_02_00_06/linuxutils_2_26_01_02/packages/ti/sdo/linuxutils/edma/src/module/edmak.c
2.If there are errors check /etc/init.d/loadmodule-rc. Below is mine
#!/bin/sh
# Default DM368 EVM Memory Map
#
# Start Addr Size Description
# -------------------------------------------
# 0x00001000 32K ARM TCM memory
# 0x80000000 48 MB Linux
# 0x83000000 12 MB Video driver memory (Linux)
# 0x83C00000 68 MB CMEM
# 0x88000000 BOTTOM ADDRESS
load () {
modprobe cmemk phys_start=0x83C00000 phys_end=0x88000000 allowOverlap=1 phys_start_1=0x00001000 phys_end_1=0x00008000 pools_1=1x28672 useHeapIfPoolUnavai
lable=1
modprobe irqk
modprobe edmak
modprobe dm365mmap
mknod /dev/dm365mmap c `awk "\\$2==\"dm365mmap\" {print \\$1}" /proc/devices` 0
}
unload () {
rmmod cmemk 2>/dev/null
rmmod irqk 2>/dev/null
rmmod edmak 2>/dev/null
rmmod dm365mmap 2>/dev/null
rm -f /dev/dm365mmap
}
case "$1" in
start)
load
;;
stop)
unload
;;
restart)
unload
load
;;
*)
echo "$0 "
;;
esac
3.Decode test to verify if DSP works.
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_decode_io2_dm368.x470MV -c h264dec -e decode -i /usr/share/ti/data/videos/davincieffect.264 -n 30 -o output.yuv
Starting application...
Loader created and primed, entering main loop..
Loaded Frame 1: frame size 401
Loaded Frame 2: frame size 36
Loaded Frame 3: frame size 804
Loaded Frame 4: frame size 844
Loaded Frame 5: frame size 863
Loaded Frame 6: frame size 933
Loaded Frame 7: frame size 1189
Loaded Frame 8: frame size 1253
Loaded Frame 9: frame size 1509
Display Frame 1: Wrote 420P frame size 1382400 (1280x720) to disk
Loaded Frame 10: frame size 1573
Display Frame 2: Wrote 420P frame size 1382400 (1280x720) to disk
Loaded Frame 11: frame size 1829
4.Now, it's time to encode video from camera. I got mt9p031 (LI-BCM5M03).
If you got kernel log below, the camera is ready
...
Leopard: switch to HD imager-MT9P031 video input
mt9p031 1-0048: Detected a MT9P031 chip ID 1801
mt9p031 1-0048: mt9p031 1-0048 decoder driver registered !!
vpfe-capture vpfe-capture: v4l2 sub device mt9p031 registered
...
5.Test if camera works
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_loopback_dm368.x470MV -O component -I camera -y5
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
Leopard: switch to HD imager-MT9P031 video input
-----Exposure time = 456
-----Exposure time = 456
vpfe-capture vpfe-capture: width = 1920, height = 1080, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1920, height = 1080, bpp = 1, bytesperline = 1920, sizeimage = 3110400
vpfe-capture vpfe-capture: width = 1920, height = 1080, bpp = 1
vpfe-capture vpfe-capture: adjusted width = 1920, height = 1080, bpp = 1, bytesperline = 1920, sizeimage = 3110400
davinci_v4l2 davinci_v4l2.1: Before finishing with S_FMT:
layer.pix_fmt.bytesperline = 1920,
layer.pix_fmt.width = 1920,
layer.pix_fmt.height = 1080,
layer.pix_fmt.sizeimage =3110400
davinci_v4l2 davinci_v4l2.1: pixfmt->width = 1920,
layer->layer_info.config.line_length= 1920
6.There's a application can do H.264 RTP which included in my dmai_2_20_00_15 patch called video_encode_rtp.
This application get frames from camera through VPFE then encoded in H.264 format packeted with H264RTP packet then send to network.
From LeopardBoard DM368
$ cd /usr/share/ti/ti-dmai-apps
$ ./video_encode_rtp_dm368.x470MV -I camera -y 4 -c h264enc -i /dev/video0 -o 192.168.168.72 -p 1234 -e encode -b 2000000
-I camera = camera input
-y 4 = 720P,
-o 192.168.168.72 = Send to 192.168.168.72
-p 1234 = port 1234
-b 2000000 = Bit rate 2000000
I'm decoding the video stream with gstreamer on PC Ubuntu.
$ gst-launch udpsrc port=1234 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264" ! gstrtpjitterbuffer latency=100 ! rtph264depay ! ffdec_h264 ! xvimagesink
If the video frame sometimes droped, try larger gstrtpjitterbuffer latency = 200 / 300 / 500.
7.Full HD
From LeopardBoard DM368
-y 5 = 1080P
$ ./video_encode_rtp_dm368.x470MV -I camera -y 5 -c h264enc -i /dev/video0 -o 192.168.168.72 -p 1234 -e encode -b 2000000
訂閱:
文章 (Atom)