title_parttitle_parttitle_part
静岡県浜松市であれこれソフトを開発している A.K.I Software のブログです。日々の開発日記やサーバー・セキュリティ関連の話題なども掲載。
<< 2024/04 >>123456789101112131415161718192021222324252627282930
《《《 ネットワーク機器の購入は Amazon で! 》》》
Powered by BLOM Delphi で TJpegImage vs Intel Jpeg Library vs libjpeg-turbo での Benchmark
小さくも大きくも閉じたりもしません
13/06/19 23:48 / IT関連

以前の動態検知の記事で Motion JPEG でエンコードを行うことにしたのですが、録画に使っている PC の CPU パワーが全然無いので 6fps とかのていたらくぶりです。

開発に使っている Delphi には、TJpegImage という Jpeg ファイルを処理するライブラリが標準で備わっています。
内容的には、基本となる IJG JPEG ライブラリを利用しているのだと思います。

非常に手堅いライブラリなのですが(まぁ、エラー処理がきちんとしすぎていて、Jpeg エラー #42 とかの例外ダイアログを出してくれるので別に意味で困るんですが)いかんせん処理速度が遅いです。

そこで、Jpeg を高速化する方法は無いものかとあれこれ考えていたのですが、検索しているうちに ソフトウェア工房α様のサイトに IJG JPEG ライブラリを MMX や SSE2/SSE3 などを使って高速化した IJG's JPEG software with x86 SIMD extension V.1.02 というオープンソースを発見。

ダウンロードして見たのですが、当然のごとく Delphi では利用できません(笑)
でも、Borland C++ でコンパイルが出来るようなので「これはひょっとしていけるんじゃないか?」とあれこれやってみます。

NASM 環境を作って、bcc32 を使ってコンパイルするところまでは、すぐに出来るんですが、出来上がった .obj ファイルを Delphi から参照しようとしますと、E2045 でフォーマットが不正です(E2045 Bad format error)が発生します。

あれ?bcc32 でコンパイルすれば OMF 形式で出力されるんでないの?と tdump で確認してみますが、特に問題はなさそうです。
他にも大量のエラーが発生しているので(よくある関数先頭のアンダースコア命名規則とかの関係)まず、そこから書き換えていきます。

全部をザラッと書き換えてリコンパイルしてみたのですが、やっぱり Bad format error です。なぜに〜!!

しょうがないので、ダメ元で Visual Studio からコンパイルした後に COFF形式の .obj を COFF2OMF(RAD Studio についてくるコンバーター)を使って強引に変換してみますが、出力ファイルが全部 512byte になります(^-^;

なんかないかなと探していたら objconv.exe という変換ソフトがあったので、これを使って変換をしてみます。
今度は変換は出来たようなので、再度 Delphi から LINK してみたのですが、やっぱり Bad format error...

うーーん、LINK する順番なのかな?と思っていたのですが、時間がかかりそうなので、ここで断念。

そういえば、昔 Intel JPEG Library ってのがあって使ったことがあったよな、と思い出し古いバックアップを漁ってみたらありました。
当時作った C のヘッダファイルから移植した Delphi のソースもありましたので組み込んでみます。
が!ここで大きな問題が。
当時デコードの為に使っていたので、デコード関連しか作りこんでいません。今回はエンコードが必要なので使い物にならん!ってことで、しょうがないのでエンコード関連も作るかなと思って C のヘッダファイルを見つつ、compress 関連を移植します。(移植する言うても、compress 関連の関数定義を Delphi で定義して LoadLibrary するだけなんですが)
動くところまで出来たので、試してみると、おぉ!確かに速いわ〜、これいいわ〜!採用だな!と思っていたのですが、Intel のサイトにもっと新しいバージョン無いのかな?と探してみると、どうやら現在 Intel JPEG Library は有償(正確には Intel が販売しているライブラリの一部)になっていて、確かに手持ちの IJL1.5 は当時無償だったのですが、既に持っている人が個人的に使うなら問題は無さそうなんですが、同梱しての再配布などはまずそうです。

さすがにフリーで公開しているから。なんて勝手な理屈をつけて添付する訳にもいかないので、こちらも断念。
まぁ、自分だけで使う分ならいいかなと思って別の事をしていたのですが(当然仕事も)やっぱり気になって気になって・・・(^-^;

なんか無いのか〜と再度検索してみると libjpeg-turbo なるライブラリが出ているそうです。
どうやら最初に見つけた、IJG's JPEG software with x86 SIMD extension をベースにした改良版らしく、オープンソースで開発が進められているようです。

あ、これいいな。と思って早速ダウンロードしてみたのですが、ソースが見当たらない、あるのは LIB ファイル orz

C/C++ なんかでは LIB ファイルが当たり前なんですが、Delphi は LIB ファイルを利用することができません!
ダメじゃん!! IJLもライセンスが不明だし、遅い TJpegImage を使うしか無いじゃん!って思ったのですが・・・神は見放しませんでした。
libjepg-turbo win32 版には jpeg62.dll という DLL で提供がされているのです。

おまけに、関数も libjpeg 互換のようなので(ちょっとだけ違うんかな?jpeg_memory_dest が jpeg_mem_dest だったり。LoadProcAddress が失敗するので、バイナリエディタで除いて関数名確認しました(^-^;)殆どコードの使い回しが出来ます。

逆に LIB を使って組み込むとライセンスの問題が出てくると思われますが、DLL があったら動的リンクする形にすればいいんでない?(無かったら遅い TJpegImage を使う)
高速処理が必要な人は libjpeg-turbo をダウンロードしてね。で済むし。
ライセンスに問題があるとしたら、別に動的リンクを止めれば良いだけだし〜ってことで、これを使うことにします。

さて、前置きが超長いのですが、一通りのコードが出来上がりましたので、各ライブラリでの benchmark を試してみます。

photo


測定対象は3つです。
計測方法は Load は Jpeg ファイルを読み出して TBitmap 形式のストリームに出力します(decompress)

Save は、Bitmap ファイルを読み出して、Jpeg 形式のストリームに出力します(compress)

サンプルの Bitmap は 24bit / 720x479 filesize 1,011KB です。
同じくサンプルの Jpeg は 24bit / 600x900 filesize 66KB です。

ループ回数は 100 回です。

1) TJpegImage

Delphi 標準です。
Load 4,399ms
Save 2,792ms
decompress が遅いですね。decompress に比べると compress は少しはマシなのですが、1回の処理速度が 27ms になりますので、これだけで見れば 30fps で処理は可能なんですが、JPT3815 などの ip camera は JPEG が飛んでくる→一旦 Bitmap に decompress する→日付や画像処理をする→Compressして Jpeg に再変換する→ AVI Stream に書き出す。という流れで処理が必要になるので、仮にその他の処理が 5ms だったとしても、43ms + 27ms + 5ms = 75ms で 13fps でしか処理できません。
(ちなみに CPU は Core i3 - 2.13GHzです。録画機はこの 1/3 くらいしか CPU パワーが無いので標準を使っていた時は 5〜6fpsしか出ていませんでした)

2)Intel JPEG Library

Load 2,309ms (IJG vs x1.90)
Save 1,045ms (IJG vs x2.67)

かなり高速です。これくらいでも充分です。
上の前提で行くと、23ms + 10ms + 5ms = 38ms で 26fps で処理が可能です。
これを使った状態では録画機で約 8〜10fps での記録が出来ていました。

3)libjpeg-turbo

Load 1,997ms (IJG vs x2.20)
Save 748ms (IJG vs x3.73)

非常に高速です。
同じく上の前提で行くと、20ms + 7.5ms + 5ms = 32.5ms でギリギリ 30fps で処理が可能となります。

蛇足ですが、いわゆるこれはソフトウェアエンコードですので、ハードウェアエンコードを使う専用機とは条件が違います。
ハードウェア Jpeg エンコーダチップで 200fps とか出せるのは専用ハードだからであり、それらと比較して、これらのライブラリが遅いという訳では決してありません。

これを使った状態では録画機で約 12fps での記録が出来ていました。
大体、JPT3815 から全力で受信した場合の最高速度が 12〜13fps ですので(これはネットワークの性能も関連します)ほぼ取りこぼすことなく録画が出来るようになりました。

素晴らしいですね!

[更新日付:2013/06/19 23:48:33]
トラックバックを見る(0)
Log Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+sl+c814c240cc430a3863f9c25e955eecd06c4ec7b5]
TB Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+tb+c814c240cc430a3863f9c25e955eecd06c4ec7b5]

記事へのコメント

コメントはありません

名前
コメントキー
 
コメントする時はキーを正確に入力して下さい
コメント
アドレスを含んだコメントはできません
© 2008-10 A.K.I Software all rights reserved.