オンボードでハフマンを展開しようとしてかなりハマった。
結局、uint8_t*を渡すところに、buff[2][4096]を、static_cast<uint8_t*>(buff[0][0])としていたのが問題で、static_cast<uint8_t*>(&buff[0][0])のようにする必要があった。uint8_tからuint8_t*のキャストは可能なので、エラーもワーニングも出ない。
元々はテンプレートで処理していたので厳密にチェックされていたが、ADC用のダブルバッファを流用するにあたってポインタに書き換えたので、そこにバグが入り込んだ。
で、デコードしてみたのだが、8KiBのバッファを埋めるのに1秒くらいかかる。最終的に160KiBくらいになるから、デコード処理だけで20秒くらいかかる。160KiBのエンコードは16ミリ秒くらいだから、圧縮より展開のほうが1000倍以上も遅い。
確かに、デコードの場合は1ビットずつ取り出して、都度ハフマンツリーと比較する、という作業を行っているので、処理時間は多く必要なのだが、それにしたってそこまで遅いのか。
高速化の方法としては、1bitずつ読み出すのでなく、複数ビットを一気に読みだした上でマスクして比較とか、全ハフマンコードとの比較はせず、ビット長ごとに配列を作るとか、色々方法はありそうだが、結構手間がかかる。
そもそもなんでオンボードでデコードしようとしているかというと、展開を行うには圧縮に使ったハフマン木が必要だが、これは計算的に作れないので、どうにかして圧縮側と展開側で木をやりとりする必要がある。
また、圧縮データは32bitで管理しているが、そのままだとエンディアンの問題が出てくる。展開データは8bitだから、エンディアン問題を気にする必要がない。
というような理由から、展開後のデータを記録すれば諸々の問題を解決できる、と目論んでいた。
ただ、ハフマン木のやりとりは、大きく見積もっても2KiB程度だから、160KiBの生データを記録すより、100KiBの圧縮データと2KiBのハフマン木をまとめて記録したほうが、データ量を削減できる。それに、今回使っているハフマン木のデータの都合から、ハフマン木のデータを解析すればエンディアンも把握することができる(はず)。
とすると、わざわざ時間をかけて展開して記録するより、ハフマン木+圧縮データをセットで記録したほうがいいか、と思っている。
***
NTSCってオワコンだと思ってたけど、最近は競技用ドローンのFPVで結構使われてるのね。なのでカメラとかも売ってる。車のバックビュー用とかもまだ売ってるみたい。
FPV用だとOSD対応のカメラとかもあるらしい。AttiとかLatLngとかの表示ができるので、缶サットとかに付ければ便利そう。ただ、おそらくUARTとかでテレメを入れるんだと思うんだけど、あんまり情報が出てこない。
競技用ドローンってArduinoとかSTM32とかをベースにした制御基板が有って、中国製の安いやつを買ってきてソフトウェアは自分で設定する、みたいなのが主流らしくて、日本語圏だと低レベル部分の情報がほとんど出てこない。でもまぁ、GitHubとか覗けばコードとかドキュメントとかあるんだろうし、イザとなればどうにかできるはず。
あるいは、カメラのOSD機能は使わなくても、NTSCで輝度情報だけを上書きするなら、結構簡単に作れそうな気もする。加算回路がちょっと面倒か。受動素子だけで作れれば楽でいいけど。
そのあたりも追々やってみたい。
0 件のコメント:
コメントを投稿