2.24.2010

Change Disk Cluster Size in CE

MSDN的這一篇:Register Setting for FAT Format

FormatClusterSize

可以設定 format 時的 ClusterSize。
例如:
FormatClusterSize"=dword:200
就是設定 cluster size = 2k.


改 Cluster Size 有什麼好處?
好像可以加快 disk Read/Write Speed.. ... 好像.

這個設定只有在 partition formate 時才會參考到。

2.22.2010

這一篇 說 debug serial port 除了可以用來 output debug message 外,也可以用來 input data。
但是 OEM vendor 要提供 OEMReadDebugByte( ) 的實作。

照他的方法,在 private code 中找 OEMReadDebugByte( ) 最後可以找到在 printf.c 中InputDebugCharW ( ) 為最上層..


format printf - I64

link : MS 特殊的 printf format:
http://msdn.microsoft.com/en-us/library/ms860371.aspx

由於 printf 是用 valist,所以 format 裡的 size 特別重要。

MS 比較特殊的有.. I64 - 指定 long long 的 variable

0x%016I64X

就是印出 long long 的 variable.

2.08.2010

Code Reading - Gabest - mplayer : mpeg4 (?) demux 部份

http://sourceforge.net/projects/guliverkli/develop 拿 source code.
在 http_proxy 後的,只要 export https_proxy="http://192.168.147.242:3128" 就可以 (你的 proxy server address, port)

search 0x47 在:

guliverkli\trunk\guliverkli\src\filters\parser\basesplitter\BaseSplitterFileEx.cpp

果然出現一堆..

衍生的class 有:
  • class CMP4SplitterFile : public CBaseSplitterFileEx
  • class CMpaSplitterFile : public CBaseSplitterFileEx
  • class CMpegSplitterFile : public CBaseSplitterFileEx
從上次的 post,class id 來search..

MPEG [IN] Input:

Filter : MPC - Mpeg Splitter (Gabest) - CLSID : {DC257063-045F-4BE2-BD5B-E12279C464F0}

- Connected to:

CLSID: {E436EBB5-524F-11CE-9F53-0020AF0BA770}
Filter: G:\log.trp
Pin: Output

- Connection media type:

Unknown

Class ID : DC257063-045F-4BE2-BD5B-E12279C464F0
是 guliverkli\src\filters\parser\mpegsplitter\MpegSplitter.h



2.05.2010

音訊檔案處理軟體 Audacity

Audacity 很不錯喔。

原來是 音訊檔的 調整軟體。
可以切割/合併,增大/縮小聲音檔。

也可以產生特定的tone,波形,頻率可以自己產生。

支援 wave, mp3, flac.... 等檔案格式。

而且還是 open source 的喔

ISDB-T TRP file content info

日本 ISDB-T (13 seg) 的 streamming file : *.trp。

由 property 來看:
  • Video : Mpeg4 Video (H264) 320x172 , 14.99fps
  • Audio : AAC 48000Hz sterro 37Kbps

可以用 K lite Codec Pack 新版來看。

* 最新的版本還可以看到:

General
Complete name : G:\log.trp
Format : MPEG-TS
Format profile : No PAT/PMT
File size : 17.8 MiB

Video
ID : 1024 (0x400)
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Baseline@L1.2
Format settings, CABAC : No
Format settings, ReFrames : 1 frame
Width : 320 pixels
Height : 180 pixels
Display aspect ratio : 16:9
Frame rate : 29.970 fps
Resolution : 8 bits
Colorimetry : 4:2:0
Scan type : Progressive

Audio
ID : 1280 (0x500)
Format : MPEG Audio
Video delay : -899ms

再詳細用 Play -- Filter --Audio Filte -- Proerties -- [IN]log.trp/Audio 看:

Filter : Audio Switcher - CLSID : {18C16B08-6497-420E-AD14-22D21C2CEAB7}

- Connected to:

CLSID: {0F40E1E5-4F79-4988-B1A9-CC98794E6B55}
Filter: ffdshow Audio Decoder
Pin: Out

- Connection media type:

Audio: PCM 48000Hz stereo 1536kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 1
cbFormat: 18

WAVEFORMATEX:
wFormatTag: 0x0001
nChannels: 2
nSamplesPerSec: 48000
nAvgBytesPerSec: 192000
nBlockAlign: 4
wBitsPerSample: 16
cbSize: 0 (extra bytes)

pbFormat:
0000: 01 00 02 00 80 bb 00 00 00 ee 02 00 04 00 10 00 ....€.........
0010: 00 00 ..



用 一樣的 MPC MPEG Filter 來看
[IN] input:

Filter : MPC - Mpeg Splitter (Gabest) - CLSID : {DC257063-045F-4BE2-BD5B-E12279C464F0}

- Connected to:

CLSID: {E436EBB5-524F-11CE-9F53-0020AF0BA770}
Filter: G:\log.trp
Pin: Output

- Connection media type:

Unknown

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Stream {E436EB83-524F-11CE-9F53-0020AF0BA770}
subtype: MEDIASUBTYPE_MPEG2_TRANSPORT {E06D8023-DB46-11CF-B4D1-00805F6CBBEA}
formattype: TIME_FORMAT_NONE {00000000-0000-0000-0000-000000000000}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 1
cbFormat: 0

[OUT] Video

Filter : MPC - Mpeg Splitter (Gabest) - CLSID : {DC257063-045F-4BE2-BD5B-E12279C464F0}

- Connected to:

CLSID: {04FE9017-F873-410E-871E-AB91661A4EF7}
Filter: ffdshow Video Decoder
Pin: In

- Connection media type:

Video: MPEG4 Video (H264) 320x192 14.99fps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Video {73646976-0000-0010-8000-00AA00389B71}
subtype: Unknown GUID Name {31435641-0000-0010-8000-00AA00389B71}
formattype: FORMAT_MPEG2_VIDEO {E06D80E3-DB46-11CF-B4D1-00805F6CBBEA}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 1
cbFormat: 159

VIDEOINFOHEADER:
rcSource: (0,0)-(0,0)
rcTarget: (0,0)-(0,0)
dwBitRate: 0
dwBitErrorRate: 0
AvgTimePerFrame: 667333

VIDEOINFOHEADER2:
dwInterlaceFlags: 0x00000000
dwCopyProtectFlags: 0x00000000
dwPictAspectRatioX: 320
dwPictAspectRatioY: 192
dwControlFlags: 0x00000000
dwReserved2: 0x00000000

MPEG2VIDEOINFO:
dwStartTimeCode: 0
cbSequenceHeader: 27
dwProfile: 0x00000042
dwLevel: 0x0000000c
dwFlags: 0x00000004

BITMAPINFOHEADER:
biSize: 40
biWidth: 320
biHeight: 192
biPlanes: 0
biBitCount: 0
biCompression: AVC1
biSizeImage: 0
biXPelsPerMeter: 0
biYPelsPerMeter: 0
biClrUsed: 0
biClrImportant: 0

pbFormat:
0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020: 00 00 00 00 00 00 00 00 c5 2e 0a 00 00 00 00 00 ...............
0030: 00 00 00 00 00 00 00 00 40 01 00 00 c0 00 00 00 ........@......
0040: 00 00 00 00 00 00 00 00 28 00 00 00 40 01 00 00 ........(...@...
0050: c0 00 00 00 00 00 00 00 41 56 43 31 00 00 00 00 .......AVC1....
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070: 00 00 00 00 1b 00 00 00 42 00 00 00 0c 00 00 00 ........B.......
0080: 04 00 00 00|00 13 67 42 e0 0c b6 81 41 9f 9e 10 ......gB.A.
0090: 00 00 3e 90 00 07 53 08 40 00 04 68 ce 3c 80 ..>..S.@..h<€ - Enumerated media type 0: Set as the current media type


以上的 demuxer 是用 Gabest 的 MPEG Splitter。
這個是 open source project, Wiki : Media Player Classic

相關的Link

2.04.2010

memo : timeGetTime in windows ce

有時後 kernel driver 要用 timeGetTime( ) 取得 system tick (雖然說比較準,但是實際上code 跟 gettickcount( ) 是一樣的)

source code 要 include windows.h
還有要 link mmtimer.lib

2.02.2010

Get Powe Notification : AP

AP 要收到 suspend/wakeup 的通知,可以用 RequestPowerNotifications
Sample Code 在 google groupe 上: PowerChange Notifications : Resume

很好心的把 code 都貼出來,但是我用起來有一點問題,就是 Notification Thread 沒有辦法terminate 掉,

/ John Baik: Sample code for Power Notification

#include <windows.h>
#include <PM.h>
// from pmimpl.h file.
#ifndef QUEUE_ENTRIES
#define QUEUE_ENTRIES 3
#endif
#ifndef MAX_NAMELEN
#define MAX_NAMELEN 128
#endif

#ifndef QUEUE_SIZE
#define QUEUE_SIZE (QUEUE_ENTRIES * (sizeof(POWER_BROADCAST) + \\
(MAX_NAMELEN * sizeof(TCHAR))))
#endif

int WINAPI PMNotifyThread(LPVOID pvParam);
void PMNotification(HANDLE hMsgQ);

HANDLE ghPMNotifyQ = NULL;


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSGQUEUEOPTIONS msgQpm = {0};
HANDLE hPwrNotify=NULL; // Power manager handle
HANDLE hPMThread=NULL;

// create a message queue for Power Manager notifications
msgQpm.dwSize = sizeof(MSGQUEUEOPTIONS);
msgQpm.dwFlags = 0;
msgQpm.dwMaxMessages = QUEUE_ENTRIES;
msgQpm.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;
msgQpm.bReadAccess = TRUE;

ghPMNotifyQ= CreateMsgQueue(NULL, &msgQpm);

if (ghPMNotifyQ == NULL)
{
DWORD dwErr = GetLastError();
RETAILMSG(1, (TEXT(" PMNotify:CreateMessageQueue ERROR:%d \r\n"), dwErr));
return 1;
}

// request Power notifications
hPwrNotify = RequestPowerNotifications(ghPMNotifyQ, PBT_TRANSITION |
PBT_RESUME);

if (hPwrNotify == NULL)
{
DWORD dwErr = GetLastError();
RETAILMSG(1, (TEXT(" PMNotify:RequestPowerNotifications ERROR:%d\r\n"), dwErr));
return 2;
}

// Create PMNotifyThread
hPMThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE )PMNotifyThread, NULL, 0, NULL);

if(hPMThread)
{
// wait for PMNotifyThread done
WaitForSingleObject(hPMThread, INFINITE);
CloseHandle(hPMThread);

if(hPwrNotify)
{
StopPowerNotifications(hPwrNotify);
}
}

return 0;

}

// PMNotifyThread: Wait for Message from PM Driver.
//
int WINAPI PMNotifyThread(LPVOID pvParam)
{
DWORD dwStatus;

while (TRUE)
{
dwStatus = WaitForSingleObject(ghPMNotifyQ, INFINITE);

if(dwStatus == WAIT_OBJECT_0)
{
PMNotification(ghPMNotifyQ);
}
else
{
RETAILMSG(1,
(TEXT(" PMNotify: WaitForSingleObject returned %d (error %d)\r\n"),
dwStatus, GetLastError()));
break;
}
}

return 0;

}

void PMNotification(HANDLE hMsgQ)
{
UCHAR pmbuf[QUEUE_SIZE];
int nBytesRead=0;
DWORD dwFlags = 0;
int dwCount = 0;

memset(pmbuf, 0, sizeof(pmbuf));

if ( !ReadMsgQueue(hMsgQ,
pmbuf,
QUEUE_SIZE,
(LPDWORD)&nBytesRead,
INFINITE, // Timeout
&dwFlags))
{
DWORD dwErr = GetLastError();
RETAILMSG(1,
(TEXT(" ProcessPowerNotification: ReadMsgQueue:ERROR:%d\n"), dwErr));
}
else if(nBytesRead >= sizeof(POWER_BROADCAST))
{
// process power notifications
//-----------------------------
PPOWER_BROADCAST pPB = (PPOWER_BROADCAST) pmbuf;

switch (pPB->Message)
{
case PBT_RESUME:
RETAILMSG(1, (TEXT(" PMNotify:PBT_RESUME \r\n")));
break;

case PBT_POWERSTATUSCHANGE:
RETAILMSG(1, (TEXT(" PMNotify:PBT_POWERSTATUSCHANGE: \r\n")));
break;

case PBT_POWERINFOCHANGE:
RETAILMSG(1, (TEXT(" PMNotify:PBT_POWERSTATUSCHANGE: \r\n")));
break;

case PBT_TRANSITION:
{
switch (POWER_STATE(pPB->Flags))
{
case POWER_STATE_ON:
break;
case POWER_STATE_OFF:
break;
case POWER_STATE_CRITICAL:
break;
case POWER_STATE_BOOT:
break;
case POWER_STATE_IDLE:
break;
case POWER_STATE_SUSPEND:
break;
case POWER_STATE_RESET:
break;
default:
break;
}
break;
}

default:
break;
}
}

}


實際上用要稍微修改一下..
  • PMThread 要有 Exit 的機制 - 在 WaitForSingleObject 加 Timeout check flag 或是用 WaitForMultipleObject 代替
  • WinMain 的 code 其實要分兩部份: InitPowerHandler, ClosePowerHandler. 放在 Dialog Proc 的 WM_INITDIALOG 和 WM_CLOSE

2.01.2010

pid and contunuity code in Transport Stream

雖然 Wiki 上寫的 pid 是在 high byte,continuity code 也是在 high byte。
但是實際上做起來:
byte 0 : sync 0x47
byte 1 : pid high and xxx bit
byte 2 : pid low and
byte 3 : continuity code and xxx

pid = ((byte1 << 8) | byte2) & 0x1FFF
cnt = byte3 % 0x0F