Date

(2010.6.22 ソースコード、本文、全体的に見直し。ソースコードをVS2010プロジェクトで製作。)

Windows Vista/7 には Media Foundation と呼ばれる映像・音声プラットフォームがあるので、 それを利用して手軽に高精度なタイマーを取得してみたい。

以下のサンプルプログラムは、Media Foundation を用いてシステムクロックを取得し、1秒ごとにデバッグ出力に現在のクロック値を出力するプログラムである。10秒で停止する。

```c++ stdafx.h

include

include

pragma comment(lib,"mfplat.lib")

pragma comment(lib,"mf.lib")

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
mfapi.h と mfidl.h をインクルードし、 mfplay.lib と mf.lib をリンクする。

```c++ MF_SysClock2.cpp
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    HRESULT hr;
    CComPtr<IMFClock> clock;
    CComPtr<IMFPresentationTimeSource> time_src;

    hr = MFStartup(MF_VERSION);
    if (FAILED(hr)) return 0;
    hr = MFCreateSystemTimeSource(&time_src);
    if (FAILED(hr)) goto SHUTDOWN;
    time_src->GetUnderlyingClock(&clock);

    DWORD characteristics;
    clock->GetClockCharacteristics(&characteristics);
    ATLASSERT(characteristics & (DWORD)MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK);

    LONGLONG ll_time;
    MFTIME start_time, sys_time;
    clock->GetCorrelatedTime(0, &ll_time, &start_time);

    do {
        TCHAR buf[100];
        Sleep(1000);
        clock->GetCorrelatedTime(0, &ll_time, &sys_time);
        _snwprintf_s(buf, _TRUNCATE, L"%I64d\n", ll_time);
        OutputDebugString(buf);
    } while((sys_time - start_time) / MFCLOCK_FREQUENCY_HNS < 10);
SHUTDOWN:
    MFShutdown();
    return 0;
}

MFStartup(MF_VERSION) で Media Foundation が使用可能に、MFShutdown() で使用終了する。

MFCreateSystemTimeSourceを使って、システムクロックをタイムソースとするIMFPresentationTimeSourceインターフェイスを取得する。

実際のクロック値を取得するためにIMFClock::GetCorrelatedTimeを呼び出す。IMFClockインターフェイスはIMFPresentationTimeSource::GetUnderlyingClockを呼び出して取得する。

c++ IMFClock::GetCorrelated HRESULT GetCorrelatedTime( [in] DWORD dwReserved, [out] LONGLONG *pllClockTime, [out] MFTIME *phnsSystemTime );

dwReserved 0でなければならない。
pllClockTime クロック周波数の単位での時刻。
phnsSystemTime 100ナノ秒単位の時刻。

Media Foundation では 100 ナノ秒単位が基準である。1秒 = 10000000ナノ秒だが MFCLOCK_FREQUENCY_HNS で定義されている。

https://github.com/mahorigahama/MF_SysClock2


Comments

comments powered by Disqus