這幾天一個學生在調試視頻捕捉程序的時候遇到了一個問題。他使用capGetVideoFormat函數獲得視頻的格式時,發現m_bmpinfo.bmiHeader.biBitCount為16,他認為這是表示16位的RGB格式。可是不管他是使用RGB565,還是RGB555格式進行轉換時,發現轉換后的YUV文件都是不對的。在我的Sony筆記本上運行他的程序,其中的m_bmpinfo.bmiHeader.biCompression的值為1498831189,這說明筆記本的攝像頭所采集的數據的格式并不是普通的16位RGB數據,而是UYVY格式的。UYVY格式是YUV格式的一個變種,在網上可以找到詳細的說明,在此就不贅述了。
要想知道biCompression到底有多少種取值,可以參考一下:http://files.codes-sources.com/fichier.aspx?id=45735&f=src/org/hypik/webcamlib/codecs/Codecs.java。在這里詳細的列出了各種視頻壓縮的編碼。
怎樣才能知道自己的攝像頭到底支持哪種格式的輸出呢?可以使用capDlgVideoFormat函數:
capDlgVideoFormat(m_wndVideo);
這個函數會激活攝像頭驅動的視頻格式設置對話框,如下圖所示。
我的這個攝像頭支持2種輸出格式,一種是UYVY,另一種是YUV2。 如果將m_bmpinfo.bmiHeader.biCompression設置為這兩種之外的值,再使用capSetVideoFormat改變輸出格式,由于驅動程序不支持而不會獲得成功。
posted @
2010-11-16 22:30 zealsoft 閱讀(1941) |
評論 (1) |
編輯 收藏
這兩天一直希望找個可以移植到VxWorks上的Log庫,早就知道大名鼎鼎的Log4c,但一直想找個更好的,本來看上了Pantheios,覺得它的架構非常清晰,使用也很簡便,特別是其網站上宣傳它的性能非常卓越。但是仔細看了這個庫后發現這個庫基于STL和STLsoft,STL在VxWorks是很影響性能的,只好放棄。看看其他的Log庫,大多數都是基于C++的,對于嵌入式應用還是不適合。我覺得一個理想的輕量級Log庫,最好具有以下特征:
- 完全用C編寫
- 核心模塊不依賴任何第3方的函數庫
- 可以動態開關Log功能。當關閉Log功能時,所產生的開銷應當明顯小于打開Log功能。
- API接口清晰易用,就象printf一樣。
找了一圈,發現還是Log4c最合適。所以只好決定在Log4c的基礎上移植了,看來找到一個輕量級的Log庫不太容易。
posted @
2009-10-10 22:25 zealsoft 閱讀(2990) |
評論 (11) |
編輯 收藏
今天嘗試用Visual Studio 2005編譯以前用Visual Studio 2003編譯成功過的一個Wireshark插件,生成后發現居然無法在官方的Wireshark中加載插件。在 KenThompson的“Creating Your Own Custom Wireshark Dissector”一文中提到使用Visual Studio 2005編譯生成的插件只能在使用Visual Studio 2005生成的Wireshark版本中測試。使用自己采用Visual Studio 2005生成的Wireshark版本測試,發現確實可以,而官方的就不行了。使用Dependency Walker看了看,發現使用Visual Studio 2005生成的DLL文件需要使用MSVCR80.DLL,而官方的Wireshark使用的是MSVCRT.DLL,兩者不兼容,所以會出現錯誤。在微軟的網站上可以找到解決的方法:
mt.exe –manifest MyLibrary.dll.manifest -outputresource:MyLibrary.dll;2
將這樣處理后的DLL再拷貝到官方的Wireshark的插件目錄中就可以了。不過采用Visual Studio 2005生成的插件要分發時必須同時分發Visual Studio 2005的C語言運行庫,看來不如Visual Studio 2003方便。
posted @
2009-04-24 23:26 zealsoft 閱讀(2798) |
評論 (4) |
編輯 收藏
今天甲方通知要統計一下我們協議棧代碼的行數,好久沒有關心過這樣的問題,上一次統計代碼行數好像是好多年前的事情了,也忘記了用的什么工具。最開始想用NLOC,因為需要.NET 2.0,我的機器裝不上。為了這個工具安裝.NET 2.0有點不劃算。又找了一個C++編寫的工具Code Counter Tool。這個工具可以支持Visual C++ 6.0的工程。不過我們的工程是VxWorks工程,對于非VC6的工程需要建立一個.map文件,里面包括所有需要統計的文件。這個工作可以在命令行中完成:
dir /b > prj.map
其中的/b參數表示只顯示文件名,dir的結果會寫入prj.map文件,正好可以滿足要求。
最后的統計結果表明,我們的協議棧有109個文件(不包括需要的運行庫),共161,688行代碼,其中空白行13,554,注釋行為38,311。這是一個小巧的,但是完整的基站協議棧代碼。
posted @
2009-01-22 16:30 zealsoft 閱讀(1254) |
評論 (1) |
編輯 收藏
因為TETRA標準中分組數據的壓縮協議為V.42 bis,讓學生在網上找個代碼來用。學生找了半天,只找到LZW的代碼,沒有找到V.42bis,雖然兩者差別較少,但是還是不同的,只好自己找。其實找起來很容易,在
Google CodeSearch上輸入v42bis就找到了。找到的是
SpanDSP這個庫中的一個文件,寫得很清晰,注釋也比較全。SpanDSP是一個專用于電話領域的信號處理庫,包括各種語音編碼、采用的協議處理等等,象項目中用到的
HDLC協議在這里也可以找到。在查找代碼方面,Google CodeSearch比直接使用Google方便多了。
posted @
2009-01-21 22:07 zealsoft 閱讀(1263) |
評論 (0) |
編輯 收藏
最近太太的學校使用思維導圖總結教學中的知識點,她因為電腦不熟,我幫了下忙,結果發現這個思維導圖真的很方便!今天用思維導圖整理了一下項目的知識體系,為下一步安排學生課題、申請專利和發表文章做準備。由于課題內容比較敏感,下面用一些簡單的例子代替實際做的工程。
使用思維導圖的最大好處是方便,只要使用Enter鍵就可以添加一個節點,而使用Tab鍵就可以添加一個子節點,如果發現節點的層次或順序不對,可以隨意地拖動節點進行調整,一起都很方便,不象Visio或者SmartDraw,必須點幾下鼠標才能完成這些操作。你可以想到哪里,就畫到哪里,特別適合邊思考,邊整理,比在紙上比劃還方便。下面就是一個簡單的例子。

以前我整理項目的知識體系,往往使用SmartDraw(Visio在這方面比SmartDraw更難使)。使用SmartDraw,一是操作比思維導圖麻煩,二是如果圖太大了,為了便于閱讀,就必須將體系結構圖按照層次分割成很多文件,然后利用SmartDraw的鏈接功能將它們鏈接到一起。而在思維導圖中,這一切就變得很容易。你可以在一張圖中畫下所有層次關系,如果覺得層次多了,可以用鼠標點下節點右側“減號”,就可以把子節點都收起來,象下圖一樣。如果想看子節點,再點一下節點右側“加號”就可以,收縮自如,非常方便。

有時候子節點太多,希望在一個單獨的窗口中編輯或顯示,可以選擇Drill down功能,它可以把所有子節點都顯示在一個單獨的窗口中,而選擇Drill up功能又可以回到頂層。這樣既可以方便地觀察全局,又可以照顧導細節,比SmartDraw/Visio方便多了。
其實最早接觸思維導圖,是前段時間在廣州,七所的吳挺用MindMap制作了一個項目的進度表,每個節點前可以加上Marker清晰地看出每個項目進展的情況,象下面這張圖一樣。不過當時誤以為這個軟件是類似Visio或者Project那樣的軟件,沒有重視,現在才發現完全不是那么回事。

在網上搜索了一下,對思維導圖的介紹還真是很多,可惜我今天才用上。我推薦百度百科的相關介紹,值得一讀。
支持思維導圖的軟件很多,前面的博客已經說了,我要盡量使用開源軟件。在網上真找到一款相當不錯的:XMind。
posted @
2008-12-11 23:29 zealsoft 閱讀(3559) |
評論 (7) |
編輯 收藏
Google CTemplate提供了調節器(Modifier)功能。所謂調節器,類似于在模板中可以使用的用戶自定義函數,也就是對于相同的數據字典內容,模板中使用不同的調節器就可以顯示不同的內容。
要編寫一個調節器,需要從template_modifiers::TemplateModifier派生一個類:

Code
class BitStringModifier : public template_modifiers::TemplateModifier {
void Modify(const char* in, size_t inlen,
const ctemplate::PerExpandData* per_expand_data,
ExpandEmitter* outbuf, const std::string& arg) const;
};
BitString 調節器的作用是將數值型數據轉換為二進制字符串顯示。其在模板中的使用如下所示:
bstr = bstr + '{{item_type3id:x-bitstring=4}}'b;
用戶自定義的調節器一般采用“x-”開頭。調節器可以帶有用戶參數,例如上例的“=4”就是用戶參數,表示生成的二進制串的長度為4,如果不足4位,前面自動補0。
調節器的主要功能是在Modify函數中實現的,在該函數中調用outbuf->Emit函數來輸出所需要的結果。

Code
void BitStringModifier::Modify(const char* in, size_t inlen,
const ctemplate::PerExpandData* per_expand_data,
ExpandEmitter* outbuf, const std::string& arg) const
{
int x = atoi(string(in, inlen).c_str());
unsigned int len = atoi(arg.c_str() + 1);
string sID = itoa(x, 2);
while(sID.size() < len)
sID = "0" + sID;
outbuf->Emit(sID);
}
要在程序中支持調節器,還需要調用google::template_modifiers::AddModifier函數添加BitStringModifier的實例。如:

Code
BitStringModifier bitStringModifier;
/// 注冊自定義的Modifier
google::template_modifiers::AddModifier("x-bitstring=", &bitStringModifier);
posted @
2008-10-15 22:03 zealsoft 閱讀(1486) |
評論 (0) |
編輯 收藏
TAU G2程序本身的仿真功能很強,如果程序在目標機上運行時出現邏輯錯誤,你總是可以在TAU G2的仿真環境下模擬出這個錯誤并找到出錯的原因,一般不需要借助操作系統的C代碼調試工具。但是如果是在TAU G2中調用了C語言的函數,或者在環境函數中出現錯誤,問題就復雜了,因為TAU G2的仿真環境無法跟蹤這些C語言的代碼,你只能借助操作系統自身的調試功能了。
TAU G2生成的程序至少是2個線程:一個是主線程,就是main函數所在的線程,象環境函數中的xInitEnv和xInEnv都是在主線程中的,主線程設置斷點很容易,只要在啟動調試器后,使用Debug菜單中的Toggle Breakpoint(F9)就可以了,因為調試器默認就是把主線程當作當前線程的;另一個線程是UML代碼所在的線程,通常你不需要在生成的UML代碼中設置斷點,但是xOutEnv在這個線程中,而且如果在UML代碼中調用了C語言的函數,那么這些C語言的函數也在這個線程中,而在這個線程中如果還是用F9直接設置斷點就往往不會成功了,程序往往不會停下來而是繼續執行。
要想在xOutEnv或者自己編寫的C語言函數中設置斷點進行調試,可以使用Debug菜單中的Toggle Global Breakpoint(Shift F9)設置全局斷點。設置全局斷點后,當UML代碼所在的線程執行到斷點處,這個線程就會停下來,此時可以使用Debug菜單中的Attach功能,將當前線程由主線程變為UML線程,這樣就可以單步跟蹤調試了。UML線程在Attach對話框中通常是最后一個線程,默認情況下其名字應該為t1,但是有的時候線程名會顯示為亂碼。
posted @
2008-10-13 23:18 zealsoft 閱讀(1308) |
評論 (0) |
編輯 收藏
模板引擎(Template engine)是實現模型和視圖分離的一個重要手段。如果你從未接觸過模板引擎可以看看
Wiki的介紹。模板引擎的流行最初是因為網站開發的需要,象比較重要的幾個模板引擎:SMARTY、Velocity、StringTemplate都是來源于網頁設計的。當然,除了網頁設計,模板引擎還可以應用于其他領域,而我主要將其應用與代碼生成器的設計中。
有關模板引擎,我推薦StringTemplate的作者Terence Parr 寫的一篇
英文論文。Terence Parr是一個大學教授,寫的文章自然學術性比較強,較難懂,但是很有參考價值。借助這篇文章的分析,我們可以發現當前模板引擎有著兩種不同的思路:一種是嚴格將模型和視圖分開的,設計模板系統時往往提供的模板語言比較簡單,避免在模板語言中加入運算符號等,另一種是提供強大的模板語言功能,模板語言具有類似高級語言的功能,如各種條件判斷語句,甚至數學運算能力。顯然從模板編寫者的角度看,后者具有更強大的功能,幾乎無所不能,但是安全性不如前者,模板的編寫者更容易利用系統漏洞做模板系統設計者沒有想到的事情。這個問題仁者見仁,智者見智,好在由很多的模板系統可以選擇。
絕大多數模板引擎都是支持Java、PHP、Python的,這當然和模板引擎的應用領域相關。我的代碼生成器是用C++寫的,而且必須支持Windows平臺,所以選擇的范圍就比較有限了,從網絡上搜索了一下,似乎只有
Teng、
CT++和
Google CTemplate可以使用了。我對3個系統進行了簡單的評估,并實際使用過CT++和CTemplate,現在總結一下自己的心得,希望對大家有一些幫助。
1、操作系統的支持
我的主要工作是在Windows上的,而模板引擎絕大多數是面向Unix/Linux的,這和我的需求有一定距離。當初曾經下載過Teng,但是折騰了半天也沒有能夠讓其在Visual Studio 2003下成功編譯,所以就放棄了,后來將CT++ 1.8簡單地處理了一下就可以跑了,很開心。而Google CTemplate更提供了完全的Windows支持,這對于我這樣的用戶當然是非常省心了。
2、軟件開發的活躍度
這些軟件都是開源的,軟件開發的活躍度當然是我關心的,有的工具剛開始用的時候很開心,但是后來開發者沒有興趣不玩了,而又沒有人接手,BUG也無法更新了,就比較苦了,典型的象TurboPower。Teng似乎已經很長時間不更新了,CT++一直在更新,但是開發者是俄羅斯人,全部文檔是俄文的,包括程序注釋,以前1.8還有英文文檔,從2.0以后就沒有了,雖然最近承諾2.4以后會報告英文文檔,但是我擔心他哪天不高興就不玩了,所以最后下定決心轉到CTemplate去了。CTemplate雖然是Google的,而且據說Google內部也在使用,但是在模板引擎領域的名氣卻不大,好像作者的熱情仍然很高,持續更新,而且可能很快要升級到1.0版本了,這給我很大的信心。
3、模板語言的功能
在我看來,模板語言的功能越強,提供的函數越多,它可能越受模板編寫者的歡迎,但是可能不符合模型和視圖嚴格分離的原則。Teng和CT++都屬于模板語言功能強的一類,象Teng甚至提供了大量的運算符,而CTemplate顯然是嚴格按照模型和視圖分離原則設計的,它甚至沒有提供if/else這樣在其他模板系統中都有的功能。如前所述,這個問題仁者見仁,智者見智,不爭論了。下面簡單地列個表比較一下。由于CT++ 2沒有英文文檔,一直就沒有使用過,可能會遺漏一些新功能。
|
Teng |
CT++ |
CTemplate |
變量 |
支持 |
支持 |
支持 |
函數 |
支持 |
支持 |
支持(Modifier) |
包含 |
支持 |
支持 |
支持 |
條件語句 |
支持 |
支持 |
不支持 |
循環 |
支持 |
支持 |
支持 |
計算 |
支持 |
不支持 |
不支持 |
賦值 |
支持 |
不支持 |
不支持 |
注釋 |
支持 |
支持 |
支持 |
安全性設計 |
不支持 |
不支持 |
支持 |
用戶定義函數 |
不支持 |
支持 |
支持 |
4、C++ API
基本的API幾個軟件都差不多,我覺得CTemplate更完善一些,特別喜歡它的調試功能。
總體來說,我對CT++還是有些難舍,但是綜合考慮之后還是決定轉到CTemplate上。
posted @
2008-09-17 21:42 zealsoft 閱讀(2680) |
評論 (2) |
編輯 收藏
最近開始嘗試使用Doxygen生成程序的文檔。程序的源代碼采用的是GB2312的格式存儲的,而Doxygen輸出的文檔是UTF-8格式的,出現了亂碼。雖然Visual Studio 2003支持以UTF-8格式存儲源代碼,但是要把所有文件都轉換擔心太麻煩。于是,在配置文件中增加了一行代碼:
INPUT_ENCODING = GB2312
這下問題解決了,Doxygen在生成文檔時自動將文件的編碼從GB2312轉換為UTF-8,輸出就沒有亂碼了。
posted @
2008-09-09 16:49 zealsoft 閱讀(1949) |
評論 (0) |
編輯 收藏