IAMTimecodeReader
COM公式ドキュメント
IAMTimecodeReader インターフェースは、外部デバイスから SMPTE または MIDI タイムコードを読み取ります。MSDV および MSTape ドライバーは、外部の DV または MPEG-2 カムコーダーからタイムコードを読み取るために、このインターフェースをサポートしています。
解説(Remarks)
Windows Driver Model (WDM) デバイスの場合、WDM ドライバーが PROPSETID_TIMECODE_READER プロパティ セットをサポートしていれば、WDM ビデオ キャプチャ フィルターがこのインターフェースを自動的に公開します。詳細については、Windows Driver Kit (WDK) のドキュメントを参照してください。
SMPTE タイムコードは、ビデオおよびオーディオ ソースを識別し、トラックの自動同期を可能にし、ソース素材に関連する追加データのコンテナーを提供する、フレーム アドレッシング システムです。SMPTE タイムコードの主な目的は、ビデオおよびオーディオに対して機械が読み取り可能なアドレスを提供することです。hh:mm:ss:ff(時、分、秒、フレーム)形式で表示され、ANSI/SMPTE 12-1986 で詳細に定義されています。
アプリケーションは通常、タイムコードを 2 通りの方法のいずれかで保存します。追加のストリームとしてキャプチャ ファイルに書き込むか、拡張 AVI ファイル インデックスに格納される不連続テーブルとして書き込みます。タイムコードは一般的に、キャプチャや再生のトリガーとして、またソース素材が完成品にどのように構成されるかを記述するエディット デシジョン リストの作成に使用されます。
タイムコードをキャプチャする場合は、独自のメディア タイプを持つ別個のストリームとして扱ってください。これは適切なファイル書き込み用マルチプレクサ フィルターによって処理できます。ただし、ドロップアウトやその他のテープの機械的な問題により、テープからのタイムコードの読み取りにエラーが発生することがあります。そのような場合、タイムコード ソース フィルターは単純にサンプルを破棄し、次の有効なサンプルに不連続プロパティを付けるようにします。
タイムコードが記録された(すなわち「ストライプ処理された」)ビデオテープからのキャプチャや再生をトリガーするためにタイムコードを使用する場合、一連の処理は次のようになります。
- キャプチャ グラフを構築し、対象の AVI ファイルを開き、必要に応じてディスク領域を事前割り当てします。キャプチャした素材を既存の AVI ファイルに追加する場合は、書き込み前にファイルの末尾へシークします。この時点でキャプチャ グラフは一時停止しています。
- VCR をキャプチャ開始点までサーチし、タイムコードを記録します。この値はプログラムに手動で入力することも、アプリケーションが自動的に読み取ることもできます。自動読み取りには、グラフが実行中である一方で、ファイル マルチプレクサの入力ピンにあるストリーム制御インターフェースが入力サンプルを破棄し、実質的にキャプチャをゲート制御している必要があります。
- VCR をプリロール位置(通常は目標点の 5 秒前)までキューイングします。
- VCR とグラフを開始します。トリガー点(またはトリガー点からファイル ライターのプリロールを差し引いた点)に到達すると、ストリーム制御インターフェースがファイル マルチプレクサを解放し、メディア サンプルのファイル ライターへのストリーミングを開始します。
- キャプチャ処理は、手動で、またはストリーム制御インターフェースに継続時間プロパティを設定することで停止できます。
ハードウェア要件
ハードウェア要件については、IAMExtTransport インターフェースを参照してください。フィルター開発者
外部デバイスが SMPTE/MIDI タイムコード情報をどのように読み取るべきかを指定したい場合は、このインターフェースを外部デバイス フィルターに実装します。アプリケーションが IMediaSeeking::ConvertTimeFormat メソッドを使用してタイムコードを基準時間に変換できるよう、フィルターに IMediaSeeking インターフェースを公開してください。外部デバイスは、タイムコードを読み取り、その制御インターフェースを介してコンピューターに送信できる必要があります。そうでない場合は、コンピューターにタイムコード リーダー カードを装備するか、キャプチャしたビデオ フレーム内の VITC(Vertical Interval Timecode)、またはオーディオ信号としてキャプチャした LTC(Linear Timecode)を DirectShow タイムコード サンプルに変換するソフトウェア デコーダーを作成する必要があります。
メソッド 5
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
GetTCRMode メソッドは、タイムコード リーダーのプロパティを取得します。
| Param | INT | in | 取得するタイムコード リーダーのプロパティ(ED_TCR_SOURCE または ED_TCR_NOTIFY_ENABLE のいずれか)。 | ||||||||||
| pValue | INT* | out | 要求したタイムコード リーダー プロパティの値へのポインター。Param が ED_TCR_NOTIFY_ENABLE に設定されている場合、このパラメーターは OATRUE(通知が有効であることを意味します)または OAFALSE を返します。Param が ED_TCR_SOURCE に設定されている場合、この値は次のいずれかである必要があります。
|
戻り値
E_NOTIMPL を返します。
解説(Remarks)
リニア タイムコードは、bi-phase mark 符号化された信号として、アナログ オーディオ トラックに記録されます。各タイムコード フレームの継続時間は、ビデオ 1 フレーム分の時間です。
垂直タイムコードは通常、ビデオ信号の垂直インターバルの 2 本のライン、おおむね 11 行目から 20 行目までのいずれかに格納されます。
コントロール トラックは、テープ上の特別なトラックに記録される、フレームごとに 1 回の信号です。ヘッドおよびドライブのサーボ機構は、これを利用してすべてをロック状態に保ちます。また、タイムコード機能を持たない機器でカウンターを駆動するために使用されるほか、タイムコード リーダーを備えた機器でも任意で使用できます。
ED_TCR_LAST_VALUE は、アプリケーションが外部デバイスへの新たなタイムコード要求を発行したくない場合に、タイムコード通知を実装する際に使用される点に注意してください。このメソッドは、マルチスレッドに関する問題があるため、フレーム精度が求められるアプリケーションには推奨されません。
SetTCRMode メソッドは、タイムコード リーダーのプロパティを設定します。
| Param | INT | in | 設定するプロパティ(ED_TCR_SOURCE または ED_TCR_NOTIFY_ENABLE を使用します)。 | ||||||||||
| Value | INT | in | 指定されたプロパティの値。Param が ED_TCR_NOTIFY_ENABLE を返す場合、この値は OATRUE または OAFALSE を返します。Param が ED_TCR_SOURCE を返す場合、この値は次のいずれかである必要があります。
|
戻り値
E_NOTIMPL を返します。
解説(Remarks)
リニア タイムコードは、NRZ bi-phase mark 符号化された信号として、アナログ オーディオ トラックに記録されます。各タイムコード フレームの継続時間は、ビデオ 1 フレーム分の時間です。
垂直タイムコードは通常、ビデオ信号の垂直インターバルの 2 本のライン、おおむね 10 行目から 20 行目までのいずれかに格納されます。
コントロール トラックは、テープ上の特別なトラックに記録される、フレームごとに 1 回の信号です。ヘッドおよびドライブのサーボ機構は、これを利用してすべてをロック状態に保ちます。また、タイムコード機能を持たない機器でカウンターを駆動するために使用されるほか、タイムコード リーダーを備えた機器でも任意で使用できます。
ED_TCR_LAST_VALUE は、アプリケーションが外部デバイスへの新たなタイムコード要求を発行したくない場合に、タイムコード通知を実装する際に使用される点に注意してください。このメソッドは、マルチスレッドに関する問題があるため、フレーム精度が求められるアプリケーションには推奨されません。
put_VITCLine メソッドは、タイムコード リーダーがタイムコードの読み取りに使用する垂直インターバル ラインを指定します。
| Line | INT | in | タイムコード情報を含む垂直ライン(有効なラインは 11 ~ 20。0 は自動選択を意味します)。 |
戻り値
E_NOTIMPL を返します。
解説(Remarks)
IAMTimecodeReader::SetTCRMode メソッドで VITC モードが指定されている場合は、どのラインにタイムコード情報が含まれるかを指定する必要があります。特定の複数ラインで VITC を読み取るには、呼び出し側は目的のライン 1 本ごとに IAMTimecodeReader::put_VITCLine を続けて呼び出します。
複数ラインにわたってテストを行うリーダーの場合、最上位ビットを設定してラインのリストに追加します。
get_VITCLine メソッドは、タイムコード リーダーがタイムコードの読み取りに使用している垂直インターバル ラインを取得します。
| pLine | INT* | out | タイムコード情報を含む垂直ラインへのポインター(有効なラインは 11 ~ 20)。 |
戻り値
E_NOTIMPL を返します。
解説(Remarks)
最上位ビットは、複数のラインが使用されており、続けて呼び出すことでライン番号が順に切り替わることを示します。
GetTimecode メソッドは、ストリームで利用可能な最新のタイムコード、ユーザービット、およびフラグの各値を取得します。
| pTimecodeSample | TIMECODE_SAMPLE* | out | TIMECODE_SAMPLE 構造体へのポインター。 |
戻り値
インターフェースの実装に依存する HRESULT 値を返します。
解説(Remarks)
このメソッドは、タイムコードを監視し、重複や不連続を解析するために使用します。
タイムコードには、ユーザービットと呼ばれる未定義のビットが含まれます。アプリケーションはこれらのビットを使用して、同期情報やその他のカスタム情報を格納できます。
DV および MPEG カムコーダーの実装
MSDV ドライバーは、SMPTE タイムコードまたは絶対トラック番号(ATN)の読み取りをサポートしています。MSTape ドライバーは、相対時間カウンター(RTC)の読み取りをサポートしています。これらのデバイスで時間情報を読み取るには、次の手順を実行します。TIMECODE_SAMPLE 構造体の dwFlags メンバーを、次のいずれかの値に設定します。
| 定数 | 説明 |
|---|---|
| ED_DEVCAP_TIMECODE_READ | タイムコード(DV) |
| ED_DEVCAP_ATN_READ | 絶対トラック番号(DV) |
| ED_DEVCAP_RTC_READ | 相対時間カウンター(MPEG テープ) |
TIMECODE_SAMPLE 構造体の timecode メンバーは、TIMECODE 構造体です。この構造体の dwFrames メンバーを 0 に初期化します。
その他のすべての構造体メンバーは無視されます。
メソッドが戻ると、dwFrames メンバーには、次の形式で時間情報が格納されます。
| 時間情報 | 形式 |
|---|---|
| タイムコード | 時、分、秒、フレームを二進化十進数(BCD)値で表したもの: 0xhhmmssff。 |
| ATN | トラック番号。 |
| RTC | 時、分、秒、フレームを BCD 値で表したもの: 0xhhmmssff。フレーム バイトの最上位ビットは符号ビットです。フレーム カウントが利用できない場合、残りのフレーム ビットは 0x7F に設定されます。 |
また、dwUser メンバーには、デバイスから ブランク フラグ ビットが格納され、次のいずれかの値になります。
| 値 | 説明 |
|---|---|
| 0x00 | 不連続ではありません。 |
| 0x01 | 不連続です。 |
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IAMTimecodeReader "{9B496CE1-811B-11CF-8C77-00AA006B6814}" #usecom global IAMTimecodeReader IID_IAMTimecodeReader "{}" #comfunc global IAMTimecodeReader_GetTCRMode 3 int,var #comfunc global IAMTimecodeReader_SetTCRMode 4 int,int #comfunc global IAMTimecodeReader_put_VITCLine 5 int #comfunc global IAMTimecodeReader_get_VITCLine 6 var #comfunc global IAMTimecodeReader_GetTimecode 7 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_IAMTimecodeReader "{9B496CE1-811B-11CF-8C77-00AA006B6814}" #usecom global IAMTimecodeReader IID_IAMTimecodeReader "{}" #comfunc global IAMTimecodeReader_GetTCRMode 3 int,sptr #comfunc global IAMTimecodeReader_SetTCRMode 4 int,int #comfunc global IAMTimecodeReader_put_VITCLine 5 int #comfunc global IAMTimecodeReader_get_VITCLine 6 sptr #comfunc global IAMTimecodeReader_GetTimecode 7 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。