v4l2-uvm-test: use the prefered display mode

PD#SWPL-24309

Problem:
currently, the test app use the largest display mode
maybe is not same as the vout display mode.

Solution:
use the prefered display mode

Verify:
v4l2-uvm-test -f 4k.h265 -m 3840x2160 -p 26 -d 0
v4l2-uvm-test -f 4k.h265 -m 3840x2160-60 -p 26 -d 0
v4l2-uvm-test -f 1080p.h265 -m 1920x1080 -p 26 -d 0
v4l2-uvm-test -f 1080p.h265 -m 1920x1080-60 -p 26 -d 0

Change-Id: I4e5042899de9b10c055822372c6025b9fb219e6f
Signed-off-by: Ao Xu <ao.xu@amlogic.com>
diff --git a/v4l2-uvm-test/src/drm.c b/v4l2-uvm-test/src/drm.c
index 55c1320..0eac333 100644
--- a/v4l2-uvm-test/src/drm.c
+++ b/v4l2-uvm-test/src/drm.c
@@ -38,6 +38,8 @@
 static int drm_mode_set;
 static int secure_mode;
 extern unsigned int global_plane_id;
+extern char mode_str[16];
+extern unsigned int vfresh;
 
 struct gem_buffer {
     uint32_t width;
@@ -514,7 +516,7 @@
     drmModeConnector *connector = NULL;
     drmModeEncoder *encoder = NULL;
     int i, area;
-    drmModeModeInfo *curr_mode;
+    drmModeModeInfo *curr_mode = NULL;
 
 
     resources = drmModeGetResources(fd);
@@ -545,17 +547,37 @@
     setup.connector_id = connector->connector_id;
 
     /* find preferred mode or the highest resolution mode: */
-    for (i = 0, area = 0; i < connector->count_modes; i++) {
-        drmModeModeInfo *current_mode = &connector->modes[i];
 
-        if (current_mode->type & DRM_MODE_TYPE_PREFERRED) {
-            curr_mode = current_mode;
+    if (*mode_str) {
+        for (i = 0; i < connector->count_modes; i++) {
+            drmModeModeInfo *current_mode = &connector->modes[i];
+
+            if (current_mode->name && strcmp(current_mode->name, mode_str) == 0) {
+                if (vfresh == 0 || current_mode->vrefresh == vfresh) {
+                    curr_mode = current_mode;
+                    printf("found the request mode: %s-%d.\n", current_mode->name,
+                            current_mode->vrefresh);
+                    break;
+                }
+            }
         }
+    }
 
-        int current_area = current_mode->hdisplay * current_mode->vdisplay;
-        if (current_area > area) {
-            curr_mode = current_mode;
-            area = current_area;
+    if (!curr_mode) {
+        printf("requested mode not found, using default mode!\n");
+        for (i = 0, area = 0; i < connector->count_modes; i++) {
+            drmModeModeInfo *current_mode = &connector->modes[i];
+
+            if (current_mode->type & DRM_MODE_TYPE_PREFERRED) {
+                curr_mode = current_mode;
+                break;
+            }
+
+            int current_area = current_mode->hdisplay * current_mode->vdisplay;
+            if (current_area > area) {
+                curr_mode = current_mode;
+                area = current_area;
+            }
         }
     }
 
diff --git a/v4l2-uvm-test/src/test.c b/v4l2-uvm-test/src/test.c
index 9201e0b..4527f22 100644
--- a/v4l2-uvm-test/src/test.c
+++ b/v4l2-uvm-test/src/test.c
@@ -26,6 +26,8 @@
 static char* media_file;
 static sem_t wait_for_end;
 int global_plane_id;
+char mode_str[16];
+unsigned int vfresh;
 int g_dw_mode = 16;
 static int secure_mode = 0;
 int ffmpeg_log = 0;
@@ -44,13 +46,15 @@
                  "-f | --file name     media file\n"
                  "-h | --help          Print this message\n"
                  "-p | --plane=id      select display plane. 26[pri] 28[overlay 1] 30[overlay 2] 32[video]\n"
+                 "-m | --mode str      set display mode. such as 3840x2160 or 3840x2160-60\n"
+                 "                                               1920x1080 or 1920x1080-60\n"
                  "-l | --log           enable more ffmpeg demux log.\n"
                  "-s | --secure        secure video path.\n"
                  "",
                  argv[0]);
 }
 
-static const char short_options[] = "d:hf:p:ls";
+static const char short_options[] = "d:hf:p:m:ls";
 
 static const struct option
 long_options[] = {
@@ -58,6 +62,7 @@
         { "file", required_argument, NULL, 'f' },
         { "help",   no_argument,       NULL, 'h' },
         { "plane",  required_argument, NULL, 'p' },
+        { "mode", required_argument, NULL, 'm' },
         { "log",  no_argument, NULL, 'l' },
         { "secure",  no_argument, NULL, 's' },
         { 0, 0, 0, 0 }
@@ -81,6 +86,8 @@
 
 static int parse_para(int argc, char *argv[])
 {
+    char *p;
+    unsigned int len;
     for (;;) {
         int idx;
         int c;
@@ -127,6 +134,19 @@
                 secure_mode = 1;
                 break;
 
+            case 'm':
+                p = strchr(optarg, '-');
+                if (p == NULL) {
+                    len	= strlen(optarg);
+                } else {
+                    vfresh = strtoul(p + 1, NULL, 0);
+                    len = p - optarg;
+                }
+
+                strncpy(mode_str, optarg, len);
+                printf("mode:%s, vfresh:%d.\n", mode_str, vfresh);
+                break;
+
             default:
                 usage(argc, argv);
                 return -1;