2010年12月24日 星期五

inline function

在想要optimize AAC encoder 的速度的時候
想要inline fabs()
卻無法成功

1. inline is for C++, __inline is for C & C++
2.要change compiler option /Ob0 to /Ob1 or /Ob2 ( In C++ --> Optimization --> Inline function expansion )
http://msdn.microsoft.com/en-us/library/47238hez.aspx
3. /Ob1 和 /ZI (Edit and Continue) 選項衝突,改用 /Zi
4. __forceinline 強迫inline 但compiler 不一定會照做,參考
http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx

2010年12月5日 星期日

JSAMPARRAY & jpeg_read_scanlines

JSAMPROW data[1];
data[0] = new JSAMPLE[1920*1080];



while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, data, maxlines );
        }
      
        jpeg_read_scanlines 的第二個參數 JSAMPARRAY 是一個儲存 pointer to row 的陣列。
如果有一行 就得有一個元素,兩行就要有兩個元素。
也就是 & JSAMPROW 或 & data[n]


libjpeg.txt 的範例


        JSAMPROW row_pointer[1]; /* pointer to a single row */
int row_stride; /* physical row width in buffer */

row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */

while (cinfo.next_scanline < cinfo.image_height) {
   row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
   jpeg_write_scanlines(&cinfo, row_pointer, 1);
}


ycc_rgb_convert() in jdcolor.c

2010年12月1日 星期三

Long Lasted Problem Solved. After OEMInit hang

在db1200 的板子上,之前一開始做新的Image
NK.bin 都會Hang 在 -OEMInit 之後。
因為在 startup.s 中,呼叫完 OEMInit 之後 會reenable interrupt
而因為在公版中 有用到GPIO7 也就是 IC1 interrupt 7
如果這個GPIO7 pin 的狀態為 High 沒問題, 如果為 Low 的話 則會trigger interrupt 導致系統Hang住。 (使用MMPG module 就可以pass, 因為它把GPIO7 pull high

之前粗魯的解決方法就是 Disable 整個 IC1 (在startup.s 中 disable interrupt mask )或者在 intr.c (OEMInterruptInit()  )中 disable 整個 IC1 handler。

但是正確解法應該是,修改 db1200.h 或 pb1200.h
修改 PLATFORM_INTR_IC1_07


// Platform-specific interrupt defintions for kernel/hal/intr.c
#define PLATFORM_INTR_IC1_07 irqLL | INTR_MODE_UNMASK // 39 GPIO7 Board Interrupt Controller

不要定義 PLATFORM_INTR_IC1_07 的話 在intr.c
的  InterruptConfiguration[HWINTR_MAXIMUM ] array 就會定義 PLATFORM_INTR_IC1_07 為 irqNA


#ifndef PLATFORM_INTR_IC1_07
#define PLATFORM_INTR_IC1_07 irqNA
#endif
PLATFORM_INTR_IC1_07,

2010年11月17日 星期三

CreateDIBSection

在做印表機驅動程式的時候,要在圖片旁邊加字。
使用到CreateDIBSection

因為 Resolution 太大( 2392x3400) 所以 CreateDIBSection 只能一次
第二次會失敗。

所以每次都要釋放乾淨。
要用

SelectObject 把 DIBSection select 出來
然後 DeleteObject

2010年9月30日 星期四

USB Request Block & USB Protocol

5.1 Sync Field
Each USB packet starts with a SYNC field. This is basically used to synchronise the transmitter and the receiver so that the data can be transferred accurately.
In a USB slow / full speed system this SYNC field consists 3 KJ pairs followed by 2 K’s to make up 8 bits of data.
In a USB Hi-Speed system the synchronisation requires 15 KJ pairs followed by 2 K’s to make up 32 bits of data

Bus Hound 裏面有關 URB

USB Request Block 是定義在 Windows 或 Linux 中
跟實際的USB Protocol 沒有關係
URB 的定義在 usb.h 中
它是各種不同的定義的集合 ( union )
http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx

2010年9月27日 星期一

sal.h

在做 USB Printer 的專案(x86)時,會用到 GUID_DEVINTERFACE_USB_DEVICE
及 IOCTL_PAR_QUERY_DEVICE_ID
所以要
#include
#include

而這兩個檔案是在 Windows DDK (WDK)裏有,所以要 add additional include directory
在 wdk 中的 \inc\api

現在問題來了,原來的project 為 vs2005
轉換成vs2008後 會出現一堆沒有定義 _In_opt 等等的錯誤
(為什麼要轉成 vs2008 的原因 是因為在vs2005中 下斷點有問題
有些部份無法設 breakpoint 會出現 the breakpoint will not currently be hit. invalid file line xxx
改成vs2008 之後就好了)

那是因為 vs2008 的 sal.h 和 ddk sdk 中的 sal.h 定義不同
必需要用到原來 vs2008中的 sal.h ( Visual Studio 9.0\vc\include ) 才行
但是因為我們加了 additional include directory
所以 wdk 中的 sal.h 會被先用到....
而造成錯誤

解決方法就是修改 Visual Studio 9.0\vc\include\crtdefs.h
在crtdefs.h 中會
#include
把它改成
#include "sal.h"
就可解決。(目前完美的方式)

...簡單的東西搞出麻煩的過程

2010年9月20日 星期一

build gnash on Windows

http://wiki.gnashdev.org/Building_on_Windows



boost
boost 1.44

cd \tools\jam
build_dist.bat

然後 build 出3個 Library?
libboost_program_options-vc100-mt-gd-1_44.lib
libboost_filesystem-vc100-mt-gd-1_44.lib
libboost_system-vc100-mt-gd-1_44.lib

2010年9月14日 星期二

WINCE 6.0 image making

嘗試 WinCE 6.0 Image 的 build,
在build minimal configuration 時
出現don't know how to make xxx\....\ndis.lib 的錯誤
ndis.lib 是在 core os->CEBASE -> shell and interface -> user interface -> network user interfacer


porting 參考 
http://blog.csdn.net/xilidecai/archive/2009/09/18/4566731.aspx


LNK2001: unresolved external symbol __CxxFrameHandler3 in otg


要加選 C++ Runtime support for Exception Handling and RTTI




Config.bib 中還是設定 AUTOSIZE=ON 比較好,一來沒有空間不夠的問題,二來能釋放出更多的記憶體。

2010年9月9日 星期四

Thread, Thread Quantum 測試

為了解決一些常見的煩人問題
只好實地下去測試 WinCE Thread 的運作機制

結果非常有趣,跟想像理解中有所不同


1. WinCE default time slice ( quantum )是為 100ms,OEM可以自己設定。(在OEMInit中設定 dwDefaultThreadQuantum) 。CE 也提供了2個函式 CeGetThreadQuantum and CeSetThreadQuantum


extern DWORD dwDefaultThreadQuantum;
 
 
void OEMInit()
{
                dwDefaultThreadQuantum = 50;
}

2.  Sleep(0)  就是把目前thread 剩下的 quantum 時間 ( <=100ms) 讓給 同Priority 的 Thread。如果沒有同Priority 的Thread ,則馬上 return. 也就是說 Sleep(0) 有兩種可能(效果)  
 I. 睡100ms (或更少) 
 II.沒有效果(馬上return)

3. Sleep(1) (或Sleep(X))  就很有趣了,就實地測試,依環境不同,有不同的結果。
如果只有2個同 Priority 的Thread, Sleep(1) 後再度醒來已經是 100ms後了。
如果有3個 Thread,則 Sleep(1) 大概睡 3~9ms。
神奇吧?

2010年9月7日 星期二

null, nullptr

簡單來說
在 C# / Java, use null
在 C++, use NULL
在 C++ .NET ( compile with /clr ), use nullptr

2010年8月4日 星期三

USB Audio Class Driver 開發

在開發的過程中, USBDeviceAttach 被呼叫了四次(第三個參數usb interface 都不相同,因為總共有4個 interface,USBAudio算是 interface driver,所以第一個interface 載入成功的話會載入下個interface。詳情請看 LoadDeviceDrivers() in usbd.cpp。
雖然被載入4次,但不會重複載入DLL (也就是DLLMain PROCESS_ATTACH 只會CALL 一次,之後的應該是THREAD_ATTACH)。
如果你的USB Client Driver 不是 interface driver 的話,則USBDeviceAttach第三個參數為 NULL。
還有 LoadDeviceDrivers 的載入interface driver 部份有點問題,它總共會載入 bNumInterfaces 次, 這個bNumInterfaces 是 active configuration 的 descriptor (USB_CONFIGURATION_DESCRIPTOR) 但 interface++ 的部份有點不對,因為每個interface又有可能有alternate setting ,所以總共的interface (含alternate setting) 應該是 dwNumInterfaces 個 ( USB_CONFIGURATION ) 。這一點我發現在 WINCE 6 usbd.cpp中改了過來,有把alternate setting 的狀況考慮進去。



USB Audio Output procedure

1. Set Interface  ( Interface 1, Alternate Setting 1 )
2. GetEndpoint
3. OpenPipe
4. IssueIsochTransfer

而 USB Mic Recording 基本上跟 Audio Out 一樣,不過怎麼試
都得不到正確資料,而是抓到整個 Configuration Descriptor

想破腦袋後,並從Bus Hound,發現Set Interface 後有 SET_CUR
而這個SET_CUR 就是設定 Audio In Endpoint 的 frequency,果然再 issue 這個
SET_CUR 的 VendorTransfer 後就可以正常讀取 Audio Stream 了。(請參考 Audio Class spec
第五章 request ),當然 bits 數 ,frequency, channel 都要正確才行。


USB Audio Input procedure

1. Set Interface  ( Interface 2, Alternate Setting 2 )
2. GetEndpoint
3. Send Endpoint Frequency Request
4. OpenPipe
5. IssueIsochTransfer


Note: 在 IssueIsochTransfer 的 callback function 中呼叫 closepipe的話,
會再多出一次 callback

Note!! 在 IssueIsochTransfer 的 callback function 中呼叫 WriteFile,而這個檔案又位在
USB Disk上時,這個WriteFile 會block住。所以,要再Create專門WriteFile 的Thread
不能在 callback中 WriteFile

如果要做 Isoch Transfer 這篇文章很重要
http://support.microsoft.com/?scid=kb;en-us;317434&x=14&y=7

DRVM_MAPPER_PREFERRED_SET 
設定 default waveout device
http://msdn.microsoft.com/en-us/library/dd187525.aspx
http://msdn.microsoft.com/en-us/library/aa908376.aspx
http://relatedterms.com/thread/2314671/Multiple%20Audio%20Devices%20Win%20CE



MMRESULT Err = waveOutMessage((HWAVEOUT)WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_SET,
CurDeviceID,
0
);

    把指定的 audio driver id 設成 0 (也就是 default audio driver )



MMRESULT Err = waveOutMessage((HWAVEOUT)WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_SET,
CurDeviceID,
(DWORD)-1
); 

 把指定的 audio driver id 設成-1 (變成最後一個,比如說總共有3個driver, 0 1 2 那就會變成 2 )




USB Audio Class Driver 除了 USB 的部份還有Audio Driver的部份
之後有2個 audio device,所以才會想到用 DRVM_MAPPER_PREFERRED_SET 來設定 default audio device。DRVM_MAPPER_PREFERRED_SET 在 WINCE 5 NavReady 2009 ( ARM Only )和在 WINCE 6 R3之後才有支援。不支援的話呼叫會傳回 8 (MMSYSERR_NOTSUPPORTED)




除了不支援設定哪個default 之外,要load 2 個 audio driver 也遇到了問題
http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-pb/10473/how-to-install-the-second-audio-driver
 search   "load audio driver wince"






但是看了WINCE 5 的help 之後,發現Audio Driver 有兩種,一種是 MDD+PDD 另一種是 UAM
(Unified Driver Model )。
可惜的是,MDD+PDD 只support only one device ( waveOutGetNumDevs always returns 1 )
新發現第三種 wavedev2 audio model ( Sample available in WINCE 6 ) (or WINCE 5 NMD Pack )
http://msdn.microsoft.com/en-us/library/ee485233.aspx
wavedev2 好像有support S/PDIF
http://www.ms-news.net/f3868/question-about-audio-driver-wince5-0-a-11725972.html

google wavedev2 waveapi.dll
http://news.rdeasy.cn/yingyong/20100208/7921.html


Writing a Network Audio Driver in WINCE
http://blogs.msdn.com/b/cenet/archive/2005/10/10/479282.aspx

Audio MDD PDD
在使用 MDD (wavemdd.lib) 的時候,PDD 部份要定義 gIntrAudio,並InterruptConnect 此 gIntrAudio。


Audio Stack 架構圖 ( described in wavedev.h )


//  @topic  Wave Audio API Manager Device Interface |
//          The COREDLL.DLL Dynamic Link Library gives user applications
//          access to the Waveform Audio functions.
//
//          The Waveform Audio API Manager exports the waveXXX functions via the
//          device manager's IOCTL calls. IOCTL_XXX constants are defined in
//          wavedev.h.
//
//  @ex     Software Layers |
//  
// *       ===============    ===============
// *       | Application |    | Application |  Module(s)
// *       ===============    ===============
// *    
// *         --------- MMSYSTEM.H ---------    Interface
// *    
// *       ==================================
// *       |          COREDLL.DLL           |  Module  (coredll.dll)
// *       ==================================
// *    
// *         ---------- WAVEDEV.H ---------    Interface
// *    
// *         ------ DeviceIoControl() -----    PSL API
// *    
// *       ==================================
// *       |     WAPI (Wave API Manager)    |  Module (waveapi.dll)
// *       ==================================
// *    
// *         ---------- WAVEDEV.H ---------    Interface
// *    
// *         ------ DeviceIoControl() -----    PSL API
// *    
// *       ==================================
// *       |            WAVEMDD             |  Module (wavedev.dll)
// *       ==================================
// *    
// *         --------- WAVEDDSI.H ---------    Interface
// *    
// *       ==================================
// *       |            WAVEPDD             |  Module (wavedev.dll)
// *       ==================================





DRVM_MAPPER_PREFERRED_SET and DRVM_MAPPER_PREFERRED_GET are not defined by Windows Embedded CE. To use these messages, you must first define them in your code, as follows:


#define DRVM_MAPPER 0x2000
#define DRVM_MAPPER_PREFERRED_GET (DRVM_MAPPER+21) 
#define DRVM_MAPPER_PREFERRED_SET (DRVM_MAPPER+22) 

2010年7月27日 星期二

Run Control Panel .cpl in command prompt

在WINCE下面,有 touchpanel 的control panel .cpl
因為不想重新 make image。
所以試著直接copy .cpl檔案 到機器上 run。

在Windows 底下, run control.exe 或 rundll32.exe shell32.dll,Control_RunDLL hdwwiz.cpl
control   --- 會叫出control panel window
control hdwwiz.cpl  會叫出相對應的control panel。

...而在WINCE 5 下面,打 control xxx.cpl 並不會呼叫相對應的 control panel,
只會叫出 control panel的 window。
還有有些 .cpl可以直接  double click 執行,有些不行。
還有 WINCE 底下沒有 rundll32.exe ....

DEBUGZONE

善用DEBUGZONE是很重要的
這樣程式的DEBUG輸出才會條理不容易亂
不過常常忘記DEBUGZONE 的用法
現在把它整理後寫在這邊


1.  Define DEBUGZONE



#define ZONE_INIT   DEBUGZONE(0)
#define ZONE_TEST   DEBUGZONE(1)
....


2. 定義 dpCurSettings

如以下


#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("USBPRN"), {
    TEXT("Errors"),    TEXT("Warnings"),  TEXT("Init"),        TEXT("Trace"),
    TEXT("LPT_INIT"),  TEXT("LPT_READ"),  TEXT("LPT_WRITE"),   TEXT("LPT_IOCTL"),
    TEXT("USB_PARSE"), TEXT("USB_INIT"),  TEXT("USB_CONTROL"), TEXT("USB_BULK"),
    TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),   TEXT("USBCLIENT")
    },
     0x0003 // ZONE_WRN|ZONE_ERR
};
#endif  // DEBUG


DBGPARAM 的第三個參數 zonemask 決定哪個DEBUG MSG打開

3. 使用 DEBUGREGISTER macro
在程式進入點的地方 call DEBUGREGISTER



BOOL
DllEntry(
   HANDLE hDllHandle,
   DWORD  dwReason,
   LPVOID lpreserved
   )
{
    UNREFERENCED_PARAMETER(hDllHandle);
    UNREFERENCED_PARAMETER(lpreserved);
    switch (dwReason) {

      case DLL_PROCESS_ATTACH:
           DEBUGREGISTER((HINSTANCE)hDllHandle);
  DisableThreadLibraryCalls((HMODULE) hDllHandle);
           break;

      case DLL_PROCESS_DETACH:
           break;

      default:
        break;
    }
    return TRUE;
}

一般程式(非DLL)的話,使用DEBUGREGISTER(NULL);

DEBUGREGISTER 只有在 DEBUG BUILD 中才有定義
而 RETAILREGISTERZONES 用在DEBUG 及 RETAIL BUILD 中

4. 完成

2010年7月23日 星期五

USB 研究

正在研究走 USB 還是走 SPDIF Optical 的音質哪一個比較好的時候
找到以下的網頁
http://msdn.microsoft.com/en-us/library/ff540194(VS.85).aspx

關於SPDIF Wikipedia 已經有詳細的說明
就我目前的了解
SPDIF 發送端的品質影響很大。因為接收端不能控制Data Rate。
高等的 Amplifier 可能會有特別的處理,如 clock lock, jitter free。


相對的,USB方面可能有兩種傳送方式。
第一種最常用的就是走 Isochronous Transfer。
這個可能會有問題,跟SPDIF比也不知道誰好誰壞。go
就我使用Digital Music SX的經驗,聽音樂時,再使用其它USB裝置如隨身碟傳大檔案,
有時會破音。(也或許是 creative 的driver沒有寫好)

第二種就是把Audio Stream 當成data 來傳,這樣就有 error correction 及 data resend。
好像 emu0404 是採用此種方式。

看了上面那篇文章,USB Protocol 對bandwidth allocation好像是 first-come first-serve
如此看來 USB Isoch Transfer 如果用得好的話,應該會比SPDIF好?
http://www.my-hiend.com/vbb/showthread.php?t=1965

http://forum.audiogon.com/cgi-bin/fr.pl?ddgtl&1179056058&openflup&5

請再search asynchronous USB

Ayre QB-9 vs Lavry DA11

2010年6月23日 星期三

GetPixel too slow & CreateDIBSection in WINCE

在做 Text 的Overlay 的時候,有人用 GetPixel。但是GetPixel 實在很慢,查了一下網上的資料,
可能的替代的方法有
use GetDIBits
use GetBitmapBits
use LockBits ( C#, .NET FrameWork )
use LockBits ( ImagingFactory )

但是,很可惜的,在WINCE底下,前兩個函式都沒有。
所以只能用.NET CF或 ImagingFactory。

或是使用 DDB ( via CBitmap in MFC) 或者 DIBSection.
很可惜的,在MFC中 也沒有提供 DIBSection Wrapper.
詳情請參照
http://www.codeproject.com/KB/graphics/dibsection.aspx

所以說 最簡單的方式 就是使用 CreateDIBSection
然後直接對 pvBits 做存取。
對bitmap 直接存取,改善之後的速度大幅提升。
真不知道 GetPixel內部是怎麼做的,那麼慢!

2010年5月25日 星期二

Link error: unresolved external symbol __imp_CommandBar_XXXXXX

在編譯 CE下的 format程式時,選擇 windows program, 並且編譯 沒有問題。
因為要link storeapi.lib
但是當我在lib path 中include C:\WINCE\PUBLIC\COMMON\OAK\LIB\MIPS\RETAIL 時
會出現以下錯



1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_AddAdornments referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_InsertMenubar referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_Create referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_Show referenced in function "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z)

調查後發現 在Standard SDK下的 Commctrl.lib 和 PUBLIC\COMMON\OAK\LIB下的 Commctrl.lib 並不相同

SDK下的 Commctrl.lib 只是一個 dll import library
OAK\LIB 下的則為實際的 static library

但是Standard SDK 下的Commctrl.h 和 PUBLIC\COMMON\SDK\INC 下的 Commctrl.h
是一樣的。

在 commctrl.h

//
// Define API decoration for direct importing of DLL references.
//
#ifndef WINCOMMCTRLAPI
#if !defined(_COMCTL32_) && defined(_WIN32)
#define WINCOMMCTRLAPI DECLSPEC_IMPORT
#else
#define WINCOMMCTRLAPI
#endif
#endif // WINCOMMCTRLAPI



IN winnt.h
#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC) || defined(_M_IA64)) && !defined(MIDL_PASS)
#define DECLSPEC_IMPORT __declspec(dllimport)
#else
#define DECLSPEC_IMPORT
#endif

所以 __imp_ 是Microsoft 為 dllimport 所加上的修飾詞

目前能想到的暫時解決方法(非完美)為
把Standard SDK 的Lib 也加入 在PUBLIC\COMMON\OAK\LIB 的前面





主要是 WINCOMMCTRLAPI 的定義
不應該跑到上面 DECLSPEC_IMPORT



2010年5月17日 星期一

Warning C4512 assignment operator could not be generated

The compiler will also generate an assignment operator function for a class that does not define one. This assignment operator is simply a member wise copy of the data members of an object. Because const data items cannot be modified after initialization, if the class contains a const item, the default assignment operator would not work.




You can resolve the C4512 warning for this code in one of three ways:



•Explicitly define an assignment operator for the class.



•Remove const from the data item in the class.



•Use the #pragma warning statement to suppress the warning.


這個Warning (Level 4)是因為編譯器會自動產生 default assignment operator
但是如果 class 裡面有 const data member,  因為 const data member 在 initialize 之後
就無法改變( assign )其值,所以沒有辦法產生default assignment operator。

2010年5月14日 星期五

WINCE底下的錄音 ( Waveform API)

最近要用到 voice note 功能,把之前寫的錄音程式拿出來。
測試之後發現了2個問題,一個是聲音之間會有中斷,如 1 2 3 4 5 6 7 8 會變成 1 3 5 6 8
第二個問題是錄音的尾段部份消失。


聲音之間有中斷是因為 buffer 只有allocate 一個,
使用 double buffer or multiple buffer 就可以解決
( waveInPrepareHeader 對每個buffer 只需call 一次)

錄音尾部消失是因為最後一個chunk的data沒有寫入。
當呼叫 waveInStop() 停止錄音,並不會call waveInProc = ="
waveInProc 是只有當buffer 滿的時候才會被呼叫。
所以要改用別的方法...

If there are any buffers in the queue, the current buffer will be marked as done (the dwBytesRecorded member in the header will contain the length of data)

判斷buffer done , 由 WAVEHDR 中的 dwFlags
是否為WHDR_DONE

再來從The code project 看到他人所寫的code,
要寫成wave檔,可用mmioWrite函式
但是WINCE下沒有,所以... 要自己寫檔頭,
以及結尾時 寫在檔頭部份的長度。

第三個問題是
如果沒有正確的 waveInClose()  (傳回值為WAVERR_STILLPLAYING  0x21)
則下一次無法正常打開device  waveInOpen()
必須要重開機。

2010年5月5日 星期三

AAC in QuickTime 7.6.6 error 2041 2048

!從7.6.5 換成 7.6.6之後
好像之前用 mp4muxer mux 的聲音+影像檔無法撥放
出現 error 2041: an invalid sample description was found in the movie

目前還不清楚哪裡出錯
試過各種mux參數還是無法成功

下面這個網站說要用
-aac-profile=4
http://bahut.alma.ch/2010/02/quicktime-error-2041-invalid-sample.html

還在試驗中
(VLC撥放ok)

libfaac
在libfaac 的 gui 版本中 只能選擇 Low Complexity 其它的被mark 掉了
但是實際上又沒設好這個值 所以 config->aacObjectType 為0

/* AAC object types */

#define MAIN 1
#define LOW 2
#define SSR 3
#define LTP 4
 
if (config->aacObjectType == SSR) /* Set to LTP */

config->aacObjectType = LTP;
 
(解決了,把 config->aacObjectType = LOW 然後再mux,ok)

後來又遇到開檔錯誤 2048, 無法分辨其格式
經過實驗後 發現 libfaac MPEG version 要用 MPEG2 才能播 MPEG4 不行

最後結論

QuickTime 似乎
1.  只支援 AAC LC.
2. AAC 播放的話 只能播放 MPEG-2 Profile 的 AAC
3. 要Mux 成MP4的話,要使用 MPEG-4 的AAC 及勾選 MPEG-4 Profile。

2010年5月4日 星期二

C++ 心得(無法用pointer存取父類別的 protected member)

在C++中 子類別如果想要存取父類別的函式、data member ( non-static member )
直接叫用就行。

但是如果是用pointer 存取的方式那就會導致 error C2248。

2010年4月29日 星期四

Switch between MIPS and Win32

在VS2008中 要switch MIPS & Win32,
發現
1. Standard SDK x86 build 出來的執行檔無法在Windows(Win32) 下執行??
2. comment stdafx.h, include 及其它的如 就可以 compile了
3. 研究 CE 下的 stdafx.h
// stdafx.h : include file for standard system include files,


// or project specific include files that are used frequently, but

// are changed infrequently

//



#pragma once



#pragma comment(linker, "/nodefaultlib:libc.lib")

#pragma comment(linker, "/nodefaultlib:libcd.lib")



// NOTE - this value is not strongly correlated to the Windows CE OS version being targeted

#define WINVER _WIN32_WCE



#include

#if defined(WIN32_PLATFORM_PSPC)

defined(WIN32_PLATFORM_WFSP)

#define SHELL_AYGSHELL

#endif



#ifdef _CE_DCOM

#define _ATL_APARTMENT_THREADED

#endif



#include









#include

#include



#if defined(WIN32_PLATFORM_PSPC)

defined(WIN32_PLATFORM_WFSP)

#ifndef _DEVICE_RESOLUTION_AWARE

#define _DEVICE_RESOLUTION_AWARE

#endif

#endif



#ifdef _DEVICE_RESOLUTION_AWARE

#include "DeviceResolutionAware.h"

#endif



#if _WIN32_WCE < 0x500 && ( defined(WIN32_PLATFORM_PSPC)

defined(WIN32_PLATFORM_WFSP) )

#pragma comment(lib, "ccrtrtti.lib")

#ifdef _X86_

#if defined(_DEBUG)

#pragma comment(lib, "libcmtx86d.lib")

#else

#pragma comment(lib, "libcmtx86.lib")

#endif

#endif

#endif



#include



// TODO: reference additional headers your program requires here


WIN32_PLATFORM_PSPC   WinCE Pocket PC ( or Palm Size PC )
WIN32_PLATFORM_WFSP  WinCE SmartPhone

Printer.swap

在 CE 的根目錄下發現了 Printer.swap 這個檔案,大小為 2,000,000
搜尋了一下,這個檔案是由 smbserver 所create,作為network printer的spool
好像沒辦法消除,不過目前可由registry控制其大小。

[HKEY_LOCAL_MACHINE\Services\SMBServer]


"PrintSwapFile"="\\Hard Disk\\Spooler.file"

"PrintSwapMax"=dword:A00000

"PrintSwapInc"=dword:5000

2010年4月28日 星期三

Silverlight for Windows Embedded

http://msdn.microsoft.com/en-us/library/ee502198(v=WinEmbedded.60).aspx
http://geekswithblogs.net/WindowsEmbeddedCookbook/archive/2009/10/01/silverlight-for-embedded-tutorial.aspx

在Windows CE 6 R3 中加入 silverlight component

Silverlight for Windows Embedded 對應到 Silverlight 2 版本
而且 只能用C++ 來寫而非 C# or Visual Basic
而且好像不依賴 .net compact framework

大致上是
http://msdn.microsoft.com/en-us/library/ee503558.aspx

To create an application for a Windows Embedded CE powered device that is based on Silverlight, you create the XAML file that defines the UI and create a subproject. Then, use the Silverlight C++ API to initialize Silverlight, parse the XAML file into an object tree, and add event handlers to the parsed elements.

1. include some header
2. call XamlRuntimeInitialize()

詳細範例可參考
\WINCE600\PUBLIC\COMMON\OAK\DEMOS\XAMLPERF

和silverlight 差異的部份
http://msdn.microsoft.com/en-us/library/ee501848(v=WinEmbedded.60).aspx

2010年4月27日 星期二

Visual Studio 2008 Link Problem

http://msdn.microsoft.com/en-us/library/cc664727.aspx

在Visual Stdio 2008 中,要使用 #define _BIND_TO_CURRENT_VCLIBS_VERSION 1;
才會對 SP1 的Library binding 。不然的話,預設的連結方式為連結到 release version。

To show what version of libraries that lib file needs, type:
dumpbin /directives .lib
The output might contain something like:




Linker Directives

-----------------

/manifestdependency:"type='win32'

name='Microsoft.VC90.CRT'

version='9.0.21022.8'

processorArchitecture='x86'

publicKeyToken='1fc8b3b9a1e18e3b'"

/DEFAULTLIB:"MSVCRT"

/DEFAULTLIB:"OLDNAMES"



related info:
http://www.nuonsoft.com/blog/2008/10/29/binding-to-the-most-recent-visual-studio-libraries/
http://blogs.msdn.com/vcblog/archive/2008/08/12/bugs-fixed-in-mfc-in-visual-studio-2008-sp1.aspx

2010年4月26日 星期一

WaitForSingleObject thread (等待執行緒結束)

WaitForSingleObject ( threadHandle )
會等待執行緒結束

USB Timeout Related Issue

USB stick 插入和拔出的時間問題。

在USB Host Client Driver Registry Settings 有一項

[HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\Mass_Storage_Class\6]
MediaPollInterval:1250 ; msec
ReadSectorTimeout:2000
WriteSectorTimeout:2000
ScsiCommandTimeout:5000
UnitAttnRepeat:10

UnitAttnRepeat 是指測試 Unit 是否Ready,其測試次數。

flow:
IOCTL_DISK_READ, IOCTL_DISK_WRITE ( disk.c ) -->
ScsiRWSG --> ScsiReadWrite ( scsi2.c )  --> ScsiUnitAttention
--> ScsiTestUnitReady

如果 UnitAttnRepeat 為10的話,則 ScsiTestUnitReady 執行10次

而MediaPollInterval
則是在 disk.c 的 MediaChangeThread() 裡面會用到

2010年4月20日 星期二

German TimeZone Problem

德國的客戶有個問題,用網路存取檔案,總是會有一些時間差。懷疑是TimeZone的Problem。

的確,因為我根本還沒有處理時區的問題。

經過查證後(Use GetTimeZoneInformation() ),WINCE 5 default time zone 為 Pacific Standard Time, UTC -0800。

德國,查證 Wiki後,為 Central European Time (CET),現在(4月)為 CEST, Central European Summer Time。

CET 為 UTC + 0100, CEST 為 UTC + 0200
切換時間為 每年三月的最後一個星期日 UTC 1:00
及每年 十月的最後一個星期日 UTC 1:00

其它請參閱 SetTimeZoneInformation

註:
設定秘訣 year 為 0 ,幾月的第幾個星期格式, 5為最後
然後此函數daylight轉換的時間 為local time,要注意。

2010年4月16日 星期五

JPEG Library Study

 jpeg_write_raw_data() -->

jpeg_write_raw_data() 每次16行,也就是一個 imcu row

encode_mcu_huff() 被 call 8160 次
encode_one_block() 被 call 65280次

2010年4月13日 星期二

Warning: Image exceeds specified memory size by 9280 bytes and may not run.

When makeimg, there is the warning above.
AUTOSIZE
要修改 config.bib 或 eboot.bib

ce.bib 也是最終的 bib

WINCE 6 SD Card driver build error, PBInitEnv.bat

In AU1200 BSP, build SD Card driver has the following error!
There is no SDbus.lib.
So remove SD Card driver.
In platform.bib we want to remove BSP_SDHC_AU1X,
and it is defined in PBInitEnv.bat.

But PBInitEnv.bat is created by system.
When u setup catalog item. It will write variables to pbinitenv.bat.

2010年3月11日 星期四

MP4 格式解密

根據 14496-12  ISO base media file format,
以下幾個atom是必要的

ftyp
moov
         mvhd
         trak
                tkhd
                mdia
                        mdhd
                        hdlr
                        minf
                                dinf
                                       dref
                                stbl
                                      stsd
                                      stts
                                      stsc
                                      stco

但根據實測,少了 stss, quicktime 無法正常播放。

stco 是fill 資料chunk 的offset,而且以file 開頭來計算。

2010年2月1日 星期一

JPEG emit_bits_s

emit_bits_s()  called by encode_one_block() in jchuff.c
所做的事就是單純地把bit 輸出

put_buffer 32bit 只用到右邊24bit
每次進來的bits 最多是16bit
再加上之前殘餘的最多不超過8bit( <= 7bit )
所以24bit 就足夠了


At most 16 bits can be passed to emit_bits

 in one call, and we never retain more than 7 bits in put_buffer
 between calls, so 24 bits are sufficient.

前次殘餘的bit + 這次進來的 bit
超過8bit 就輸出一個byte

1. 進來的code
2. 往左shift 靠在第24bit的位置
3. OR 之前的bit
4. 每8個bit 輸出一個byte 直到資料小於8bit

MP4 Audio Mux & AAC header format

用 DVBPortal (mp4creator) mux AVC & AAC
總共有2個trak
2個 mdat section




AAC Header
(參考 http://mp4tech.net/document/audiocomp/0000207.asp )

 http://www.hydrogenaudio.org/forums/lofiversion/index.php/t21617.html



AAC的音频文件格式有以下两种:
ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。

ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。


Mux 完在mp4 mdat section 中的aac 比原始的aac 少了n個 7bytes的header
這些header 的格式為 FF F1 DC 40 XX XX XX

emphasis field 2 bit 現在沒有用了,所以是 Fixed header( 28bits) + Variable header(28bits) = 7 bytes

sync word  12bit : 1111 1111 1111  所以是 FF F

ID 1     0: MPEG-4, 1: MPEG-2

layer 2 always: '00'


protection_absent 1

profile 2

sampling_frequency_index 4

private_bit 1

channel_configuration 3

original/copy 1

home 1

ADTS Variable header: these can change from frame to frame


copyright_identification_bit 1

copyright_identification_start 1

aac_frame_length 13 length of the frame including header (in bytes)

adts_buffer_fullness 11 0x7FF indicates VBR

no_raw_data_blocks_in_frame 2

ADTS Error check

crc_check 16 only if protection_absent == 0

After that come (no_raw_data_blocks_in_frame+1) raw_data_blocks.

Some elaborations:

profile

bits ID == 1 (MPEG-2 profile) ID == 0 (MPEG-4 Object type)

00 (0) Main profile AAC MAIN

01 (1) Low Complexity profile (LC) AAC LC

10 (2) Scalable Sample Rate profile (SSR) AAC SSR

11 (3) (reserved) AAC LTP



 
ADTS詳細格式請參考 14496-3
由上可知 AAC Frame Length 為13bit, 所以一個AAC Frame最大值為8K
ADIF格式主要是應用在一般的檔案資料中,而ADTS格式則主要利用在網路的傳輸 上,為了避免傳輸產生的錯誤,ADTS格式在AAC檔案的每一個音框(frame)中都傳一次檔 頭;而ADIF格式只有一個檔頭。


ADTS 每一個frame前都有加檔頭 7bytes,
然後檔頭後面的格式 為raw format
有七種格式
常見的為
CPE
請參考 14496-3
http://www.aeroquartet.com/movierepair/aac.html


CPE 格式

21 0B CF or 21 0B CD

0010 0001 0000 1011 1100


1. 前3個bit 代表格式 在這邊 001 代表 此frame 為CPE ( Channel Pair Element )
其它還有 000   SCE ( Single Channel Element )
                 010  CCE
                 011  LFE ....
2. 再來 4個bit 為 element_instance_tag
3. 再來1個bit 為 common_window
4. 如果 common_windows 為1 在CPE中 接下來就是 ics_info
5. window_sequence 如果等於 EIGHT_SHORT_SEQUENCE (10) 就 ...
在此我們可以看到 window_sequence 不等於 EIGHT_SHORT_SEQUENCE
6. maxsfb 在此為 6bit 101111 (47)  剛好是呼叫 AACQuantize() 時 參數num_cb 的值

2010年1月6日 星期三

Y Color Range, Color space problem

Old standard use ITU 601
HD format use ITU 709

ITU 709 使用不同的轉換公式

Rec. 601 Y' = 0.299 R' + 0.587 G' + 0.114 B'
Rec. 709 Y' = 0.2126 R' + 0.7152 G' + 0.0722 B'

請參考
http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm
還有Rec. 709 in wikipedia
http://en.wikipedia.org/wiki/Rec._709

http://dcmc.ee.ncku.edu.tw/pdf/course/Reports/Adaptive_Logarithmic_Mapping_For_Displaying_High_Contrast_Scenes.pdf

sRGB 和 Rec. 709 的primaries 一樣

Color 校正討論
http://my3c.com/D5/archiver/?tid-3187.html


Color system  ( Color appearance model )

CIEXYZ 1931
CIELAB 1976

Munsell 1930s
CIECAM 2002

CIECAM02 is used in Windows Vista's Windows Color System.