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