Win32 API 日本語リファレンス
ホームMedia.WindowsMediaFormat › IWMWriter

IWMWriter

COM
IID96406bd4-2b2b-11d3-b36b-00c04f6108ff継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

IWMWriter インターフェースは、ASF ファイルの書き込みに使用します。

メソッド 13

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT SetProfileByID(GUID* guidProfile)

SetProfileByID メソッドは、現在の書き込みタスクで使用するプロファイルを、その GUID によって識別して指定します。

guidProfileGUID*inプロファイルの GUID。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_UNEXPECTED
原因不明の理由でメソッドが失敗しました。

解説(Remarks)

ID を持つのはシステムプロファイルのみです。システムプロファイルを調べるには、IWMProfileManager インターフェースのメソッドを使用してください。ヘッダーファイル Wmsysprf.h に、システムプロファイルとその ID の一覧が記載されています。

vtbl 4 HRESULT SetProfile(IWMProfile* pProfile)

SetProfile メソッドは、現在の書き込みタスクで使用するプロファイルを指定します。

pProfileIWMProfile*inIWMProfile インターフェースへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
ASF_E_STREAMNUMBERINUSE
プロファイル内の複数のストリームが同じストリーム番号を持っています。
NS_E_INVALIDPROFILE
プロファイルのストリーム数がゼロです。

CBR エンコードモードでビットレートがゼロに指定されました。

複数のスクリプトストリームが指定されました。

帯域幅共有情報が正しくないか、一貫性がありません。

NS_E_INVALID_STATE
ライターが構成可能な状態ではありません。
NS_E_INVALID_STREAM
すべてのストリームに共通:
  • 100,000 を超えるバッファーウィンドウが指定されました。
  • ストリーム番号が 1 未満または 63 を超える値で指定されました。
オーディオストリームの場合:
  • formattypeWMFORMAT_WaveFormatEx ではありません。
  • wformatTagWAVE_FORMAT_PCM ではなく、nAvgBytesPerSec がゼロです。
  • サブタイプ GUID から導出された FOURCC が dwFormatTag と一致しません。
  • PCM オーディオで、nAvgBytesPerSec が (nSamplesPerSec * nBlockAlign) と等しくありません。
  • PCM オーディオで、nBlockAlign が (nChannels * wBitsPerSample / 8) と等しくありません。
ビデオストリームの場合:
  • formattypeWMFORMAT_VideoInfo ではありません。
  • cbFormat が sizeof(WMVIDEOINFOHEADER) と等しくありません。
  • IWMStreamConfig を通じて指定されたビットレートが、VIDEOINFOHEADERdwBitrate の値と等しくありません。(IWMStreamConfig::SetBitrate でビットレートをゼロに設定した場合は該当しません。)
  • 非圧縮ビデオストリームで、bmiHeader.biSizeImage が正しく指定されていません。
  • bmiHeader で指定された矩形の幅または高さが、圧縮タイプに対して有効ではありません。(一部のタイプでは 2 バイトまたは 4 バイトの境界調整が必要です。)
  • rcSource または rcTarget 矩形のいずれかのメンバーが負の値です。
  • サブタイプ GUID から導出された FOURCC が bmiHeader.biCompression と一致しません。
  • bmiHeader.biCompression メンバーが BI_BITFIELDS ですが、cbFormat が正しくありません。
  • bmiHeader.biCompression = BI_RGB または BI_BITFIELDS の場合に、biBitCountbiClrUsed、または cbFormat の値が矛盾しているか無効です。(BITMAPINFOHEADER がパレット値のインデックスを含む場合、フォーマットブロックのサイズが大きくなる点に注意してください。)
スクリプトストリームの場合:
  • formattypeWMFORMAT_Script として指定されていません。
  • サブタイプが GUID_NULL として指定されていません。
NS_E_SDK_BUFFERTOOSMALL
オーディオストリーム内の言語文字列に指定されたサイズが小さすぎます。

解説(Remarks)

このメソッドを呼び出すと、それまでに設定されたヘッダー属性情報はすべて削除されます。

このメソッドを呼び出した後にプロファイルオブジェクトへ加えた変更は、SetProfile を再度呼び出すまで有効になりません。

プロファイル内のストリームの最大数は、定数 WM_MAX_STREAMS で定義されているとおり 63 です。別の定数 WM_MAX_VIDEO_STREAMS はビデオストリームの最大数を定義しており、これも 63 です。

vtbl 5 HRESULT SetOutputFilename(LPWSTR pwszFilename)

SetOutputFilename メソッドは、書き込むファイルの名前を指定します。

pwszFilenameLPWSTRinファイル名を格納したワイド文字の null 終端文字列へのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_UNEXPECTED
原因不明の理由でメソッドが失敗しました。
NS_E_INVALID_STATE
ライターが構成可能な状態ではありません。

解説(Remarks)

このメソッドは、インデックス 0 のファイルシンクを作成し、IWMWriterAdvanced::AddSink の呼び出しを通じて追加することと同等であり、便宜のために提供されています。

このメソッドで作成されたファイルシンクの IWMWriterSink インターフェースへのポインターは、IWMWriterAdvanced::GetSink を呼び出すことで取得できます。ライターは、関連付けられたシンクのステータスメッセージを配信しないため、これは重要です。IWMWriterSink に対して QueryInterface を呼び出すことで、IWMRegisterCallback へのポインターを取得できます。これは、シンクがステータスメッセージを配信する先の IWMStatusCallback::OnStatus コールバックメソッドを設定するために使用します。

vtbl 6 HRESULT GetInputCount(DWORD* pcInputs)

GetInputCount メソッドは、非圧縮入力ストリームの数を取得します。

pcInputsDWORD*out入力数へのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
pcInputs パラメーターが NULL です。

解説(Remarks)

このメソッドは GetInputProps とともに使用して、さまざまな入力を列挙し、それぞれの入力フォーマットを取得できます。これらは、プロファイルで指定される出力 Windows Media ストリームではありません。マルチビットレートのシナリオでは、1 つの入力ストリームが複数の Windows Media ストリームに対応することがあります。

vtbl 7 HRESULT GetInputProps(DWORD dwInputNum, IWMInputMediaProps** ppInput)

GetInputProps メソッドは、指定した入力ストリームの現在のメディアプロパティを取得します。

dwInputNumDWORDin入力インデックス番号を格納した DWORD
ppInputIWMInputMediaProps**outIWMInputMediaProps オブジェクトへのポインターへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
dwInputNum の値が最大インデックス番号を超えています。

解説(Remarks)

dwInputNum パラメーターに使用するインデックスの範囲は、GetInputCount を呼び出すことで確認できます。

IWMInputMediaProps オブジェクトを操作しても、アプリケーションが入力を構成するために SetInputProps メソッドを呼び出さない限り、ライターには影響しません。

vtbl 8 HRESULT SetInputProps(DWORD dwInputNum, IWMInputMediaProps* pInput)

SetInputProps メソッドは、入力ストリームのメディアプロパティを指定します。

dwInputNumDWORDin入力番号を格納した DWORD
pInputIWMInputMediaProps*inIWMInputMediaProps インターフェースへのポインター。「解説」を参照してください。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
dwInputNum が最大インデックス番号を超えています。
E_OUTOFMEMORY
使用可能なメモリが不足しています。
E_UNEXPECTED
原因不明の理由でメソッドが失敗しました。

解説(Remarks)

IWMInputMediaProps オブジェクトを操作しても、アプリケーションが入力を構成するためにこのメソッドを呼び出すまでは、ライターには影響しません。

入力が、再圧縮されずに (IWMWriterAdvanced::WriteStreamSample を使用して) 新しいストリームに直接書き込まれる圧縮済みサンプルを含む場合は、pInputNULL を指定してください。

vtbl 9 HRESULT GetInputFormatCount(DWORD dwInputNumber, DWORD* pcFormats)

GetInputFormatCount メソッドは、ライター上のこの入力がサポートするメディアフォーマットタイプの数を取得します。

dwInputNumberDWORDin入力番号を格納した DWORD
pcFormatsDWORD*outフォーマット数へのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
pcFormats パラメーターが NULL です。

または

dwInputNumber が大きすぎます。

vtbl 10 HRESULT GetInputFormat(DWORD dwInputNumber, DWORD dwFormatNumber, IWMInputMediaProps** pProps)

GetInputFormat メソッドは、指定した入力に対して可能なメディアフォーマットを取得します。

dwInputNumberDWORDin入力番号を格納した DWORD
dwFormatNumberDWORDinフォーマット番号を格納した DWORD
pPropsIWMInputMediaProps**outIWMInputMediaProps インターフェースへのポインターへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
dwInputNumber が大きすぎます。
vtbl 11 HRESULT BeginWriting()

BeginWriting メソッドは、書き込みプロセスを初期化します。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_OUTOFMEMORY
使用可能なメモリが不足しています。
E_UNEXPECTED
原因不明の理由でメソッドが失敗しました。
NS_E_AUDIO_CODEC_ERROR
オーディオコーデックでエラーが発生しました。
NS_E_AUDIO_CODEC_NOT_INSTALLED
必要なオーディオコーデックが利用できません。
NS_E_DRM_RIV_TOO_SMALL
より新しいコンテンツ失効リストが必要です。
NS_E_INVALID_OUTPUT_FORMAT
出力フォーマットが有効ではありません。
NS_E_VIDEO_CODEC_ERROR
ビデオコーデックでエラーが発生しました。
NS_E_VIDEO_CODEC_NOT_INSTALLED
必要なビデオコーデックが利用できません。

解説(Remarks)

BeginWriting メソッドは、サンプルを書き込む前に呼び出す必要があります。このメソッドは実際に書き込みを開始するのではなく、プロセスを初期化します。この呼び出しから EndWriting の呼び出しまでの間、ライターの構成を変更することはできません。サンプルの書き込みを正常に終了するには、EndWriting メソッドを呼び出す必要があります。

次の操作は、BeginWriting を呼び出す前にのみ実行できます:

次のメソッドは、プロファイルが設定された後、かつ BeginWriting を呼び出す前にのみ呼び出すことができます:

注: SetInputSetting は、g_wszDeinterlaceMode、g_wszInitialPatternForInverseTelecine、g_wszInterlacedCoding、および g_wszJPEGCompressionQuality については BeginWriting の後に呼び出すことができます。

次の操作は、プロファイルが設定された後であればいつでも実行できます:

次の操作は、BeginWriting を呼び出した後にのみ実行できます: 次の操作は、いつでも実行できます:

次のサンプルコードは、ライターをセットアップし、出力をネットワークシンクとアーカイブファイルの両方に送信する方法の概要を示しています。


IWMWriter *             pWriter = NULL;
IWMWriterAdvanced *     pWriterAdvanced = NULL;
IWMWriterFileSink2 *    pWriterFileSink = NULL;
IWMWriterNetworkSink2 * pWriterNetworkSink = NULL;
HRESULT                 hr = S_OK;
DWORD                   dwPort;

// エラー処理を簡単にするため、すべてをダミーループ内で行います。

do
{
    // 基本オブジェクトを作成します。

    hr = WMCreateWriter( &pWriter );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = WMCreateWriterFileSink( &pWriterFileSink );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = WMCreateWriterNetworkSink( &pWriterNetworkSink );
    if( FAILED( hr ) )
    {
        break;
    }

    // IWMWriterAdvanced インターフェースへのポインターを取得し、シンクを追加します。

    hr = pWriter->QueryInterface( IID_IWMWriterAdvanced, (void **)&pWriterAdvanced );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriterAdvanced->AddSink( pWriterFileSink );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriterAdvanced->AddSink( pWriterNetworkSink );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriterFileSink->Open( L"Archive file name" );
    if( FAILED( hr ) )
    {
        break;
    }

    // ポート番号をゼロに設定すると、SDK が適切な
    // ポート番号を選択できるようになります。
    dwPort = 0;
    hr = pWriterNetworkSink->Open( &dwPort );
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriter->BeginWriting();
    if( FAILED( hr ) )
    {
        break;
    }

    // ライターへデータを送信するコードをここに記述します (省略)。

    // 両方のシンクを閉じます。
    hr = pWriterFileSink->Close();
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriterNetworkSink->Close();
    if( FAILED( hr ) )
    {
        break;
    }

    hr = pWriter-> EndWriting();
    if( FAILED( hr ) )
    {
        break;
    }
}
while( FALSE );

// クリーンアップします。

if ( pWriter )
{
    pWriter->Release();
}
if ( pWriterAdvanced )
{
    pWriterAdvanced->Release();
}
if ( pWriterFileSink )
{
    pWriterFileSink->Release();
}
if ( pWriterNetworkSink )
{
    pWriterNetworkSink->Release();
}
vtbl 12 HRESULT EndWriting()

EndWriting メソッドは、書き込みセッションの終了時に必要なタスクを実行します。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
NS_E_INVALID_STATE
現在、ライターを実行できません。

解説(Remarks)

エンコードが完了する前にディスク領域を使い果たした場合でも、このメソッドは失敗コードを返しません。ファイル書き込みエラーの通知を受け取るには、アプリケーションで IWMStatusCallback メソッドを実装し、NS_E_FILE_WRITE イベントをリッスンする必要があります。

vtbl 13 HRESULT AllocateSample(DWORD dwSampleSize, INSSBuffer** ppSample)

AllocateSample メソッドは、ライターにサンプルを提供するために使用できるバッファーを割り当てます。

dwSampleSizeDWORDinサンプルサイズ (バイト単位) を格納した DWORD
ppSampleINSSBuffer**outサンプルを含むオブジェクトの INSSBuffer インターフェースへのポインターへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
NS_E_INVALID_REQUEST
現在、ライターが実行されていません。

解説(Remarks)

ライターオブジェクトに渡す各サンプルには、新しいバッファーを使用する必要があります。IWMWriter::WriteSample の呼び出しに渡した後のバッファーを再利用すると、ライターオブジェクトはバッファーオブジェクトへの参照をすぐには解放しないため、エラーが発生します。バッファーオブジェクトのインターフェースは、WriteSample の呼び出しが返った後であればいつでも安全に解放できます。

vtbl 14 HRESULT WriteSample(DWORD dwInputNum, ULONGLONG cnsSampleTime, DWORD dwFlags, INSSBuffer* pSample)

WriteSample メソッドは、圧縮されて作成中のファイルに追加される非圧縮データを渡します。

dwInputNumDWORDin入力番号を格納した DWORD
cnsSampleTimeULONGLONGinサンプル時間 (100 ナノ秒単位) を格納した QWORD
dwFlagsDWORDin

次のフラグを 1 つ以上格納した DWORD

フラグ 説明
フラグ未設定 他のフラグの条件のいずれにも該当しません。たとえば、デルタフレームはほとんどの場合、フラグが設定されません。
WM_SF_CLEANPOINT サンプルをキーフレームとして書き込むよう強制します。オーディオサンプルはすべてクリーンポイントであるため、オーディオ入力に対してこのフラグを設定しても効果はありません。
WM_SF_DISCONTINUITY オーディオ入力の場合、このフラグはサンプル間に生じる可能性のあるギャップの処理に役立ちます。ギャップの後の最初のサンプルには、このフラグを設定してください。
WM_SF_DATALOSS このフラグはライターオブジェクトでは使用されません。
pSampleINSSBuffer*inサンプルを表す INSSBuffer インターフェースへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
dwInputNum の値が最大インデックス番号を超えています。
E_UNEXPECTED
原因不明の理由でメソッドが失敗しました。
NS_E_INVALID_STATE
ライターが実行されていません。
NS_E_INVALID_DATA
サンプルが有効ではありません。これは、入力スクリプトストリームに有効でないスクリプトサンプルが含まれている場合に発生することがあります。
NS_E_INVALID_NUM_PASSES
ストリームの出力タイプに対して、前処理パスの数が誤っています。

通常、このエラーは、ストリーム構成が前処理パスを必要とするにもかかわらず、前処理を先に構成せずにサンプルが渡された場合に返されます。このエラーをチェックすることで、ストリームが前処理パスを必要とするかどうかを判断できます。前処理パスが必要になるのは、ビットレートベースの VBR の場合のみです。

NS_E_LATE_OPERATION
ライターが、プレゼンテーション時間の差が最大同期許容値を超えるサンプルを受け取りました。同期許容値は、IWMWriterAdvanced::SetSyncTolerance を呼び出すことで設定できます。

このエラーは、ストリームが複数あり、アプリケーションが一方のストリームのサンプルをもう一方のストリームより速いレートで送信した場合に発生することがあります。ある時点で、2 番目のストリームが 1 番目のストリームより大きく遅れ、ライターはこのエラーコードを返します。

NS_E_TOO_MUCH_DATA
リアルタイムソースからのサンプルが予想より速く到着しています。このエラーは、ライブソースを示すために IWMWriterAdvanced::SetLiveSource が呼び出されている場合にのみ返されます。

解説(Remarks)

出力ストリームにタイムコードのデータユニット拡張があり、サンプルにタイムコード拡張がない場合、後でファイルをインデックス化する際に問題を引き起こさないよう、このメソッドは失敗します。その他のデータユニット拡張は、サンプルでは省略可能です。つまり、ストリームに対してデータユニット拡張が指定されていても、サンプルに実際のデータ拡張が存在しない場合、このメソッドは成功します。WriteSample は、サンプルに拡張が指定されていないサンプルについては、ファイルにゼロを書き込みます。

vtbl 15 HRESULT Flush()

Flush メソッドの機能は削除されました。IWMWriter::EndWriting が必要なチェックを内部で実行するためです。古いアプリケーションとの互換性のため、flush の呼び出しは何も行いませんが、常に S_OK を返します。

戻り値

このメソッドは常に S_OK を返します。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

出力引数:
#define global IID_IWMWriter "{96406BD4-2B2B-11D3-B36B-00C04F6108FF}"
#usecom global IWMWriter IID_IWMWriter "{}"
#comfunc global IWMWriter_SetProfileByID       3 var
#comfunc global IWMWriter_SetProfile           4 sptr
#comfunc global IWMWriter_SetOutputFilename    5 wstr
#comfunc global IWMWriter_GetInputCount        6 var
#comfunc global IWMWriter_GetInputProps        7 int,sptr
#comfunc global IWMWriter_SetInputProps        8 int,sptr
#comfunc global IWMWriter_GetInputFormatCount  9 int,var
#comfunc global IWMWriter_GetInputFormat       10 int,int,sptr
#comfunc global IWMWriter_BeginWriting         11
#comfunc global IWMWriter_EndWriting           12
#comfunc global IWMWriter_AllocateSample       13 int,sptr
#comfunc global IWMWriter_WriteSample          14 int,int64,int,sptr
#comfunc global IWMWriter_Flush                15
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。