Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
GOB52 committed Jun 26, 2023
2 parents f167f9f + a9220b2 commit f831f3f
Show file tree
Hide file tree
Showing 15 changed files with 293 additions and 559 deletions.
53 changes: 15 additions & 38 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The data format is modified for playback.
## Overview
This application streams video files converted to the dedicated format gmv from SD.
It uses multi-cores to perform rendering with DMA and audio playback.
Old format (gcf + wav) can be played back (however, audio playback is restricted on machines without PSRAM).
***The old format gcf + wav is no longer playable since 0.1.1. Please regenerate it in gmv format or convert it using the gcf + wav => gmv conversion script.***


## Target devices
Expand All @@ -24,8 +24,6 @@ It must be able to run the libraries it depends on and have an SD card.
* M5Stack Gray
* M5Stack Core2
* M5Stack CoreS3

However, Basic and Gray, which do not have PSRAM, have significant limitations on the amount of time that audio can be played.

## Required libraries
* [M5Unified](https://github.com/m5stack/M5Unified)
Expand Down Expand Up @@ -54,8 +52,7 @@ However, Basic and Gray, which do not have PSRAM, have significant limitations o
|S3\_release_DisplayModule| Support DisplayModule |

### Sample data for playback
Download [sample_003.zip](https://github.com/GOB52/M5Stack_FlipBookSD/files/11746898/sample_003.zip) and copy it to **/gcf** on your SD card.

Download [sample_0_1_1.zip](https://github.com/GOB52/M5Stack_FlipBookSD/files/11871296/sample_0_1_1.zip), unzip it and copy to **/gcf** on your SD card.

## How to make data
### Required tools
Expand All @@ -73,13 +70,13 @@ Video data can be in any format that can be processed by FFmpeg.
1. Copy video data to an arbitrarily created directory.
1. Copy [conv.sh](script/conv.sh) and [gmv.py](script/gmv.py) to the same directory.
1. Execute the shell script as follows
**bash conv.sh move_file_name frame_rate [ jpeg_maxumu,_size (Default if not specified is 7168) ]**
**bash conv.sh move_file_name frame_rate [ jpeg_maxumum_size (Default if not specified is 7168) ]**

| Argument | Required?| Description |
|---|---|---|
|move_file_path|YES|Source movie|
|frame_rate|YES|Output frame rate (1 - 30)|
|jpeg_maximum_size|NO|Maximum file size of one image to output (1024 - 10240)<BR>Larger size helps maintain quality but increases the likelihood of crashes (see Known Issues)|
|frame_rate|YES|Output frame rate (1.0 - 30.0)<br>**Integer or decimal numbers can be specified**|
|jpeg_maximum_size|NO|Maximum file size of one image to output (1024 - 10240)<BR>Larger sizes preserve quality but are more likely to cause processing delays (see "Known Issues").|

4. The files that named "videofilename.gmv" output to same directory.
5. Copy the above files to **/gcf** on the SD card.
Expand All @@ -91,7 +88,7 @@ cp bar.mp4 foo
cp script/conv.sh foo
cp script/gcf.py foo
cd foo
bash conv.sh bar.mp4 24
bash conv.sh bar.mp4 29.97
cp bar.gmv your_sd_card_path/gcf
```

Expand All @@ -111,21 +108,21 @@ You can change the output quality, filters, etc. to your liking. The best parame
### Data restrictions
* wav data quality (8KHz unsigned 8bit mono)
The quality of the audio data is lowered to reduce the processing load.
It is possible to edit the script to improve the quality, but the processing load may cause crashes. (See Known Issues).
Scripts can be edited to improve quality, but processing delays may occur due to processing load. (See Known Issues)

* Image size and frame rate
* Image size and frame rate
When converting a video to JPEG, the width is 320px and the height is a value that maintains the aspect ratio.
<ins>Currently, 320 x 240 can be played back at about 24 FPS, and 320 x 180 at about 30 FPS.</ins>
To change the image size, edit the parameter for FFmpeg in conv.sh. **(scale=)**

## Known issues
### Reset during playback
If a reset occurs during execution, the Serial monitor should display a message that the assertion was caught.
The cause is that drawing did not finish within the specified time, and the SD and Lcd buses collided.
If this occurs at a specific point in the video, it can be avoided by modifying the data side.
* Image size and output device size
If the image size is narrower or wider than the output device size, it will be centered.

Also, in rare cases, it may take a long time to read from SD, which may cause a reset as described above.
The cause of this is not known.There may be SD card compatibility issues.
## Known issues
### Audio is choppy or playback speed is slow.
This may be due to the processing not being completed in time within a frame.
In rare cases, it may take a long time to read from the SD card, which may cause some frames to not be processed in time.
There may be a problem with the compatibility or formatting of the SD card.

https://github.com/greiman/SdFat/issues/96#issuecomment-377332392

Expand Down Expand Up @@ -156,25 +153,6 @@ conv.sh
# ...
```

#### Workaround by the program (deprecated)
* Switch multi-core playback to single-core playback.
Switch the corresponding section of main.cpp to the one using a single core.
Playback speed will be reduced, but bus contention will be reliably avoided.

```cpp
src/main.cpp
static void loopRender()
{
// ...
{
ScopedProfile(drawCycle);
//mainClass.drawJpg(buffers[(bufferIndex - 1 + NUMBER_OF_BUFFERS) % NUMBER_OF_BUFFERS], JPG_BUFFER_SIZE); // Process on multiple cores
mainClass.drawJpg(buffers[(bufferIndex - 1 + NUMBER_OF_BUFFERS) % NUMBER_OF_BUFFERS], JPG_BUFFER_SIZE, false); // Process on single core. Try it, if If assert occurs on xQueueSend call. (However, FPS will be reduced)
}
// ...
}
```

## How to operate
### Menu
| Button | Description |
Expand All @@ -194,7 +172,6 @@ static void loopRender()


## Conversion from old format (gcf + wav)
Currently, the old format (gcf + wav) can be played,
Pyhton script for conversion [gcf\_to\_gmv.py](script/gcf_to_gmv.py) and shell script for conversion of files in the current directory [convert\_gcf\_to\_gmv.sh](script/convert_gcf_to_gmv.sh) for converting files in the current directory.

```sh
Expand Down
46 changes: 13 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ SINTEL (Trailer)
## 概要
動画ファイルを専用の形式 (gmv) へ変換したファイルを SD からストリーミング再生するアプリケーションです。
マルチコアを使用して DMA による描画と、音声再生を行っています。
旧形式である gcf + wav 再生可能です(但し PSRAM 非搭載機では音声再生制限あり)
***旧形式である gcf + wav は 0.1.1 より再生不可となりました。gmv 形式で再生成するか、gcf + wav => gmv 変換スクリプトを用いて変換してください。***


## 対象デバイス
Expand Down Expand Up @@ -51,7 +51,7 @@ SINTEL (Trailer)
|S3\_release_DisplayModule| ディスプレイモジュール 対応|

### 再生用サンプルデータ
[sample_003.zip](https://github.com/GOB52/M5Stack_FlipBookSD/files/11746898/sample_003.zip) をダウンロードして SD カードの **/gcf** へコピーしてください。
[sample_0_1_1.zip](https://github.com/GOB52/M5Stack_FlipBookSD/files/11871296/sample_0_1_1.zip) をダウンロードして解凍し、 SD カードの **/gcf** へコピーしてください。

## データの作成方法
### 必要なもの
Expand All @@ -68,13 +68,13 @@ SINTEL (Trailer)
1. 任意に作ったデータ作成用ディレクトリに動画データをコピーする
1. 同ディレクトリに [conv.sh](script/conv.sh)[gmv.py](script/gmv.py) をコピーする
1. シェルスクリプトを次のように指定して実行する。
**bash conv.sh move_file_path frame_rate [ jpeg_maxumu,_size (無指定時は 7168) ]**
**bash conv.sh move_file_path frame_rate [ jpeg_maxumum_size (無指定時は 7168) ]**

|引数|必須?|説明|
|---|---|---|
|move_file_path|YES|元となる動画|
|frame_rate|YES|出力されるデータの FPS (1 - 30)|
|jpeg_maximum_size|NO|JPEG 1枚あたりの最大ファイルサイズ( 1024 - 10240)<br>大きいと品質が維持されやすいがクラッシュする可能性が高くなる(既知の問題参照)|
|frame_rate|YES|出力されるデータの FPS (1.0 - 30.0)<br>整数または小数を指定可能|
|jpeg_maximum_size|NO|JPEG 1枚あたりの最大ファイルサイズ( 1024 - 10240)<br>大きいと品質が維持されるが処理遅延が発生する可能性が高くなる(既知の問題参照)|

4. 動画ファイル名.gmv が出力される。
5. gmv ファイルを SD カードの **/gcf** にコピーする。
Expand All @@ -86,7 +86,7 @@ cp bar.mp4 foo
cp script/conv.sh foo
cp script/gcf.py foo
cd foo
bash conv.sh bar.mp4 24
bash conv.sh bar.mp4 29.97
cp bar.gmv your_sd_card_path/gcf
```

Expand All @@ -106,22 +106,21 @@ ffmpeg -i $1 -r $2 -vf scale=320:-1,dejudder -qmin 1 -q 1 jpg$$/%06d.jpg
### データの制限
* wav データの品質 (8KHz 符号なし 8bit mono)
処理負荷軽減の為、音声データの品質は下げています。
スクリプトを編集して品質を上げることは可能ですが、処理負荷によってクラッシュする場合が生じるかもしれません。(既知の問題参照)
スクリプトを編集して品質を上げることは可能ですが、処理負荷によって処理遅延が生じるかもしれません。(既知の問題参照)

* 画像サイズとフレームレート
動画から JPEG 化する際には幅 320p 高さはアスペクト比を維持した値で出力します。
<ins>現在の所 320 x 240 で 24 FPS 程度、 320 x 180 で 30 FPS 程度の再生が可能です。</ins>
画像サイズを変更したい場合は [conv.sh](conv.sh) の FFmpeg へ与えているパラメータを変更してください。 **(scale=)**

* 画像サイズと出力先サイズ
画像データが出力先サイズに満たない、または逸脱する場合は、センタリングして表示されます。

## 既知の問題
### 再生時にリセットがかかる
実行中にリセットがかかった場合 Serial モニタに assert で引っ掛かった旨が表示されているはずです。
原因は描画が所定の時間内に終わらず、 SD と Lcd のバスが衝突した事による物です。
動画の特定箇所で発生する場合はデータ側を修正することで回避することができます。

またごく稀に SD からの読み込みに時間がかかる時があり、それによって上記と同様にリセットがかかる場合があります。
これは原因がわかっていません。 SD カードの相性かフォーマット状態に問題があるかもしれません。
### 音声が途切れる、再生速度が遅い
1 フレーム内での処理が間に合っていないことが原因です。
またごく稀に SD からの読み込みに時間がかかる時があり、それによって処理が間に合わないフレームが生じているかもしれません。
SD カードの相性かフォーマット状態に問題がある可能性があります。

https://github.com/greiman/SdFat/issues/96#issuecomment-377332392

Expand Down Expand Up @@ -159,24 +158,6 @@ conv.sh
# ...
```

#### プログラムでの回避策(非推奨)
* マルチコア再生をシングルコア再生に切り替える
main.cpp の該当箇所をシングルコア使用の物に切り替えます。
再生速度は落ちますが、バス競合を確実に避けるようになります。

```cpp
src/main.cpp
static void loopRender()
{
// ...
{
ScopedProfile(drawCycle);
//mainClass.drawJpg(buffers[(bufferIndex - 1 + NUMBER_OF_BUFFERS) % NUMBER_OF_BUFFERS], JPG_BUFFER_SIZE); // Process on multiple cores
mainClass.drawJpg(buffers[(bufferIndex - 1 + NUMBER_OF_BUFFERS) % NUMBER_OF_BUFFERS], JPG_BUFFER_SIZE, false); // Process on single core. Try it, if If assert occurs on xQueueSend call. (However, FPS will be reduced)
}
// ...
}
```
## 操作方法
### メニュー
|ボタン|説明|
Expand All @@ -195,7 +176,6 @@ static void loopRender()
|Cボタン押下|画面右 1/3|音量上げる|

## 旧形式 (gcf + wav) からの変換
現在の所、旧形式(gcf + wav) も再生できますが、
変換用 Pyhton スクリプト [gcf_to_gmv.py](script/gcf_to_gmv.py) と、カレントディレクトリのファイル群の変換の為のシェルスクリプト [convert_gcf_to_gmv.sh](script/convert_gcf_to_gmv.sh) を用意しました。

```sh
Expand Down
53 changes: 35 additions & 18 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,9 @@ monitor_speed = 115200
monitor_filters = esp32_exception_decoder, time
upload_speed = 921600

; BOARD_HAS_PSRAM is specified because we want to use PSRAM.
; If the device does not have the PSRAM, PSRAM initialization will fail and the device will continue to operate as is.
; PSRAM 搭載機種では PSRAM を使いたいので BOARD_HAS_PSRAM を指定しています。
; 非搭載機では PSRAM 初期化に失敗し、そのまま動作します。
;
; FBSD_SUPPORT_GCF
; 旧形式のサポートする場合は定義する
; Support old format if defined
build_flags = -Wall -Wextra -Wreturn-local-addr -Werror=format -Werror=return-local-addr
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
;-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
-DSD_FAT_TYPE=3
-DFBSD_SUPPORT_GCF

; --------------------------------
; Choose build options
Expand Down Expand Up @@ -63,22 +54,22 @@ build_flags = -DCORE_DEBUG_LEVEL=5
[env:release]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE
build_flags=${env.build_flags} ${option_release.build_flags}

; Support display module
; ディプレイモジュールのみサポート
[env:release_DisplayModule]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE -DFBSD_ENABLE_DISPLAY_MODULE
build_flags=${env.build_flags} ${option_release.build_flags} -DFBSD_ENABLE_DISPLAY_MODULE
board_build.partitions = min_spiffs.csv

; Support SD-Updater
; SD-Updater のみサポート
[env:release_SdUpdater]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE -DFBSD_ENABLE_SD_UPDATER
build_flags=${env.build_flags} ${option_release.build_flags} -DFBSD_ENABLE_SD_UPDATER
lib_deps= ${env.lib_deps}
tobozo/M5Stack-SD-Updater @1.2.5
board_build.partitions = min_spiffs.csv
Expand All @@ -88,36 +79,62 @@ board_build.partitions = min_spiffs.csv
[env:release_SdUpdater_DisplayModule]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE -DFBSD_ENABLE_DISPLAY_MODULE -DFBSD_ENABLE_SD_UPDATER
build_flags=${env.build_flags} ${option_release.build_flags} -DFBSD_ENABLE_DISPLAY_MODULE -DFBSD_ENABLE_SD_UPDATER
lib_deps= ${env.lib_deps}
tobozo/M5Stack-SD-Updater @1.2.5
board_build.partitions = min_spiffs.csv

; For profiling
[env:profile]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_debug.build_flags} -DENABLE_PROFILE

; For logging
[env:log]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_log.build_flags}

; For debug
[env:debug]
board = m5stack-core-esp32
build_type=debug
build_flags=${env.build_flags} ${option_debug.build_flags} -DENABLE_PROFILE

;----
;For CoreS3
; For CoreS3
[env:S3_release]
board = esp32s3box
board_build.arduino.memory_type = qio_qspi
upload_speed = 1500000
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE
build_flags=${env.build_flags} ${option_release.build_flags}

[env:S3_release_DisplayModule]
board = esp32s3box
board_build.arduino.memory_type = qio_qspi
upload_speed = 1500000
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE -DFBSD_ENABLE_DISPLAY_MODULE
build_flags=${env.build_flags} ${option_release.build_flags} -DFBSD_ENABLE_DISPLAY_MODULE

[env:S3_profile]
board = esp32s3box
board_build.arduino.memory_type = qio_qspi
upload_speed = 1500000
build_type=release
build_flags=${env.build_flags} ${option_release.build_flags} -DENABLE_PROFILE

[env:S3_log]
board = esp32s3box
board_build.arduino.memory_type = qio_qspi
upload_speed = 1500000
build_type=release
build_flags=${env.build_flags} ${option_log.build_flags}

[env:S3_debug]
board = esp32s3box
board_build.arduino.memory_type = qio_qspi
upload_speed = 1500000
build_type=debug
build_flags=${env.build_flags} ${option_debug.build_flags} -DENABLE_PROFILE
build_flags=${env.build_flags} ${option_debug.build_flags} -DENABLE_PROFILE
Loading

0 comments on commit f831f3f

Please sign in to comment.