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