在 Embedded system 上儲存空間是相當珍貴的,目前除了智慧型手機上有Giga等級的flash儲存空間,其他能有個8M flash已經是相當奢侈了.
在這麼小的flash中想用c++來program最大的問題就是libstdc++.so實在太肥了.
gigijoe@gigijoe-i5-2500k:/opt/arm-linux-uclibcgnueabi/lib$ ls libstdc++* -al
-rw-r--r-- 1 root root 7233624 8月 18 2010 libstdc++.a
-rwxr-xr-x 1 root root 1307 8月 18 2010 libstdc++.la
-rw-r--r-- 1 root root 7224318 8月 18 2010 libstdc++_pic.a
lrwxrwxrwx 1 root root 18 8月 18 2010 libstdc++.so -> libstdc++.so.6.0.8
lrwxrwxrwx 1 root root 18 8月 18 2010 libstdc++.so.6 -> libstdc++.so.6.0.8
-rwxr-xr-x 1 root root 3750191 8月 18 2010 libstdc++.so.6.0.8
這個library包含了c++ STL / dynamic_cast / exception等功能,往後c++11,c++14等規格再陸續實作後只會越來越大.那麼用c來program就好啦,幹嘛找麻煩用c++啊?
c++ 有許多feature能讓程式更加結構化並容易閱讀,例如 function overload.
物件導向所提供的 繼承 / 多型 更能讓整個程式有更多的彈性.
以下是在網路上找到的方式,我自己也驗證過可行.
限制是不能使用 STL / dynamic_cast / exception
http://ptspts.blogspot.tw/2010/12/how-to-write-c-program-without-libstdc.html
以g++ compile .cpp ( -fno-rtti -fno-exceptions ), 以 gcc link 所有的.o
gigijoe@gigijoe-i5-2500k:~/SourceCode/test$ ldd main
linux-gate.so.1 => (0xb773c000)
libpicowm.so (0xb7736000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7560000)
/lib/ld-linux.so.2 (0xb773d000)
libstdc++.so 已經不再需要囉 :)
2013年6月17日 星期一
2013年3月12日 星期二
Fixed-Point Fast Fourier Transform (FFT)
Fast Fourier Transform is very important for signal processing.
This time I will demostrate Fixed-Point FFT running on embedded system.
There's NO FPU on most of embedded CPU and most of implement of FFT using floating point variable.
This means bad performance of FFT calculation, so I found an Fixed-Point FFT library Written by Tom Roberts which fit the requirement.
The purpose of using FFT is to detect DTMF in 16 bits / 8k sample rate raw sound data.
DTMF is multi-frequency signal which mixture of two difference tone.
This is the foundation of modern telephone system.
1209 Hz 1336 Hz 1477 Hz
697 Hz 1 2 3
770 Hz 4 5 6
852 Hz 7 8 9
941 Hz * 0 #
The procdure to detect DTMF is to pass raw sound data into FFT then check frequency domain to determinate which frequencies with higher energy.
1.Fixed-Point FFT
The prototype of fix_fft function
int fix_fft(short fr[], short fi[], short m, short inverse)
fr[] is the real part array, fi[] is the imaginary part array.
m is power of 2 of the array size, the array size must be power of 2.
For example the array size is 256 (2^8) then m is 8.
Pass input sound data into fr[] and leave all zero to fi[]
Return value of fix_fft is useless while forward FFT.
The result of FFT is storing in fr[] and fi[].
2.Phyical of FFT
It's not hard to realize more input data lead to more precision of result.
The input sound data is 16 bit / 8k sample rate. Assume number of input samples is 256 (2^8)
So we have 256 buckets divided over 8khz, each bucket represents 31.25 hz ( 8k hz / 256).
But, the maximum frequency we can measure is half of the sampling rate so if we sample at 8Khz our maximum is 4Khz
(this is called the Nyquist frequency).
0.000000 ~ 31.250000hz
31.250000 ~ 62.500000hz
62.500000 ~ 93.750000hz
93.750000 ~ 125.000000hz
125.000000 ~ 156.250000hz
156.250000 ~ 187.500000hz
187.500000 ~ 218.750000hz
...
...
...
3812.500000 ~ 3843.750000hz
3843.750000 ~ 3875.000000hz
3875.000000 ~ 3906.250000hz
3906.250000 ~ 3937.500000hz
3937.500000 ~ 3968.750000hz
3968.750000 ~ 4000.000000hz
So, the frequency domain is from 0 ~ 4k hz and how about the energy of each frequency range ?
energy = sqrt(fr[i]^2 + fi[i]^2), where i form 0 to 127
Then check the higher energy (Threshold) of frequency and see if the frequency fit the range of DTMF tone.
3.The source code and result
fix_fft.c
dtmf_detect.c
T159.snd
The target machine is MIPS 4KEc running 162Mhz. No FPU support.
Enable DEBUG flag to see what's going on, but terrible performance due to printf()
1.5 second sound data takes more than 4 seconds to process.
$ ./dtmf_detect T159.snd
Detect None ...
Detect None ...
Detect None ...
Detect None ...
687.500000 ~ 718.750000hz : 2838
718.750000 ~ 750.000000hz : 2271
1218.750000 ~ 1250.000000hz : 3761
Max freq : 1218.750000 ~ 1218.750000hz (Value : 3761)
dtmf is 1
687.500000 ~ 718.750000hz : 3915
718.750000 ~ 750.000000hz : 2246
1218.750000 ~ 1250.000000hz : 4853
Max freq : 1218.750000 ~ 1218.750000hz (Value : 4853)
687.500000 ~ 718.750000hz : 3762
718.750000 ~ 750.000000hz : 2243
1218.750000 ~ 1250.000000hz : 6525
Max freq : 1218.750000 ~ 1218.750000hz (Value : 6525)
687.500000 ~ 718.750000hz : 4066
718.750000 ~ 750.000000hz : 2288
1218.750000 ~ 1250.000000hz : 5760
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5760)
687.500000 ~ 718.750000hz : 3601
718.750000 ~ 750.000000hz : 2086
1218.750000 ~ 1250.000000hz : 5968
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5968)
687.500000 ~ 718.750000hz : 4108
718.750000 ~ 750.000000hz : 2375
1218.750000 ~ 1250.000000hz : 6532
Max freq : 1218.750000 ~ 1218.750000hz (Value : 6532)
687.500000 ~ 718.750000hz : 3330
718.750000 ~ 750.000000hz : 2034
1218.750000 ~ 1250.000000hz : 4783
Max freq : 1218.750000 ~ 1218.750000hz (Value : 4783)
687.500000 ~ 718.750000hz : 3717
718.750000 ~ 750.000000hz : 2401
1218.750000 ~ 1250.000000hz : 5406
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5406)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
750.000000 ~ 781.250000hz : 2635
781.250000 ~ 812.500000hz : 2451
1312.500000 ~ 1343.750000hz : 2238
1343.750000 ~ 1375.000000hz : 2872
Max freq : 1343.750000 ~ 1343.750000hz (Value : 2872)
dtmf is 5
750.000000 ~ 781.250000hz : 3027
781.250000 ~ 812.500000hz : 3084
1312.500000 ~ 1343.750000hz : 2692
1343.750000 ~ 1375.000000hz : 4415
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4415)
750.000000 ~ 781.250000hz : 3119
781.250000 ~ 812.500000hz : 3196
1312.500000 ~ 1343.750000hz : 3174
1343.750000 ~ 1375.000000hz : 4766
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4766)
750.000000 ~ 781.250000hz : 3127
781.250000 ~ 812.500000hz : 3333
1312.500000 ~ 1343.750000hz : 3198
1343.750000 ~ 1375.000000hz : 4750
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4750)
750.000000 ~ 781.250000hz : 3129
781.250000 ~ 812.500000hz : 3451
1312.500000 ~ 1343.750000hz : 2803
1343.750000 ~ 1375.000000hz : 4114
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4114)
750.000000 ~ 781.250000hz : 3143
781.250000 ~ 812.500000hz : 3534
1312.500000 ~ 1343.750000hz : 3393
1343.750000 ~ 1375.000000hz : 4978
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4978)
750.000000 ~ 781.250000hz : 3144
781.250000 ~ 812.500000hz : 3561
1312.500000 ~ 1343.750000hz : 2593
1343.750000 ~ 1375.000000hz : 3631
Max freq : 1343.750000 ~ 1343.750000hz (Value : 3631)
750.000000 ~ 781.250000hz : 3195
781.250000 ~ 812.500000hz : 3544
1312.500000 ~ 1343.750000hz : 3246
1343.750000 ~ 1375.000000hz : 4971
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4971)
1312.500000 ~ 1343.750000hz : 2850
1343.750000 ~ 1375.000000hz : 2935
Max freq : 1343.750000 ~ 1343.750000hz (Value : 2935)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
843.750000 ~ 875.000000hz : 3998
1468.750000 ~ 1500.000000hz : 5109
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5109)
dtmf is 9
843.750000 ~ 875.000000hz : 4803
1468.750000 ~ 1500.000000hz : 6069
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6069)
843.750000 ~ 875.000000hz : 4620
1468.750000 ~ 1500.000000hz : 5350
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5350)
843.750000 ~ 875.000000hz : 5024
1468.750000 ~ 1500.000000hz : 6536
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6536)
843.750000 ~ 875.000000hz : 4157
1468.750000 ~ 1500.000000hz : 5645
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5645)
843.750000 ~ 875.000000hz : 5140
1468.750000 ~ 1500.000000hz : 5768
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5768)
843.750000 ~ 875.000000hz : 3629
1468.750000 ~ 1500.000000hz : 6446
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6446)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Number samples : 12544, Duration : 4 seconds and 84537 usecs
Disable DEBUG with good performance.
1.5 second sound data takes 31.346 ms to process.
$ ./dtmf_detect T159.snd
dtmf is 1
dtmf is 5
dtmf is 9
Number samples : 12544, Duration : 0 seconds and 31346 usecs
This time I will demostrate Fixed-Point FFT running on embedded system.
There's NO FPU on most of embedded CPU and most of implement of FFT using floating point variable.
This means bad performance of FFT calculation, so I found an Fixed-Point FFT library Written by Tom Roberts which fit the requirement.
The purpose of using FFT is to detect DTMF in 16 bits / 8k sample rate raw sound data.
DTMF is multi-frequency signal which mixture of two difference tone.
This is the foundation of modern telephone system.
1209 Hz 1336 Hz 1477 Hz
697 Hz 1 2 3
770 Hz 4 5 6
852 Hz 7 8 9
941 Hz * 0 #
The procdure to detect DTMF is to pass raw sound data into FFT then check frequency domain to determinate which frequencies with higher energy.
1.Fixed-Point FFT
The prototype of fix_fft function
int fix_fft(short fr[], short fi[], short m, short inverse)
fr[] is the real part array, fi[] is the imaginary part array.
m is power of 2 of the array size, the array size must be power of 2.
For example the array size is 256 (2^8) then m is 8.
Pass input sound data into fr[] and leave all zero to fi[]
Return value of fix_fft is useless while forward FFT.
The result of FFT is storing in fr[] and fi[].
2.Phyical of FFT
It's not hard to realize more input data lead to more precision of result.
The input sound data is 16 bit / 8k sample rate. Assume number of input samples is 256 (2^8)
So we have 256 buckets divided over 8khz, each bucket represents 31.25 hz ( 8k hz / 256).
But, the maximum frequency we can measure is half of the sampling rate so if we sample at 8Khz our maximum is 4Khz
(this is called the Nyquist frequency).
0.000000 ~ 31.250000hz
31.250000 ~ 62.500000hz
62.500000 ~ 93.750000hz
93.750000 ~ 125.000000hz
125.000000 ~ 156.250000hz
156.250000 ~ 187.500000hz
187.500000 ~ 218.750000hz
...
...
...
3812.500000 ~ 3843.750000hz
3843.750000 ~ 3875.000000hz
3875.000000 ~ 3906.250000hz
3906.250000 ~ 3937.500000hz
3937.500000 ~ 3968.750000hz
3968.750000 ~ 4000.000000hz
So, the frequency domain is from 0 ~ 4k hz and how about the energy of each frequency range ?
energy = sqrt(fr[i]^2 + fi[i]^2), where i form 0 to 127
Then check the higher energy (Threshold) of frequency and see if the frequency fit the range of DTMF tone.
3.The source code and result
fix_fft.c
dtmf_detect.c
T159.snd
The target machine is MIPS 4KEc running 162Mhz. No FPU support.
Enable DEBUG flag to see what's going on, but terrible performance due to printf()
1.5 second sound data takes more than 4 seconds to process.
$ ./dtmf_detect T159.snd
Detect None ...
Detect None ...
Detect None ...
Detect None ...
687.500000 ~ 718.750000hz : 2838
718.750000 ~ 750.000000hz : 2271
1218.750000 ~ 1250.000000hz : 3761
Max freq : 1218.750000 ~ 1218.750000hz (Value : 3761)
dtmf is 1
687.500000 ~ 718.750000hz : 3915
718.750000 ~ 750.000000hz : 2246
1218.750000 ~ 1250.000000hz : 4853
Max freq : 1218.750000 ~ 1218.750000hz (Value : 4853)
687.500000 ~ 718.750000hz : 3762
718.750000 ~ 750.000000hz : 2243
1218.750000 ~ 1250.000000hz : 6525
Max freq : 1218.750000 ~ 1218.750000hz (Value : 6525)
687.500000 ~ 718.750000hz : 4066
718.750000 ~ 750.000000hz : 2288
1218.750000 ~ 1250.000000hz : 5760
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5760)
687.500000 ~ 718.750000hz : 3601
718.750000 ~ 750.000000hz : 2086
1218.750000 ~ 1250.000000hz : 5968
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5968)
687.500000 ~ 718.750000hz : 4108
718.750000 ~ 750.000000hz : 2375
1218.750000 ~ 1250.000000hz : 6532
Max freq : 1218.750000 ~ 1218.750000hz (Value : 6532)
687.500000 ~ 718.750000hz : 3330
718.750000 ~ 750.000000hz : 2034
1218.750000 ~ 1250.000000hz : 4783
Max freq : 1218.750000 ~ 1218.750000hz (Value : 4783)
687.500000 ~ 718.750000hz : 3717
718.750000 ~ 750.000000hz : 2401
1218.750000 ~ 1250.000000hz : 5406
Max freq : 1218.750000 ~ 1218.750000hz (Value : 5406)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
750.000000 ~ 781.250000hz : 2635
781.250000 ~ 812.500000hz : 2451
1312.500000 ~ 1343.750000hz : 2238
1343.750000 ~ 1375.000000hz : 2872
Max freq : 1343.750000 ~ 1343.750000hz (Value : 2872)
dtmf is 5
750.000000 ~ 781.250000hz : 3027
781.250000 ~ 812.500000hz : 3084
1312.500000 ~ 1343.750000hz : 2692
1343.750000 ~ 1375.000000hz : 4415
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4415)
750.000000 ~ 781.250000hz : 3119
781.250000 ~ 812.500000hz : 3196
1312.500000 ~ 1343.750000hz : 3174
1343.750000 ~ 1375.000000hz : 4766
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4766)
750.000000 ~ 781.250000hz : 3127
781.250000 ~ 812.500000hz : 3333
1312.500000 ~ 1343.750000hz : 3198
1343.750000 ~ 1375.000000hz : 4750
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4750)
750.000000 ~ 781.250000hz : 3129
781.250000 ~ 812.500000hz : 3451
1312.500000 ~ 1343.750000hz : 2803
1343.750000 ~ 1375.000000hz : 4114
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4114)
750.000000 ~ 781.250000hz : 3143
781.250000 ~ 812.500000hz : 3534
1312.500000 ~ 1343.750000hz : 3393
1343.750000 ~ 1375.000000hz : 4978
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4978)
750.000000 ~ 781.250000hz : 3144
781.250000 ~ 812.500000hz : 3561
1312.500000 ~ 1343.750000hz : 2593
1343.750000 ~ 1375.000000hz : 3631
Max freq : 1343.750000 ~ 1343.750000hz (Value : 3631)
750.000000 ~ 781.250000hz : 3195
781.250000 ~ 812.500000hz : 3544
1312.500000 ~ 1343.750000hz : 3246
1343.750000 ~ 1375.000000hz : 4971
Max freq : 1343.750000 ~ 1343.750000hz (Value : 4971)
1312.500000 ~ 1343.750000hz : 2850
1343.750000 ~ 1375.000000hz : 2935
Max freq : 1343.750000 ~ 1343.750000hz (Value : 2935)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Detect None ...
843.750000 ~ 875.000000hz : 3998
1468.750000 ~ 1500.000000hz : 5109
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5109)
dtmf is 9
843.750000 ~ 875.000000hz : 4803
1468.750000 ~ 1500.000000hz : 6069
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6069)
843.750000 ~ 875.000000hz : 4620
1468.750000 ~ 1500.000000hz : 5350
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5350)
843.750000 ~ 875.000000hz : 5024
1468.750000 ~ 1500.000000hz : 6536
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6536)
843.750000 ~ 875.000000hz : 4157
1468.750000 ~ 1500.000000hz : 5645
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5645)
843.750000 ~ 875.000000hz : 5140
1468.750000 ~ 1500.000000hz : 5768
Max freq : 1468.750000 ~ 1468.750000hz (Value : 5768)
843.750000 ~ 875.000000hz : 3629
1468.750000 ~ 1500.000000hz : 6446
Max freq : 1468.750000 ~ 1468.750000hz (Value : 6446)
Detect None ...
Detect None ...
Detect None ...
Detect None ...
Number samples : 12544, Duration : 4 seconds and 84537 usecs
Disable DEBUG with good performance.
1.5 second sound data takes 31.346 ms to process.
$ ./dtmf_detect T159.snd
dtmf is 1
dtmf is 5
dtmf is 9
Number samples : 12544, Duration : 0 seconds and 31346 usecs
2012年8月6日 星期一
OpenCV 2.4.2 V4L2 Camera resolution bug fix
When using camera with opencv api, the default camera resolution is ALWAYS 160x120
From source code modules/highgui/src/cap_libv4l.cpp the default resolution should be 640x480
/* Defaults - If your board can do better, set it here. Set for the most common type inputs. */
#define DEFAULT_V4L_WIDTH 640
#define DEFAULT_V4L_HEIGHT 480
I have study a little bit of modules/highgui/src/cap_libv4l.cpp then I found the problem.
CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
if (!capture) {
fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n");
return NULL;
}
/* set the default size */
capture->width = DEFAULT_V4L_WIDTH;
capture->height = DEFAULT_V4L_HEIGHT;
...
...
/* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
if (_capture_V4L2 (capture, deviceName) == -1) {
The memset instruction is called after setting width & height. @@
So, just move up memset behind alloc memory.
--- modules/highgui/src/cap_libv4l.cpp.org 2012-08-06 19:28:58.746347834 +0800
+++ modules/highgui/src/cap_libv4l.cpp 2012-08-06 19:29:42.510348966 +0800
@@ -1007,6 +1007,9 @@
return NULL;
}
+ /* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
+ memset(capture,0,sizeof(CvCaptureCAM_V4L));
+
/* set the default size */
capture->width = DEFAULT_V4L_WIDTH;
capture->height = DEFAULT_V4L_HEIGHT;
@@ -1028,8 +1031,6 @@
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(deviceName, "/dev/video%1d", index);
- /* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
- memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
From source code modules/highgui/src/cap_libv4l.cpp the default resolution should be 640x480
/* Defaults - If your board can do better, set it here. Set for the most common type inputs. */
#define DEFAULT_V4L_WIDTH 640
#define DEFAULT_V4L_HEIGHT 480
I have study a little bit of modules/highgui/src/cap_libv4l.cpp then I found the problem.
CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
if (!capture) {
fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n");
return NULL;
}
/* set the default size */
capture->width = DEFAULT_V4L_WIDTH;
capture->height = DEFAULT_V4L_HEIGHT;
...
...
/* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
if (_capture_V4L2 (capture, deviceName) == -1) {
The memset instruction is called after setting width & height. @@
So, just move up memset behind alloc memory.
--- modules/highgui/src/cap_libv4l.cpp.org 2012-08-06 19:28:58.746347834 +0800
+++ modules/highgui/src/cap_libv4l.cpp 2012-08-06 19:29:42.510348966 +0800
@@ -1007,6 +1007,9 @@
return NULL;
}
+ /* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
+ memset(capture,0,sizeof(CvCaptureCAM_V4L));
+
/* set the default size */
capture->width = DEFAULT_V4L_WIDTH;
capture->height = DEFAULT_V4L_HEIGHT;
@@ -1028,8 +1031,6 @@
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(deviceName, "/dev/video%1d", index);
- /* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
- memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
2012年7月22日 星期日
Ubuntu 12.04 stutter sound
The stuttering sound while playing mp3 or video bother me for a while.
After some googling I found solution
1.Edit
/etc/pulse/client.conf
from
; extra-arguments = --log-target=syslog
to
; extra-arguments = --log-target=syslog --resample-method=ffmpeg
2.Edit
/etc/modprobe.d/alsa-base.conf
Add
options snd-hda-intel model=generic
3.reboot
After some googling I found solution
1.Edit
/etc/pulse/client.conf
from
; extra-arguments = --log-target=syslog
to
; extra-arguments = --log-target=syslog --resample-method=ffmpeg
2.Edit
/etc/modprobe.d/alsa-base.conf
Add
options snd-hda-intel model=generic
3.reboot
2012年5月29日 星期二
S3C6410 MFC H.264 mp4 player (Bug fix)
In the previous post, I implement an mp4 player.
There's a problem confuse me.
The start of video frame seems broken. Then after some time (maybe seconds) the video frame goes well.
Finally, I found a way to solve it.
Just to decode the first frame twice. Really strange but work. Also there's some minor fix included
https://docs.google.com/open?id=0Bx901QMLr9WlVE1ldHVCaERkRkk
Patch
--- /home/gigijoe/mp4player.c 2012-05-29 16:11:06.094007930 +0800
+++ mp4player.c 2012-05-29 16:17:55.073995127 +0800
@@ -176,8 +176,12 @@
pp_param.dst_width = pp_param.dst_full_width;
pp_param.dst_height = pp_param.dst_full_height;
pp_param.dst_color_space = FB0_COLOR_SPACE;
+#if 1
pp_param.out_path = DMA_ONESHOT;
-
+#else
+ pp_param.out_path = FIFO_FREERUN;
+ pp_param.scan_mode = PROGRESSIVE_MODE;
+#endif
ioctl(pp_fd, S3C_PP_SET_PARAMS, &pp_param);
printf("stream width %d, height %d\n", pp_param.src_full_width, pp_param.src_full_height);
@@ -193,7 +197,7 @@
return -1;
}
- memset(fb_addr, 0, fb_size);
+ //memset(fb_addr, 0, fb_size);
s3c_win_info_t osd_info_to_driver;
osd_info_to_driver.Bpp = FB0_BPP; // RGB16
@@ -212,6 +216,13 @@
initialize = 1;
//return 0;
+/*
+* Decode first frame again to avoid problem ...
+*/
+ if(SsbSipH264DecodeExe(handle, len) != SSBSIP_H264_DEC_RET_OK) {
+ printf("MFC Decoder Configuration Failed.\n");
+ return -1;
+ }
}
unsigned int pYUVBuf[2];
@@ -229,6 +240,12 @@
ioctl(fb_fd, FBIOGET_FSCREENINFO, &lcd_info);
pp_param.dst_buf_addr_phy = lcd_info.smem_start; // LCD frame buffer
ioctl(pp_fd, S3C_PP_SET_DST_BUF_ADDR_PHY, &pp_param);
+
+ struct pollfd test_fd;
+ test_fd.fd = pp_fd;
+ test_fd.events = POLLOUT|POLLERR;
+ poll(&test_fd, 1, 3000);
+
ioctl(pp_fd, S3C_PP_START);
return 0;
@@ -342,12 +359,15 @@
AVCodecContext *codecContext = is->codec;
long long delay = (1000000 * is->r_frame_rate.den) / (is->r_frame_rate.num);
-
-#if 0
+#if 1
i = 0;
#endif
while(1) {
r = av_read_frame(formatContext, &pkt);
+ if(r != 0) { /* No more frame, seek head and replay */
+ av_seek_frame(formatContext, 0, 1, AVSEEK_FLAG_BACKWARD);
+ r = av_read_frame(formatContext, &pkt);
+ }
if(r != 0)
break; /* No more frame */
@@ -367,11 +387,16 @@
i, pkt.stream_index, pkt.dts, pkt.size, pkt.data);
av_pkt_dump(stdout, &pkt, 0);
#endif
+ if(pkt.flags & PKT_FLAG_KEY)
+ printf("Key frame %d\n", i);
unsigned char *lp = 0;
int len = 0;
- filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
-
+ // filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
+ r = filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags));
+ if(r != 1)
+ printf("Frame %d : Fail to filter ...\n", i);
+//printf("Frame %d: %d\n", pkt.stream_index, len);
decode_mfc(lp, len);
av_free_packet(&pkt);
@@ -393,7 +418,7 @@
} else
break;
}
-#if 0
+#if 1
i++;
#endif
}
@@ -403,6 +428,10 @@
avcodec_close(is->codec);
+ munmap(fb_addr, fb_size);
+ close(pp_fd);
+ close(fb_fd);
+
deinit_mfc();
return 0;
There's a problem confuse me.
The start of video frame seems broken. Then after some time (maybe seconds) the video frame goes well.
Finally, I found a way to solve it.
Just to decode the first frame twice. Really strange but work. Also there's some minor fix included
https://docs.google.com/open?id=0Bx901QMLr9WlVE1ldHVCaERkRkk
Patch
--- /home/gigijoe/mp4player.c 2012-05-29 16:11:06.094007930 +0800
+++ mp4player.c 2012-05-29 16:17:55.073995127 +0800
@@ -176,8 +176,12 @@
pp_param.dst_width = pp_param.dst_full_width;
pp_param.dst_height = pp_param.dst_full_height;
pp_param.dst_color_space = FB0_COLOR_SPACE;
+#if 1
pp_param.out_path = DMA_ONESHOT;
-
+#else
+ pp_param.out_path = FIFO_FREERUN;
+ pp_param.scan_mode = PROGRESSIVE_MODE;
+#endif
ioctl(pp_fd, S3C_PP_SET_PARAMS, &pp_param);
printf("stream width %d, height %d\n", pp_param.src_full_width, pp_param.src_full_height);
@@ -193,7 +197,7 @@
return -1;
}
- memset(fb_addr, 0, fb_size);
+ //memset(fb_addr, 0, fb_size);
s3c_win_info_t osd_info_to_driver;
osd_info_to_driver.Bpp = FB0_BPP; // RGB16
@@ -212,6 +216,13 @@
initialize = 1;
//return 0;
+/*
+* Decode first frame again to avoid problem ...
+*/
+ if(SsbSipH264DecodeExe(handle, len) != SSBSIP_H264_DEC_RET_OK) {
+ printf("MFC Decoder Configuration Failed.\n");
+ return -1;
+ }
}
unsigned int pYUVBuf[2];
@@ -229,6 +240,12 @@
ioctl(fb_fd, FBIOGET_FSCREENINFO, &lcd_info);
pp_param.dst_buf_addr_phy = lcd_info.smem_start; // LCD frame buffer
ioctl(pp_fd, S3C_PP_SET_DST_BUF_ADDR_PHY, &pp_param);
+
+ struct pollfd test_fd;
+ test_fd.fd = pp_fd;
+ test_fd.events = POLLOUT|POLLERR;
+ poll(&test_fd, 1, 3000);
+
ioctl(pp_fd, S3C_PP_START);
return 0;
@@ -342,12 +359,15 @@
AVCodecContext *codecContext = is->codec;
long long delay = (1000000 * is->r_frame_rate.den) / (is->r_frame_rate.num);
-
-#if 0
+#if 1
i = 0;
#endif
while(1) {
r = av_read_frame(formatContext, &pkt);
+ if(r != 0) { /* No more frame, seek head and replay */
+ av_seek_frame(formatContext, 0, 1, AVSEEK_FLAG_BACKWARD);
+ r = av_read_frame(formatContext, &pkt);
+ }
if(r != 0)
break; /* No more frame */
@@ -367,11 +387,16 @@
i, pkt.stream_index, pkt.dts, pkt.size, pkt.data);
av_pkt_dump(stdout, &pkt, 0);
#endif
+ if(pkt.flags & PKT_FLAG_KEY)
+ printf("Key frame %d\n", i);
unsigned char *lp = 0;
int len = 0;
- filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
-
+ // filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
+ r = filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags));
+ if(r != 1)
+ printf("Frame %d : Fail to filter ...\n", i);
+//printf("Frame %d: %d\n", pkt.stream_index, len);
decode_mfc(lp, len);
av_free_packet(&pkt);
@@ -393,7 +418,7 @@
} else
break;
}
-#if 0
+#if 1
i++;
#endif
}
@@ -403,6 +428,10 @@
avcodec_close(is->codec);
+ munmap(fb_addr, fb_size);
+ close(pp_fd);
+ close(fb_fd);
+
deinit_mfc();
return 0;
2012年4月10日 星期二
S3C6410 MFC H.264 mp4 player
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);
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年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就解決囉
訂閱:
文章 (Atom)