Home | History | Annotate | Download | only in utils
      1 #include <cstdio>
      2 #include <poll.h>
      3 #include <unistd.h>
      4 #include <algorithm>
      5 #include <fstream>
      6 #include <map>
      7 #include <system_error>
      8 
      9 #include <kms++/kms++.h>
     10 #include <kms++util/kms++util.h>
     11 #include <kms++util/videodevice.h>
     12 
     13 const uint32_t NUM_SRC_BUFS=2;
     14 const uint32_t NUM_DST_BUFS=2;
     15 
     16 using namespace std;
     17 using namespace kms;
     18 
     19 static const char* usage_str =
     20 		"Usage: wbm2m [OPTIONS]\n\n"
     21 		"Options:\n"
     22 		"  -f, --format=4CC          Output format"
     23 		"  -h, --help                Print this help\n"
     24 		;
     25 
     26 const int bar_speed = 4;
     27 const int bar_width = 10;
     28 
     29 static unsigned get_bar_pos(DumbFramebuffer* fb, unsigned frame_num)
     30 {
     31 	return (frame_num * bar_speed) % (fb->width() - bar_width + 1);
     32 }
     33 
     34 static void read_frame(DumbFramebuffer* fb, unsigned frame_num)
     35 {
     36 	static map<DumbFramebuffer*, int> s_bar_pos_map;
     37 
     38 	int old_pos = -1;
     39 	if (s_bar_pos_map.find(fb) != s_bar_pos_map.end())
     40 		old_pos = s_bar_pos_map[fb];
     41 
     42 	int pos = get_bar_pos(fb, frame_num);
     43 	draw_color_bar(*fb, old_pos, pos, bar_width);
     44 	draw_text(*fb, fb->width() / 2, 0, to_string(frame_num), RGB(255, 255, 255));
     45 	s_bar_pos_map[fb] = pos;
     46 }
     47 
     48 int main(int argc, char** argv)
     49 {
     50 	// XXX get from args
     51 	const uint32_t src_width = 800;
     52 	const uint32_t src_height = 480;
     53 	const auto src_fmt = PixelFormat::XRGB8888;
     54 	const uint32_t num_src_frames = 10;
     55 
     56 	const uint32_t dst_width = 800;
     57 	const uint32_t dst_height = 480;
     58 	auto dst_fmt = PixelFormat::XRGB8888;
     59 
     60 	const string filename = "wb-out.raw";
     61 
     62 	OptionSet optionset = {
     63 		Option("f|format=", [&](string s)
     64 		{
     65 			dst_fmt = FourCCToPixelFormat(s);
     66 		}),
     67 		Option("h|help", [&]()
     68 		{
     69 			puts(usage_str);
     70 			exit(-1);
     71 		}),
     72 	};
     73 
     74 	optionset.parse(argc, argv);
     75 
     76 	if (optionset.params().size() > 0) {
     77 		puts(usage_str);
     78 		exit(-1);
     79 	}
     80 
     81 	VideoDevice vid("/dev/video10");
     82 
     83 	Card card;
     84 
     85 	uint32_t src_frame_num = 0;
     86 	uint32_t dst_frame_num = 0;
     87 
     88 	VideoStreamer* out = vid.get_output_streamer();
     89 	VideoStreamer* in = vid.get_capture_streamer();
     90 
     91 	out->set_format(src_fmt, src_width, src_height);
     92 	in->set_format(dst_fmt, dst_width, dst_height);
     93 
     94 	out->set_queue_size(NUM_SRC_BUFS);
     95 	in->set_queue_size(NUM_DST_BUFS);
     96 
     97 
     98 	for (unsigned i = 0; i < min(NUM_SRC_BUFS, num_src_frames); ++i) {
     99 		auto fb = new DumbFramebuffer(card, src_width, src_height, src_fmt);
    100 
    101 		read_frame(fb, src_frame_num++);
    102 
    103 		out->queue(fb);
    104 	}
    105 
    106 	for (unsigned i = 0; i < min(NUM_DST_BUFS, num_src_frames); ++i) {
    107 		auto fb = new DumbFramebuffer(card, dst_width, dst_height, dst_fmt);
    108 		in->queue(fb);
    109 	}
    110 
    111 	vector<pollfd> fds(3);
    112 
    113 	fds[0].fd = 0;
    114 	fds[0].events =  POLLIN;
    115 	fds[1].fd = vid.fd();
    116 	fds[1].events =  POLLIN;
    117 	fds[2].fd = card.fd();
    118 	fds[2].events =  POLLIN;
    119 
    120 	ofstream os(filename, ofstream::binary);
    121 
    122 	out->stream_on();
    123 	in->stream_on();
    124 
    125 	while (true) {
    126 		int r = poll(fds.data(), fds.size(), -1);
    127 		ASSERT(r > 0);
    128 
    129 		if (fds[0].revents != 0)
    130 			break;
    131 
    132 		if (fds[1].revents) {
    133 			fds[1].revents = 0;
    134 
    135 
    136 			try {
    137 				DumbFramebuffer *dst_fb = in->dequeue();
    138 				printf("Writing frame %u\n", dst_frame_num);
    139 				for (unsigned i = 0; i < dst_fb->num_planes(); ++i)
    140 					os.write((char*)dst_fb->map(i), dst_fb->size(i));
    141 				in->queue(dst_fb);
    142 
    143 				dst_frame_num++;
    144 
    145 				if (dst_frame_num >= num_src_frames)
    146 					break;
    147 
    148 			} catch (system_error& se) {
    149 				if (se.code() != errc::resource_unavailable_try_again)
    150 					FAIL("dequeue failed: %s", se.what());
    151 
    152 				break;
    153 			}
    154 
    155 			DumbFramebuffer *src_fb = out->dequeue();
    156 
    157 			if (src_frame_num < num_src_frames) {
    158 				read_frame(src_fb, src_frame_num++);
    159 				out->queue(src_fb);
    160 			}
    161 		}
    162 
    163 		if (fds[2].revents) {
    164 			fds[2].revents = 0;
    165 		}
    166 	}
    167 
    168 	printf("exiting...\n");
    169 }
    170