The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

u/sink: Add Bayer format converter

authored by

Jakob Bornecrantz and committed by
Jakob Bornecrantz
eec3446e 5b6e6bf6

+163 -3
+1
doc/changes/auxiliary/mr.665.md
··· 1 + u/sink: Add Bayer format converter.
+9
src/xrt/auxiliary/util/u_sink.h
··· 49 49 * @relates xrt_frame_context 50 50 */ 51 51 void 52 + u_sink_create_to_r8g8b8_bayer_or_l8(struct xrt_frame_context *xfctx, 53 + struct xrt_frame_sink *downstream, 54 + struct xrt_frame_sink **out_xfs); 55 + 56 + /*! 57 + * @relatesalso xrt_frame_sink 58 + * @relates xrt_frame_context 59 + */ 60 + void 52 61 u_sink_create_to_yuv_yuyv_uyvy_or_l8(struct xrt_frame_context *xfctx, 53 62 struct xrt_frame_sink *downstream, 54 63 struct xrt_frame_sink **out_xfs);
+153 -3
src/xrt/auxiliary/util/u_sink_converter.c
··· 343 343 344 344 /* 345 345 * 346 + * Bayer 347 + * 348 + */ 349 + 350 + static void 351 + from_BAYER_GR8_to_R8G8B8(struct xrt_frame *dst_frame, uint32_t w, uint32_t h, size_t stride, const uint8_t *data) 352 + { 353 + const uint8_t *src_data = data; 354 + uint32_t src_stride = stride; 355 + 356 + uint8_t *dst_data = dst_frame->data; 357 + uint32_t dst_stride = dst_frame->stride; 358 + 359 + for (uint32_t y = 0; y < h; y++) { 360 + const uint8_t *src0 = src_data + (y * 2) * src_stride; 361 + const uint8_t *src1 = src_data + (y * 2 + 1) * src_stride; 362 + uint8_t *dst = dst_data + (y * dst_stride); 363 + 364 + for (uint32_t x = 0; x < w; x++) { 365 + uint8_t g0 = src0[0]; 366 + uint8_t r = src0[1]; 367 + uint8_t b = src1[0]; 368 + uint8_t g1 = src1[1]; 369 + 370 + dst[0] = r; 371 + dst[1] = (g0 + g1) / 2; 372 + dst[2] = b; 373 + 374 + src0 += 2; 375 + src1 += 2; 376 + dst += 3; 377 + } 378 + } 379 + } 380 + 381 + 382 + /* 383 + * 346 384 * Misc functions. 347 385 * 348 386 */ 349 387 350 388 351 389 /*! 352 - * Creates a frame that the conversion should happen to. 390 + * Creates a frame that the conversion should happen to, allows to set the size. 353 391 * 354 392 * @todo Allocate from a pool of frames. 355 393 */ 356 394 static bool 357 - create_frame_with_format(struct xrt_frame *xf, enum xrt_format format, struct xrt_frame **out_frame) 395 + create_frame_with_format_of_size( 396 + struct xrt_frame *xf, uint32_t w, uint32_t h, enum xrt_format format, struct xrt_frame **out_frame) 358 397 { 359 398 struct xrt_frame *frame = NULL; 360 - u_frame_create_one_off(format, xf->width, xf->height, &frame); 399 + u_frame_create_one_off(format, w, h, &frame); 361 400 if (frame == NULL) { 362 401 U_LOG_E("Failed to create target frame!"); 363 402 *out_frame = NULL; ··· 375 414 return true; 376 415 } 377 416 417 + /*! 418 + * Creates a frame that the conversion should happen to. 419 + */ 420 + static bool 421 + create_frame_with_format(struct xrt_frame *xf, enum xrt_format format, struct xrt_frame **out_frame) 422 + { 423 + return create_frame_with_format_of_size(xf, xf->width, xf->height, format, out_frame); 424 + } 425 + 378 426 static void 379 427 receive_frame_r8g8b8_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf) 380 428 { ··· 385 433 switch (xf->format) { 386 434 case XRT_FORMAT_L8: 387 435 case XRT_FORMAT_R8G8B8: s->downstream->push_frame(s->downstream, xf); return; 436 + case XRT_FORMAT_BAYER_GR8:; 437 + uint32_t w = xf->width / 2; 438 + uint32_t h = xf->height / 2; 439 + if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) { 440 + return; 441 + } 442 + from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data); 443 + break; 444 + case XRT_FORMAT_YUYV422: 445 + if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 446 + return; 447 + } 448 + from_YUYV422_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data); 449 + break; 450 + case XRT_FORMAT_UYVY422: 451 + if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 452 + return; 453 + } 454 + from_UYVY422_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data); 455 + break; 456 + case XRT_FORMAT_YUV888: 457 + if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 458 + return; 459 + } 460 + from_YUV888_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data); 461 + break; 462 + #ifdef XRT_HAVE_JPEG 463 + case XRT_FORMAT_MJPEG: 464 + if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 465 + return; 466 + } 467 + if (!from_MJPEG_to_R8G8B8(converted, xf->size, xf->data)) { 468 + return; 469 + } 470 + break; 471 + #endif 472 + default: U_LOG_E("Can not convert from '%s' to R8G8B8 or L8!", u_format_str(xf->format)); return; 473 + } 474 + 475 + s->downstream->push_frame(s->downstream, converted); 476 + 477 + // Refcount in case it's being held downstream. 478 + xrt_frame_reference(&converted, NULL); 479 + } 480 + 481 + static void 482 + receive_frame_r8g8b8_bayer_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf) 483 + { 484 + struct u_sink_converter *s = (struct u_sink_converter *)xs; 485 + 486 + struct xrt_frame *converted = NULL; 487 + 488 + switch (xf->format) { 489 + case XRT_FORMAT_L8: 490 + case XRT_FORMAT_R8G8B8: 491 + case XRT_FORMAT_BAYER_GR8:; s->downstream->push_frame(s->downstream, xf); return; 388 492 case XRT_FORMAT_YUYV422: 389 493 if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 390 494 return; ··· 431 535 432 536 switch (xf->format) { 433 537 case XRT_FORMAT_R8G8B8: s->downstream->push_frame(s->downstream, xf); return; 538 + case XRT_FORMAT_BAYER_GR8:; 539 + uint32_t w = xf->width / 2; 540 + uint32_t h = xf->height / 2; 541 + if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) { 542 + return; 543 + } 544 + from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data); 545 + break; 434 546 case XRT_FORMAT_YUYV422: 435 547 if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { 436 548 return; ··· 533 645 xrt_frame_reference(&converted, NULL); 534 646 } 535 647 648 + XRT_MAYBE_UNUSED static void 649 + receive_frame_bayer(struct xrt_frame_sink *xs, struct xrt_frame *xf) 650 + { 651 + struct u_sink_converter *s = (struct u_sink_converter *)xs; 652 + 653 + uint32_t w = xf->width / 2; 654 + uint32_t h = xf->height / 2; 655 + struct xrt_frame *converted = NULL; 656 + 657 + if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) { 658 + return; 659 + } 660 + 661 + from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data); 662 + 663 + s->downstream->push_frame(s->downstream, converted); 664 + 665 + // Refcount in case it's being held downstream. 666 + xrt_frame_reference(&converted, NULL); 667 + } 668 + 536 669 static void 537 670 break_apart(struct xrt_frame_node *node) 538 671 {} ··· 597 730 598 731 *out_xfs = &s->base; 599 732 } 733 + 734 + void 735 + u_sink_create_to_r8g8b8_bayer_or_l8(struct xrt_frame_context *xfctx, 736 + struct xrt_frame_sink *downstream, 737 + struct xrt_frame_sink **out_xfs) 738 + { 739 + struct u_sink_converter *s = U_TYPED_CALLOC(struct u_sink_converter); 740 + s->base.push_frame = receive_frame_r8g8b8_bayer_or_l8; 741 + s->node.break_apart = break_apart; 742 + s->node.destroy = destroy; 743 + s->downstream = downstream; 744 + 745 + xrt_frame_context_add(xfctx, &s->node); 746 + 747 + *out_xfs = &s->base; 748 + } 749 + 600 750 601 751 void 602 752 u_sink_create_to_yuv_yuyv_uyvy_or_l8(struct xrt_frame_context *xfctx,