xref: /aosp_15_r20/external/libkmsxx/utils/kmsview.cpp (revision f0687c8a10b3e371dbe09214db6664e37c283cca)
1 #include <cstdio>
2 #include <fstream>
3 #include <unistd.h>
4 #include <cassert>
5 
6 #include <kms++/kms++.h>
7 #include <kms++util/kms++util.h>
8 
9 using namespace std;
10 using namespace kms;
11 
read_frame(ifstream & is,DumbFramebuffer * fb,Crtc * crtc,Plane * plane)12 static void read_frame(ifstream& is, DumbFramebuffer* fb, Crtc* crtc, Plane* plane)
13 {
14 	for (unsigned i = 0; i < fb->num_planes(); ++i)
15 		is.read((char*)fb->map(i), fb->size(i));
16 
17 	unsigned w = min(crtc->width(), fb->width());
18 	unsigned h = min(crtc->height(), fb->height());
19 
20 	int r = crtc->set_plane(plane, *fb,
21 				0, 0, w, h,
22 				0, 0, fb->width(), fb->height());
23 
24 	ASSERT(r == 0);
25 }
26 
27 static const char* usage_str =
28 	"Usage: kmsview [options] <file> <width> <height> <fourcc>\n\n"
29 	"Options:\n"
30 	"  -c, --connector <name>	Output connector\n"
31 	"  -t, --time <ms>		Milliseconds to sleep between frames\n";
32 
usage()33 static void usage()
34 {
35 	puts(usage_str);
36 }
37 
main(int argc,char ** argv)38 int main(int argc, char** argv)
39 {
40 	uint32_t time = 0;
41 	string dev_path;
42 	string conn_name;
43 
44 	OptionSet optionset = {
45 		Option("c|connector=", [&conn_name](string s) {
46 			conn_name = s;
47 		}),
48 		Option("|device=", [&dev_path](string s) {
49 			dev_path = s;
50 		}),
51 		Option("t|time=", [&time](const string& str) {
52 			time = stoul(str);
53 		}),
54 		Option("h|help", []() {
55 			usage();
56 			exit(-1);
57 		}),
58 	};
59 
60 	optionset.parse(argc, argv);
61 
62 	vector<string> params = optionset.params();
63 
64 	if (params.size() != 4) {
65 		usage();
66 		exit(-1);
67 	}
68 
69 	string filename = params[0];
70 	uint32_t w = stoi(params[1]);
71 	uint32_t h = stoi(params[2]);
72 	string modestr = params[3];
73 
74 	auto pixfmt = FourCCToPixelFormat(modestr);
75 
76 	ifstream is(filename, ifstream::binary);
77 
78 	is.seekg(0, std::ios::end);
79 	unsigned fsize = is.tellg();
80 	is.seekg(0);
81 
82 	Card card(dev_path);
83 	ResourceManager res(card);
84 
85 	auto conn = res.reserve_connector(conn_name);
86 	auto crtc = res.reserve_crtc(conn);
87 	auto plane = res.reserve_overlay_plane(crtc, pixfmt);
88 	FAIL_IF(!plane, "available plane not found");
89 
90 	auto fb = new DumbFramebuffer(card, w, h, pixfmt);
91 
92 	unsigned frame_size = 0;
93 	for (unsigned i = 0; i < fb->num_planes(); ++i)
94 		frame_size += fb->size(i);
95 
96 	assert(frame_size);
97 
98 	unsigned num_frames = fsize / frame_size;
99 	printf("file size %u, frame size %u, frames %u\n", fsize, frame_size, num_frames);
100 
101 	for (unsigned i = 0; i < num_frames; ++i) {
102 		printf("frame %d", i);
103 		fflush(stdout);
104 		read_frame(is, fb, crtc, plane);
105 		if (!time) {
106 			getchar();
107 		} else {
108 			usleep(time * 1000);
109 			printf("\n");
110 		}
111 	}
112 
113 	is.close();
114 
115 	if (time) {
116 		printf("press enter to exit\n");
117 		getchar();
118 	}
119 
120 	delete fb;
121 }
122