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