Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
GOB52 committed Nov 25, 2023
2 parents 9e508b0 + 3840c96 commit f628545
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 66 deletions.
16 changes: 11 additions & 5 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ This application playback streams movie files that converted to the dedicated fo
It uses multi-cores to perform rendering with DMA and audio playback.
***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
It must be able to run the libraries it depends on and have an SD card.
* M5Stack Basic 2.6 or later
Expand Down Expand Up @@ -52,7 +51,10 @@ It must be able to run the libraries it depends on and have an SD card.
|S3\_release_DisplayModule| Support DisplayModule |

### Sample data for playback
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.
Download [sample_0_1_1.zip](https://github.com/GOB52/M5Stack_FlipBookSD/files/11871296/sample_0_1_1.zip), unzip it and copy to **/gmv** on your SD card.




## How to make data
### Required tools
Expand All @@ -79,17 +81,17 @@ Movie data can be in any format that can be processed by FFmpeg.
|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 "movie\_file\_name.gmv" output to same directory.
5. Copy the above files to **/gcf** on the SD card.
5. Copy the above files to **/gmv** on the SD card.

e.g.)
```sh
mkdir foo
cp bar.mp4 foo
cp script/conv.sh foo
cp script/gcf.py foo
cp script/gmv.py foo
cd foo
bash conv.sh bar.mp4 29.97
cp bar.gmv your_sd_card_path/gcf
cp bar.gmv your_sd_card_path/gmv
```

### Processes performed by shell scripts
Expand Down Expand Up @@ -121,6 +123,10 @@ To change the image size, edit the parameter for FFmpeg in conv.sh. **(scale=)**
* Image size and output device size
If the image size is narrower or wider than the output device size, it will be centered.

### Movie data search
Searches for files in **/gmv**. If it does not exist, the old version **/gcf** is searched.
If both exist, only /gmv is searched.

## 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.
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ SINTEL (Trailer)
|S3\_release_DisplayModule| ディスプレイモジュール 対応|

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

## データの作成方法
### 必要なもの
Expand All @@ -77,17 +77,17 @@ SINTEL (Trailer)
|jpeg\_maximum\_size|NO|JPEG 1枚あたりの最大ファイルサイズ( 1024 - 10240)<br>大きいと品質が維持されるが処理遅延が発生する可能性が高くなる(既知の問題参照)|

4. 動画ファイル名.gmv が出力される。
5. gmv ファイルを SD カードの **/gcf** にコピーする。
5. gmv ファイルを SD カードの **/gmv** にコピーする。

例)
```sh
mkdir foo
cp bar.mp4 foo
cp script/conv.sh foo
cp script/gcf.py foo
cp script/gmv.py foo
cd foo
bash conv.sh bar.mp4 29.97
cp bar.gmv your_sd_card_path/gcf
cp bar.gmv your_sd_card_path/gmv
```

### シェルスクリプトで行っている事
Expand Down Expand Up @@ -119,6 +119,11 @@ FFMpeg が扱う事ができないフォーマットはサポートされませ
* 画像サイズと出力先サイズ
画像データが出力先サイズに満たない、または逸脱する場合は、センタリングして表示されます。

### データの検索
**/gmv** 内のファイルを探索します。もし存在しない場合は旧版の **/gcf** 内を検索します。
両方存在する場合は /gmv のみ対象となります。


## 既知の問題
### 音声が途切れる、再生速度が遅い
1 フレーム内での処理が間に合っていないことが原因です。
Expand Down Expand Up @@ -187,7 +192,7 @@ cp script/gcf_to_gmv.py gcf_dir
cp script/convert_gcf_to_gmv.sh gcf_dir
cd gcf_dir
bash convert_gcf_to_gmv.sh
cp *.gmv your_sd_card_path/gcf
cp *.gmv your_sd_card_path/gmv
```

## 余談
Expand Down
6 changes: 3 additions & 3 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ board_build.f_flash = 80000000L

lib_deps = m5stack/M5Unified @ 0.1.10
greiman/SdFat @ 2.2.2
gob/gob_unifiedButton @ ^0.1.0
gob/gob_unifiedButton
lib_ldf_mode = deep

monitor_speed = 115200
Expand Down Expand Up @@ -88,7 +88,7 @@ board_build.partitions = min_spiffs.csv
[env:profile]
board = m5stack-core-esp32
build_type=release
build_flags=${env.build_flags} ${option_debug.build_flags} -DENABLE_PROFILE
build_flags=${env.build_flags} ${option_log.build_flags} -DENABLE_PROFILE

; For logging
[env:log]
Expand Down Expand Up @@ -123,7 +123,7 @@ 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_log.build_flags} -DENABLE_PROFILE

[env:S3_log]
board = esp32s3box
Expand Down
30 changes: 2 additions & 28 deletions src/file_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ uint32_t FileList::make(const char* base, const char* ext)
_base = base;
_cur = 0;
_list.clear();

M5_LOGI("base dir:[%s]", base);

FsFile dir;
Expand All @@ -44,36 +44,10 @@ uint32_t FileList::make(const char* base, const char* ext)

M5_LOGD("list:[%s]", path);
_list.emplace_back(path);
++_files;
f.close();
}
sort();
return _files;
}

uint32_t FileList::append(const char* ext)
{
auto psize = _files;

FsFile dir;
if(!dir.open(_base.c_str())) { return 0; }

FsFile f;
while(f.openNext(&dir, O_RDONLY))
{
if(f.isDir()) { continue; }

char path[256];
f.getName(path, sizeof(path));
if(path[0] == '.' || getExt(path) != ext) { continue; }

M5_LOGD("list:[%s]", path);
_list.emplace_back(path);
++_files;
f.close();
}
sort();
return _files - psize;
return _list.size();
}

void FileList::shuffle()
Expand Down
4 changes: 1 addition & 3 deletions src/file_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ class FileList
FileList();

uint32_t make(const char* base, const char* ext = "gcf");
uint32_t append(const char* ext = "gcf");

inline int32_t current() const { return _cur; }
inline int32_t files() const { return _files; }
inline int32_t files() const { return _list.size(); }

String getCurrent() const { return _cur < _list.size() ? _list[_cur] : String(""); }
String getCurrentFullpath() const
Expand Down Expand Up @@ -45,7 +44,6 @@ class FileList
String _base{"/"};
std::vector<String> _list{};
int32_t _cur{};
int32_t _files{};
bool _shuffle{};
};
#endif
47 changes: 25 additions & 22 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ void sleepUntil(const std::chrono::time_point<ESP32Clock, UpdateDuration>& absTi
auto& display = M5.Display;
SdFs sd;

uint8_t volume{72}; // 0~255
uint8_t volume{}; // 0~255
uint32_t currentFrame{}, maxFrames{};
uint32_t loadCycle{}, drawCycle{}, wavCycle{};
uint32_t loadCycleTotal{}, drawCycleTotal{}, wavCycleTotal{};
bool primaryDisplay{};

MainClass mainClass;
Expand All @@ -110,7 +111,7 @@ gob::GMVFile gmv{};
uint8_t* buffers[NUMBER_OF_BUFFERS]; // For 1 of JPEG and wav block
uint32_t bufferIndex{}, outIndex{}, jpegSize{}, wavSize{}, wavTotal{};

goblib::UnifiedButton unfiedButton;
goblib::UnifiedButton unifiedButton;

enum class PlayType : int8_t { Single, RepeatSingle, RepeatAll, Shuffle };
PlayType& operator++(PlayType& pt)
Expand Down Expand Up @@ -197,6 +198,7 @@ static bool playMovie(const String& path, const bool bus = true)
{
M5.Speaker.stop();
wavTotal = currentFrame = maxFrames = 0;
loadCycleTotal = wavCycleTotal = drawCycleTotal = 0;
clearFpsQueue();

if(gmv) { gmv.close(); }
Expand Down Expand Up @@ -278,9 +280,7 @@ void setup()
M5.Speaker.config(spk_cfg);

M5_LOGI("Output to %s", primaryDisplay ? "Display" : "Lcd");
if(M5.getBoard() == m5::board_t::board_M5Stack) { volume = 144; }
if(primaryDisplay) { volume = 128; }
M5.Speaker.setVolume(volume);
volume = M5.Speaker.getVolume();

#if defined(FBSD_ENABLE_SD_UPDATER)
// SD-Updater
Expand All @@ -306,10 +306,14 @@ void setup()
M5.BtnA.setHoldThresh(500);
M5.BtnB.setHoldThresh(500);
M5.BtnC.setHoldThresh(500);
unfiedButton.begin(&display);
unifiedButton.begin(&display);

// file list
list.make("/gcf", "gmv");
// file list (Search "/gcf" if "/gmv" is empty or not exists.)
if(list.make("/gmv", "gmv") == 0)
{
M5_LOGI("Research directory gcf");
list.make("/gcf", "gmv");
}

// Allocate buffer
for(auto& buf : buffers)
Expand Down Expand Up @@ -349,7 +353,7 @@ static void loopMenu()
if(playMovie(list.getCurrentFullpath()))
{
loop_f = loopRender;
unfiedButton.changeAppearance(goblib::UnifiedButton::appearance_t::transparent_all);
unifiedButton.changeAppearance(goblib::UnifiedButton::appearance_t::transparent_all);
lastTime = ESP32Clock::now();
return;
}
Expand Down Expand Up @@ -388,30 +392,24 @@ static void loopMenu()
display.drawString(str, display.width()/2, display.height()/2 + 16);
display.drawString(ptTable[(int8_t)playType], display.width()/2, display.height()/2 + 48);

unfiedButton.draw(dirty);
unifiedButton.draw(dirty);
}

static void changeToMenu()
{
M5.Speaker.stop();
loop_f = loopMenu;
unfiedButton.changeAppearance(goblib::UnifiedButton::appearance_t::bottom);
unifiedButton.changeAppearance(goblib::UnifiedButton::appearance_t::bottom);
display.clear(0);

}

// Render to lcd directly with DMA
static void loopRender()
{
static int32_t showVolume{};
static float afps{};

#if defined(DEBUG)
if(showVolume-- >= 0)
{
display.fillRect(0, 0, display.width(), 4, TFT_BLACK);
if(showVolume >0) { display.fillRect(0, 0, display.width() * (volume / 255.0f), 4, TFT_BLUE); }
}
display.setCursor(0, 4);
display.printf("F:%2.2f C:%u", afps, currentFrame);
#endif
Expand All @@ -423,8 +421,8 @@ static void loopRender()
display.endWrite();

// Change volume
if(M5.BtnA.isPressed()) { if(volume > 0) { M5.Speaker.setVolume(--volume); showVolume = BASE_FPS;} }
if(M5.BtnC.isPressed()) { if(volume < 255) { M5.Speaker.setVolume(++volume); showVolume = BASE_FPS;} }
if(M5.BtnA.isPressed()) { if(volume > 0) { M5.Speaker.setVolume(--volume); }}
if(M5.BtnC.isPressed()) { if(volume < 255) { M5.Speaker.setVolume(++volume); }}
// Stop
if(M5.BtnB.wasClicked()) { changeToMenu(); return; }

Expand All @@ -435,6 +433,7 @@ static void loopRender()
{
case PlayType::RepeatAll:
case PlayType::Shuffle:
M5_LOGD("Total: %u / %u / %u", loadCycleTotal, wavCycleTotal, drawCycleTotal);
M5_LOGI("To next file");
list.next();
// fallthrough
Expand Down Expand Up @@ -473,7 +472,7 @@ static void loopRender()
M5.Speaker.playRaw(buf, wavSize, wh.sample_rate, wh.channel >= 2, 1, 0);
}
wavTotal += wavSize;
M5_LOGD("outIdx:%u jsz:%u wsz:%u/%u", outIndex, jpegSize, wavSize, wavTotal);
M5_LOGV("outIdx:%u jsz:%u wsz:%u/%u", outIndex, jpegSize, wavSize, wavTotal);
}

auto now = ESP32Clock::now();
Expand All @@ -482,14 +481,18 @@ static void loopRender()
fps = BASE_FPS / std::chrono::duration_cast<UpdateDuration>(delta).count();
pushFpsQueue(fps);
afps = averageFps();
M5_LOGD("%5d/%5d %2.2f/%2.2f %u/%u/%u", currentFrame, maxFrames, fps, afps, loadCycle, wavCycle, drawCycle);
uint32_t addCycle = loadCycle + wavCycle + drawCycle;
loadCycleTotal += loadCycle;
wavCycleTotal += wavCycle;
drawCycleTotal += drawCycle;
M5_LOGD("%5d/%5d %2.2f/%2.2f %u/%u/%u [%u]", currentFrame, maxFrames, fps, afps, loadCycle, wavCycle, drawCycle, addCycle);
}

//
void loop()
{
M5.update();
unfiedButton.update();
unifiedButton.update();
loop_f();
}

0 comments on commit f628545

Please sign in to comment.