連載2 画像転送システム その4
圧縮処理はICCompress()を一つ使うだけなので簡単。また、引数が多いですがAMVビデオコーデックをはじめ最近のコーデックの場合は殆どの引数を無視しますので0にしておきましょう(もちろんコーデックによっては個々の引数が意味を持つ場合もあるのでそういったコーデックを利用する場合はしっかり調べましょう)。
結局、重要な引数は入力フォーマットと、入力バッファのアドレス、出力フォーマットと出力バッファのアドレスと非常にシンプルです。
各フォーマットは準備編で用意したものを使いますが、ICCompress()の引数の型がなぜかLPBITMAPINFOHEADERとなっているので念のためヘッダーの方を指定しています。入力バッファのアドレスはDIBセクションのアドレスを指定します。出力バッファのアドレスは準備編で用意したものを使いましょう。
// コーデックを使ってDIBの画像を圧縮する BOOL CodecMain( void ) { DWORD dwFlagsIn = 0; DWORD dwFlagsOut = 0; DWORD dwckid = 0; long lFrameNum = 0; DWORD dwFrameSize = 0; // 目標ビットレート(指定なし) DWORD dwQuality = 0; DWORD ret = ICCompress( ghIC, // コーデックのハンドル dwFlagsIn, // 圧縮動作の制御フラグ(キーフレームなど) // AMVコーデックでは使いません。 &glpbiOut->bmiHeader, // 圧縮後のフォーマット(ビットマップインフォヘッダー) glpCompressBuff, // 圧縮後の画像データを格納するバッファ &glpbiIn->bmiHeader, // 圧縮元のフォーマット(ビットマップインフォヘッダー) glpOff, // 圧縮元の画像データを格納したバッファ(DIB) &dwckid, // 予約されています。使わないで下さい。 &dwFlagsOut, // 圧縮後のステータスが格納される(キーフレームの検出に利用) lFrameNum, // AMVコーデックでは使いません。 dwFrameSize, // 目標ビットレート、AMVコーデックでは使いません。 dwQuality, // 画質、AMVコーデックでは使いません。 NULL, // 前フレームのフォーマット、AMVコーデックでは使いません。 NULL // 前フレームを格納するバッファ、AMVコーデックでは使いません。 ); if (ret != ICERR_OK) return FALSE; DWORD dwDataSize = glpbiOut->bmiHeader.biSizeImage; // 圧縮後のバイト数はメンバー変数に格納されている DWORD dwKeyframe = FALSE; if (dwFlagsOut & AVIIF_KEYFRAME) dwKeyframe = TRUE; // キーフレームとして圧縮された return TRUE; } |
ICCompress()が正常に終わると戻り値としてICERR_OKがセットされ、出力バッファに圧縮後のデータがセットされています。
圧縮後のデータが何バイトになるかは出力フォーマットのメンバー変数glpbiOut->bmiHeader.biSizeImageで確認できます。
また、処理したフレームがキーフレームになる場合はdwFlagsOutにAVIIF_KEYFRAMEがセットされます。他のフラグと一緒にセットされることもあるようなので、イコールで判定するのではなく論理積(and)を使って該当するビットが立っているかどうかで確認するようにしましょう。
以上で、コーデックを使った圧縮処理は終わりとなりますが、APIの中には他にもICSeqCompressFrame()というコーデックを使って動画を圧縮出来るものがあります。こちらの方が細かい部分をAPIの方で管理してもらえるので扱いが楽なのですが、出力バッファを指定できないと言う欠点がありまして、処理速度が求められる場合などには向きません。
アマレココの3.00まではICSeqCompressFrame()を使っていたのでコーデックにより圧縮されたデータはAPIが管理するバッファへ格納されてしまい、それをワザワザ自分で用意した出力バッファ(ファイルバッファ)へコピーしていました。このコピー処理がまるまる無駄となりコーデックを使った場合のオーバーヘッドとなっていましたが、3.01からICCompress()を使うようにしたので直接ファイルバッファへ書き出すことが出来(コピー処理が無くなった分)高速化となっています。
次回はサーバー編の最終回、ネットワークの送信処理を紹介します。
- 関連記事
trackback
コメントの投稿