&size(24){&color(darkgreen){''Streaming''};}; #navi(Vweb) ~''CONTENTS'' #contents ---- ~''REFERENCES'' -[[ストリーミングメディアガイド>http://homepage2.nifty.com/netwarp/]] -ETR 290 Digital Video Broadcasting (DVB);Measurement guidelines for DVB systems -[[DVB Stream Analyzer, MPEG Analyzer>http://dvbsnoop.sourceforge.net/]] -[[Transport Stream Analyzer for HDTV standard>http://www.codeproject.com/csharp/Transport_Stream_Analyzer.asp]] -[[MPEG dump>http://www.ifp.uiuc.edu/~rwang/mpeg_dump.html]] -[[MPEG-2 Digital Video>http://erg.abdn.ac.uk/research/future-net/digital-video/]] ---- **HEC [#r06c37e6] ***Problem [#w59d3f41] HEC wrote: > -評価結果ですが、御社のパケット伝送方式では固定長で機械的に送信されているため、受信側で MPEGヘッダを探索する必要があり、非常にサーバとして負荷の高い処理を要求することになります。 -このため、再配信処理に非常に不向きな形態なので、このままでは製品として採用するのは困難な状況です。 -そこで相談ですが、可能であれば、MPEGのパケット伝送形態をヘッダー情報が先頭にくるように調整できないかどうか検討お願い致します。 ***MPEG-2 TS [#v0031bf5] :TS|Transport Stream :DSM-CC|Digital Storage Media Command and Control -UDP Packet (variable) --Header --Payload > -TS Packet (fixed 188byte) --Header (fixed 4byte) --Addaptation field --Payload -TS packetのSynchronization Byte: 0x47 -ヘッダー情報が先頭にくるというのはUDP packet payloadの先頭にTS Packetの先頭がくるように調整するということかな。 疑惑のUDP送信シーン udp_send_data( (char*)p_buf, read_size, p_network_info ); read_sizeはどうやって決められているかというと chip_interface->readData( (RWDeviceOption)p_param->dev_opt, (PVOID)p_buf, p_param->TransferSize, read_size, p_param->lpOverlapIo ); readData @param dev_opt = device option, can be one of the following: RW_DEV_OPTION_TRANSPORT_STREAM_MUX, RW_DEV_OPTION_PROGRAM_STREAM_MUX, RW_DEV_OPTION_TRANSPORT_STREAM_DEMUX, RW_DEV_OPTION_PROGRAM_STREAM_DEMUX @param p_buf = pointer to the buffer where read data will be written to @param size_to_read = size of data to read from device @param size_actually_read = size of data actually read from device @param overlapped = overlapped signal area (only used on windows) @return SUCCESS or FAILURE */ virtual int readData( RWDeviceOption dev_opt, PVOID p_buf, UINT32 size_to_read, UINT32 &size_actually_read, LPOVERLAPPED overlapped ) = 0; ところでp_bufの大きさは PVOID p_buf = malloc(p_param->TransferSize); TransferSizeは capture_param.TransferSize = xferSize; xferSizeは xferSize = computeTransferSize( cfg_parser.getBitRate(), cfg_parser.getStreamType(), cfg_parser.getSignalType(), cfg_parser.getMPEGType(), cfg_parser.getControlMode(), (cfg_parser.getFirmwareType() == G7XX_CODEC) ); -xfersize.h computeTransferSizeでTSのときはtransferサイズは512byte単位で bitrateとfamerateから計算される。 -もしreadSize = transferSizeならTS packet単位で取り出せていない。 --readSize % 188 != 0ならともいえる。 // cap this at 66176 bytes (multiple of 2*188) xfer_size = MIN(xfer_size, 66176); -最大サイズでかすぎないか?64KBぐらいあるんですけど。 -ひょっとしてHECは1 TS packet / udp packetにしたいのだろうか? -net_sendの場合MAX_UDP_SEND_SIZEは1128byte。 --これを超えると分割送信される‥ダメじゃん。 -ストリームアナライザでTS packetの様子をみたいところ。 ***net_send改造計画 [#b535a3c1] -じゃまなメッセージを消してしまおう。printf("+");とかをコメントアウト -read_sizeをモニターしてみると,ぜんぜん188の倍数になってません。 -A size to read is always equal to the size actually read. -16384とか平気でいってるので,udp_sendの時点で分割されています。 --UDPデータ長は16bitあるので最高で65535byteまでいけるわけですが --大抵MTUが1500以下なので1128なのかしら? --TCP dumpしてみると1128byteが14回の後592byteが1回のUDPパケットが送られている。 ---TCP dumpして表示されるlengthはpayload長だよね? --16384 = 1128 * 14 + 592 だ。なるほど。しっかり分割されてるし。 ---xfersize.hにて xfersize = MIN(xfersize, 1128); にしてしまう。ファイルに書き込むときは効率が悪くなるけどシラネ。 ---ありゃま。たしかにUDPレベルでの分割は起きなくなったけど,高レートのときに絵が壊れる。 ---つまり,VW2010からのreadDataはある程度大きくしないとだめらしい。 -姑息な対処 xfersize.h xfer_size /= 188 * 2; xfer_size *= 188 * 2; **stoneでudpを中継 [#k8688371] -(金子)UDPのテストプログラム作ってみたよ。 --wiki.wivicom.co.jp/~kaneko/usr/udptest --udpsvはUDPのサーバ ---./udpsv PORT と起動する。 ---":quit"という文字列を受信すると終了。 --udpclはUDPのクライアント ---./udpcl HOST PORT と起動する ---CTRL-Dで終了する。 --udpclで文字列を1行入力すると、udpsvで表示される。 --使ってみてね。 ---stoneで中継されていることを確認 ---ただしudpの中継とhttpプロキシ越えは同時には不可 ---でもなぜかVLCのUDPは中継してくれない。 ---単に処理が追いついてないだけだった。 ---child process 200個ぐらい立ち上げればOK(ぉ ** VW2010 Streaming実験 [#pb3f0c50] - IEEE802.11a MPEG2-TS 352x480 |128kbps|音声がたまに途切れる。ビデオはブロック単位の解像度。| |256kbps|音声は正常。ちょっとした動きでもフレームドロップ。| |512kbps|激しい動きがある場合にフレームドロップ。| |1Mbps|動きのある部分でややブロックひずみが認識できる。シーンチェンジ時にまれにフレームドロップ&ブロックひずみが画面全体に認識される| |2Mbps|平坦な部分の量子化ノイズが認識できる。激しい動きやシーンチェンジ時にブロック効果| |3Mbps|良好。ソース依存| |5Mbps|劣化が確認できない| |10Mbps|同上。正常再生できる上限ビットレート| |11Mbps|シーンチェンジじに画像が一瞬停止| |12Mbps|シーンチェンジ時に画像が停止&音声が一瞬途切れる| |15Mbps|音声がとぎれとぎれ。映像が一瞬停止する場合あり。| |20Mbps|音声が再生されず。紙芝居| |21Mbps|再生停止。| - IEEE802.11a MPEG2-TS 704x480 |128kbps|音声がたまに途切れる。ビデオはブロック単位の解像度。数秒ごとの静止画。| |256kbps|音声は正常。数秒ごとの静止画。| |512kbps|数秒動いては静止,の繰り返し。| |1Mbps|シーンチェンジ時に静止。| |2Mbps|激しい動きやシーンチェンジ時にブロックノイズ。| |3Mbps|良好。| |5Mbps|高画質。| |10Mbps|高画質。| |11Mbps|高画質。| |12Mbps|高画質。| |15Mbps|映像が一瞬停止する場合あり。| |20Mbps|音声が再生されず。紙芝居| |21Mbps|再生停止。| - IEEE802.11a MPEG4-TS 352x480 |128kbps|映像と音声が数秒ごとに停止。ブロックがみえる。| |256kbps|音声は正常。シーンチェンジ時にビデオが静止。ブロックが見える。| |512kbps|シーンチェンジ時に一瞬静止。ブロックが見える。| |1Mbps|シーンチェンジ時にブロックが見える。ぼんやりしているがそれ以外はきれい。| |2Mbps|十分な画質| |3Mbps|高画質。| |5Mbps|高画質。| |10Mbps|高画質。| |12Mbps|映像と音声が一瞬停止する場合あり。| |15Mbps|音声がとぎれとぎれ。| |20Mbps|音声が再生されず。紙芝居。| |21Mbps|再生停止。| - IEEE802.11a MPEG4-TS 704x480 |128kbps|音声がたまに途切れる。映像が数秒ごとに停止。ブロックがみえる。| |256kbps|音声は正常。映像が数秒ごとに停止。ブロックがみえる。| |512kbps|シーンチェンジ時にブロックが見え,静止。| |1Mbps|激しい動き,でブロック。シーンチェンジ時にブロックが見え,一瞬静止| |2Mbps|シーンチェンジ時にブロック| |3Mbps|十分な画質。| |5Mbps|高画質。| |10Mbps|高画質。| |12Mbps|映像と音声が一瞬停止する場合あり。| |15Mbps|映像と音声が一瞬停止数秒ごとに静止。| |20Mbps|音声が再生されず。紙芝居。| |21Mbps|再生停止。| ** リファレンスマニュアルからの覚書 [#hab046be] - 2つの128バイトの共有メモリがある。 -- 0x3F1800からの128バイト host -> VW2010 -- 0x3F1880からの128バイト VW2010 -> host -- セマフォ使ってください。 - Linuxドライバのコマンドは3つだけ -- open() -- close() -- ioctl() ** net_send/net_recv [#m8c9fd97] Vweb SDK付属のnet_send/net_recvを修正し,以下のようなことができるようになりました。 + NTSC信号を入力 + MPEG-2TSにハードウェアエンコード + UDP通信 + ハードウェアデコード + NTSC/VGA信号を出力 ** Hardware [#y6176a10] +----------------+ +--------------+ +-----+ + Vweb on x86 PC |---<UDP>---| Vweb on WPAR |---<VGA>---| CRT | +----------------+ +--------------+ +-----+ | | <NTSC> <NTSC> | | +-----+ +--+--+ | VCR | | TV + +-----+ +-----+ ** Software [#c8e8743d] *** net_send on x86 [#t35573d6] net_send option_files/enc_mp2ts_ntsc_01m.ini do_network=true hostname=192.168.100.10 \\ video_input_device=0xc40242 *** net_recv on WPAR [#p9f025b8] reset the chipの後に以下の3行を挿入。vw2002モードで動くようにする。 UINT32 size = 0; printf("=> Enable VW2002 MODE\n"); chip_interface->sendCommand(VW_IOCTL_DECODER_ONLY, NULL, size, NULL); net_recv option_files/dec_mp2ts_ntsc.ini do_network=true hostname=192.168.100.7 *** encoder/decoder [#sc2e997a] encoder.exe option_files\enc_mp2ts_ntsc_03m.ini foo.mpg video_input_device=0xc40242 decoder.exe option_files\dec_mp2ts_ntsc.ini foo.mpg -vw2002 *** net_send/net_recv on x86 [#u8de5860] VW2010ひとつだけでnet_send/net_recvを動かす方法。 net_send option_files/enc_mp2ts_ntsc_01m.ini do_network=true hostname=127.0.0.1 \\ video_input_device=0xc40242 net_recv option_files/dec_mp2ts_ntsc.ini -save hoge.mpg do_network=true hostname=127.0.0.1 net_recvで-saveオプションを用いると,ハードウェアデコードが無効化され, 単に受け取ったストリームをファイルに書き込むようになる。 書き込まれたファイルは(実行属性を与えて)decoderで再生することができる。 *** option_files [#zca3790d] - option_filesの内容は引数key=valueで上書きできる。 - ファームウェアのパスをフルパスで指定すると,ファイルシステムの任意の場所から ファームをロードできる。 - video_input_device=0xc40242をoption_filesに記入することができる。 - option_filesで設定可能な変数はvwSDK_ConfigUtils.cppを見てしらべる。 ドキュメントに書かれていない変数がいっぱい。 *** VWeb謎のコツ [#ac85930f] - 再生するファイルに666以上のパーミッションが必要。 -- どうしてかわからないけど、decoderのプログラムはfileをopenするときに、RW modeでopenするんだよね。だから、write権限がないとfile open時にerrorになります。いいじゃんread modeで...