連載2 画像転送システム その6

今回からはクライアント側の話になります。基本的にはサーバー側と似ていますので要点以外はチャチャッと行きます。
先ずはネットワーク処理からですが特別な処理は必要ないので省略して、コーデックの処理から始めます。

構造体やグローバル変数はサーバー側と同じモノを使い、最初にサーバー側で使ったコーデックの情報をネットワークから受信します。
受信は2回に分けて行い、一回目はコーデックのFourCCとサーバー側glpbiOutのバイト数を取得。次にバイト数分のバッファをglpbiInに確保してから二回目の通信でサーバー側のglpbiOutの内容をglpbiInへ受信します。
コレによりサーバー側のglpbiOutとクライアント側のglpbiInが同じ内容となりクライアントの入力フォーマットとします。

次に出力フォーマットglpbiOutです。基本的にはサーバー側のglpbiInと同じ設定になりますが完全に一致させる必要は無いのでネットワークは使わずに独自に設定しましょう。このとき画像サイズの設定だけ注意が必要です。画像サイズはコーデックにより変更される場合がありまして、例えばAMV3ビデオコーデックのハーフサイズオプションにより画像サイズが変更されます。こう言ったケースに対応するためにglpbiOutの画像サイズはキャプチャー時の画像サイズではなくglpbiInに設定されている画像サイズを使います。

入力/出力フォーマットが用意できたら、コーデックのデコンプレッサーのハンドルを取得します。このときコーデックのFourCCが必要になりますがこのFourCCはサーバー側から受信したFourCCを使います。

次にデコンプレッサーを初期化してデコンプレッサーの準備は完了です。
最後に圧縮されたデータを格納するためのバッファglpCompressBuffを確保して終わり。

#include <vfw.h>
#include <aviriff.h>
#pragma comment(lib,"vfw32")
 
// コーデック情報の送信につけるヘッダー
struct NETWORK_CODEC_HEADER
{
    DWORD dwbiSize;             // コーデック情報のバイト数
    DWORD dwFcc;                // コーデックのFourCC
    DWORD dwReserve[2];         // 未使用
};
 
// コーデック処理で使う変数
HIC            ghIC      = NULL;      // コーデックのハンドル
LPVOID glpCompressBuff   = NULL;      // 圧縮された画像を格納するバッファへのポインタ
BITMAPINFO     *glpbiIn  = NULL;      // 圧縮された画像フォーマット(実態はコーデックにより異なる)
BITMAPINFO     *glpbiOut = NULL;      // 復元された画像フォーマット(ビットマップインフォで確定)
 
// コーデック処理の初期化
BOOL CodecInit(SOCKET sock)
{
    DWORD size;
 
    // コーデック情報のヘッダーを取得(コーデック情報のバイト数とFourCC)
    NETWORK_CODEC_HEADER network_codec_header;
    size = recv_all(sock, (char*)&network_codec_header, sizeof(network_codec_header), 0 );
    if (size == SOCKET_ERROR) return FALSE;
       
    // コーデック情報(可変長)を格納する為のバッファを確保
    glpbiIn = (BITMAPINFO*)malloc( network_codec_header.dwbiSize );
    if (glpbiIn == NULL) return FALSE;
 
    // コーデック情報を取得(最終的な画像サイズや、どの様に圧縮したか等が記録されています)
    size = recv_all(sock, (char*)glpbiIn, network_codec_header.dwbiSize, 0 );
    if (size == SOCKET_ERROR) return FALSE;
 
    // 復元に使うフォーマットを作成
    glpbiOut = (BITMAPINFO*)malloc( sizeof(BITMAPINFO) );
    if (glpbiOut == NULL) return FALSE;
    ZeroMemory(glpbiOut, sizeof(BITMAPINFO) );
    glpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    glpbiOut->bmiHeader.biBitCount    = 32;
    glpbiOut->bmiHeader.biPlanes      = 1;
    glpbiOut->bmiHeader.biWidth       = glpbiIn->bmiHeader.biWidth;
    glpbiOut->bmiHeader.biHeight      = glpbiIn->bmiHeader.biHeight;
    glpbiOut->bmiHeader.biSizeImage   = glpbiIn->bmiHeader.biWidth* glpbiIn->bmiHeader.biHeight*4;
    glpbiOut->bmiHeader.biCompression = BI_RGB;
 
    // コーデックのデコンプレッサーのハンドルを取得
    ghIC = ICOpen(
                ICTYPE_VIDEO,
                network_codec_header.dwFcc, // glpbiIn->biCompressionを使ってはダメ。
                                            // 必ず、圧縮の時に使ったFourCCを使いましょう。
                ICMODE_DECOMPRESS           // ICMODE_DECOMPRESSとなります。圧縮時とは異なるので注意。
                );
    if (ghIC == NULL) return FALSE;
 
    // デコンプレッサーの初期化
    if (ICERR_OK != ICDecompressBegin(
                ghIC,
                glpbiIn,               // 圧縮された画像データのフォーマット(サーバー側のICCompressGetFormatで取得したlpbiOutをそのまま使う)
                glpbiOut               // 復元する画像データのフォーマット(クライアント側で用意する)
                )) return FALSE;
 
    // 圧縮された画像データを格納するバッファを確保する。
    // 確保するバイト数はサーバー側の初期化処理でICCompressGetSize等を使って取得する
    // 未圧縮よりもサイズが大きくなるコーデックも有りです。必ずコーデックから
    // 最大データサイズを取得しましょう。
    glpCompressBuff = malloc(glpbiIn->bmiHeader.biSizeImage );
    if (glpCompressBuff == NULL) return FALSE;
 
    return TRUE;
}

サーバー側のコンプレッサーの準備に比べると、クライアント側のデコンプレッサーの準備はその殆どをサーバ側から受信して済ませるので楽ですね。

レアなケースですが画像サイズが変更される可能性があることだけ注意しておけば大丈夫だと思います。次回は実際にデコンプレッサーを使って圧縮された画像の復元処理を紹介します。
関連記事


コメントの投稿

 
 
あまラボへようこそ
このブログでは自作ソフトの最新情報やtips、PC動画に関する話題を掲載していきます。各記事へは下にあるカテゴリからアクセスして下さい。

ファイルのダウンロードはホームページの方でお願い致します。

質問・要望・不具合報告はこちら
アマレコTV
アマミキ!
アマレココ
アマレコ・ライト
ファンタジーリモート
AMVコーデック



ホームページ
カテゴリ
最新コメント
カレンダー
07 | 2017/08 | 09
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
最新記事
最新トラックバック
ブログ内タグ

アマレコTV ビデオキャプチャ AMVコーデック アマレココ アマミキ! コーデック SC500 動画配信 ファンタジーリモート アマレコライト プラグイン AMV4 SC512 ライブ機能 デスクトップキャプチャ AVX2 FAQ リモートソフト 質問コーナー ニコニコ動画 DirectShow HDキャプチャ 組み換え 4K レゴ 遅延 可変再生速度 解説動画 LEGO XL2420T ベンチマーク Intensity AMV2MT 120Hz 倍速液晶 GV-USB2 アマステ 液晶モニター PS4 Pro デインターレース 32ZP2 Shadow VideoKeeper2 31024 RDT233WX-Z ffmpeg GV-USB AVX Play Alternate designs 31006 RGBキャプチャ RYZEN SD-USB2CAP4 XCAPTURE-1 DirectShowFilter キャプチャーツール Livetube シンクライアント イベント AtomでHDキャプチャ プレビュー 擬似NTSCキャプチャ IntensityPro SD-USB2CUP4 額縁遅延 MPC ハイパースレッディングテクノロジー HT インストール OBS QSV NVEnc 31021 フィギュア Kabelake SSE MonsterX3A XCapture-1 オーバーレイ 音ズレ 録画 HDMI HDCP 32ZP32 SKnet REGZA 液晶テレビ 倍速駆動 リプレイ機能 モノステ ZP3 倍速補完処理 MP3 Haswell 電源オプション LameACM 音遅延 ゲームスムーズモード MonsterXU3.0R DC-HD1 

ブログ内検索
月別アーカイブ
アマレココに関するリンク
お世話になっているソフトのリンク
RSSリンクの表示
管理画面
  • 管理画面