brly.github.io

04 December 2018 : シンデレラガールズ 6thLive に行った

idolm@ster

https://idolmaster.jp/event/cinderella6th.php に行った。 ライブ自体の感想は Triad のオタクとして「最高だった」という他ない (語彙力崩壊) ので、それ以外の部分、旅行記について書いていく。

1日目

11:33 東京駅発 13:17 名古屋駅着の新幹線に乗る。となりの席はプロデュンヌだった。 自分の車両の乗車率はほぼ 100% で、そのうち自分と同じ目的のいわゆる P は 1/3 ~ 1/4 と言ったところだった。

ナゴヤドームの最寄り駅としては、地下鉄の名城線の「ナゴヤドーム前矢田」駅となるため、 桜通線で「久屋大通」まで行き、名城線に乗り換える。

その後会場について、適当に物販をあさる。

今回のキャパは5万人らしく、それだけの人の多さを感じる。なので、弊害がいろいろあり、 例えば SSA などはけやき広場のような、入場前の人達用のバッファとなるような場所が存在するが、 ナゴヤドームの場合それはなく、そのバッファとしてドームの通路までの脇だったりとなるため、人で溢れかえっていた。

連番する P と合流して入場。1塁側スタンド 30 列目。

ライブが終わり https://daruma-sakaba.com/ で打ち上げる。

ホテルは ジャストインプレミアム名古屋。夕食なしのビジネスホテルだったが、 1泊朝食付きで 18k になった…。2017年築らしく、様々な設備が新しくてよかったし、ベッドも高いなりにデカかった (セミダブルくらい)。

ホテルも P だらけだった。

寝る前に、東京駅から名古屋駅までのテクテクテクテクの予約塗り埋めをやろうとしたけど、全く埋まらない。

少なくとも新幹線の予約塗りの速度で塗れなさそうなことがわかり…、 つまり行きの新幹線にかかった時間は少なくともかかることを理解し、 諦めの気持ちを持ったまま 1/4 くらい塗って寝る。

2日目

朝飯は食べるつもりはなかったが、周りの音で目が覚めてしまったので起きて食べに行く。 設置されているテレビにちょうどプリキュアの ED が流れていた。

ホテル、Do not disturb を貼っておいたけど、ドアを数回ガチャガチャされたのが気になった。

チェックアウトして再び会場に向かい、同僚 P と合流する。

会場限定 CD を買う。11時くらいの時点では、西武ドームで販売されていた春と夏の CD は売り切れていた。

近くのイオン。

ナゴヤドーム横のイオンで UO を探すか、という話になり向かってみるとイオンとナゴヤドームの連絡橋のイオン側で ゲリラ的にイベントグッズの露店 (おそらくイオンが公式に用意した店と思われる) が出店しており、 UO 25 本入りが定価の 1.5 倍であるところの 3700 円くらいで売られていた。そしてすでに列形成がなされていた。

人の列は途切れるどころか、むしろどんどん列が成長しているようにみえた。自分は買う必要なかったので並ばなかった。 このとき、名古屋の栄のドンキホーテやヨドバシでも UO が売り切れているという話を聞く。

そのまま成長する列を見届けてイオンのサンマルクカフェで昼飯を食べる。 カフェなどではなく別のお店でがっつり飯を食べようとしたが、その手の店は概ね P の行列が出来ており、諦めた。

そして、トイレを探すことにしたがどこのトイレも空いてないので、仕方なく駅移動した。

トイレに向かう途中、コール本配布を見つけたのでいただく。

ナターリアのポケットティッシュ配布があり、驚いた。

再び会場に戻りつつイオンの UO 露店の方に目をやると、先程より列はだいぶ成長しており…というか、すでにあらゆる通路が人で飽和しており もうどこが列なのかもわからない感じではあったが、とにかく人だらけになっており、やはりバッファの必要性を感じた。

もろもろ済ませて、入場。昨日と同じ1塁側スタンドだが、11列目となったので幾分近づいた。 視力1.2でトロッコのキャストさんの顔や表情が概ね見える程度の近さ。

ライブが終わり、名古屋駅近くの居酒屋で1杯乾杯してフライドポテトをつまんで帰り、名古屋 22:02 発の新幹線に飛び乗って帰る。 隣の席は P だった。

反省

  • 地方遠征後の月曜は有給をとる、疲れた。
  • 腕がつかれた。今回の旅行バッグとして、日常的に使っているハンドバッグを使っていたが、大量の荷物を運ぶには 向いていないことがよくわかった。
    • キャリーカートかリュックを買う。

01 December 2018 : コンピュータアーキテクチャの本を読んだ

Reading

https://www.amazon.co.jp/dp/4434218484

上腕二頭筋に ALU やらレジスタファイル書かれている面白い本を読み終わった。 この本は本の大きさがそもそもでかくて読みづらい嫌な側面があったが、ドラゴンブックみたいに変な道の逸れ方はしないので読みやすかった。 気合の入った演習問題集・口頭試問集みたいのが各章末についており、やる気のある人にはとても良さそう。ほぼやらなかったけど。

前半の 1~3 章くらいはおそらく大学だと情報/電気電子みたいなところだと学ばされるかな、と言った内容で、その次は SystemVerilog/VHDL の言語の話が続く。 その次の章は、CPU を作るためのライブラリ (ビルディングブロック) づくりの仕方を学ぶ。レジスタとか。Enable を立ててクロックの立ち上がりで書き込む、みたいな。

そこまでの章で大体の道具は揃ったので、実際に ARM ISA の CPU を作っていく。単一サイクルプロセッサ、マルチサイクルプロセッサ、パイプラインプロセッサの 3 種類。 単一サイクルプロセッサで、データパスとコントローラ (必要なあらゆる制御信号を管理するやつ) の作り方を見て、マルチサイクルプロセッサでは Moore-FSM (直前の状態にのみ依存する) で状態を管理しつつ制御信号の処理をうまいことやる話が、パイプラインプロセッサではパイプラインレジスタを途中で挟んで処理する話、各種ハザードを処理していく話が乗っている。

商用製品はパイプラインプロセッサなので、やはりそこらの話が気になった。 紹介されていたハザードの処理はフォワーディングかストールで、それくらいは確かに話としては聞いたことがあっても、回路レベルで実際に処理する部分は見たことがなかったので、なかなか面白い。

ここまででもそれなりに面白いのだが、教材/演習でやっていない領域には命令/データのキャッシュ機構とか複数命令デコード/スーパースカラ実行/アウトオブオーダ実行みたいなものもあるわけで、まだまだ深みを感じる。

ところで、RISC-V の OoO するやつ https://github.com/riscv-boom/riscv-boom もあるみたいなので、やる気になればこれを読んだりすれば上でいったような機構を学ぶ/遊べそうではある。Chisel という Scala DSL を読み解く必要があるけれど。 この先に進んでいくには実際に開発/評価ボードを買ってやっていく、という多少のお金とそれなりのやる気が必要な道になる。

29 November 2018 : 無料で光回線が適用された

web

賃貸での話。

よくわからないけど、住んでいる物件に無料で光回線が引かれる事となり、先日工事の業者が来て一通りの設定をしていった。

今日、よくわからないルータと ISP から ID/パスワードが届いたので、適当に設定を終えた。

NTT 純正のルータみたいなもの (ONU というモデム/名称か?) で有線接続して Google のスピードテストを試すと 500 Mbps とか出る。すごい。 ところで、普段は有線接続を全くしないので、ほぼ恩恵はないわけだけど。 そこに以前もらった友人のルータを噛ませて有線接続したら 200 Mbps まで下がった。面白い。

また、そのルータで無線接続してみると速度は 30 Mbps ~ 50 Mbps と言ったところ。 これはすでに現在契約しているケーブルテレビ回線らしいインターネットの無線接続によるスピードは、ほぼ同じであった。

なので、自分が新たに有線接続をするようになるか、無線の性能が向上するルータ (?) があれば、ネット環境がより快適になるかもしれない。

28 November 2018 : 続 Javascriptでライブカメラっぽいアプリケーションを作ったメモ

codec

https://qiita.com/brly__/items/25cd423c348cbc302b4a

は書かれてからそれなりに時間の経った記事にもかかわらず、いまだに いいね・ブックマークされるのですが、その度になんとなく申し訳ない気持ちになるので続きを書きます。

というのも今は諸事情があって、多少なり動画圧縮・動画配信に関する一定の知識が付いたこともあり、 上記の記事だけで満足してほしくない・もう少しマシな記事をかけるぞ、という自負があるので続きを書きます。

もともとの話を簡単にまとめてみると

  • js だけで完結するライブカメラ配信アプリを作る
  • クライアントは example.com にアクセスするだけで視聴
  • 配信者は server.example.com にアクセスするだけで Web カメラから配信
  • 映像は backend.example.com を介して配信者からクライアントへ流れる

こんな感じでしょうか。この記事が褒められることがあるとすれば、「動画の作り方」くらいでしょう。 参考にさせて頂いてる丁寧な記事へのリンクなどを用意し、動画とはパラパラ漫画のようなもの、であることを説明している点ですかね。 それ以外は大したことない気がします。すいません。単純に、この記事を書いた時に知識が無かっただけの話なのですが。

しかも javascript と題している割にはコードも一切出てきませんし…。 配信するにあたって Web カメラ持ちパソコンで「ブラウザアクセス」するだけ、ってのは手軽で良かったですかね。

圧縮効率がわるい

自分が使っていた時も趣味プロジェクトの範囲でしたし、上記の記事を読んで万が一にも商用で検討している人はいないと思いますが、 とにかく説明していたやり方は圧縮効率は悪いです。画像の伝送に多大な帯域を使用します。携帯回線ならあっという間に上限に到達してしまうかも知れません。

本文からやり方を読み取ってみると

  • 完全フレームは canvas.toDataURL(“image/octet-stream”) で生成する
  • 差分フレームは canvas の rgb チャンネルごとに舐めて Uint8Array を生成する

とあり、 Uint8Array と宣言しているのは大きさが 3 となる、それぞれ RGB を示す Uint8Array とするとします。

この時のかすかな記憶として、「差分フレームがたいしてサイズが縮まなかったな…」という記憶があります。 対して、toDataURL の方は完全フレームながらも「以外と圧縮されるな…」という感じでした。 これは、完全フレームが生データではなく何らかの圧縮が効いているものと考えられるのですが、すいません、仕組みはわかりません。

ただ少なくともピクセルあたり 3ch/8bit = 3byte のサイズではなかったと認識しています。 一方、差分フレームの方は差分ピクセル毎にピクセルのインデックスと差分ピクセル値の3つの値を保持するようにしていた記憶があります。 差分ピクセル値の値域は 8bit なので大きさとしては 1ch あたり 1byte で十分ですが、 画面上のどこの差分かを示すインデックスの情報については 0~255 では足りない可能性があります。もしかしたら 16, 32 bit あたりを使っていたかも知れません。 ここでは 32 bit だったと仮定しましょう。

すると、1ピクセルあたりの差分を表示するために必要なデータ長は 32 + 32 + 8 * 3 bit = 88 bit = 11 byte にもなります。 8bit/3ch の 1px が 24bit = 3byte かかるのに対して、インデックスとやらで 8byte もかかっています。もし、画面全体の差分情報が必要だとすると、生データと比較しても 3 倍近くの容量が必要になります。これは厳しいです。

じゃあどうやるのが圧縮率がいいのか、普段見ている動画はどうやって圧縮されているのか気になるところです。

身の回りの圧縮コーデック

よく聞くのは H.264 とか H.265 とか AV1 とか、になるでしょうか。

これらの実際の処理をちょっと見てみるとわかるのは、上で書いたみたいに 1px ずつ処理されることはない、ということです。 H.264 を例に出すと、例えば基本の処理単位は 16x16 ピクセルのグリッドとしていて、その中をさらに分割したりして最小では 4x4 を最小の処理単位としています。 どういうことかというと、1 px 毎に処理するのでなく 4x4 とか 16x16 毎に処理して、処理単位にインデックスのような情報を付随させるほうが結果として処理ビットを節約できるのです。

例えば、縦 1px で 横 4px のピクセル群があったとして、1フレーム後に右に 5px 動いたとしましょう。

1フレーム目「□□□□■■■■■」
2フレーム目「■■■■■□□□□」

移動した部分を表現するためには、先程のやり方だと 44 byte (11byte * 4px) とか、かかるわけですが、そうではなく「□□□□」の 1x4 が全体として右に 5px 動いた、という風に記述できると 44 byte もかからずできそうですよね。なんとなくですけど。

さて、これをやるためにはこの 4x4 などの「処理単位」ごとにどういう風に動いたのかな、と推定する必要があるわけですが、 この推定処理を「動き推定」、で推定したピクセルで補完することは 動き補償 とか呼ばれていて、 推定をするには実際に総当たりとか、それの近似計算とか、いろいろ組み合わせてエンコーダが頑張っています。

これが動画エンコード (ソフトウェア) の計算が重たい理由のうちの一つです。

これだけでもだいぶビットをケチれそうなのですが、さらにもう一つ頑張っているのが DCT です。

https://people.xiph.org/~xiphmont/demo/daala/demo1.shtml

上記のデモページの中断にある「DCT」の部分がわかりやすくておすすめです。 DCT することでかなり情報が削れる (ほとんどが 0 になっている) のでほんまか?という感じですが…。 DCT は情報を周波数成分に変換する、と言われてます。ピクセルの平均的な色は「低周波」へ、そうでなくまばらな色なんかは「高周波」成分に変換されます(ざっくりとした説明…)。

この DCT をどこに適用するのかというと、先程の文脈で言うところの「差分ピクセル」に使っていきます。 最小処理単位はもはや 1px ではなく 4x4 とかになっているので、差分ピクセルとしての情報もそれだけの大きさ(行列みたいなもの)になっているのですが、そこに DCT を適用します。 うまくいけば、デモページのように数字は行列の左上に集中してそれ以外は 0 となり、伝送すべき情報が減らせることでしょう。

それで、動き補償のことは MC とか呼ばれているんですが、身の回りのおおよそのコーデックはこの MC と DCT をベースとした仕組みに乗っかった形になっています。 じゃあ新しいコーデックは何を頑張っているのかというと、扱える処理単位の種類を増やしたり (16x16, 4x4 だけでなく 32x32 とか 64x64 など)、 DCT をした後に、情報を欠落させる、不可逆圧縮となる「量子化」の処理を適用したり、さらに算術符号などを利用したエントロピー符号化を用いたりして 1 bit でも削ろうと頑張っています。

処理単位が増えて、例えば 16x16 を4つ使って伝送していたものが 32x32 の1つで済むようになると、処理単位にかかるオーバーヘッド分の ビットがケチれそうだな、というのは直感的に理解できると思います。 ただ、その分エンコーダは利用するすべてのパターンのエンコードを試して良いものを選ぶというプロセスを取る必要があるため、 必然的にエンコード処理が重たくなります。

仕組みはなんとなくわかった、さて

ざっくりここまで読むと、普通のコーデックは MC/DCT のおかげで最初に述べたような 1px ごとの処理より圧縮できるんだな、ということはわかりました。

じゃあ、最初にあげていた javascript で作っていたの仕組みのところになんとか入れるプランを検討してみましょう。 ところで、実際にエンコーダのライブラリを書くのは結構たいへんです。たとえば pdf 版に限り H.264 は規格書が無料で読めますが、実装は大変なので試すなら すでに広く実装されている OSS なりを使うのが楽です。ffmpeg はたくさんのコーデックを内包していて、便利なやつですね。

さて、元々の仕組みだと、web カメラにアクセスするブラウザ内部で差分フレームの情報を計算させていました。 これは単純ではありますが、エンコーダの仕事をしていたと言っていいでしょう。

これは、現段階ではそんなにいいやり方でない気がします。というのも、動画エンコードというタスクはとても CPU 資源的に高価なタスクなので、 javascript の上で動かすにはいささか富豪的に見えます。Web アプリケーションが好きだったり、Web Assembly を推している皆様には申し訳ないですが、 それでもこの意見は変わりません。もうちょっと未来になって Web Assembly がより高速になったら現実的なプランとなるかも知れません。

そこで、もし、なるべく簡単に、いわゆる普通のコーデックを使うように仕組みを変更するならば、以下のように変更します。

  • 配信者側のエンコードをやめる
    • server.example.com にアクセスし、そこから一切の処理を行わず毎フレーム毎 canvas.toDataUrl("image/octet-stream") の結果を backend.example.com に投げる
    • これにより、上り回線の使用帯域は増え…ますね
      • ただ、下り回線は任意の本数を考える必要がありますが、上り回線は 1 本なので、下りに比べればまぁよいでしょう
  • backend.example.com で一連の受け取った画像の集合を動画に変換
    • 例えば https://stackoverflow.com/questions/42735121/ffmpeg-continuously-stream-refreshing-image-to-rtmp のようなやり方
      • image を loop で rtmp に変換
        • ナイーブに真似するなら、例えば localhost に設置して ffmpeg が取りに行くようにするなどで出来そう (もっとスマートに出来そうだけれど…)
      • rtmp でなく HLS にすると hls.js などのライブラリで視聴可能に
      • ffmpeg に -vcodec [hoge] でコーデックを指定
  • 視聴者は example.com で backend.example.com からの動画を受信して視聴

もしくは、上で否定していたブラウザエンコードをやる方法もあります。C/C++ のコードを emscripten などで js に変換して、ffmpeg をブラウザ上で動かすようにして、 backend.example.com に rtmp を受け付けて変換して配信する ffmpeg を起動し、配信者側からはその rtmp を受け付けているところに向けてブラウザ上の ffmpeg で Web カメラを入力として送信するなど… いろいろやり方はあります。

これらはあくまで趣味プロジェクトレベル、のやり方の話です。

まぁ、でも

現実のコーデックを使うと、とても圧縮効率を高められますが、「めんどくさ」「2,3秒に1回画像が更新できれば問題ないよ」という人は Qiita の記事のままのやり方で大丈夫でしょう。

ただ、どうやったら圧縮効率が高まるのか、どうやって圧縮されているのか知っておくのは良い事だと思います。

27 November 2018 : ハードウェアハッカーを読む

Reading

読み終わった。こういっちゃなんだけど、内容の半分くらいは理解できなかった。 もはや前半はコンピュータサイエンスというよりかは、物理的な話や量産を行う、深センの工場の話だったりであり、 様々な専門用語が飛び交うのだが、正直一つ一つを調べて読んでく丁寧なことをしなかった。そこら編の話は、とにかく大変さが伝わってきた。

途中でパテントの話を挟んで、最後の方は SD カードのハッキングとか、 ようやくギリギリ理解できるコンピュータサイエンス的な話 (インタラクティブな逆アセンブラを作る話) とか、 果ては大腸菌の DNA 解析、薬剤耐性みたいな話をしており、この本、というか著者は一体何者なんだ…という気持ちになる。

SD カードについている intel のマイコンにファームウェアを流し込む形で任意のコードを実行させる話は本当に面白い。

ハッキング対象がハードウェアである以上、物理的にいろいろ引っ剥がしたり、外装を溶かしたり、顕微鏡を使ったりして 本当にハッキングしていく様子は読んでてわくわくした。

ところで、最近友人から、なぜか激安の使いづらいルータを貰う機会があったので、やる気が出たらこれで遊びたい。