Been working on this off and on for a while. KurtE posted some code that was a big help on getting this to work. It stores decoded jpeg to SDRAM GFX Canvas, then writes to screen. Configured Mjpeg to use a large SDRAM buffer which seemed to help considerably.
Haven't been able to play Mjpegs from USB yet, code fails because of incompatibility between USB Mbed5 file class and Stream class. Maybe someone can help out with this.
Edit: I solved this problem today, see post #2.
Download Zip, it has all the code and media.
Giga_Display_SDFat_USB_SDRAMGFXCanvas.zip (7.6 MB)
You can touch screen to toggle SD - USB devices.
Here's the main .ino
#include <Arduino_GigaDisplay_GFX.h>
#include <Arduino_USBHostMbed5.h>
#include <DigitalOut.h>
#include <FATFileSystem.h>
#include <SdFat.h>
#include "Arduino_GigaDisplayTouch.h"
#include <elapsedMillis.h>
#include "WrapperFile.h"
#include "SDRAMGFXcanvas.h"
#include "JPEGDEC.h"
#include "MjpegClass.h"
static MjpegClass mjpeg;
REDIRECT_STDOUT_TO(Serial)
GigaDisplay_GFX tft;
Adafruit_GFX *pgfx = &tft;
SDRAMGFXcanvas16 canvas(800, 480); // Allocate canvas in SDRAM
#define sd_chipSelect 53 // Card select for shield use
#define ENABLE_DEDICATED_SPI 1
#define SD_FAT_TYPE 3
//SdFat SD; File file; File dirFile; //SD_FAT_TYPE 0
//SdFat32 SD; File32 file; //SD_FAT_TYPE 1
//SdExFat SD; ExFile file; ExFile dirFile; //SD_FAT_TYPE 2
SdFs SD; FsFile file; FsFile dirFile; //SD_FAT_TYPE 3
USBHostMSD msd;
mbed::FATFileSystem usb("usb");
DIR *root_USB = nullptr;
#define USB_DRIVE 0x01
#define SD_DRIVE 0x04
uint8_t g_current_device = 0;
int g_display_image_time = 2000;
int g_tft_width = 0;
int g_tft_height = 0;
JPEGDEC jpeg;
Arduino_GigaDisplayTouch touchDetector;
bool changedDevice = false;
void gigaTouchHandler(uint8_t contacts, GDTpoint_t* points) {
//Serial.print("Contacts: "); Serial.println(contacts);
if (contacts > 0) {
//Serial.print(points[0].x); Serial.print(" "); Serial.println(points[0].y);
if (g_current_device == SD_DRIVE) {
g_current_device = USB_DRIVE;
Serial.print("Switched to USB_DRIVE: ");
}
else {
g_current_device = SD_DRIVE;
Serial.print("Switched to SD_DRIVE: ");
}
Serial.println(g_current_device, HEX);
changedDevice = true;
delay(200);
}
else changedDevice = false;
}
void setup() {
Serial.begin(115200);
SDRAM.begin();
tft.begin(); // start the display
tft.setRotation(1); // set up text to display horizonal in the display
tft.fillScreen(0);
if (touchDetector.begin()) {
Serial.println("Touch controller init - OK");
} else {
Serial.println("Touch controller init - FAILED");
while(1) ;
}
touchDetector.onDetect(gigaTouchHandler);
Serial.print("Initializing SD card...");
//if (!SD.begin()) {
if (!SD.begin(sd_chipSelect, SD_SCK_MHZ(160))) {
Serial.println("initialization failed!");
tft.setCursor(10, tft.height()-180);
tft.print(" SD INIT. FAILED...");
delay(2000);
}
else Serial.println("initialization done.");
while (!msd.connect()) {
//while (!port.connected()) {
delay(100);
}
Serial.print("Mounting USB device... ");
int err = usb.mount(&msd);
if (err) {
Serial.print("Error mounting USB device ");
Serial.println(err);
//while (1);
}
canvas.begin();
Serial.print("Canvas buffer: ");
Serial.println((uint32_t)canvas.getBuffer(), HEX);
pgfx = &canvas;
g_tft_width = tft.width();
g_tft_height = tft.height();
//g_current_device = USB_DRIVE;
g_current_device = SD_DRIVE;
Serial.println("Current Device: SD_DRIVE");
Serial.println("Touch screen to toggle SD USB devices...");
}
void loop() {
tft.fillScreen(0);
tft.setRotation(1);
int x = tft.width ()/2 - 320/2; // Center mjpeg width
int y = tft.height()/2 - 320/2; // Center mjpeg height
drawMjpeg("/Mjpeg/Drone.mjpeg", x, y); //This mjpeg is 320x320
for (int i = 0; i < 5; i++) {
drawJpeg("TheyLive1.jpg", 0, 0);
drawJpeg("TheyLive2.jpg", 0, 0);
}
fetchDirFiles("/Jpg800x480L", 0, 0, 0, 0);
}
void drawJpeg(char* jpegName, int x, int y) {
elapsedMillis em;
char fullPath[512];
File jpegFile;
FILE* jFile;
WrapperFile wpfImage;
if(changedDevice){changedDevice=0;return;}
if (g_current_device == SD_DRIVE) {
strcpy(fullPath, "/");
strcat(fullPath, jpegName);
jpegFile = SD.open(fullPath, FILE_READ);
wpfImage.setFile(jpegFile);
}
if (g_current_device == USB_DRIVE) {
strcpy(fullPath, "/usb/");
strcat(fullPath, jpegName);
jFile = fopen(fullPath, "rb");
if (!jFile) Serial.println("USB file not found!");
wpfImage.setFile(jFile);
}
Serial.println(" "); Serial.println(fullPath);
processJPGFile(wpfImage, fullPath, true);
tft.drawRGBBitmap(0, 0, canvas.getBuffer(), tft.width(), tft.height());
Serial.print("Draw Time: "); Serial.println(em, DEC); Serial.print(" ");
if (g_current_device == SD_DRIVE) file.close();
if (g_current_device == USB_DRIVE) fclose(jFile);
}
void fetchDirFiles(char *dirName, int x, int y, int w, int h) {
int fCount = 1;
char filename[256];
char fullPath[512];
char dirUSB[512];
WrapperFile wpfImage;
FsFile imageFile;
FILE *jFile;
DIR* d;
struct dirent *dir_entry;
bool dirEnd = false;
if (g_current_device == SD_DRIVE) {
if (!dirFile.open(dirName, O_READ)) {
SD.errorHalt("Open directory failed");
}
}
if (g_current_device == USB_DRIVE) {
strcpy(dirUSB, "/usb");
strcat(dirUSB, dirName);
//Serial.println(dirUSB);
d = opendir(dirUSB);
}
while (!dirEnd) {
elapsedMillis drawTime;
if(changedDevice){changedDevice=0;return;}
if (g_current_device == SD_DRIVE) {
imageFile = dirFile.openNextFile();
if (!imageFile.isSubDir()) {
if (!imageFile) {dirEnd = true; break;}
sprintf(fullPath, "%s/", dirName);
imageFile.getName(filename, sizeof(filename));
strcat( fullPath, filename );
wpfImage.setFile(imageFile);
file.close();
}
}
if (g_current_device == USB_DRIVE) {
dir_entry = readdir(d);
if (!dir_entry) dirEnd = true;
strcpy(fullPath, dirUSB);
strcat(fullPath, "/");
strcat(fullPath, dir_entry->d_name);
jFile = fopen(fullPath, "r+");
wpfImage.setFile(jFile);
}
String strname = String(fullPath);
Serial.print("Image Filepath: "); Serial.println(fullPath);
if (strname.endsWith(".raw")) {
//drawRAW (fullPath, x, y, w, h);
}
if (strname.endsWith(".bin")) {
//drawRAW (fullPath, x, y, w, h);
}
if (strname.endsWith(".jpg")) {
processJPGFile(wpfImage, fullPath, true);
//drawJpeg(wpfImage, fullPath);
}
fCount++;
tft.drawRGBBitmap(0, 0, canvas.getBuffer(), tft.width(), tft.height());
Serial.print("Draw Time: "); Serial.println(drawTime, DEC);
if (g_current_device == SD_DRIVE) file.close();
if (g_current_device == USB_DRIVE) fclose(jFile);
}
Serial.println("End of Directory");
Serial.println(" ");
}
.