- ベストアンサー
TCPでデータを受け取って連続表示するストリーミング動画再生ソフトの作成方法
- TCPでデータを受け取って連続表示するストリーミング動画再生ソフトを作成する方法を探しています。
- データは非圧縮のベタデータで送られてくるため、データを表示する際のメモリー消費に問題があります。
- VC++とDirectXを使用して高速に表示する方法を試していますが、まだうまくいっていません。最適な手法や手順についてのヒントを教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
D3DXCreateTextureFromFileInMemoryEx が遅そうですね。 DirectXを使わずに、ビットマップをBitBltで描画する方法はどうでしょうか。 参考URL: 保存した100枚のビットマップ画像を連続表示 - 質問・相談ならMSN相談箱 http://questionbox.jp.msn.com/qa4477113.html GDI/GDI+のビットマップ転送能力 http://lamoo.s53.xrea.com/develop/gdiplus/gdiplus_blt.html また、YUV→RGB変換には、実数演算がふくまれているので、整数の処理に置き換えると良いかもしれません。 参考URL: KnowledgeBase: RGB<-->YUV変換 http://tyre.gotdns.org/domino/web01/tecrep2.nsf/By+Category/51583FE03EC06DAF49256B220018E62C?Open
その他の回答 (3)
- blueflower1024
- ベストアンサー率53% (16/30)
非圧縮ということにこだわらないのであれば、1枚ずつJPEG圧縮をかけるのはどうでしょうか。これでもサイズは数10分の1になります。 処理がフレーム単位で独立していますので、送信側、受信側とも苦労せずに対応可能だと思います。送信サイズが小さくなる分、無圧縮で送信するよりも負荷は小さく出来るでしょう。 ちなみに、初代Playstationは、この方法で動画を表示していました。規格的には「MotionJPEG」と呼ばれています。
補足
今回はTCP転送が高速にできますよというデモに使用しますので、圧縮して転送するのはNGとなります。 また、実際TCPデータの受信およびデータのチェックだけであれば、CPU使用率は20~30%にとどまっています。 今回、TCPの通信を行わない状態で、画像データをPCプログラム内でパターンを生成しているのみにもかかわらず、CPU使用率は50%を超え(Core duoなので、実質使用率は100%です)、60fpsの描画ができていない状況です。 一般的な動画とは違い、60fpsなので重いというのはわかってはいるのですが、WindowsではOpenGLよりDirectXのほうが軽いのではとの思いがあり、今回質問させていただいたしだいです。 DirectShowのレンダラーを使えばできそうな感じではあるのですが、DirectX以上にベタデータの表示に関する情報が少なく、困っております。
- Wr5
- ベストアンサー率53% (2173/4061)
>これで1280*720*60*16なので、885Mbpsになるかと考えています。 やっぱりギガビットイーサでも足りません。 「ギガビットイーサなら1000Mbpsだから足りるのでは?」 とか思っています? 規格上は1000Mbpsでも、その速度がフルで出るコトはありません。 またTCP/IPのヘッダが付与されたりしますから全部は使えません。 TCPは比較的重いです。 UDPなら多少は早くなりますが、エラー時の再送などはありませんしパケットの到着順も保証されません。 データ圧縮して転送するなりしないとどうにもならんでしょう。
補足
今回ハードワイヤードTCP/IPをFPGAで作成しまして、PCで受信して データ比較も行って実測で900Mbps出ることを確認しています。 これはもちろんヘッダを除いた実データ部分の速度です。 以下は、実際のデータ転送の模様で、4GBの転送を35秒以内で完了しています。 http://www.youtube.com/watch?v=g1gigQT1dec ただデータが流れてるだけでは面白くないので、ハイビジョンカメラのデータを イーサネット経由でPCで受信して表示するというデモを作成しようと思っております。 通信部分は今回問題としておりませんので、できれば、今回の質問そのものに お答えいただけますと助かります。 DirectXで、 D3DXCreateTextureFromFileInMemoryEx→BeginScene→Begin→Draw→End→EndScene→Present→SAFE_RELEASE をループさせることで表示させることはできましたが、負荷が高すぎて60fpsはまったく出ませんでした。(表示する画像はプログラム内で簡単なパターンを作成しています) この方法があっているかどうかがわかっておりませんが。。 OpenGLも、試してみましたが少し厳しいようです。 (glutIdleFuncで画像パターンデータ生成と、glutPostRedisplayを回しております。) そもそも画像データパターン生成だけでも重いようで(したがって、ソフトウェアでのYUV→RGB変換も重いと思われます)、そこから考えないといけないようではあるのですが。。
- php504
- ベストアンサー率42% (926/2160)
ソフトの問題より通信速度的にギガビットイーサネットでも無理です
補足
すいません。相談する部分とは直接関係なかったので詳しくは書きませんでしたが、イーサネットで来るデータはYUVで、Yに8bit、UVにそれぞれ4bitを割り当てる予定です。これで1280*720*60*16なので、885Mbpsになるかと考えています。 表示するときにRGBに変換して24bitにしようかと考えています。
お礼
BitBltの情報をいただけたおかげで、デモのほう完成いたしました。 結局DDBは直接触れないようで、DIBで作成しました。 YUV→RGB変換は、演算そのものよりピクセルごとにデータを書き込むのに時間がかかるようで(ライトバックキャッシュはどうなってるんでしょうか。。)、送信側でYUV→RGB変換して、ソケットの受信バッファに直接DIBの画像データポインタを指定することで表示させました。 そのため、32bitの転送となり、フレームレートは30fpsに下げざるを得なくなりましたが、DIBの表示自体も若干重かったので、ちょうどよかったのかなと考えています。 なんだか、Windowsプログラミングは、MicroSoftの手のひらで踊らされているようですね。 ともかく、ありがとうございました。
補足
ありがとうございます。 BitBltを試してみましたが、圧倒的に早いですね。 ただ、LoadImageでbmpファイルから作ったビットマップの表示はできるのですが、 メモリー上にあるデータをビットマップ(DDB)にする方法がわからず四苦八苦しております。 CreateBitmapである程度できるようですが、カラーにはCreateCompatibleBitmapで作れとありCreateBitmapでカラーDDBを作るサンプルが見当たらず、CreateCompatibleBitmapで作ろうとすると、こいつは画像データのポインタを渡してくれないらしく、結局メモリー上のデータをDDBにすることができず。。。 このあたりなにかヒントがあれば、お教えいただければと思います。