發表文章

GStreamer Debugging 參數說明

[ GStreamer ] 是一個優異的多媒體處理元件 Library,其架構了最先進的多媒體資料流機制,在目前主流的 Linux 系統中,應用極為廣範。GStreamer 支援以 Plugin 的形態擴充自身功能,可以是編解碼器(Encoder/Decoder),亦或是效果處理(Processing),因此,有許多生產硬體解碼晶片的廠商,都會透過提供 Gstreamer Plugin 的方式,支援 Linux 上的多媒體播放。說到多媒體架構,或許讀者也曾聽過 OpenCore/OpenMax,其實 Gstreamer 和 OpenCore 兩者是相類似的東西,只是前者主要被應用在桌面系統居多,後者則常見於嵌入式系統(Embedded System)應用,最廣為人知的便是 Android Multimedia Framework。在此,細節就不多談,本文將要探討 GStreamer Debugging 的一些手段。 如果曾開發過 GStreamer Application,對初始化 GStreamer Backend 應該很熟悉: gst_init(&argc, &argv); 我們可以理解所有的 GStreamer Application,都會經過這段 Initialization 的動作,因此 gst_init() 會從 main() 得到程式被執行時所代入的後綴參數,換言之,理論上不管是什麼 Application ,我們可以透過這種方式去開啟 GStreamer 的 Debug 模式: $ ./totem --gst-debug-level=3 0:00:00.003322140 13127 0x8c530a0 INFO GST_INIT gstquery.c:105:_gst_query_initialize: init queries 0:00:00.004700946 13127 0x8c530a0 INFO GST_INIT gstmessage.c:73:_gst_message_initialize: init messages 0:00:00.005529752 13127 0x8c530a0 INFO GST_PLUGIN_LOADING g...

親手打造 Window Manager - Transient 和 OverrideRedirect

若嘗試去讀各個 Window Manager 的程式碼,最大的挫折就是會遭遇其中了龐大數量的專有名詞和屬性,假設沒有對 XWindow 和 Window Manager 整體架構有清楚概念,必定會花不少時間在查詢 X11/Xlib 的官方文件和映證,不過,查證過程雖繁瑣,對瞭解整個實作很有幫助。筆者將在本文記錄幾個比較特別的視窗(window)屬性,以便讀者懂得如何處理一些特殊的 window。 WM_TRANSIENT_FOR 此 Hint 屬性記載著短暫視窗的父視窗的 Window ID,若不是短暫視窗,將回傳沒有父視窗。短暫視窗有與一般視窗不同之特性,其將不會在工作列上被顯示,只是用來做短時間顯示使用,如對話視窗(Dialog Window) 就屬此類。想取得該屬性的設定值,可以藉由此 XGetTransientForHint() 得到: XGetTransientForHint(Display *, Window, Window*) OverrideRedirect 此 Window Attributes 參數表明忽略重新定向,若此參數為真(True),視窗管理員(Window Manager) 將不會為該視窗畫上標題框和邊框,如選單視窗(Menu Window)就屬此種會忽略重新定向的視窗。我們可以透過 XGetWindowAttributes() 去取得該屬性,簡單的範例如下: XWindowAttributes attr; XGetWindowAttributes(display, win, &attr); if (attr.overrideRedirect) .... else .... 暫且撇開一般 X Application 開發者熟知的視窗形態(Type),如:Dock 、Desktop、Toolbar 等等,Window Manager 在畫視窗時,首先要處理的是 WM_TRANSIENT_FOR 和 overrideRedirect 這類的屬性,而視窗形態應該是考量於 Window Manager 自身的應用後,才有不同的設計和呈現。

親手打造 Window Manager - 監聽 Screen 上的 XEvent

在 Linux 等 Unix's like 的系統上,擁有數十載歷史的 X11 通常為主流的圖形介面支援方案,雖架構看似老舊,卻在世界上眾高手的努力下,成就了現在的各種極絢麗的桌面環境,而最為眾人所知的,便是 Compiz 這類『視窗管理器(Window Manager)』,其運用 3D 技術帶來震憾的桌面體驗,因此在目前主流的 Linux 發行版中,無一不預設搭載。而許多人在此時,才真正了解 Window Manager 的厲害和重要性,新興的系統中,無論是 Moblin 還是 Google Chrome OS,也都特地為自家系統打造專屬的 Window Manager。 然而,Window Manager 實作細節雖看起來複雜,但實際上沒有想像中這麼艱澀,單純透過 X Protocol 和 API 去控制 window 的行為,這類工作極為簡單,而真正令人感到棘手的,是在事件(event)處理和 ICCCM/EWMH 的部份。ICCCM/EWMH 現在是由 [ FreeDesktop.org ] 所維護,其定義了一系列的屬性,用來記錄視窗環境的狀態,並可供所有 X Client 存取,而 Window Manager 要做的就是成為一個常註程式(Daemon),並隨時去提供和更新這些狀態。不過由於 ICCCM/EWMH 這部份細節繁雜,暫不在本文討論範疇(有興趣可自行參閱 FreeDesktop.org EWMH Spec ),我們主要是討論如何監聽畫面上視窗的 event。 一般 window 監聽自己的 XEvent 是家常便飯,只要有以 Xlib 寫過純 X Application 的人應該都多少有些了解,會比較不瞭解的部份,就是該如何去監聽整個 screen 上的 event,但在這之前,我們有必要先大致瞭解 X window 的架構。通常在 X 上所呈現的桌面環境,是一層層 window 疊起來而成,舉例來說,桌面上常見的工具列(Panel),上面的狀態 Icon ,如:網路管理、Pidgin Icon 等,都是一個個 window 放在 Panel 的 window 之上,而在 Panel 之後,到最底層便是 screen 的 Root Window,Root Window 在所有 window 之下。 所以,若要做到監聽整個 s...

Reverse SSH Tunnel 反向打洞實錄

近來經手了幾個案子,其目標都是設計一台做特定用途的系統,但往往這台機器都會被鎖在防火牆後面,甚至不會連上網際網路,是完全封閉的環境。每當接近結案,將系統交到客戶手中以做最後的壓力測試時,便是痛苦的開始。怎麼說呢?因為當面對最後的大量測試,各種大大小小的臭蟲(Bugs)就會原形畢露,一一浮上臺面。而每次問題發生,便要千里迢迢趕到客戶那了解情況、解決問題。如果問題不大倒還好,一旦問題嚴重,被客戶關到三更半夜也是常有的事,更誇張的還必須每天都去報到。所以,為避免車程來回的時間和人力浪費,是否有可以遠端連線做處理呢?便思考起這問題。 雖然這些機器通常都不會有真實 IP,客戶也不會為了我們特別請 MIS 去開啟 NAT 或防火牆,但還好 SSH 提供了反向(Reverse)的機制讓我們可以連進去。其做法就是讓在客戶那的系統,透過 SSH 先連回我們自家有真實 IP 的主機,然後建立反向的通道即可。如此,我們便可從自家的主機,從 SSH 連回放在客戶那的系統。 實際的操作步驟: # 首先,在客戶那理的機器下指令連回我們自己的 Server,並設定自己 Server 上的 12345 port 會對應到幾器上的 SSH port ssh -NfR 12345:localhost:22 fred@myhost.com # 然後在 myhost 的機器上連自己的 12345 port,就可以連回在客戶那的機器 ssh localhost -p 12345 後記 可以將建立 Reverse SSH tunnel 的命令設定在開機後執行,並且透過設定 ssh config 讓斷線時自動重連,如此就可以確保 SSH 連線不會中斷。此外,若是客戶端那的機器是處於完全無法對外連線的環境,則可以考慮使用 3G 網卡,並將網卡暫時借放於客戶那,然後等結案後再取回,雖然 3G 通訊月租不便宜,但和經常來回的通勤費和時間花費相比,可滑算多了。

善用 DRI 加速貼圖

近日以來,筆者都在著手處理 Linux 下圖形運算的議題,不久前也曾發表一篇『 善用 XShm 加速貼圖 』以探討 X 架構之下的貼圖機制,舊文最後也提出範例,使用共享記憶體(Shared Memory)的方式,達到效能的改善。不過,透過減少資料複製,雖然能有效提升貼圖的效率,但都還只是停留在彌補 X 架構先天上的缺陷,令人不禁去想,是否有更直接的解決方案?尋思,現今硬體能力不可同日而語,幾乎每台電腦都具備著基本能力的影像晶片,若運用 DRI 直接對硬體貼圖應該是種可行的手段。 欲在 X 上透過 DRI 繪圖,最簡單的方法是使用 GLX Extension,藉由建立 OpenGL Window 開啟直接和硬體溝通的管道。我們可以修改與舊文相同的程式碼,並改用 OpenGL 來達成相同的效果: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <X11/Xlib.h> #include <GL/gl.h> #include <GL/glx.h> #include <GL/glu.h> int main(void) { Window win; Display display = XOpenDisplay(getenv("DISPLAY")); unsigned char *buffer; GLint glxattr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 32, GLX_DOUBLEBUFFER, None }; /* Initialize GLX */ xvinfo = glXChooseVisual(display, 0, glxattr); if (xvinfo == NULL) exit(1); /* Initial Window */ win = XCreateSimpleWindow(display, RootWindow(display, DefaultScreen(display)), ...

Android is Working on X

圖片
As you know, Android was designed for mobile device, so there is no large value from Android for desktop environment. But there is no denying that Android has extreme applications resources. If we can combine Android and desktop environment, it will make great experience on Linux. By hacking Android framework, we made Android work on X with success, it is a "real" X application right now. You can see these screenshots: From screenshots, Android is running on Chromium OS, based on Android-x86 project . Currently, we can use chromium browser to surf internet and use Android application in the same time. In first screenshot, using "ps ax" to show all process on system to prove Android is running on X Server rather than emulator.

善用 XShm Extension 加速貼圖

如今的 Xorg 千變萬化,發展出各種(DRI/DRI2/EAA/EXA/UXA/AIGLX)等加速機制,更有極絢麗的 3D 視窗技術,一點也不讓 Mac OS 和 Windows 上的 3D 視窗特效專美於前。話雖如此,很多人們早已遺忘 X Window System 的歷史原由,我們反觀當年的 XFree86 就有如醜小鴨般,其為 Networking 考量的 Client/Server 架構,就是舊 Unix 終端機時代所留下的東西。到目前為止,隨著硬體速度越來越快,Client/Server 的界限雖被 DRI/DRI2/AIGLX 等技術逐漸打破,但無論如何,Xorg 大底上還是維持著 Client/Server 的本質。只不過應用程式層的軟體,因為經過各種 GTK/GDK/Qt 等 Graphical Toolkits 包裝後,多數開發者和使用者已經不會再看到 X 底層的運作模式。 這裡記載著一個簡單的範例程式,用來說明 X 如何利用 XImage 做貼圖運算,其主要是將 buffer(100x100x32bits 的影像)畫在視窗上,該 buffer 可以是讀取圖檔或是使用各種資料來源,為一塊記憶體。此程式將會用 XCreateImage() 建立一組 Structure,然後使用 XPutImage() 將該 Structure 和影像資料吃從 XClient 透過 X Protocol(Socket)傳送到 X Server,X Server 再依 XImage 的敘述將圖形畫在視窗上。 XImage 範例程式: void main(void) {     Window win;     Display display = XOpenDisplay(getenv("DISPLAY"));    XImage *ximage;     unsigned char *buffer;     /* Initial Window */     win = XCreateSimpleWindow(display, RootWindow(display, DefaultSc...

GLib 就是懶.GThreadPool 高效的執行緒池

開發複雜的程式時,執行緒(Thread)隨處可見,在高負載的應用程式中,就常會使用到多執行緒所構成的演算法,如 Apache 此類有許多流量及使用者操作的程式,就運用 Thread 做負載的分配。但是,每當 Thread 的建立和摧毀,會造成額外的系統資源開銷,若是有大量 Thread 增減將會造成程式效能不彰,所以最好的辦法便是回收並重新運用已經被建立的 Thread。因此,GLib 提供了 GThreadPool 的機制,可重復利用 Thread 以減少不必要的開銷。 這是一個使用 GThreadPool 的範例程式: void mythread(gpointer data, gpointer user_data) {     printf("%s\n", data);     printf("%s\n", user_data); } void main() {     gchar *data = "this is data";     gchar *user_data = "this is user_data";     GThreadPool *pool;     if(!g_thread_supported())          g_thread_init(NULL);      /* create thread pool */      pool = g_thread_pool_new(mythread, user_data, -1, FALSE, NULL);      if (pool==NULL)          printf("ERROR\n");     /* start three threads */      g_thread_pool_push(pool, data, NU...

體驗舊台灣經濟奇蹟之感

偶見長輩們提起,台灣早期的繁華和奇蹟,而奇蹟發光時,筆者年幼,懵懵懂懂,卻難以感受一二。如今再從長輩口中傳述,只知,當時台灣人民為錢打拼,不遺餘力。此外,由於當時金融和經濟體制不健全,透過所謂的銀行對保等支付方式相當麻煩,也因為當時國際關係,許多金流是在暗地中轉動,廠商間的往來,往往一句話敲定便算。甚至當下,因為一句信任就交付現額鉅款,也是常見的例子,難以令人想像。只能說,在一切混沌的黑暗時期,人人都為了賺進鈔票而努力,先不論黑白兩道的縱橫交錯,最重要的是誠信便成了當時莫明的默契。 上有誠意,下有衝勁 最近走入南部拓展,因緣際會而接觸了早期的科技產業,卻他們仍保有著台灣早期繁榮的文化,做生意總是滿懷誠意,只要合理,二話也不多說,便開始進行後續流程,用台灣話『阿沙力!』來形容,一點也不為過。但更令筆者感到震憾的,是他們工作伙伴的效率驚人,沒有現代的『工作管理系統』和『協同作業機制』,團隊依然有相當可觀的產能。反觀當今主流資訊業大大小小公司,團隊往往是被流程和管理機制推著走,研發人員已經失去了不畏虎的衝勁。 解決問題的態度,令人自形慚愧 也許是現今產業的專業分工所致,許多人總將問題不分清紅皂白推往別處,只堅守自家陣地。往往工程人員解決問題,都早已忘了初衷,只專注於眼前表面的障礙。久而久之,『會動就好』就變成了一種處理事情的態度。但是態度蔓延,從零組件廠開始,『零組會用就好』就成了最後做產品的態度,所有細節問題通通丟給各大零件廠商去處理。就商業考量上雖沒有不對,但是生產出來的東西就不盡人意了,換言之,要是最後的系統整合商不懂得要求,產品就不會有頂尖的品質。 而在某公司的教育訊練中,就因為幾句對話,讓我驚醒: 『這部份的驅動程式官方沒提供程式碼,可能不能移殖』我說。 『官方沒提供程式碼呀?沒有問題,我們自己重寫這驅動程式』該公司工程師說。 『這部份的硬體可能會不合用』我說。 『沒有問題,那我們就改硬體』該公司主管說。 更令我一再省思的,便是該公司無意間提到一些點子和解決方案時: 『CPU 架構不一樣呀?那你可以幫我們實做 emulator 嗎?只要給我們介面, 從外部抽出裡面各個 register 的資料即可, 東西放哪我們能 reversing。』該公司主管說。 先不論技術問題,就出發點而言,他們的技術研發是貼近著產品化而...

fork()、pipe()、dup2() 和 execlp() 的組合技法

對一般程式來說,管線(pipe)機制很少會用到,尤其對於在 Windows 底下的程式開發者來說,很可能前所未聞,而在 Unix-like 環境中常見的例子,就是往往在命令後面加上『|』,其意味使用『管子(pipe)』將內容導入另一個程式裡,如:『dmesg | grep ALSA』。在該例中,Shell 有趣的將 demsg 標準輸出(standard output)全數導入 grep 程式的標準輸入(standard input)中,再交由 grep 處理並找出存在 ALSA 字串的句子所在。 另一個情況,Web Server 在支援 CGI 時,也會使用到 pipe。這是最典型的例子,當 Web Server 欲執行一支外部 CGI Program 時,會利用 pipe 去模擬該 CGI 的標準輸入及輸出(Standard I/O)。以上說明當然只是大致上的做法,細節還需加上 fork() 和 dup2() 的配合,透過個範例可清楚瞭解這部份的實作。 這是一個簡單的範例: void cgi_run(const char* filename) { char buffer[1024] = { 0 }; int len; int pfd[2]; int status; pid_t pid; /* create pipe */ if (pipe(pfd)<0) return -1; /* fork to execute external program or scripts */ pid = fork(); if (pid<0) { return 0; } else if (pid==0) { /* child process */ dup2(pfd[1], STDOUT_FILENO); close(pfd[0]); /* execute CGI */ execlp(filename, filename, NULL); exit(0); } else { /* parent process */ close(pfd[...

SCIM Patch: Auto enable input method when getting keyboard focus for a GTK+ text entry

圖片
As you know, Apple iPad is the latest craze and brings back tablet PC marketing cause most manufactories aim to begin to produce products with touchscreen. In order to make applications work with touchscreen for tablet PC, implementing on-screen keyboard is the major issue. There are many open source solutions you can get from internet, but you may get a question, what time is better to start the on-screen keyboard? It is a good idea that enable on-screen keyboard when input box get focus, that is just like Apple iPhone, iPod, iPad and a lot smart phone. SCIM has panel support, it can provide on-screen keyboard. So I have patched scim-bridge to support that auto enable input method when getting keyboard focus for a GTK+ text entry. If so input method is enabled, SCIM will show on-screen keyboard automatically. Here is my patch you can get: http://people.linux.org.tw/~fred/patches/scim-bridge-0.4.16_client-gtk-autoshow.patch

親手打造 HD 多媒體播放器,簡報上線

承年初『 親手打造 HD 多媒體播放器 』所述,小弟有幸於今年 1/23(六)、1/24(日)、3/27(六)、3/28(日),在台中『靜宜大學應數系』開設嵌入式系統實作課程,課程宗旨欲藉由一步步的實作,揭露嵌入式系統開發細節。本課程嘗試避免提及過於深奧的理論和艱澀的名詞,以玩樂中學習並體驗嵌入式系統相關技術。除了實作外,也略微說明相關基礎知識,如:Compiler、 NEON intrinsics 等。 感謝各界參與,本課程已順利結束,有興趣者可自行下載上課簡報檔: http://people.linux.org.tw/~fred/slides/training/hdplayer.pdf