kmsview: small improvements
[android/external-libkmsxx.git] / utils / kmsview.cpp
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;