連載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コーデック



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

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