List below is briefly what I did:
- Capture an image from a MP4 file using OpenCV capture.
- Convert image to LVGL format (tested working).
- Display on screen through SDL2.
- Goto step 1 again.
The image displayed successfully for about 3 to 4 times before it crashes. I attach my codes below:
int main(int argc, char** argv)
{
// Initialise LVGL
lv_init();
// Initialise the HAL (display, input devices, tick) for LVGL
hal_init();
// Create a thread to keep the timer kicking
pthread_create(&th, NULL, tick, NULL);
display_video();
while(true)
{
sleep(1);
}
return 0;
}
static void* tick(void* ptr)
{
while(true)
{
// Periodically call the lv_task_handler().
// It could be done in a timer interrupt or an OS task too.
lv_tick_inc(1);
lv_timer_handler();
usleep(1 * 1000);
}
}
static void display_image(cv::Mat img)
{
static lv_obj_t* img_lv_obj = lv_img_create(lv_scr_act());
static lv_img_dsc_t img_bg;
if(!img.empty())
{
cv::resize(img, img, cv::Size(LV_HOR_RES, LV_VER_RES), cv::INTER_LINEAR);
// LVGL defines LV_COLOR_DEPTH as 16 in lv_conf.h
// This represents: Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)
// Hence we convert img from BGR to BGR565
// Although LVGL says RGB565, seems like OpenCV BGR565 works!!
cv::cvtColor(img, img, cv::COLOR_BGR2BGR565);
int dataSzLvgl = 40000 * LV_COLOR_SIZE / 8;
img_bg.header.always_zero = 0;
img_bg.header.w = img.cols;
img_bg.header.h = img.rows;
img_bg.data_size = dataSzLvgl;
img_bg.header.cf = LV_IMG_CF_TRUE_COLOR;
img_bg.data = img.data;
lv_img_set_src(img_lv_obj, &img_bg);
lv_obj_align(img_lv_obj, LV_ALIGN_CENTER, 0, -20);
}
else
{
cout << "Empty image. " << endl;
}
}
static void display_video(void)
{
cv::Mat frame;
cv::VideoCapture cap;
cap.open("people-train-station.mp4");
if(!cap.isOpened())
{
cout << "Open video error." << endl;
}
else
{
int i = 0;
while(true)
{
cout << "Reading a frame ..." << endl;
cap.read(frame);
if(!frame.empty())
{
display_image(frame);
}
else
{
cout << "No frame found." << endl;
break;
}
usleep(30*1000);
}
}
}
Thanks.