diff options
Diffstat (limited to 'utils/wbcap.cpp')
-rw-r--r-- | utils/wbcap.cpp | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/utils/wbcap.cpp b/utils/wbcap.cpp index 19b8b46..4ec87ee 100644 --- a/utils/wbcap.cpp +++ b/utils/wbcap.cpp | |||
@@ -20,11 +20,11 @@ static vector<DumbFramebuffer*> s_ready_fbs; | |||
20 | class WBStreamer | 20 | class WBStreamer |
21 | { | 21 | { |
22 | public: | 22 | public: |
23 | WBStreamer(VideoStreamer* streamer, Crtc* crtc, uint32_t width, uint32_t height, PixelFormat pixfmt) | 23 | WBStreamer(VideoStreamer* streamer, Crtc* crtc, PixelFormat pixfmt) |
24 | : m_capdev(*streamer) | 24 | : m_capdev(*streamer) |
25 | { | 25 | { |
26 | m_capdev.set_port(crtc->idx()); | 26 | m_capdev.set_port(crtc->idx()); |
27 | m_capdev.set_format(pixfmt, width, height); | 27 | m_capdev.set_format(pixfmt, crtc->mode().hdisplay, crtc->mode().vdisplay); |
28 | m_capdev.set_queue_size(s_fbs.size()); | 28 | m_capdev.set_queue_size(s_fbs.size()); |
29 | 29 | ||
30 | for (auto fb : s_free_fbs) { | 30 | for (auto fb : s_free_fbs) { |
@@ -101,8 +101,8 @@ public: | |||
101 | 101 | ||
102 | req.add(m_plane, "CRTC_X", x); | 102 | req.add(m_plane, "CRTC_X", x); |
103 | req.add(m_plane, "CRTC_Y", y); | 103 | req.add(m_plane, "CRTC_Y", y); |
104 | req.add(m_plane, "CRTC_W", width); | 104 | req.add(m_plane, "CRTC_W", min((uint32_t)m_crtc->mode().hdisplay, fb->width())); |
105 | req.add(m_plane, "CRTC_H", height); | 105 | req.add(m_plane, "CRTC_H", min((uint32_t)m_crtc->mode().vdisplay, fb->height())); |
106 | 106 | ||
107 | req.add(m_plane, "SRC_X", 0); | 107 | req.add(m_plane, "SRC_X", 0); |
108 | req.add(m_plane, "SRC_Y", 0); | 108 | req.add(m_plane, "SRC_Y", 0); |
@@ -161,16 +161,11 @@ private: | |||
161 | class BarFlipState : private PageFlipHandlerBase | 161 | class BarFlipState : private PageFlipHandlerBase |
162 | { | 162 | { |
163 | public: | 163 | public: |
164 | BarFlipState(Card& card, Crtc* crtc) | 164 | BarFlipState(Card& card, Crtc* crtc, Plane* plane, uint32_t width, uint32_t height) |
165 | : m_card(card), m_crtc(crtc) | 165 | : m_card(card), m_crtc(crtc), m_plane(plane) |
166 | { | 166 | { |
167 | m_plane = m_crtc->get_primary_plane(); | ||
168 | |||
169 | uint32_t w = m_crtc->mode().hdisplay; | ||
170 | uint32_t h = m_crtc->mode().vdisplay; | ||
171 | |||
172 | for (unsigned i = 0; i < s_num_buffers; ++i) | 167 | for (unsigned i = 0; i < s_num_buffers; ++i) |
173 | m_fbs[i] = new DumbFramebuffer(card, w, h, PixelFormat::XRGB8888); | 168 | m_fbs[i] = new DumbFramebuffer(card, width, height, PixelFormat::XRGB8888); |
174 | } | 169 | } |
175 | 170 | ||
176 | ~BarFlipState() | 171 | ~BarFlipState() |
@@ -217,7 +212,18 @@ private: | |||
217 | draw_bar(fb, m_frame_num); | 212 | draw_bar(fb, m_frame_num); |
218 | 213 | ||
219 | req.add(m_plane, { | 214 | req.add(m_plane, { |
215 | { "CRTC_ID", m_crtc->id() }, | ||
220 | { "FB_ID", fb->id() }, | 216 | { "FB_ID", fb->id() }, |
217 | |||
218 | { "CRTC_X", 0 }, | ||
219 | { "CRTC_Y", 0 }, | ||
220 | { "CRTC_W", min((uint32_t)m_crtc->mode().hdisplay, fb->width()) }, | ||
221 | { "CRTC_H", min((uint32_t)m_crtc->mode().vdisplay, fb->height()) }, | ||
222 | |||
223 | { "SRC_X", 0 }, | ||
224 | { "SRC_Y", 0 }, | ||
225 | { "SRC_W", fb->width() << 16 }, | ||
226 | { "SRC_H", fb->height() << 16 }, | ||
221 | }); | 227 | }); |
222 | 228 | ||
223 | int r = req.commit(this); | 229 | int r = req.commit(this); |
@@ -250,8 +256,10 @@ static const char* usage_str = | |||
250 | 256 | ||
251 | int main(int argc, char** argv) | 257 | int main(int argc, char** argv) |
252 | { | 258 | { |
253 | string src_conn_name = "unknown"; | 259 | string src_conn_name; |
254 | string dst_conn_name = "hdmi"; | 260 | string src_mode_name; |
261 | string dst_conn_name; | ||
262 | string dst_mode_name; | ||
255 | PixelFormat pixfmt = PixelFormat::XRGB8888; | 263 | PixelFormat pixfmt = PixelFormat::XRGB8888; |
256 | 264 | ||
257 | OptionSet optionset = { | 265 | OptionSet optionset = { |
@@ -259,10 +267,18 @@ int main(int argc, char** argv) | |||
259 | { | 267 | { |
260 | src_conn_name = s; | 268 | src_conn_name = s; |
261 | }), | 269 | }), |
270 | Option("m|smode=", [&](string s) | ||
271 | { | ||
272 | src_mode_name = s; | ||
273 | }), | ||
262 | Option("d|dst=", [&](string s) | 274 | Option("d|dst=", [&](string s) |
263 | { | 275 | { |
264 | dst_conn_name = s; | 276 | dst_conn_name = s; |
265 | }), | 277 | }), |
278 | Option("M|dmode=", [&](string s) | ||
279 | { | ||
280 | dst_mode_name = s; | ||
281 | }), | ||
266 | Option("f|format=", [&](string s) | 282 | Option("f|format=", [&](string s) |
267 | { | 283 | { |
268 | pixfmt = FourCCToPixelFormat(s); | 284 | pixfmt = FourCCToPixelFormat(s); |
@@ -281,41 +297,45 @@ int main(int argc, char** argv) | |||
281 | exit(-1); | 297 | exit(-1); |
282 | } | 298 | } |
283 | 299 | ||
300 | if (src_conn_name.empty()) | ||
301 | EXIT("No source connector defined"); | ||
302 | |||
303 | if (dst_conn_name.empty()) | ||
304 | EXIT("No destination connector defined"); | ||
305 | |||
284 | VideoDevice vid("/dev/video11"); | 306 | VideoDevice vid("/dev/video11"); |
285 | 307 | ||
286 | Card card; | 308 | Card card; |
287 | ResourceManager resman(card); | 309 | ResourceManager resman(card); |
288 | 310 | ||
311 | card.disable_all(); | ||
312 | |||
289 | auto src_conn = resman.reserve_connector(src_conn_name); | 313 | auto src_conn = resman.reserve_connector(src_conn_name); |
290 | auto src_crtc = resman.reserve_crtc(src_conn); | 314 | auto src_crtc = resman.reserve_crtc(src_conn); |
291 | src_crtc->refresh(); | 315 | auto src_plane = resman.reserve_generic_plane(src_crtc, pixfmt); |
292 | Videomode src_mode = src_conn->get_default_mode(); | 316 | FAIL_IF(!src_plane, "Plane not found"); |
293 | DumbFramebuffer src_fb(card, src_mode.hdisplay, src_mode.vdisplay, PixelFormat::ARGB8888); | 317 | Videomode src_mode = src_mode_name.empty() ? src_conn->get_default_mode() : src_conn->get_mode(src_mode_name); |
294 | src_crtc->set_mode(src_conn, src_fb, src_mode); | 318 | src_crtc->set_mode(src_conn, src_mode); |
295 | 319 | ||
296 | uint32_t src_width = src_crtc->mode().hdisplay; | ||
297 | uint32_t src_height = src_crtc->mode().vdisplay; | ||
298 | |||
299 | printf("src %s, crtc %ux%u\n", src_conn->fullname().c_str(), src_width, src_height); | ||
300 | 320 | ||
301 | auto dst_conn = resman.reserve_connector(dst_conn_name); | 321 | auto dst_conn = resman.reserve_connector(dst_conn_name); |
302 | auto dst_crtc = resman.reserve_crtc(dst_conn); | 322 | auto dst_crtc = resman.reserve_crtc(dst_conn); |
303 | Videomode dst_mode = dst_conn->get_default_mode(); | ||
304 | DumbFramebuffer dst_fb(card, dst_mode.hdisplay, dst_mode.vdisplay, PixelFormat::ARGB8888); | ||
305 | dst_crtc->set_mode(dst_conn, dst_fb, dst_mode); | ||
306 | dst_crtc->refresh(); | ||
307 | auto dst_plane = resman.reserve_overlay_plane(dst_crtc, pixfmt); | 323 | auto dst_plane = resman.reserve_overlay_plane(dst_crtc, pixfmt); |
308 | FAIL_IF(!dst_plane, "Plane not found"); | 324 | FAIL_IF(!dst_plane, "Plane not found"); |
325 | Videomode dst_mode = dst_mode_name.empty() ? dst_conn->get_default_mode() : dst_conn->get_mode(dst_mode_name); | ||
326 | dst_crtc->set_mode(dst_conn, dst_mode); | ||
327 | |||
328 | uint32_t width = src_mode.hdisplay; | ||
329 | uint32_t height = src_mode.vdisplay; | ||
330 | |||
331 | printf("src %s, crtc %s\n", src_conn->fullname().c_str(), src_mode.to_string().c_str()); | ||
309 | 332 | ||
310 | uint32_t dst_width = min((uint32_t)dst_crtc->mode().hdisplay, src_width); | 333 | printf("dst %s, crtc %s\n", dst_conn->fullname().c_str(), dst_mode.to_string().c_str()); |
311 | uint32_t dst_height = min((uint32_t)dst_crtc->mode().vdisplay, src_height); | ||
312 | 334 | ||
313 | printf("dst %s, crtc %ux%u, plane %ux%u\n", dst_conn->fullname().c_str(), | 335 | printf("fb %ux%u\n", width, height); |
314 | dst_crtc->mode().hdisplay, dst_crtc->mode().vdisplay, | ||
315 | dst_width, dst_height); | ||
316 | 336 | ||
317 | for (int i = 0; i < CAMERA_BUF_QUEUE_SIZE; ++i) { | 337 | for (int i = 0; i < CAMERA_BUF_QUEUE_SIZE; ++i) { |
318 | auto fb = new DumbFramebuffer(card, src_width, src_height, pixfmt); | 338 | auto fb = new DumbFramebuffer(card, width, height, pixfmt); |
319 | s_fbs.push_back(fb); | 339 | s_fbs.push_back(fb); |
320 | s_free_fbs.push_back(fb); | 340 | s_free_fbs.push_back(fb); |
321 | } | 341 | } |
@@ -325,14 +345,14 @@ int main(int argc, char** argv) | |||
325 | s_free_fbs.pop_back(); | 345 | s_free_fbs.pop_back(); |
326 | 346 | ||
327 | // This draws a moving bar to SRC display | 347 | // This draws a moving bar to SRC display |
328 | BarFlipState barflipper(card, src_crtc); | 348 | BarFlipState barflipper(card, src_crtc, src_plane, width, height); |
329 | barflipper.start_flipping(); | 349 | barflipper.start_flipping(); |
330 | 350 | ||
331 | // This shows the captures SRC frames on DST display | 351 | // This shows the captures SRC frames on DST display |
332 | WBFlipState wbflipper(card, dst_crtc, dst_plane); | 352 | WBFlipState wbflipper(card, dst_crtc, dst_plane); |
333 | wbflipper.setup(0, 0, dst_width, dst_height); | 353 | wbflipper.setup(0, 0, width, height); |
334 | 354 | ||
335 | WBStreamer wb(vid.get_capture_streamer(), src_crtc, src_width, src_height, pixfmt); | 355 | WBStreamer wb(vid.get_capture_streamer(), src_crtc, pixfmt); |
336 | wb.start_streaming(); | 356 | wb.start_streaming(); |
337 | 357 | ||
338 | vector<pollfd> fds(3); | 358 | vector<pollfd> fds(3); |