summaryrefslogtreecommitdiff
path: root/utils/kmsview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/kmsview.cpp')
-rw-r--r--utils/kmsview.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/utils/kmsview.cpp b/utils/kmsview.cpp
new file mode 100644
index 0000000..7cee024
--- /dev/null
+++ b/utils/kmsview.cpp
@@ -0,0 +1,121 @@
+#include <cstdio>
+#include <fstream>
+#include <unistd.h>
+#include <cassert>
+
+#include <kms++/kms++.h>
+#include <kms++util/kms++util.h>
+
+using namespace std;
+using namespace kms;
+
+static void read_frame(ifstream& is, DumbFramebuffer* fb, Crtc* crtc, Plane* plane)
+{
+ for (unsigned i = 0; i < fb->num_planes(); ++i)
+ is.read(reinterpret_cast<char*>(fb->map(i)), fb->size(i));
+
+ unsigned w = min(crtc->width(), fb->width());
+ unsigned h = min(crtc->height(), fb->height());
+
+ int r = crtc->set_plane(plane, *fb,
+ 0, 0, w, h,
+ 0, 0, fb->width(), fb->height());
+
+ ASSERT(r == 0);
+}
+
+static const char* usage_str =
+ "Usage: kmsview [options] <file> <width> <height> <fourcc>\n\n"
+ "Options:\n"
+ " -c, --connector <name> Output connector\n"
+ " -t, --time <ms> Milliseconds to sleep between frames\n";
+
+static void usage()
+{
+ puts(usage_str);
+}
+
+int main(int argc, char** argv)
+{
+ uint32_t time = 0;
+ string dev_path;
+ string conn_name;
+
+ OptionSet optionset = {
+ Option("c|connector=", [&conn_name](string s) {
+ conn_name = s;
+ }),
+ Option("|device=", [&dev_path](string s) {
+ dev_path = s;
+ }),
+ Option("t|time=", [&time](const string& str) {
+ time = stoul(str);
+ }),
+ Option("h|help", []() {
+ usage();
+ exit(-1);
+ }),
+ };
+
+ optionset.parse(argc, argv);
+
+ vector<string> params = optionset.params();
+
+ if (params.size() != 4) {
+ usage();
+ exit(-1);
+ }
+
+ string filename = params[0];
+ uint32_t w = stoi(params[1]);
+ uint32_t h = stoi(params[2]);
+ string modestr = params[3];
+
+ auto pixfmt = fourcc_str_to_pixel_format(modestr);
+
+ ifstream is(filename, ifstream::binary);
+
+ is.seekg(0, std::ios::end);
+ unsigned fsize = is.tellg();
+ is.seekg(0);
+
+ Card card(dev_path);
+ ResourceManager res(card);
+
+ auto conn = res.reserve_connector(conn_name);
+ auto crtc = res.reserve_crtc(conn);
+ auto plane = res.reserve_overlay_plane(crtc, pixfmt);
+ FAIL_IF(!plane, "available plane not found");
+
+ auto fb = new DumbFramebuffer(card, w, h, pixfmt);
+
+ unsigned frame_size = 0;
+ for (unsigned i = 0; i < fb->num_planes(); ++i)
+ frame_size += fb->size(i);
+
+ assert(frame_size);
+
+ unsigned num_frames = fsize / frame_size;
+ printf("file size %u, frame size %u, frames %u\n", fsize, frame_size, num_frames);
+
+ for (unsigned i = 0; i < num_frames; ++i) {
+ printf("frame %u", i);
+ fflush(stdout);
+ read_frame(is, fb, crtc, plane);
+ if (!time) {
+ getchar();
+ } else {
+ usleep(time * 1000);
+ printf("\n");
+ }
+ }
+
+ is.close();
+
+ if (time) {
+ printf("press enter to exit\n");
+ getchar();
+ }
+
+ delete fb;
+}