LovyanGFXとJpgLoopAnimeを使って、M5CameraとM5Stackの動画ストリーミング実験

LovyanGFXとJpgLoopAnimeでM5StackとM5Cameraの全画面WiFi動画ストリーミング実験

記事公開日:2020年7月15日

こんばんは。

今回は更にスゴイっす!
LovyanGFX と M5Stack_JpgLoopAnime ライブラリを取り入れて、前回記事のM5StackとM5CameraのWiFi動画ストリーミングプログラムを改良したら、メチャメチャ高速で、20~24fpsという高フレームレートが実現できました。
しかも、M5Stackの全画面(320 x 240 pixel)ですよ!!!
JPEG画質を落とせば、常時24~25fps出せたんですよ!!!

スポンサーリンク

それに加えて、カメラ画像のレイテンシ(遅延)がメチャメチャ少ないんですよ!
無線のWiFi通信で、しかも、UDPではなくTCP/IP通信ですよ!
これって凄くないですか?
とにかく以下の動画をご覧ください。

これ、ヤバイですよね。
今までのは何だったんだって感じの脅威的な速度です。

LovyanGFX と M5Stack_JpgLoopAnime ライブラリは、らびやん さんが作ったものです。
Twitterではよくアドバイスを頂き、目から鱗な情報を沢山いただきました。
いつも本当にありがとうございます。
m(_ _)m

前回記事では、私の自前ライブラリを使っていて、JPEGデコードライブラリはArduino core for the ESP32に同梱のTJpgDecライブラリを使っていました。
その時は、240 x 176 pixel で10~15fps程度でした。
それが、今回はM5StackのLCD全画面の320 x 140 pixelで、最高画質で 20~24fps を叩き出せるようになったんですよ!

画質を一段階落とせば、平均24fpsの速度を叩き出せて、かなり安定しました。
WiFiでTCP/IP通信でここまで速度が出せれば、プログラミングとしては最高じゃないでしょうか。
M5CameraのWiFi出力特性上、たぶん25fpsが限界だと思われますので、充分すぎます。

そして、M5Stackのオプションバッテリーを使うと、約3時間の連続動画ストリーミングができました。
以前は2時間半弱がせいぜいだったことを考えると、TCPによる無駄なパケット再送処理が少なくなって、省エネになったという一石二鳥の効果があったと思います。

とにかくスバラシイので、このライブラリを使わない手は無いですね。
ということで、自分のやった方法を紹介します。

因みに何度も言っていますが、私は素人アマチュアですので、何か誤りや勘違い等あるかもしれません。
もし、お気づきの点がありましたらコメント投稿等でご連絡いただけると幸いです。

    【目次】

  1. フレームレートを上げるには受信側の処理が肝だった
  2. LovyanGFXとM5Stack_JpgLoopAnimeを使うと圧倒的に高速だった
  3. 使ったもの
  4. Arduino core for the ESP32のインストール
  5. M5Stack公式ライブラリのインストール
  6. LovyanGFXライブラリのインストール
  7. M5Stack_JpgLoopAnime ライブラリのダウンロード
  8. M5Camera(送信側)の設定
  9. M5Stack(受信側)の設定およびスケッチ
  10. 操作方法
  11. M5Stack用電池モジュール(オプションバッテリー)使用について
  12. 新たに学んだこと
  13. 今回の実験の課題点
  14. 編集後記

フレームレートを上げるには受信側の処理が肝だった

M5CameraとM5StackのWiFi動画ストリーミングのフレームレートを上げる方法について、今までのこの数か月間ずっと個人的に実験した結果、受信側のデバイスがいかに高速で1フレームの画像を描画処理して次のフレームの受信に備えられるかというところが鍵だという結論に至りました。

なぜなら、M5Cameraとパソコンのブラウザとの通信では高速フレームレートなことからも明らかです。
前回記事までの結果だと、M5Stackの画角 240 x 176 pixel でせいぜい15fpsだったのが、パソコンのブラウザの場合は25fpsの速度が出ていたことからも、受信側の処理能力が原因だと分かると思います。

個人的考察だと、M5Camera側の送信フレームレートは 25fpsが最高という結論でした。
イメージセンサOV2640からは50fpsのDMA (Direct Memory Access)でESP32に送られてきて、ESP32が1フレーム受け取ると、次のフレームを間引いてWiFi送信しているからです。
それに、ESP32のWiFi送信は、通信の輻輳の問題もあって、あまり速度を上げられません。
JPEG画質を下げて、1フレームの送信バイト数を下げれば、フレームレートを上げられますが、個人的には 20~25fps出せれば充分スムースな動画ストリーミングだと思います。

M5Stackの能力的にパソコンの処理能力には到底及ばないので、前回記事の段階では15fpsが限界かなと思っていました。
でも、今回、全画面 320 x 240 pixel のJPEG最高画質で 20 ~ 24fps を叩き出せたということは、パソコンのブラウザに迫る能力が引き出せたのではないかと思っています。
すんごいですよね~。。。

LovyanGFXとM5Stack_JpgLoopAnimeを使うと圧倒的に高速だった

らびやん さんが作ったLCD関連ライブラリは、M5Stack等を使う場合はとにかくお勧めです。
らびやん さんの一連のツイートを見れば分かるのですが、毎日のようにLCDの高速化を探求していて、ほんとに頭が下がります。

M5StackのLCDにイメージセンサのカメラ画像をWiFi動画ストリーミングする場合は、LovyanGFXとM5Stack_JpgLoopAnimeを使った方が圧倒的に高速でした。

実は、LovyanGFXのJPEG描画だけでテストしてみたのですが、その場合は 2~4fpsしか出ませんでした。
そこで、M5Stack_JpgLoopAnime のJPEGデコード部分を組み合わせたら、なんと、20fps以上という圧倒的な高速表示を叩き出せたんです。

GitHubのLovyanGFX ソースコードを見ると、C++特有の定義や標準関数で埋め尽くされていて、「なんじゃこりゃ?」っていう感じでした。
異次元プログラミングの世界を見た感じで、とっても刺激になりましたね。
そして、M5Stackだけでなく、他のデバイスへの移植性も考えて作られているので、変数や引数の定義を見ても、とっても勉強になりますね。

では、何で M5Stack_JpgLoopAnime を組み合わせると高速になったのか。。。

JPEGデコードライブラリ TJpgDec はカスタマイズした方が断然高速だった

前回記事では、Arduino core for the ESP32 に同梱のJPEGデコードライブラリ TJpgDec をデフォルトで使いました。
ただ、今回の実験では、それを外側に出してカスタマイズした方が断然高速処理になることが分かったんです。

実は、 らびやん さんからアドバイスを受け、まずは、ESP32_ScreenShotReceiver ソースコードを参考にして、TJpgDec ライブラリを改変する挑戦をしました。
ESP32_ScreenShotReceiver ライブラリは、ブロック毎単位のWiFiでJPEGデータ受信して、マルチタスクでLCD描画している構造だと思います。
私の勝手な解釈だと、パソコン側のSenderアプリで送られるデータは、MotionJPEG (MJPEG) とは異なる方式を使っていて、1ブロック描画を終えると”JPG”というテキストデータ をアプリに送って次のデータを送信要求する方式なのだと思われました。

私もそれに習って、TJpgDec ライブラリを別途取り入れて、C++基準に合わせて変数を最適化したり、マルチタスク化したりしていると、明らかにスピードアップできたんです。
WiFi受信しながらLCDにマルチタスク並列処理で描画させると、240 x 176 pixel の画角で、15fps から 19fps まで速度アップできました。

ただ、私はブラウザとの通信ができる MotionJPEG (MJPEG) が捨て難く、それに沿った改造は私の頭では無理でした。
それをTwitterで何気につぶやいたら、らびやん さんから M5Stack_JpgLoopAnime ライブラリのマルチタスク化したJPEGデコードを試してみてはどうかというアドバイスを頂きました。
これは、JPEGデコードにWiFi通信が絡んでいないので、MotionJPEG (MJPEG) に組み込みやすいからです。

そして、実際試してみたら、ビックリ!!!
めちゃめちゃ高速じゃないですか!!!

そんでもって、M5Stack_JpgLoopAnime のソースコードを見てみると、JPEGデータをブロックごとに分けてデコードしながらLCDにマルチタスク並列処理で描画していることが分かります。
元々、TJpgDec ライブラリは、JPEGデータをブロックごとに分割してデコードしているので、それをうまく利用したと思われます。
C++でESP32用に最適化されてはいますが、それだけでこんなに大幅な速度アップができるとは驚きですね。
らびやん さんの脳ミソに感服です。

みなさんも是非ためしてみてください。

ところで、M5Stack_JpgLoopAnime のtjpgdClass.cppファイルのmultitask_begin関数にtask_outputというタスクがありますが、それは core 0 タスクでした。
私の M5Stack 側のコードでは、WiFi受信を core 0 で処理しているので、マルチコアの意味がないだろうと思って、task_outputをcore 1 に変えてみました。
しかし、そっちの方が速度が遅くなりました。

逆にWiFi受信をcore 1 にして、task_outputをcore 0 にしたりもしましたが、結局のところ一番安定して高速だったのが、task_outputがcore 0 で、WiFi受信も同じ core 0 だったのです。
これについては、この記事を書いた後、らびやん さんからTwitter上で回答いただきました。
ただ、私が勉強不足で未だ理解できずにいます。
やっぱりこのライブラリは高度過ぎました。。。

使ったもの

M5Stack

このブログではお馴染みの ESP32 を搭載した、技適取得済み全部入りモジュールです。
これを過去に分解して紹介した記事があるので、参照してみてください。

M5Stackを分解したり電源を入れてみて、いろいろ思ったこと

Amazon.co.jp
M5Stack Basic
スイッチサイエンス

Amazon.co.jp
M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

M5Camera


もう1年くらい持続してこれで遊んでいます。
これは、OmniVision 製イメージセンサ OV2640 を搭載し、ESP32-WROVER搭載のWiFi & Bluetoothマイコンモジュールです。
これも過去に分解した記事があるので、そちらも参照してみてください。

M5Camera をレビューしてみた。分解したり、Arduino IDE でスマホに映したりする実験

これはスイッチサイエンスウェブショップで販売しています。

https://www.switch-science.com/catalog/5207/

オプションバッテリー

後で述べていますが、これを使う場合はちょっと注意が必要かもしれません。
なぜなら、M5Stackのボトムと併用すると、バッテリーの寿命が低下するという情報があったからです。
M5Stack公式やスイッチサイエンスさんからはそういう情報が出ていないので、私自身は何とも言えません。
気になる方は、M5Stackのボトムを外して使用した方が良いかも知れません。

Amazon.co.jp
M5Stack用電池モジュール
スイッチサイエンス

WiFi環境

できるだけ高速のWiFiルーターを使って下さい。
私の場合は、ホテル用ルーターを使いました。
以下の製品は最新バージョンのものです。

Amazon.co.jp

事前にM5StackやM5CameraがWiFiルーターに接続できるようにセットアップを済ませておいてください。

パソコンおよびUSBケーブル

USBケーブルはできるだけ良質で、太く短いものを使って下さい。
M5Camera は特に電力消費が大きいので、粗悪なUSBケーブルだとまともに動作しません。
私が使っている良質なUSBケーブルは以下の物です。

Amazon.co.jp

Arduino core for the ESP32のインストール

各バージョンは以下で動作確認しております。

Arduino IDE ver 1.8.13
Arduino core for the ESP32 ver 1.0.4

Arduino core for the ESP32 のインストール方法は以下の記事を参照してください。

Arduino core for the ESP32 のインストール方法

M5Stack公式ライブラリのインストール

ボタン操作の為だけに M5Stack公式ライブラリを使います。。
ver 0.3.0 で動作確認しています。

M5Stack公式ライブラリのインストールは以下の記事を参照してください。

M5Stack ライブラリインストール方法 ( Arduino IDE 用)

LovyanGFXライブラリのインストール

らびやん さん作成のLovyanGFXライブラリをArduino IDEにインストールします。
これは、M5StackのLCD(液晶ディスプレイ)に高速表示させるためのライブラリです。
ver 0.1.15 で動作確認しています。

インターネットに接続しておき、下図の様に、「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理」を選択します。


すると、下図の様にライブラリマネージャが開くので、検索欄に「Lovyan」と入力して、LovyanGFXを表示させて、最新バージョンを選択し、「インストール」ボタンをクリックすればインストールできます。


インストールし終わったら、念のためArduino IDEを再起動した方が良いと思います。

M5Stack_JpgLoopAnime ライブラリのダウンロード

次に、同じく らびやん さん作成の M5Stack_JpgLoopAnime ライブラリをダウンロードします。
これはライブラリマネージャを使わず、ZIPファイルをダウンロードします。

まず、GitHubの以下のリンクを開きます。

https://github.com/lovyan03/M5Stack_JpgLoopAnime

そのサイトを開くと、下図のように表示されるので、「Code」のところをクリックすると、プルダウンメニューが表示されるので、「Download ZIP」をクリックするとZIPファイルがダウンロードされます。


GitHubがMicrosoftに買収される前は違う表示だったので、久々に見るとちょっと戸惑いますね。

では、次はM5CameraやM5Stackのスケッチ(プログラムソースコード)を紹介します。


スポンサーリンク


コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください