home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2001 July
/
VPR0107B.BIN
/
DRIVER
/
CANOPUS
/
MVR32
/
mvr32.exe
/
data1.cab
/
MpegTransfer_J
/
Vc
/
Samples
/
Com
/
MpegTransfer.txt
Wrap
Text File
|
2001-02-09
|
17KB
|
375 lines
2000/2/24
Ver 1.00
MpegTransfer(MPEG2プログラム・ストリーム転送ライブラリ)について
カノープス株式会社
1 概要
(1) MpegTransferは、MPEG2プログラム・ストリームのネットワーク経由での転送機能を実現する、C++クラス・ライブラリである。
(2) MpegTransferは、C++ソース・ファイルで提供される。
(3) ネットワーク・プロトコルとしては、UDP/IPを用いる。
(4) ネットワーク・プロトコルへのアクセスは、Windows Socket 2経由で実行される。
(5) MVR-D2000の制御は、MVR-D2000 SDK(以下、SDKと略記)が提供するAPIを用いて実行される。
(5) プログラムは、Microsoft VC++ 6.0(with service pack 3)を用いて開発されている。
2 ファイル一覧
.\MpegTransfer.txt
このファイル自身
.\MpegTransfer\
MpegTransfer C++クラスのソース・ファイル群
.\Encode_cEx\
MpegTransferを用いた送信サンプル・プログラムEncode_cEx.exeのソース・ファイル群
.\Decode_cEx\
MpegTransferを用いた受信サンプル・プログラムDecode_cEx.exeのソース・ファイル群
.\bin\
Debug\
デバッグ版Encode_cEx.exe、Decode_cEx.exe
Release\
リリース版Encode_cEx.exe、Decode_cEx.exe
3 MpegTransfer C++クラス
3-1 クラス階層
CObject MFC 基底クラス
|
+--CMpegTransfer CMpegSender/CMpegTransferのための基底クラス
|
+--CMpegSender 送信クラス
|
+--CMpegReceiver 受信クラス
3-2 CMpegTransfer
CMpegSender/CMpegReceiverの基底クラス。アプリが直接CMpegTransferのインスタンスを生成することはない。
以下に、公開(public)メンバを列挙する。
static const DWORD m_cbBuffDefault;
32KB。SDKメモリ転送バッファ・サイズ(ENC_BSS_PARAMETER.cbBuff/DEC_BSR_PARAMETER.cbBuff)であり、
同時に、(ネットワーク経由での)1回の送信/受信サイズのディフォルト値。
static const DWORD m_cBuffDefault;
16。SDKメモリ転送バッファ数(ENC_BSS_PARAMETER.cBuff/DEC_BSR_PARAMETER.cBuff)のディフォルト値。
CMpegTransfer(UINT nId = 1);
入力
nId
SDKエンコーダ/デコーダ識別子
static BOOL StartUp();
Ws2_32.dllにWinSock2の使用を開始することを通知する。
アプリの起動直後に1回だけ呼び出さなければならない。
static BOOL CleanUp();
Ws2_32.dllにWinSock2の使用を終了することを通知する。
アプリの終了直前に1回だけ呼び出さなければならない。
static BOOL SetSockAddrIn(LPCTSTR pszAddress, WORD nPort, LPSOCKADDR_IN pAddr);
インターネット・アドレス文字列とポート#からソケット・アドレス(SOCKADDR_IN)を生成する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
pszAddress
インターネット・アドレス文字列
nPort
ポート#
出力
pAddr
static int SendOverlapped(SOCKET hSocket, int fSocketType, LPVOID pBuff, DWORD cbBuff, LPDWORD pcbSent,
LPSOCKADDR_IN pAddr = NULL);
1回分の送信をWin32 overlapped IOで実行する。
返値
成功すると、0を返す。失敗すると、0以外の値を返す。
入力
hSocket
Win32 ソケット・ハンドル
fSocketType
TCP(SOCK_STREAM)またはUDP(SOCK_DGRAM)を指定する。
pBuff
送信バッファ
cbBuff
送信サイズ
pAddr
UDPの場合の、相手先のソケット・アドレスを指定する。TCPの場合は不要。
出力
pcbSent
実際に送信したバイト数
static int ReceiveOverlapped(SOCKET hSocket, int fSocketType, LPVOID pBuff, DWORD cbBuff, LPDWORD pcbReceived,
LPSOCKADDR_IN pAddr = NULL);
1回分の受信をWin32 overlapped IOで実行する。
返値
成功すると、0を返す。失敗すると、0以外の値を返す。
入力
hSocket
Win32 ソケット・ハンドル
fSocketType
TCP(SOCK_STREAM)またはUDP(SOCK_DGRAM)を指定する。
pBuff
受信バッファ
cbBuff
受信サイズ
pAddr
UDPの場合の、相手先のソケット・アドレスを指定する。TCPの場合は不要。
出力
pcbReceived
実際に受信したバイト数
operator SOCKET();
返値
Win32 ソケット・ハンドルを返す。
LPSOCKADDR_IN Addr();
返値
ローカル・マシンのソケット・アドレスを返す。
LPSOCKADDR_IN AddrOpposite();
返値
相手先のマシンののソケット・アドレスを返す。
virtual BOOL Connect(LPCTSTR pszAddress, WORD nPort, LPCTSTR pszAddressOpposite);
ソケットを生成する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
pszAddress
ローカル・マシンのインターネット・アドレス文字列
nPort
ポート#
pszAddressOpposite
相手先のマシンのインターネット・アドレス文字列
virtual BOOL Disconnect();
ソケットをクローズする。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
3-3 CMpegSender
エンコード及びエンコード結果の送信を実行するクラス。
使用例としては、Encode_cExのソース・ファイル参照。
以下に、公開(public)メンバを列挙する。
CMpegSender(UINT nEncId);
入力
nEncId
SDKエンコーダ識別子
static BOOL Init(UINT nEncId, CMpegSender* pSender = NULL,
ENC_CB_STATUS pfnStatus = NULL, ENC_CB_ERROR pfnError = NULL, ENC_CB_VOBU_ENT pfnVobuEnt = NULL);
エンコーダを初期化する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
nEncId
SDKエンコーダ識別子
pSender
CMpegSenderのインスタンス。CMpegSenderのインスタンスがまだ生成されていない場合は、NULLを指定する。
pfnStatus
pfnError
pfnVobuEnt
SDK ENC_Set_Callback APIに渡す引数と同一。詳細は、SDKマニュアル参照。
備考
通常は、CMpegSenderのインスタンスがまだ生成されていない段階でエンコーダを初期化したい場合に使用する。
CMpegSenderのインスタンスにエンコーダを初期化したい場合は、下記の(staticでない)Initメンバを使用する。
static BOOL Exit(UINT nEncId);
エンコーダの使用を終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
nEncId
SDKエンコーダ識別子
備考
通常は、CMpegSenderのインスタンスの削除後にエンコーダの使用を終了したい場合に使用する。
CMpegSenderのインスタンスがまだ存在する間にエンコーダの使用を終了したい場合は、
下記の(staticでない)Exitメンバを使用する。
BOOL Init(ENC_CB_STATUS pfnStatus = NULL, ENC_CB_ERROR pfnError = NULL, ENC_CB_VOBU_ENT pfnVobuEnt = NULL);
エンコーダを初期化する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
pfnStatus
pfnError
pfnVobuEnt
SDK ENC_Set_Callback APIに渡す引数と同一。詳細は、SDKマニュアル参照。
備考
通常は、CMpegSenderのインスタンスにエンコーダを初期化したい場合に使用する。
CMpegSenderのインスタンスがまだ生成されていない段階でエンコーダを初期化したい場合は、
上記の(static)Initメンバを使用する。
BOOL Exit();
エンコーダの使用を終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
備考
通常は、CMpegSenderのインスタンスがまだ存在する間にエンコーダの使用を終了したい場合に使用する。
CMpegSenderのインスタンスの削除後にエンコーダの使用を終了したい場合は、上記の(static)Exitメンバを使用する。
BOOL SendStart(DWORD cbBssBuff = m_cbBuffDefault, DWORD cBssBuff = m_cBuffDefault);
エンコード及びエンコード結果の送信を開始する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
cbBssBuff
SDKメモリ転送バッファ・サイズ(ENC_BSS_PARAMETER.cbBuff)であり、
同時に、(ネットワーク経由での)1回の送信サイズ。ディフォルトは、32KB。
cBuff
SDKメモリ転送バッファ数(ENC_BSS_PARAMETER.cBuff)。ディフォルトは、16。
BOOL SendStop();
エンコード及びエンコード結果の送信を終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
3-4 CMpegReceiver
MPEG2プログラム・ストリームの受信、及び、受信結果のデコードを実行するクラス。
デコーダとしてMPL-D2000(改)が使用されている場合は、CMpegReceiver内部の受信バッファ及びSDK内部のデコーダ・バッファの
空き具合に応じてデコーダ・マスター・クロックを切り替える。
使用例としては、Decode_cExのソース・ファイル参照。
以下に、公開(public)メンバを列挙する。
CMpegReceiver(UINT nDecId);
入力
nDecId
SDKデコーダ識別子
static BOOL Init(UINT nDecId, CMpegReceiver* pReceiver = NULL, DEC_CB_STATUS pfnStatus = NULL, DEC_CB_ERROR pfnError = NULL);
デコーダを初期化する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
nDecId
SDKデコーダ識別子
pSender
CMpegReceiverのインスタンス。CMpegSenderのインスタンスがまだ生成されていない場合は、NULLを指定する。
pfnStatus
pfnError
SDK DEC_Set_Callback APIに渡す引数と同一。詳細は、SDKマニュアル参照。
備考
通常は、CMpegReceiverのインスタンスがまだ生成されていない段階でデコーダを初期化したい場合に使用する。
CMpegReceiverのインスタンスにデコーダを初期化したい場合は、下記の(staticでない)Initメンバを使用する。
static BOOL Exit(UINT nDecId);
デコーダの使用を終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
nDecId
SDKデコーダ識別子
備考
通常は、CMpegReceiveのインスタンスの削除後にデコーダの使用を終了したい場合に使用する。
CMpegReceiveのインスタンスがまだ存在する間にデコーダの使用を終了したい場合は、
下記の(staticでない)Exitメンバを使用する。
BOOL Init(DEC_CB_STATUS pfnStatus = NULL, DEC_CB_ERROR pfnError = NULL);
デコーダを初期化する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
pfnStatus
pfnError
SDK DEC_Set_Callback APIに渡す引数と同一。詳細は、SDKマニュアル参照。
備考
通常は、CMpegReceiveのインスタンスにデコーダを初期化したい場合に使用する。
CMpegReceiverのインスタンスがまだ生成されていない段階でデコーダを初期化したい場合は、
上記の(static)Initメンバを使用する。
BOOL Exit();
デコーダの使用を終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
備考
通常は、CMpegReceiverのインスタンスがまだ存在する間にデコーダの使用を終了したい場合に使用する。
CMpegReceiverのインスタンスの削除後にデコーダの使用を終了したい場合は、上記の(static)Exitメンバを使用する。
BOOL ReceiveStart(DWORD cbBssBuff = m_cbBuffDefault, DWORD cBssBuff = m_cBuffDefault);
MPEG2プログラム・ストリームの受信、及び、受信結果のデコードを開始する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
入力
cbBssBuff
SDKメモリ転送バッファ・サイズ(ENC_BSR_PARAMETER.cbBuff)であり、
同時に、(ネットワーク経由での)1回の受信サイズ。ディフォルトは、32KB。
cBuff
SDKメモリ転送バッファ数(ENC_BSR_PARAMETER.cBuff)。ディフォルトは、16。
BOOL ReceiveStop();
MPEG2プログラム・ストリームの受信、及び、受信結果のデコードを終了する。
返値
成功すると、0以外の値を返す。失敗すると、0を返す。
4 サンプル・プログラム(Encode_cEx.exe/Decode_cEx.exe)の使用方法
4-1 一回の実行毎に、下記を繰り返す。
(1) 接続オプションの設定
ローカル・アドレス、ポート#、相手先のアドレスを入力する。
(2) 接続
接続は、Encode_cEx.exe、Decode_cEx.exeのどちらで先に実行してもかまわないl。
(3) 送信/受信オプションの設定
バッファ・サイズは、Encode_cEx.exeとDecode_cEx.exeで同じ値を設定しなければならない。
(4) 送信/受信開始
Decode_cEx.exeで受信を開始した後、Encode_cEx.exeで送信を開始する。
Decode_cEx.exeは、受信を開始すると、受信待ちで待機する。
Encode_cEx.exe~Decode_cEx.exe間でのハンド・シェーク(例えば、Deocode_cEx.exeから送信開始要求を送る等)は実装していない。
(5) 送信/受信終了
先にEncode_cEx.exeで送信終了を実行すると、Decode_cEx.exeの受信も自動的に終了する。
先にDecode_cEx.exeで受信を終了した場合は、Encode_cEx.exeは自動的には送信終了しないので、コマンド・メニューから
明示的に送信終了を実行しなければならない。
通常は、先にEncode_cEx.exeで送信終了を実行する。
Encode_cEx.exe~Decode_cEx.exe間でのハンド・シェーク(例えば、Deocode_cEx.exeから送信終了要求を送る等)は実装していない。
(6) 切断
切断は、Encode_cEx.exe、Decode_cEx.exeのどちらで先に実行してもかまわない。
4-2 Encode_cEx.exe/Decode_cEx.exeは、プロセス(Encode_cEx.exe/Decode_cEx.exeの実行中のインスタンス)1個当たり、
1枚のMVR-D2000カードを使用する。
複数枚のMVR-D2000カードを装着したPC上で、同時に複数のEncode_cEx.exeを動作させたい場合は、
2個め以降のEncode_cEx.exeに対し、下記の様に、起動オプションとしてエンコーダID(SDKのエンコーダID)を指定する。
Encode_cEx.exe /id:n (n = 2, 3, ...)
例えば、2個めのEncode_cEx.exeに対しては、下記の様に指定する。
Encode_cEx.exe /id:2
/idオプションが省略された場合、Encode_cEx.exeはエンコーダID = 1で実行される。
同様に、同時に複数のDecode_cEx.exeを動作させたい場合は、
2個め以降のDecode_cEx.exeに対し、下記の様に、起動オプションとしてデコーダID(SDKのデコーダID)を指定する。
Decode_cEx.exe /id:n (n = 2, 3, ...)
/idオプションが省略された場合、Decode_cEx.exeはデコーダID = 1で実行される。
5 実績
(1) 10Mbpsのイーサネット回線で接続したPC間で、Encode_cEx.exe及びDecode_cEx.exeを用いて、
ビデオ=6Mbpsまで、オーディオ=224kbpsのMPEG2プログラム・ストリームの転送動作を確認している。
但し、Windows 98ではWindows NTに比べて受信が遅いので、薦められない。
(2) エンコード~デコード間の遅延時間
以下では、ビデオ=6Mbpsの場合を例として、ビデオのビット・レートから遅延時間を概算する。
実際のビット・レートでは、オーディオのビット・レート、及び、プログラム・ストリームとしての付加情報
(パック・ヘッダ、PESヘッダ等)によるビット・レートの増加分が含まれるが、これらの値はビデオのビット・レート
と比較すると小さいので、概算では無視しても問題ない。
(a) MVR-D2000のエンコーダが実行を開始してからデータを出力し始めるまでの遅延時間は、ビット・レートに無関係に
一定であり、通常、約0.06~0.1秒である。
(b) MVR-D2000のドライバ(MvrAvc.dll)は、内部のデコーダ・バッファが一杯になるまではデコードを開始しない。
このことによる遅延時間は、
32KB × 16 ÷ (6Mbps ÷ 8) = 0.70秒
となる。
(c) MPEGデータには、デコード開始時の初期遅延が設定されている。MP@MLの場合の初期遅延は、
1835008bits ÷ 6Mbps = 0.31秒
以上から、遅延時間の合計は、1.11秒(0.1 + 0.70 + 0.31)となる。
(a)~(c)のうち、(b)は、バッファ・サイズの変更で小さくすることができる。バッファ・サイズを16KBにすると、
(b)は0.35秒になり、遅延時間の合計は、0.76秒に短縮される。
Encode_cEx.exe/Decode_cEx.exeを動作させて元の映像と再生映像との時間差を計った結果は、上記の時間に一致している。
即ち、現在の実装では無駄なオーバーヘッドはないと言える。
以上から、遅延時間を短くするにはバッファ・サイズを小さくすれば良いことになるが、逆に、小さくし過ぎると
転送が間に合わなくなる。
下表に、ビデオのビット・レートとバッファ・サイズの下限値(目安)を示す。
ビデオ(Mbps) バッファ・サイズ(KB) 遅延時間(秒)
----------------------------------------------------
6 16 × 16 0.76
4 16 × 16 1.08
2 8 × 16 1.53
6 備考
(1) Window Socket 2の実装では、APIが失敗しても、WSAGetLastError APIがエラー・コードを返さない(代わりに、0を返す)
場合がよくある。
(2) 当初のMpegTransferではネットワーク・プロトコルとしてTCP/IPを用いた転送も実装していたが、実験の結果、TCP/IPでの
安定した転送はビデオ=2Mbpsまでであったため、TCP/IPを用いた実は装削除した。