ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年6月29日 星期三

提供 camera service 的好像是
/framework/base/service/camera -- libcameraservice
使用這個 share library 的 有
  1. /framework/base/media/mediaserver
  2. /framework/base/cmds/system_server/library -- linked by system_serer
mediaserver 很有趣,就只有: int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); LOGI("ServiceManager: %p", sm.get()); AudioFlinger::instantiate(); MediaPlayerService::instantiate(); CameraService::instantiate(); AudioPolicyService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
CameraService 跟 Surface, Overlay 相關的部份,大概是 CameraService::Client::setOverlay() CameraService::Client::registerPreviewBuffers() 這兩個 function 的 format 都是 hard-coded:

setOverlay: mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_YCbCr_420_SP, mOrientation);
registerPreviewBuffers: ISurface::BufferHeap buffers(w, h, w, h, HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0, mHardware->getPreviewHeap()); 這個 FORMAT_YCrCb_420_SP 是如何決定的?


FORMAT
hardware/libhardware/include/hardware/hardware.h enum { HAL_PIXEL_FORMAT_RGBA_8888 = 1, HAL_PIXEL_FORMAT_RGBX_8888 = 2, HAL_PIXEL_FORMAT_RGB_888 = 3, HAL_PIXEL_FORMAT_RGB_565 = 4, HAL_PIXEL_FORMAT_BGRA_8888 = 5, HAL_PIXEL_FORMAT_RGBA_5551 = 6, HAL_PIXEL_FORMAT_RGBA_4444 = 7, HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar /* Legacy formats (deprecated), used by ImageFormat.java */ HAL_PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16 HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21 HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x12, // NV16 HAL_PIXEL_FORMAT_YCbCr_420_I = 0x13, // NV16 HAL_PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2 };

hardware/libhardware/include/hardware/overlay.h: enum { OVERLAY_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, OVERLAY_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, OVERLAY_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, OVERLAY_FORMAT_YCbCr_420_SP = HAL_PIXEL_FORMAT_YCbCr_420_SP, OVERLAY_FORMAT_YCbYCr_422_I = 0x14, OVERLAY_FORMAT_CbYCrY_422_I = 0x16, OVERLAY_FORMAT_DEFAULT = 99 // The actual color format is determined // by the overlay };

android : hw_get_module

其實就是load .so.
Android 自己寫了一個 load so 的 interface。讓 hw vendor 可以 implement 自己的 so.
framework 就用 hw_get_module( ) 來load hardware vendor 的 so. 。

so 與 load function 是用 id 來辨識的。
像:
frameworks/base/libs/ui/Overlay.cpp
frameworks/base/services/surfaceflinger/DisplayHardware/DisplayHardware.cp
都有.

hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) 這個呼叫。 實際上會 link 到 (以 imx51 為例):
hardware/mx5x/liboverlay/
這個 .so



找一下 hw_get_module...總共出現
     ALSA_HARDWARE_MODULE_ID
ACOUSTICS_HARDWARE_MODULE_ID
  SENSORS_HARDWARE_MODULE_ID,
  COPYBIT_HARDWARE_MODULE_ID,
  OVERLAY_HARDWARE_MODULE_ID,
   LIGHTS_HARDWARE_MODULE_ID,
      GPS_HARDWARE_MODULE_ID

android - surfaceflinger screenshot example

android surfaceflinger 有包含 example code ,在 tests 這個 folder. frameworks/base/services/surfaceflinger/tests/ 其中 screencap 是作 螢幕抓圖 (screenshoot) 的範例。 int main(int argc, char** argv) { if (argc != 2) { printf("usage: %s path\n", argv[0]); exit(0); } const String16 name("SurfaceFlinger"); sp<ISurfaceComposer> composer; getService(name, &composer); sp<IMemoryHeap> heap; uint32_t w, h; PixelFormat f; status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0); if (err != NO_ERROR) { fprintf(stderr, "screen capture failed: %s\n", strerror(-err)); exit(0); } printf("screen capture success: w=%u, h=%u, pixels=%p\n", w, h, heap->getBase()); printf("saving file as PNG in %s ...\n", argv[1]); SkBitmap b; b.setConfig(SkBitmap::kARGB_8888_Config, w, h); b.setPixels(heap->getBase()); SkImageEncoder::EncodeFile(argv[1], b, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality); return 0; } 大概就是: 1.請求 SurfaceFlinger Service 抓圖 2.交給 Skia 轉成PNG檔

2011年6月28日 星期二

Android : call getISurface( )

SurfaceControl和 Surface 的 getISurface( ) 是 private。 但是允許幾個 class 可以 direct call,所以宣告了幾個 friend class.: /* * Android frameworks friends * (eventually this should go away and be replaced by proper APIs) */ // camera and camcorder need access to the ISurface binder interface for preview friend class Camera; friend class MediaRecorder; // MediaPlayer needs access to ISurface for display friend class MediaPlayer; friend class IOMX; // this is just to be able to write some unit tests friend class Test; 其中的 class Test 是給方便用的。 所以..要用的話,就: namespace android { class Test { public: static const sp<ISurface> getISurface(const sp<SurfaceControl>& s) { return s->getISurface(); } } }; 這樣,就可以.. sp<ISurface> isurface = Test::getISurface(surface);

2011年6月23日 星期四

本來要找 vidioc_int_g_parm 找不到,只好找唯一有 vidioc_int_g_parm 字樣的 header : include/media/v4l2-int-device.h 然後就有: V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); MACRO 的內容是: #define V4L2_INT_WRAPPER_1(name, arg_type, asterisk) \ static inline int vidioc_int_##name(struct v4l2_int_device *d, \ arg_type asterisk arg) \ { \ return v4l2_int_ioctl_1(d, vidioc_int_##name##_num, \ (void *)(unsigned long)arg); \ } \ \ static inline struct v4l2_int_ioctl_desc \ vidioc_int_##name##_cb(int (*func) \ (struct v4l2_int_device *, \ arg_type asterisk)) \ { \ struct v4l2_int_ioctl_desc desc; \ \ desc.num = vidioc_int_##name##_num; \ desc.func = (v4l2_int_ioctl_func *)func; \ \ return desc; \ } 所以實際上call 的是 v4l2_int_ioctl_1 在 drivers/media/video/v4l2-int-device.c:155:int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg) int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg) { return ((v4l2_int_ioctl_func_1 *) find_ioctl(d->u.slave, cmd, (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg); } 一樣的.. static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd, v4l2_int_ioctl_func *no_such_ioctl) { const struct v4l2_int_ioctl_desc *first = slave->ioctls; const struct v4l2_int_ioctl_desc *last = first + slave->num_ioctls - 1; while (first <= last) { const struct v4l2_int_ioctl_desc *mid; mid = (last - first) / 2 + first; if (mid->num < cmd) first = mid + 1; else if (mid->num > cmd) last = mid - 1; else return mid->func; } return no_such_ioctl; } 只是在找對應 num 的 function. 這個 num - fun 列表在 register 的時候告訴vl2d, 然後這一段有點麻煩,直接看 num - function 的對應表好了: drivers/media/video/mxc/capture/adv7180.c 列表: static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = { .... {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm}, .... 也就是 call ioctl_g_parm..
然後看一下 struct v4l2_streamparm struct v4l2_streamparm { enum v4l2_buf_type type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; __u8 raw_data[200]; /* user-defined */ } parm; }; 附帶看一下 v4l2_bug_type: enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, #if 1 /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, };
VIDIOC_S_FMT: 主要在設定.. cam->v2f.fmt.fix
另外, VIDIOC_G_STD 可以用來取得 camera in video 的 standard (NTSC, PAL ..etc). 這個 function 會 call.. tv_fmt.type = V4L2_BUF_TYPE_PRIVATE; vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt); if (cam->standard_autodetect) { if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) { printk("MVC: mxc_v4l2_g_std: " "Changing standard\n"); mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat); } } *e = tv_fmt.fmt.pix.pixelformat; 會呼叫 vidioc_int_g_fmt_cap ,在 type = V4L2_BUF_TYPE_PRIVATE 時,會是 case V4L2_BUF_TYPE_PRIVATE: { v4l2_std_id std; adv7180_get_std(&std); printk(" Returning size of %d\n",std); f->fmt.pix.pixelformat = (u32)std; } break; 也就是 call adv7180 的 autodetect function 找出目前 video 的 standard.並且呼叫 s_std( ) 修改內部的變數 (所以不用再 call VIDIOC_S_STD) 總結:接 ADV7180 時,要call VIDIOC_G_STD, 讓 adv7180 重新 probe video standard。 probe 完後,v4l2 camera 的 format 應該已經設對了。 然後用 VIDIOC_G_FMT (type=V4L2_BUF_TYPE_VIDEO_CAPTURE) 取出 fmt.pix (w.h).

2011年6月22日 星期三

Android - lunch & choosecombo

只是筆記.. choosecombo 最後 call : set_stuff_for_environment. lunch 最後 call : set_stuff_for_environment. 所以最後都是一樣的。 function set_stuff_for_environment() { settitle set_java_home setpaths set_sequence_number export ANDROID_BUILD_TOP=$(gettop) }

2011年6月21日 星期二

SD Read Write Test -- force drop cache

只是要寫一個SD Card 讀寫檔案的速度測試。 簡單就是: 寫 100M, 紀錄時間,讀100M 紀錄時間。 結果: read 變成超快(200多MB/s),因為 linux cached 住剛剛用過的檔案。所以不會由 SD card 重新讀取。 follow jserv 這一篇 http://blog.linux.org.tw/~jserv/archives/002039.html 手動把 kernel cache drop 掉,再測就OK 了。 drop 的 function 是: void syncAndDropCache(void) { int fd; ssize_t s; sync(); fd = open("/proc/sys/vm/drop_caches",O_WRONLY); if(fd<0){ printf("open vm failed\n"); return; } s = write(fd,"3",2); if(s<0){ printf("write vm failed\n"); close(fd); return; } close(fd); sleep(2); } 整個 code 在 github: https://github.com/checko/SDReadWriteSpeed

2011年6月20日 星期一

android - sdcard_perf_test

android source 有附一個 sdcard performance test 的 code: system/extra/tests/sdcard 其中的 README 有詳細說明使用方法。 或是用sdcard_perf_test -h顯示 option 這個會用到 debugfs -- kernel/sched_feature. 所以要 enable kernel_debug 和 sched_xxx 才會產生。 Collect scheduler debugging info

2011年6月16日 星期四

code reading - fb_test.c

在 system/extra/tests/framebuffer
gr_fb_fd 就是 open /dev/graphics/fb0 的 handle. access("/dev/tty0",F_OK) : 用 access (unistd.h) 來 check 是否對 /dev/tty0 有 read/write 權限。 然後用 KDSETMODE,把 famebuffer 設定在圖形模式 fd = open("/dev/tty0", O_RDWR | O_SYNC); if(fd < 0) return -1; if(ioctl(fd, KDSETMODE, (void*) KD_GRAPHICS)) { close(fd); return -1; } framebuffer 的 information 有 fix, var 兩種,分別以兩種 structure 處理: fb_fix_screeninfo, fb_var_screeninfo. GGLSurface 這個 structure 宣告在 system/core/include/pixelflinger/pixelflinger.h. --- 所以是 android 獨有的。 typedef struct { GGLsizei version; // always set to sizeof(GGLSurface) GGLuint width; // width in pixels GGLuint height; // height in pixels GGLint stride; // stride in pixels GGLubyte* data; // pointer to the bits GGLubyte format; // pixel format GGLubyte rfu[3]; // must be zero // these values are dependent on the used format union { GGLint compressedFormat; GGLint vstride; }; void* reserved; } GGLSurface; 沒什麼特殊的呀,就是多了 stride 這個 field. 其中有 set_active_framebuffer.. static void set_active_framebuffer(unsigned n) { if(n > 1) return; vi.yres_virtual = vi.yres * 2; vi.yoffset = n * vi.yres; if(ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { fprintf(stderr,"active fb swap failed!\n"); } else printf("active buffer: %d\n", n); } 參考文件是說,android 支援 page flipping,會先request 兩倍大的記憶體,然後靠著更改 start mapping 的位置 (offset) ,來顯示 第 0 或 第 1 頁。 上面的 code大概就是這樣吧。 (vi.yoffset = n * yres).
ref : http://blogold.chinaunix.net/u3/104807/showart_2162774.html -- android fb double buffering

2011年6月14日 星期二

Write additional rules on Android.mk

上篇,要在 Android.mk 加入某個 rule. 還挺麻煩˙




應用範例是

這樣:



因為用了某
大陸廠的 3g module,然後 usb-uart com port 的 access 說明又不清楚。

只好請他們提供 android 3g script,結果.. 他們就改了 hardware/ril 下的幾個檔。


因為是大陸廠商,所以修改後的 code 當然是不會給 (也還好,因為是 apache license)。


所以拿到的只是幾個 so.




這下就麻煩,要整合進 Android Makefile 里。

用 BUILD_PREBUILT - 結果這個不會建立 dependent ta
rget。
所以make system 會出現 no rule to make ***.so




在 build/core/ 里又找不到適合的 build rule。
所以只好自己寫在 Android.mk 里...

先從 build error 來看:


make: *** No rule to make target `out/target/product/stingy/obj/lib/libstingy.so',
needed by `out/target/product/stingy/obj/EXECUTABLES/rild_intermediates/LINKED/stingyd'
. Stop.

所以知道需要建立的 rule target 是



out/target/product/stingy/obj/lib/libstingy.so :
acp -e hardware/ril/stingy/libstingy.so out/targ
et/product/stingy/obj/lib/libstingy.so



要注意,使
用 Android.mk 中的 LOCAL_MODULE, TARGET_OUT 這些變數,在 #include (XXX) 後,會改變。
所以就直接寫出來..

繼續 make..
error 變成:
make: *** No rule to make target `out/target/product/stingy/system/lib/libstingy.so', needed by `out/target/product/stingy/system/bin/stingyd'. Stop. 所以要再加一個 target: out/target/product/stingy/obj/lib/libstingy.so : out/target/product/stingy/system/lib/libstingy.so : acp acp -e $(MODULE_SRC) $(TARGET_OUT_INTERMEDIATES)/lib/libstingy.so

2011年6月13日 星期一

Android Makefile : findleaves.py

Android 的 make system 由 build/ 下的 Makefile 處理各 subproject 自己的 Android.mk。

build 的 Makefile 處理各 project 的 Android.mk 的方法是:

build/core/main.mk:
subdir_makefiles := \ $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk) #include $(subdir_makefiles) 看看 build/tools/findleaves.py ,就是把所有目錄的 Android.mk 找出來。

所以之後的 include .. 就把所有的 makefile include 進來..

也就是說..整個 android project makefile 被合併成一個大的 Makefile。

所以...

invoke make 時很慢.. 因為要 run findleaves.py, 還要把所有 Android.mk read 進來。
.... findleaves.py 應該不是主因..

但是

也就是說,所有的 project dep 都在 Makefile 中,所以可以自行 build 任一個 project target.
例如:
$make rild 就會 build hardware/ril/rild



另外,因為各 Project 的 Android.mk 是 Makefile 的一部分,所以可以直接寫 dep rule,不用管 Android build system 的 變數與 script。

run shell command in Android.mk

有時候需要調整一下 project 的 build 動作,所以需要在 Android.mk 中執行一些 shell command。
可以參考 /boot/recovery/updater/Android.mk 的方法
junk := $(shell mkdir -p $(dir $(inc));\ echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\ diff -q $(inc).temp $(inc).list || cp -f $(inc).temp $(inc).list) 用一個 dummy 的 target (junk) ,把要執行的 shell command 寫進去就可以

2011年6月7日 星期二

ADV7180 有3組 Video Input Pin,所以當作為 CVBS input 時,可以提工三個channel 選擇。 作為 YCbCr 時,就只能提供一個 (因為需要三條線) 這個設定是在 register : Input Selection (0x00).
bit 3:0 [ISEL]
0000 - CVBS in AIN1
0001 - CVBS in AIN2
0010 - CVBS in AIN3
在 driver 里, _hard_reset( ) 會順便設定 INPUT_CTL,這是由 probe( ) 的 argument : i2c_client->dev.platform_data 取出的。 這個 data 在 board/...../*.c 中宣告。 ==> 也就是說,要先寫好。

2011年6月2日 星期四

cpu_wp structure: struct cpu_wp { u32 pll_reg; u32 pll_rate; u32 cpu_rate; u32 pdr0_reg; u32 pdf; u32 mfi; u32 mfd; u32 mfn; u32 cpu_voltage; u32 cpu_podf; }; dvfs_wp structure: struct dvfs_wp { int upthr; int downthr; int panicthr; int upcnt; int downcnt; int emac; };

2011年6月1日 星期三

Build Android 2.3 in 32bit OS

Android 2.3 build script 會 check OS ,需要是 64 bit 才可以進行。

要修改 makefile,讓 32bit 可以動作

1. build/core/main.mk

找一下 check 64 的地方和 error prompt,把 64 改成 i686 就可以。
(可以看到是用 uname -m 看 system 的)

2. 一堆 Android.mk ,有把 CFLAG += -m64 ,要改為 -m32
自己用
find . -type f -name 'Android.mk' | xargs grep m64 找出所有的 Android.mk 出來改

build OK, 但是沒測是不是 workable.

另外, luse 說,新的 android release 已經把這個檢查移除了。

Change Id8be221d: Relax the constraint of 64bit build environment.

  1. http://blog.csdn.net/yihui8/archive/2011/04/27/6367782.aspx
  2. http://yuanfarn.blogspot.com/2011/01/32-ubuntu-android-23-gingerbread.html
  3. http://cheng-min-i-taiwan.blogspot.com/2011/05/32-android-23.html

標籤

網誌存檔