1 #include <cstdio>
2 #include <fstream>
3 #include <unistd.h>
5 #include <kms++.h>
6 #include <kms++util.h>
7 #include <opts.h>
9 using namespace std;
10 using namespace kms;
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));
17 unsigned w = min(crtc->width(), fb->width());
18 unsigned h = min(crtc->height(), fb->height());
20 int r = crtc->set_plane(plane, *fb,
21 0, 0, w, h,
22 0, 0, fb->width(), fb->height());
24 ASSERT(r == 0);
25 }
27 static const char* usage_str =
28 "Usage: kmsview [-t <ms>] <file> <width> <height> <fourcc>\n\n"
29 "Options:\n"
30 " -t, --time Milliseconds to sleep between frames\n"
31 ;
33 static void usage()
34 {
35 puts(usage_str);
36 }
38 int main(int argc, char** argv)
39 {
40 uint32_t time = 0;
41 string dev_path = "/dev/dri/card0";
43 OptionSet optionset = {
44 Option("|device=", [&dev_path](string s)
45 {
46 dev_path = s;
47 }),
48 Option("t|time=", [&time](const string& str)
49 {
50 time = stoul(str);
51 }),
52 Option("h|help", []()
53 {
54 usage();
55 exit(-1);
56 }),
57 };
59 optionset.parse(argc, argv);
61 vector<string> params = optionset.params();
63 if (params.size() != 4) {
64 usage();
65 exit(-1);
66 }
68 string filename = params[0];
69 uint32_t w = stoi(params[1]);
70 uint32_t h = stoi(params[2]);
71 string modestr = params[3];
73 auto pixfmt = FourCCToPixelFormat(modestr);
75 ifstream is(filename, ifstream::binary);
77 is.seekg(0, std::ios::end);
78 unsigned fsize = is.tellg();
79 is.seekg(0);
82 Card card(dev_path);
84 auto conn = card.get_first_connected_connector();
85 auto crtc = conn->get_current_crtc();
87 auto fb = new DumbFramebuffer(card, w, h, pixfmt);
89 Plane* plane = 0;
91 for (Plane* p : crtc->get_possible_planes()) {
92 if (p->plane_type() != PlaneType::Overlay)
93 continue;
95 if (!p->supports_format(pixfmt))
96 continue;
98 plane = p;
99 break;
100 }
102 FAIL_IF(!plane, "available plane not found");
105 unsigned frame_size = 0;
106 for (unsigned i = 0; i < fb->num_planes(); ++i)
107 frame_size += fb->size(i);
109 unsigned num_frames = fsize / frame_size;
110 printf("file size %u, frame size %u, frames %u\n", fsize, frame_size, num_frames);
112 for (unsigned i = 0; i < num_frames; ++i) {
113 printf("frame %d", i); fflush(stdout);
114 read_frame(is, fb, crtc, plane);
115 if (!time) {
116 getchar();
117 } else {
118 usleep(time * 1000);
119 printf("\n");
120 }
121 }
123 is.close();
125 if (time) {
126 printf("press enter to exit\n");
127 getchar();
128 }
130 delete fb;
131 }