Microsoft DirectX 8.0

SAMI (CC) パーサー フィルタ

SAMI (Synchronized Accessible Media Interchange) ファイルからのキャプション データを解析する。

SAMI は、HTML に似たテキスト フォーマットであり、タイム ベース キャプションのエンコードに使用される。このフィルタは、SAMI データをテキスト ストリームに変換する。ストリームの各サンプルには、キャプション エントリと共に、フォーマット情報が含まれている。サンプルのタイム スタンプは、SAMI ファイルのタイム情報から生成される。

このフィルタは、内部スクリプト コマンド レンダリング フィルタと共に使用するように設計されている。内部スクリプト コマンド レンダラは、テキスト サンプルを受け取り、イベント通知としてアプリケーションに送る。詳細については、「注意」を参照すること。

フィルタ インターフェイス IAMStreamSelectIBaseFilter
入力ピン メディア タイプ MEDIATYPE_Stream
入力ピン インターフェイス IPinIQualityControl
出力ピン メディア タイプ MEDIATYPE_Text、MEDIASUBTYPE_NULL
出力ピン インターフェイス IMediaSeekingIPinIQualityControl
フィルタ CLSID {33FACFE0-A9BE-11D0-A520-00A0D10129C0}
プロパティ ページ CLSID プロパティ ページなし
実行モジュール quartz.dll
メリット MERIT_UNLIKELY
カテゴリ CLSID_LegacyAmFilterCategory

注意

次に示すのは、単純な SAMI ファイルである。

<SAMI>
<Head>
<STYLE TYPE="text/css"> <!--
    .ENCC {Name: English; lang:en-US; SAMI_TYPE: CC;}
    .FRCC {Name: French; lang:fr-FR; SAMI_TYPE: CC;}
    #NORMAL {Name: Normal; font-family: arial;}
    #GREENTEXT {Name: GreenText; color:green; font-family: verdana;}
-->
</STYLE>
</Head>
<BODY>
<Sync Start=1000>
    <P CLASS="ENCC">One
    <P CLASS="FRCC">Un

<Sync Start=2000>
    <P CLASS="ENCC">Two
    <P CLASS="FRCC">Deux

<Sync Start=3000>
    <P CLASS="ENCC">Three
    <P CLASS="FRCC">Trois
</BODY>
</SAMI>

STYLE タグでは、英語 (.ENCC) とフランス語 (.FRCC) の 2 つの言語設定が定義される。また、#NORMAL および #GREENTEXT という 2 つのスタイルも定義される。各 SYNC タグでは、キャプションの開始タイムをミリ秒単位で定義する。P タグにはキャプション テキストが含まれ、CLASS 属性にはキャプションの適用先となる言語設定を指定する。

各言語とスタイルについて、フィルタは論理ストリームを作成する。常に、1 つの言語ストリームと 1 つのスタイル ストリームを有効にできる。フィルタがサンプルを生成する際は、現在の言語のキャプションを選択し、現在のスタイルを適用する。デフォルトでは、ファイルで宣言する最初の言語とスタイルが有効になる。アプリケーションは IAMStreamSelect::Enable メソッドを使って、異なるストリームを有効にできる。

デフォルトの設定では、サンプル ファイルの最初のキャプションによって、次の出力が作成される。

<P STYLE=" Name: English; lang:en-US; SAMI_TYPE: CC; Name: Normal; font-family: arial;">One

出力が内部スクリプト コマンド レンダラに送られると、このフィルタは EC_OLE_EVENT イベント通知を送る。2 つ目のイベント パラメータは、キャプション テキストを持つ BSTR である。アプリケーションは、イベントを取得してキャプションを表示できる。

次のサンプル コードは、SAMI ファイルのレンダリング方法、ストリーム情報の取得方法、ストリームを有効にする方法、およびキャプション テキストの表示方法について示している。この例では、以前の SAMI ファイルが C:\Sami_test_file.sami として保存されていることを想定している。簡潔にするために、このサンプル コードでは、IAMStreamSelect::Enable メソッドを呼び出す際にハード コーディングされたストリーム インデックスを使用している。

void __cdecl main()
{
    HRESULT hr;
    IGraphBuilder *pGraph;
    IMediaControl *pMediaControl;
    IMediaEventEx *pEv;
    IBaseFilter   *pSAMI;

    CoInitialize(NULL);
    
    // フィルタ グラフ マネージャを作成する。
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, 
                        IID_IGraphBuilder, (void **)&pGraph);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraph->QueryInterface(IID_IMediaEventEx, (void**)&pEv);

    // グラフを作成し、SAMI パーサーを探す。
    pGraph->RenderFile(L"C:\\Sami_test_file.sami", NULL);
    hr = pGraph->FindFilterByName(L"SAMI (CC) Parser", &pSAMI);
    if (SUCCEEDED(hr)) 
    {
        IAMStreamSelect *pStrm = NULL;
        hr = pSAMI->QueryInterface(IID_IAMStreamSelect, (void**)&pStrm);
        if (SUCCEEDED(hr)) 
        {
            DWORD dwStreams = 0;
            pStrm->Count(&dwStreams);
            printf("Stream count: %d\n", dwStreams);

            // フランス語および "GreenText" を選択する。
            hr = pStrm->Enable(1, AMSTREAMSELECTENABLE_ENABLE);
            hr = pStrm->Enable(3, AMSTREAMSELECTENABLE_ENABLE);

            // 各論理ストリームの名前を出力する。
            for (DWORD index = 0; index < dwStreams; index++)
            {
                DWORD dwFlags;
                WCHAR *wszName;
                hr = pStrm->Info(index, NULL, &dwFlags, NULL, NULL, &wszName, NULL, NULL);
                wprintf(L"Stream %d: %s [%s]\n", index, wszName, 
                    (dwFlags ?  L"ENABLED" : L"DISABLED"));
                CoTaskMemFree(wszName);
            }
            pStrm->Release();
        }
        pSAMI->Release();
    }

    // グラフを実行し、キャプションを表示する。
    pMediaControl->Run();
    while (1)
    {
        long evCode, lParam1, lParam2;
        pEv->GetEvent(&evCode, &lParam1, &lParam2, 100);
        
        if (evCode == EC_OLE_EVENT) {
            wprintf(L"%s\n", (BSTR)lParam2);
        }
        pEv->FreeEventParams(evCode, lParam1, lParam2);

        if (evCode == EC_USERABORT || evCode == EC_COMPLETE || evCode == EC_ERRORABORT)
            break;
    }

    // クリーン アップする。
    pMediaControl->Release();
    pEv->Release();
    pGraph->Release();
    CoUninitialize();
}

このフィルタは、IAsyncReader インターフェイスを使ってソース フィルタからサンプルを取得している。そのため、このフィルタは、入力ピン上で IMemInputPin インターフェイスをサポートしていない。