From 120dee8b789313bea70f834fcfa1fa83bf443fa8 Mon Sep 17 00:00:00 2001 From: echo-lalia <108598670+echo-lalia@users.noreply.github.com> Date: Sat, 23 Aug 2025 11:25:20 -0700 Subject: [PATCH 1/3] Attempt to address SDCard speed limits --- player/platformio.ini | 4 +++ player/src/AVIParser/AVIParser.cpp | 31 +++++++++++++++----- player/src/AVIParser/AVIParser.h | 2 +- player/src/VideoSource/SDCardVideoSource.cpp | 15 ++++++---- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/player/platformio.ini b/player/platformio.ini index c3ab644..51c4afc 100644 --- a/player/platformio.ini +++ b/player/platformio.ini @@ -168,6 +168,8 @@ build_flags = -DSD_CARD_MOSI=GPIO_NUM_23 -DSD_CARD_CLK=GPIO_NUM_18 -DSD_CARD_CS=GPIO_NUM_5 + ; increase file buffer size to prevent playback stalling on SD Card read + -DFILE_BUFFER_SIZE=16384 [env:touch-down] extends = esp32_common @@ -235,6 +237,8 @@ build_flags = -DSD_CARD_MOSI=GPIO_NUM_15 -DSD_CARD_CLK=GPIO_NUM_13 -DSD_CARD_CS=GPIO_NUM_2 + ; increase file buffer size to prevent playback stalling on SD Card read + -DFILE_BUFFER_SIZE=16384 [env:m5core2] extends = esp32_common diff --git a/player/src/AVIParser/AVIParser.cpp b/player/src/AVIParser/AVIParser.cpp index 798b9dd..bb31818 100644 --- a/player/src/AVIParser/AVIParser.cpp +++ b/player/src/AVIParser/AVIParser.cpp @@ -60,6 +60,13 @@ bool AVIParser::isMoviListChunk(unsigned int chunkSize) bool AVIParser::open() { mFile = fopen(mFileName.c_str(), "rb"); + + #ifdef FILE_BUFFER_SIZE + // Increase size of file buffer if needed. + Serial.printf("Setting file buffer size to %d bytes.\n", FILE_BUFFER_SIZE); + setvbuf(mFile, NULL, _IOFBF, FILE_BUFFER_SIZE); + #endif + if (!mFile) { Serial.printf("Failed to open file.\n"); @@ -129,7 +136,7 @@ bool AVIParser::open() return true; } -size_t AVIParser::getNextChunk(uint8_t **buffer, size_t &bufferLength) +size_t AVIParser::getNextChunk(uint8_t **buffer, size_t &bufferLength, bool skipRead) { // check if the file is open if (!mFile) @@ -153,14 +160,22 @@ size_t AVIParser::getNextChunk(uint8_t **buffer, size_t &bufferLength) if (mRequiredChunkType == AVIChunkType::VIDEO && isVideoChunk || mRequiredChunkType == AVIChunkType::AUDIO && isAudioChunk) { - // we've got the required chunk - copy it into the provided buffer - // reallocate the buffer if necessary - if (header.chunkSize > bufferLength) - { - *buffer = (uint8_t *)realloc(*buffer, header.chunkSize); + // we've got the required chunk + if (skipRead) + { // skip over this chunk + fseek(mFile, header.chunkSize, SEEK_CUR); + } + else + { // copy this chunk into the provided buffer + // reallocate the buffer if necessary + if (header.chunkSize > bufferLength) + { + *buffer = (uint8_t *)realloc(*buffer, header.chunkSize); + bufferLength = header.chunkSize; + } + // copy the chunk data + fread(*buffer, header.chunkSize, 1, mFile); } - // copy the chunk data - fread(*buffer, header.chunkSize, 1, mFile); mMoviListLength -= header.chunkSize; // handle any padding bytes if (header.chunkSize % 2 != 0) diff --git a/player/src/AVIParser/AVIParser.h b/player/src/AVIParser/AVIParser.h index 5aef56f..cb21c91 100644 --- a/player/src/AVIParser/AVIParser.h +++ b/player/src/AVIParser/AVIParser.h @@ -20,5 +20,5 @@ class AVIParser AVIParser(std::string fname, AVIChunkType requiredChunkType); ~AVIParser(); bool open(); - size_t getNextChunk(uint8_t **buffer, size_t &bufferLength); + size_t getNextChunk(uint8_t **buffer, size_t &bufferLength, bool skipRead=false); }; \ No newline at end of file diff --git a/player/src/VideoSource/SDCardVideoSource.cpp b/player/src/VideoSource/SDCardVideoSource.cpp index 9d8ae38..acf73f2 100644 --- a/player/src/VideoSource/SDCardVideoSource.cpp +++ b/player/src/VideoSource/SDCardVideoSource.cpp @@ -38,15 +38,18 @@ bool SDCardVideoSource::getVideoFrame(uint8_t **buffer, size_t &bufferLength, si // work out the video time from a combination of the currentAudioSample and the elapsed time int elapsedTime = millis() - mLastAudioTimeUpdateMs; int videoTime = mAudioTimeMs + elapsedTime; - int frameTime = 1000 * mFrameCount / DEFAULT_FPS; - if (videoTime <= frameTime) - { + int targetFrame = videoTime * DEFAULT_FPS / 1000; + if (mFrameCount >= targetFrame){ return false; } - while (videoTime > 1000 * mFrameCount / DEFAULT_FPS) - { + // Skip some number of frames if we have fallen behind + while (targetFrame - mFrameCount > 1){ mFrameCount++; - frameLength = parser->getNextChunk((uint8_t **)buffer, bufferLength); + frameLength = parser->getNextChunk((uint8_t **)buffer, bufferLength, true); } + // We are caught up to targetFrame-1, so load the next frame to show. + mFrameCount++; + frameLength = parser->getNextChunk((uint8_t **)buffer, bufferLength); + return true; } From d3e6527475b27b828139cd85d922b254159966a8 Mon Sep 17 00:00:00 2001 From: echo-lalia <108598670+echo-lalia@users.noreply.github.com> Date: Sat, 23 Aug 2025 12:09:54 -0700 Subject: [PATCH 2/3] Null check before setvbuf --- player/src/AVIParser/AVIParser.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/player/src/AVIParser/AVIParser.cpp b/player/src/AVIParser/AVIParser.cpp index bb31818..bec86dc 100644 --- a/player/src/AVIParser/AVIParser.cpp +++ b/player/src/AVIParser/AVIParser.cpp @@ -60,18 +60,16 @@ bool AVIParser::isMoviListChunk(unsigned int chunkSize) bool AVIParser::open() { mFile = fopen(mFileName.c_str(), "rb"); - - #ifdef FILE_BUFFER_SIZE - // Increase size of file buffer if needed. - Serial.printf("Setting file buffer size to %d bytes.\n", FILE_BUFFER_SIZE); - setvbuf(mFile, NULL, _IOFBF, FILE_BUFFER_SIZE); - #endif - if (!mFile) { Serial.printf("Failed to open file.\n"); return false; } + #ifdef FILE_BUFFER_SIZE + // Increase size of file buffer if needed. + Serial.printf("Setting file buffer size to %d bytes.\n", FILE_BUFFER_SIZE); + setvbuf(mFile, NULL, _IOFBF, FILE_BUFFER_SIZE); + #endif // check the file is valid ChunkHeader header; // Read RIFF header From 5739b15b23faafbe24214761d0e3d06fc7940803 Mon Sep 17 00:00:00 2001 From: echo-lalia <108598670+echo-lalia@users.noreply.github.com> Date: Sat, 23 Aug 2025 12:19:48 -0700 Subject: [PATCH 3/3] Error return in getVideoFrame --- player/src/VideoSource/SDCardVideoSource.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/player/src/VideoSource/SDCardVideoSource.cpp b/player/src/VideoSource/SDCardVideoSource.cpp index acf73f2..a8860b0 100644 --- a/player/src/VideoSource/SDCardVideoSource.cpp +++ b/player/src/VideoSource/SDCardVideoSource.cpp @@ -44,12 +44,19 @@ bool SDCardVideoSource::getVideoFrame(uint8_t **buffer, size_t &bufferLength, si } // Skip some number of frames if we have fallen behind while (targetFrame - mFrameCount > 1){ + size_t skipped = parser->getNextChunk(buffer, bufferLength, true); + if (skipped == 0) { + // No more data or error — bail without advancing the frame counter. + return false; + } mFrameCount++; - frameLength = parser->getNextChunk((uint8_t **)buffer, bufferLength, true); } // We are caught up to targetFrame-1, so load the next frame to show. + frameLength = parser->getNextChunk(buffer, bufferLength); + if (frameLength == 0){ + return false; + } mFrameCount++; - frameLength = parser->getNextChunk((uint8_t **)buffer, bufferLength); return true; }