Important: unclear posts may not receive useful answers.
Description
What MCU/Processor/Board and compiler are you using?
radxa zero 3E (rk3566)
What LVGL version are you using?
version=9.3.0-dev
What do you want to achieve?
improve FPS with rockchip Media Process Platform (MPP) with LVGL.
What have you tried so far?
I compiled the ffmpeg with codec support from nyanmisaka repo
And validate Using basics commands to display a full-hd mp4 (h264) video.
(I don`t care about audio)
ffplay -codec:v h264_rkmpp -an ~/video/video.mp4 -loop 0
and logging with
watch -n1 cat /proc/mpp_service/sessions-summary
and alls works great. “low” cpu usage and fluid video.
Now with LVGL.
Code to reproduce
Using lv_port_linux with wayland (tested on sdl and x11 too)
/*******************************************************************
*
* main.c - LVGL simulator for GNU/Linux
*
* Based on the original file from the repository
*
* @note eventually this file won't contain a main function and will
* become a library supporting all major operating systems
*
* To see how each driver is initialized check the
* 'src/lib/display_backends' directory
*
* - Clean up
* - Support for multiple backends at once
* 2025 EDGEMTech Ltd.
*
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
******************************************************************/
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
#include <sched.h>
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "src/lib/driver_backends.h"
#include "src/lib/simulator_util.h"
#include "src/lib/simulator_settings.h"
#define PATH_PREFIX "/home/elmer/Downloads/videos/"
/* Internal functions */
static void configure_simulator(int argc, char **argv);
static void print_lvgl_version(void);
static void print_usage(void);
/* contains the name of the selected backend if user
* has specified one on the command line */
static char *selected_backend;
/* Global simulator settings, defined in lv_linux_backend.c */
extern simulator_settings_t settings;
lv_obj_t * player_video;
/**
* @brief Print LVGL version
*/
static void print_lvgl_version(void)
{
fprintf(stdout, "%d.%d.%d-%s\n",
LVGL_VERSION_MAJOR,
LVGL_VERSION_MINOR,
LVGL_VERSION_PATCH,
LVGL_VERSION_INFO);
}
/**
* @brief Print usage information
*/
static void print_usage(void)
{
fprintf(stdout, "\nlvglsim [-V] [-B] [-b backend_name] [-W window_width] [-H window_height]\n\n");
fprintf(stdout, "-V print LVGL version\n");
fprintf(stdout, "-B list supported backends\n");
}
/**
* @brief Configure simulator
* @description process arguments recieved by the program to select
* appropriate options
* @param argc the count of arguments in argv
* @param argv The arguments
*/
static void configure_simulator(int argc, char **argv)
{
int opt = 0;
char *backend_name;
selected_backend = NULL;
driver_backends_register();
/* Default values */
// TODO: take the screen size from the environment variable
settings.window_width = atoi(getenv("LV_SIM_WINDOW_WIDTH") ? : "1080");
settings.window_height = atoi(getenv("LV_SIM_WINDOW_HEIGHT") ? : "1920");
/* Parse the command-line options. */
while ((opt = getopt (argc, argv, "b:fmW:H:BVh")) != -1) {
switch (opt) {
case 'h':
print_usage();
exit(EXIT_SUCCESS);
break;
case 'V':
print_lvgl_version();
exit(EXIT_SUCCESS);
break;
case 'B':
driver_backends_print_supported();
exit(EXIT_SUCCESS);
break;
case 'b':
if (driver_backends_is_supported(optarg) == 0) {
die("error no such backend: %s\n", optarg);
}
selected_backend = strdup(optarg);
break;
case 'W':
settings.window_width = atoi(optarg);
break;
case 'H':
settings.window_height = atoi(optarg);
break;
case ':':
print_usage();
die("Option -%c requires an argument.\n", optopt);
break;
case '?':
print_usage();
die("Unknown option -%c.\n", optopt);
}
}
}
/**
* @brief entry point
* @description start a demo
* @param argc the count of arguments in argv
* @param argv The arguments
*/
int main(int argc, char **argv)
{
configure_simulator(argc, argv);
lv_init();
/* Initialize the configured backend */
if (driver_backends_init_backend(selected_backend) == -1) {
die("Failed to initialize display backend");
}
/* Enable for EVDEV support */
#if LV_USE_EVDEV
if (driver_backends_init_backend("EVDEV") == -1) {
die("Failed to initialize evdev");
}
#endif
lv_obj_t * player = lv_ffmpeg_player_create(lv_screen_active());
lv_ffmpeg_player_set_src(player, "/home/toletus/videos/video");
lv_ffmpeg_player_set_auto_restart(player, true);
lv_ffmpeg_player_set_cmd(player, LV_FFMPEG_PLAYER_CMD_START);
lv_obj_center(player);
driver_backends_run_loop();
return 0;
}
And got 8 fps 100% cpu usage with the same video
and no registry on the mpp summary
watch -n0.1 cat /proc/mpp_service/sessions-summary
so I modifyed the ffmpeg_open_codec_context
on lv_ffmpeg.c
to open h264 rkmpp decoder
static int ffmpeg_open_codec_context(int * stream_idx,
AVCodecContext ** dec_ctx, AVFormatContext * fmt_ctx,
enum AVMediaType type)
{
int ret;
int stream_index;
AVStream * st;
const AVCodec * dec = NULL;
AVDictionary * opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if(ret < 0) {
LV_LOG_ERROR("Could not find %s stream in input file",
av_get_media_type_string(type));
return ret;
}
else {
stream_index = ret;
st = fmt_ctx->streams[stream_index];
/* find decoder for the stream */
if(st->codecpar->codec_id == AV_CODEC_ID_H264){
LV_LOG_USER("\n ############### Using Rockchip codec! ###############\n");
dec = avcodec_find_decoder_by_name("h264_rkmpp");
}
else{
LV_LOG_USER("\n ############### Using standard codec! ###############\n");
dec = avcodec_find_decoder(st->codecpar->codec_id);
}
if(dec == NULL) {
LV_LOG_ERROR("Failed to find %s codec",
av_get_media_type_string(type));
return AVERROR(EINVAL);
}
/* Allocate a codec context for the decoder */
*dec_ctx = avcodec_alloc_context3(dec);
if(*dec_ctx == NULL) {
LV_LOG_ERROR("Failed to allocate the %s codec context",
av_get_media_type_string(type));
return AVERROR(ENOMEM);
}
/* Copy codec parameters from input stream to output codec context */
if((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) {
LV_LOG_ERROR(
"Failed to copy %s codec parameters to decoder context",
av_get_media_type_string(type));
return ret;
}
/* Init the decoders */
if((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) {
LV_LOG_ERROR("Failed to open %s codec",
av_get_media_type_string(type));
return ret;
}
*stream_idx = stream_index;
}
return 0;
}
output log
Couldn't open plugin directory: No such file or directory
No plugins found, falling back on no decorations
[User] (2.223, +2223) init_pointer_evdev: Using evdev automatic discovery. evdev.c:161
... evdev discovery log
[User] (2.225, +0) discovery_cb: new 'REL' device discovered evdev.c:110
[User] (2.317, +92) ffmpeg_open_codec_context:
############### Using Rockchip codec! ###############
lv_ffmpeg.c:573
mpp[35594]: mpp_info: mpp version: unknown mpp version for missing VCS info
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/toletus/videos/video':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41isomavc1
creation_time : 2020-06-16T19:32:12.000000Z
Duration: 00:00:14.64, start: 0.000000, bitrate: N/A
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1066x1920, 5583 kb/s, 25 fps, 25 tbr, 25 tbn (default)
Metadata:
creation_time : 2020-06-16T19:32:12.000000Z
handler_name : L-SMASH Video Handler
vendor_id : [0][0][0][0]
encoder : AVC Coding
an I got a variation fps from 8 to 16 fps but with frame drop and registry on the mpp summary
Screenshot and video
with standard lvgl source (automatic decoder).
with modified lvgl source (rockchip codec)
So, any idea how can I improve this?