« 2014年6月 | トップページ | 2014年8月 »

2014年7月

2014年7月29日 (火)

AnyDeskも使ってみますかねぇ

ベータ版でのサポートプラットフォームはWindows XP/7/8.xのようです。

フレームレート60fpsは魅力ですねぇ。

AnyDesk

他のプラットフォームは、

Apple iPad (from iPad Air and iPad Mini Retina)

Apple MacOS X (from 10.9 Mavericks)

Linux (Debian-based distros)

Android-Tablets (from KitKat)

http://anydesk.com/platforms

らしいです。個人利用ならフリーとかなんとか書いてあるかも…(個人の見解です) 凝ったサービスは有料かな…

2014年7月12日 (土)

PCMデータが足りません

一時期サウンドの再生に関して問題はなかったのですが、久しぶりにサーバ側で音を出しながらwindows版で確認したらノイズだらけでした…

デバッグ情報をログに出力してみますと、

[debug] : : 2014.07.10 14:30:28.054 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.109 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.288 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.291 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.327 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.360 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.417 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.420 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.451 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.485 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.542 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.547 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.602 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.611 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.652 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.671 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.739 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.741 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.772 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.795 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.852 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.920 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:28.962 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:28.986 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:29.166 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:29.170 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:29.222 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:29.257 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:29.754 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:29.757 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:29.902 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:29.920 : [sound] StateChanged : ActiveState
[debug] : : 2014.07.10 14:30:29.972 : [sound] StateChanged : IdleState
[debug] : : 2014.07.10 14:30:29.984 : [sound] StateChanged : ActiveState

Qtの内部にあるサウンド用バッファが空になると再生できないので状態がIdleStateになります。つまりこのIdleStateになった瞬間から次の再生が始まるActiveSateに移行するまでは音の再生が止まって無音状態となります。これがノイズに聴こえるのですね…

テスト用のWindows 7 Home Edition (x64)のノートPCではサンプリングレート48KHz, 16bit, 2chステレオのPCMデータをクライアントに返しているので、単純に計算すれば、

48000 (Hz) * 2 (bytes - 16bit) * 2 (channel) = 192000 (bytes/s)

1秒間サウンドを再生するのに192000バイトのPCMデータが必要になります。デバッグログから、ネットワーク経由で受け取っているデータのサイズを確認します。これはネットワーク経由で届いたPCMデータをローカルなリングバッファに格納する時にそのサイズを出力したものです。結構小さな単位で送られてきてるようですね。

[debug] : : 2014.07.10 14:30:28.055 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.065 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.095 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.111 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.141 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.157 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.288 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.329 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.359 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.417 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.469 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.471 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.516 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.531 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.564 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.609 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.641 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.655 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.689 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.767 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.781 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:28.889 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:28.907 : [sound] writtenSize: 1920
[debug] : : 2014.07.10 14:30:28.967 : [sound] writtenSize: 7680
[debug] : : 2014.07.10 14:30:28.984 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:29.016 : [sound] writtenSize: 1920
[debug] : : 2014.07.10 14:30:29.030 : [sound] writtenSize: 7680
[debug] : : 2014.07.10 14:30:29.074 : [sound] writtenSize: 1920
[debug] : : 2014.07.10 14:30:29.093 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:29.110 : [sound] writtenSize: 5760
[debug] : : 2014.07.10 14:30:29.140 : [sound] writtenSize: 3840
[debug] : : 2014.07.10 14:30:29.187 : [sound] writtenSize: 5760

リングバッファに格納したPCMデータは、一定時間ごとに関数を呼び出すタイマー機能を利用して、定期的にサウンド出力用のバッファへ書き込めば、あとは裏方のサウンド再生処理が勝手に処理、再生してくれる手はずになっています。

1秒間に192000バイトのPCMデータが必要なのですが、現在は50msごとに前述の関数を呼び出しているので、

192000 * 0.05 = 9600 (bytes)

のPCMデータが最低限途切れなく再生するために必要になります。

デバッグログからタイマー一回ごとのPCMデータ書き込みサイズの情報を拾ってくると、

[debug] : : 2014.07.10 14:30:28.109 : [timerExpired()] : write (13440)
[debug] : : 2014.07.10 14:30:28.172 : [timerExpired()] : write (15360)
[debug] : : 2014.07.10 14:30:28.291 : [timerExpired()] : write (3840)
[debug] : : 2014.07.10 14:30:28.360 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:28.420 : [timerExpired()] : write (5760)
[debug] : : 2014.07.10 14:30:28.485 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:28.547 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:28.611 : [timerExpired()] : write (7680)
[debug] : : 2014.07.10 14:30:28.670 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:28.741 : [timerExpired()] : write (5760)
[debug] : : 2014.07.10 14:30:28.795 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:28.920 : [timerExpired()] : write (7680)
[debug] : : 2014.07.10 14:30:28.986 : [timerExpired()] : write (13440)
[debug] : : 2014.07.10 14:30:29.047 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.109 : [timerExpired()] : write (7680)
[debug] : : 2014.07.10 14:30:29.170 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.257 : [timerExpired()] : write (15360)
[debug] : : 2014.07.10 14:30:29.296 : [timerExpired()] : write (5760)
[debug] : : 2014.07.10 14:30:29.359 : [timerExpired()] : write (19200)
[debug] : : 2014.07.10 14:30:29.422 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.484 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.566 : [timerExpired()] : write (13440)
[debug] : : 2014.07.10 14:30:29.609 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.673 : [timerExpired()] : write (5760)
[debug] : : 2014.07.10 14:30:29.756 : [timerExpired()] : write (11520)
[debug] : : 2014.07.10 14:30:29.798 : [timerExpired()] : write (13440)
[debug] : : 2014.07.10 14:30:29.880 : [timerExpired()] : write (1920)
[debug] : : 2014.07.10 14:30:29.920 : [timerExpired()] : write (9600)
[debug] : : 2014.07.10 14:30:29.984 : [timerExpired()] : write (11520)
[debug] : : 2014.07.10 14:30:30.085 : [timerExpired()] : write (3840)
[debug] : : 2014.07.10 14:30:30.109 : [timerExpired()] : write (7680)
[debug] : : 2014.07.10 14:30:30.181 : [timerExpired()] : write (13440)
[debug] : : 2014.07.10 14:30:30.235 : [timerExpired()] : write (17280)
[debug] : : 2014.07.10 14:30:30.359 : [timerExpired()] : write (15360)
[debug] : : 2014.07.10 14:30:30.422 : [timerExpired()] : write (1920)

9600バイト以上毎回書き込めてればよさそうなんですが、1920バイトしか書き込めていない場合もあります…

Brynhildr 1.0.3をクライアントモードで起動してみるとサウンド再生に問題はないことから、サーバからのPCMデータ転送には問題なく、受け取る方の問題ということになりそうです…

2014年7月 9日 (水)

画像データもバッファリングする その3

JPEGファイルデータをバッファリングするクラスはPCMデータをバッファリングするのと少し構造が違うのでデバッグに少し手間取りましたが、なんとか正常にバッファリングできるようになりました。

Brynhildrサーバさんは音が出ていない時はPCMデータを送らない、具体的にはデータサイズが0として返事をするので、その場合は同期を取る必要はなさそうなので即座に画像再生を開始するようにしました。音が出ている場合は、サウンド出力を開始できるタイミングまでJPEGデータを貯めこんで、サウンド出力を開始するタイミングに合わせて、画像再生を開始します。

JPEGファイルデータをバッファリングするGraphicsBufferクラスにデバッグログを入れて確認しました。
#もちろんデスクトップ画像そのものも確認はしましたが。

"buffer data size :"と出ているのが、バッファにデータが追加された直後のトータルバッファ使用量です。
"release()"と出ているのが画像出力が終わったのでリリースしたデータバッファのサイズです。

最初はJPEGファイルデータを貯めこんで、しばらくしたら画像を再生して、その後不要になったデータをリリースしています。

現在のテスト環境だと大体2.2MBくらいでバッファリングしたデータサイズは安定しているようです。現在は念のため10MB確保しています。

$ ./release/qtbrynhildr.exe
buffer data size : 38910
buffer data size : 77820
buffer data size : 136323
buffer data size : 194826
buffer data size : 271743
buffer data size : 348660
buffer data size : 425577
buffer data size : 502494
buffer data size : 579411
buffer data size : 656328
buffer data size : 733245
buffer data size : 810162
buffer data size : 887079
buffer data size : 963996
buffer data size : 1040913
buffer data size : 1117830
buffer data size : 1194747
buffer data size : 1271664
buffer data size : 1348581
buffer data size : 1425498
buffer data size : 1502415
buffer data size : 1579369
buffer data size : 1656323
buffer data size : 1733277
buffer data size : 1810231
buffer data size : 1887185
buffer data size : 1964139
buffer data size : 2041093
buffer data size : 2118047
buffer data size : 2195001
release() : 38910
buffer data size : 2233045
release() : 38910
buffer data size : 2271089
release() : 58503
buffer data size : 2289540
release() : 58503
buffer data size : 2307991
release() : 76917
buffer data size : 2308028
release() : 76917
buffer data size : 2308065
release() : 76917
buffer data size : 2308102
release() : 76917
buffer data size : 2308139
release() : 76917
buffer data size : 2308176
release() : 76917
buffer data size : 2308213
release() : 76917
buffer data size : 2308250
release() : 76917
buffer data size : 2308287
release() : 76917
buffer data size : 2308320
release() : 76917
buffer data size : 2308353
release() : 76917
buffer data size : 2308386
release() : 76917
buffer data size : 2308419
release() : 76917
buffer data size : 2308452
release() : 76917
buffer data size : 2308485
release() : 76917
buffer data size : 2308518
release() : 76917
buffer data size : 2308551
release() : 76917
buffer data size : 2308584
release() : 76954
buffer data size : 2308580
release() : 76954
buffer data size : 2308582
release() : 76954
buffer data size : 2308584
release() : 76954
buffer data size : 2308586
release() : 76954
buffer data size : 2308588
release() : 76954
buffer data size : 2308590
release() : 76954
buffer data size : 2308592
release() : 76954
buffer data size : 2308594
release() : 76954
buffer data size : 2308596
release() : 76954
buffer data size : 2308598
release() : 76954
buffer data size : 2308600
release() : 76954
buffer data size : 2308602
release() : 76954
buffer data size : 2308604

windows版では、バッファリングする前の実装でもほぼサウンド再生の遅延は起こりませんが、より正確になると思われます。

2014年7月 8日 (火)

Android用にQt Brynhildr (仮称) をビルドする その2

crypto++をandroid向けにビルドしました。

まず、qmakeで作ったMakefileをEmacsで開いて以下のマクロの記述を手作業でcrypto++のGNUmakefileの先頭にコピーしまsした。

CXX
CXXFLAGS
INCPATH
AR
RANLIB

私の場合は、以下です。

CXX = /opt/android-ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++
CXXFLAGS = -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -std=gnu++0x -O2 -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -mthumb -Wall -Wno-psabi -W -D_REENTRANT -fPIE $(DEFINES)
INCPATH = -I/opt/Qt5.3.1_android/5.3/android_armv7/mkspecs/android-g++ -I. -I. -I../lib/cryptopp562 -I/opt/Qt5.3.1_android/5.3/android_armv7/include -I/opt/Qt5.3.1_android/5.3/android_armv7/include/QtMultimedia -I/opt/Qt5.3.1_android/5.3/android_armv7/include/QtWidgets -I/opt/Qt5.3.1_android/5.3/android_armv7/include/QtNetwork -I/opt/Qt5.3.1_android/5.3/android_armv7/include/QtGui -I/opt/Qt5.3.1_android/5.3/android_armv7/include/QtCore -I. -I. -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/include -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I/opt/android-ndk/platforms/android-9/arch-arm/usr/include
AR = /opt/android-ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar
RANLIB = /opt/android-ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib

で、元々の先頭行にあった

CXXFLAGS = -DNDEBUG -O3

の"="を"+="に変更、インクルードパスの設定を追加して

CXXFLAGS += -DNDEBUG -O3 $(INCPATH)

とします。これでCXXFLAGSに追加される形になります。

あと、CXXFLAGS +=-march=native となっているところはコメントアウトしました。native向けではなくarm向けにビルドするので。

ifneq ($(GCC42_OR_LATER),0)
ifeq ($(UNAME),Darwin)
CXXFLAGS += -arch x86_64 -arch i386
else
#CXXFLAGS += -march=native
endif
endif

で、大丈夫かなぁと思ってmakeすると以下の様なエラーが出ました。

In file included from network.cpp:5:0:
wait.h:184:2: error: 'fd_set' does not name a type
fd_set m_readfds, m_writefds;

manコマンドでfd_setを調べてみます。

man fd_set

まぁ、File Desctiptor関係ですね。androidだから、ファイルシステム周りは少し特殊そうですよね…

crypto++のライブラリには多くのクラスが入っているので、使っていなければビルド対象から外してもいいかなという判断でこのソースファイルを対象から外すことにしました。

GNUmakefileでnetwork.cppを探しますが、ありません。

SRCS = $(wildcard *.cpp)

と書いてあるので、カレントディレクトリにある".cpp"とついているファイルは全部対象になってるようです。
仕方ないので、network.cppをnetwork.cpp.backupとリネームして対象外としました。

あと、同様にwait.cppというファイルも同じエラーとなるのでwait.cpp.backupにリネームしました。

で、再度makeしてlibcryptopp.a が出来上がりました。

本体のディレクトリに戻り、makeを実行すると最後まで正常に終了しました。

しかし、qtbrynhildrというファイルはありません…makeコマンドのメッセージを確認すると

-o libqtbrynhildr.so

という部分があります。UNIX系での一般的なコマンドではなく libqtbrynhildr.so というダイナミックリンクライブラリのような名前でアプリケーションが出来上がるようです、初めて知りました(^-^;

さて、どうやって動作確認すればいいんでしょう…

Android用にQt Brynhildr (仮称) をビルドする その1

まずQt5.3.1 for androidをインストールしました。

Linux用のQt5.3.1を/opt/Qt5.3.1にインストール済みだったので、android用は/opt/Qt5.3.1_androidにインストールしました。android向けといっても、gcc_64のディレクトリがあるのでLinux用も含まれているようですが、今回はarm向けなので/opt/Qt5.3.1_android/5.3/android_armv7/binにPATHを通します。

で、qmakeを実行したのですが、いきなりエラーでした。

sh: 1: /opt/android/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc: not found
Project ERROR: You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.
Could not read qmake configuration file /opt/Qt5.3.1_android/5.3/android_armv7/mkspecs/android-g++/qmake.conf.
Error processing project file: brynhildr.pro

なにやら、android ndkに含まれるはずのgccが見つからないようです。ANDROID_NDK_ROOTという環境変数にAndroid NDKのインストールパスを設定しろとのことですね。

#/opt/androidに置けばそのまま行けそうですが…

.bashrcに

export ANDROID_NDK_ROOT=/opt/android-ndk

を追加しました。source ~/.bashrcで再読み込みします。

今度はqmakeはちゃんと実行できました。make clean を実行してLinux x64向けのファイルを削除してから make を実行します。

本体のソースコードのコンパイルはうまく行ってそうです…が、リンクでコケました。

crypto++ライブラリもandroid向けにビルドしなくてはなりませんでした…これができれば、android向けの実行ファイルができるのですが(;ω;) # その後androidのエミュレータ環境の整備も待ってますが(*^-^)

さっきqmakeで作ったMakefileを参考にcvrypto++の方のGNUmakefileを変更すれば良さそうです。

CCとかCXXとかをオーバライドすればよいですかねぇ。

2014年7月 7日 (月)

windows版インストーラをつくってみる

配布に必要なファイル(QtのDLLおよび実行ファイル)とそのディレクトリ構成がわかったので、暫定でWindowsインストーラを作ってみます。

しばらく前に検討した「EXEpress 6 Lite」を使います。フリーソフトの配布に使う分にはフリーで使えるのですが、少し機能が制限されます。

インストール時の構成は以下です。

$ find dist_win81 -print
dist_win81
dist_win81/bin
dist_win81/bin/icudt52.dll
dist_win81/bin/icuin52.dll
dist_win81/bin/icuuc52.dll
dist_win81/bin/imageformats
dist_win81/bin/imageformats/qjpeg.dll
dist_win81/bin/libgcc_s_dw2-1.dll
dist_win81/bin/libstdc++-6.dll
dist_win81/bin/libwinpthread-1.dll
dist_win81/bin/platforms
dist_win81/bin/platforms/qwindows.dll
dist_win81/bin/Qt5Core.dll
dist_win81/bin/Qt5Gui.dll
dist_win81/bin/Qt5Multimedia.dll
dist_win81/bin/Qt5Network.dll
dist_win81/bin/Qt5Widgets.dll
dist_win81/bin/qtbrynhildr.exe
dist_win81/doc
dist_win81/doc/window81update.txt
dist_win81/vcredist
dist_win81/vcredist/vcredist_sp1_x86.exe

まず、「EXEpress Lite 6」を入手して、インストールします。起動すると以下の様なウィンドウが表示されます。

20140707_085215

まず、インストーラを作る前に構成ファイルを固めた"cabファイル"というものを作る必要があります。「書庫作成」のボタンを押します。「EXEpress Compressor」というウィンドウが出てくるので、"dist_win81"を探して、左の「書庫ファイル」と表示された所にドラッグ&ドロップします。一応左側に現れた"dis_win81"をクリックして構成を確認します。確認できたら、「ファイル」メニューから「書庫ファイルを作成して終了」を選択して"cabファイル"を作成します。しばらくするとウィンドウは閉じられ、デスクトップに「EXEpress Project.cab」というファイルが現れました。

EXEpress 6 Liteのウィンドウは以下のようになります。

20140707_091332

「自己解凍化する車庫ファイル名」はそのままでいいので、「生成する自己解凍実行ファイル名」、「ウィンドウタイトル」、「メッセージ」を変更します。後者2つは日本語だけでなく、英語も変更します。

「日本語」

20140707_100704

「英語」

20140707_100716

次に「詳細設定」ボタンを押して、詳細な設定を変更します。以下は初期画面です。

20140707_100951

まず、「解凍」タブを選択して解凍先を指定しました。"Program Files"の下にQtBrynhildrというフォルダを作って、その下に展開するようにします。

20140707_101951

次にデスクトップのみにショートカットを作成するようにしたいので、「ショートカットの登録」タブを選択して、グループを空にした上で、「作成するショートカットの一覧」に1つ追加しました。スタートアップメニューにはなにも登録したくないので、グループ名を空にします。


20140707_102044


20140707_102122


ここまで設定したら、とりあえずのインストーラが作成できそうです。「詳細設定」ダイアログを閉じて、「作成」ボタンを押します。一瞬でデスクトップのインストーラの実行ファイルが現れました。

実行すると、なんとなくインストーラが立ち上がりました。

20140707_103256

ただし、アンインストーラの設定を端寄ったので、ショートカットとProgram Filesの下のファイルは手で消す必要がありますヽ(´▽`)/
# 「詳細設定」ダイアログの「アンインストーラ」タブで設定できますが、レジストリを汚すので後で検討することにしました。

2014年7月 5日 (土)

Qt 5.3.1がリリースされてました

Qt 5.3.1がリリースされてました。

変更点はwikiにあります。

http://qt-project.org/wiki/Change-files-in-Qt-5.3.1

なにが変わったんでしょうかね…

関係ありそうな所は以下なんですが…

[qtbase]

http://qt.gitorious.org/qt/qtbase/blobs/5.3.1/dist/changes-5.3.1

[qtmultimedia]

http://qt.gitorious.org/qt/qtmultimedia/blobs/5.3.1/dist/changes-5.3.1

細々としたバグフィックスという印象ですが、現在のソースコードで問題ないか見てみますかね。

2014年7月 4日 (金)

画像データもバッファリングする その2

なんとなく画像データ用のリングバッファクラスが出来ましたが…

テスト用のXPのデスクトップが1024x768の解像度で一枚のデスクトップ画像データが最高画質指定でおよそ100KB程度です。

一秒間に10FPS程度なので一秒間に1MB程度の画像データが届きます。画像データ用のバッファを4MB取ると約4秒間分バッファリングできますね。

Linuxでは数秒のサウンドの再生遅れが生じるので4秒程度はバッファリング出来たほうが良さそうです。最近のPCの性能だと1920x1080の解像度で20FPSとか出るかもしれません。解像度4倍xFPS2倍でおおよそ8倍のデータをバッファリングできないといけないかもしれません。4秒間保持するのに32MBくらい必要かもしれませんね。

#一応設定で変更できるようにしておきますが…

さて、永遠にバッファリングはできないので、適当なタイミングでデスクトップ画像を再生し、リングバッファを開放しなくてはなりません。

とりあえず、デスクトップ画像の最初の一枚目はサウンドデータが再生可能になったタイミングで良さそうですが、その後のデスクトップ画像再生タイミングはどのようにするのがいいでしょうか…パッと思いつのは、2枚目以降は次の画像データが届いたタイミングで古い順に順次再生するというのが一番簡単そうです。

Brynhildrサーバの方でも画像とサウンドデータの同期をとっているそうなので、上記の方法で実装して、Linuxで実験をしてみます。

2014年7月 2日 (水)

画像データもバッファリングする

PCMデータはリングバッファにバッファリングするようにしました。画像(JPEG)データは基本的にBrynhildrサーバから一枚分送られてきたら、すぐに表示してデータは廃棄する、という方針でした。

ところが、画像データの表示とPCMデータの再生がズレるので同期を取る必要がありそうです。現状の実装では、JPEGデータはクライアント到着直後に問答無用で表示しているので、同期タイミングの選択の余地がありません。これを改善するためには、画像データの保持と表示のタイミングをもう少し分離して、任意のタイミングで表示を可能にすることが必要となります。

で、まず画像データもPCMデータと同様に複数枚分保持するような管理方法に変更します。リングバッファっぽいクラスを用意し、画像データが届くたびにとりあえずバッファへ保存するようにします。表示する時はこのバッファから順次取り出して、Qtに表示を指示すればよいはずです。

画像データ用のソケット通信で送られてくる画像(JPEG)データは順次バッファへコピー後保存されるので、あとは表示のタイミングをどのようにするかが問題となりますね…

PCMデータの時のようにタイマーで関数を起動して、一定時間ごとに表示するのがいいのか、それともPCMデータの再生バッファへの書き込みタイミングとなんらかの形でリンクするのがいいのか、検討が必要そうです。

まず画像データ保存用のバッファの仕様みたいなものを書き出してみます。

・1枚JPEGデータが届いたら、GraphicsBuffer(以下GB)へ順次格納(put())する。

・GBは複数のJPEGデータを順に格納できる。(リング状にする)

・GBは順にJPEGデータを取り出せる。(FIFOで)
メモリの先頭へのポインタとデータのサイズが得られるようにする。バッファが空ならば、ポインタ、サイズは0, 0。

・データ格納時にバッファのオーバーフローをチェックする。エラー時は例外を送出する(?)

・JPEGデータはローカルバッファの境界は跨がないように配置する。

とりあえず、この方針でGBクラスを実装してみます。

« 2014年6月 | トップページ | 2014年8月 »