0003-add-FbPreview-support-YUYV-YVYU-display.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. From 4fd0d73ae92f4e0f49c9d0f9f7e559e55e4fe2a8 Mon Sep 17 00:00:00 2001
  2. From: sw.multimedia <sw.multimedia@starfivetech.com>
  3. Date: Mon, 22 Nov 2021 15:28:17 +0800
  4. Subject: [PATCH] add FbPreview support YUYV/YVYU display
  5. ---
  6. preview/fb_preview.cpp | 123 +++++++++++++++++++++++++++++++++++------
  7. preview/preview.cpp | 15 +++--
  8. 2 files changed, 118 insertions(+), 20 deletions(-)
  9. diff --git a/preview/fb_preview.cpp b/preview/fb_preview.cpp
  10. index 1a88b79..0b42ad1 100644
  11. --- a/preview/fb_preview.cpp
  12. +++ b/preview/fb_preview.cpp
  13. @@ -44,6 +44,7 @@ enum COLOR_FORMAT {
  14. COLOR_RGB888_RGBA, // 9
  15. COLOR_RGB888_BGRA, // 10
  16. COLOR_RGB565, // 11
  17. + COLOR_UNKOWN, // unkown
  18. };
  19. struct pp_video_mode {
  20. @@ -83,6 +84,10 @@ public:
  21. private:
  22. int NVResize(unsigned char *inBuf,
  23. unsigned char *outBuf, int imgWidth, int imgHeight);
  24. + int YUYVResize(unsigned char *inBuf,
  25. + unsigned char *outBuf, int imgWidth, int imgHeight);
  26. + void setPixformat(unsigned int format);
  27. + unsigned int getPixformat(void);
  28. int g_fb_fd;
  29. int g_stfbc_fd;
  30. struct fb_var_screeninfo g_vinfo;
  31. @@ -93,10 +98,8 @@ private:
  32. enum COLOR_FORMAT pixformat;
  33. };
  34. -static enum COLOR_FORMAT v4l2fmt_to_fbfmt(unsigned int format)
  35. +void FbPreview::setPixformat(unsigned int format)
  36. {
  37. - enum COLOR_FORMAT pixformat = COLOR_RGB565;
  38. -
  39. switch (format) {
  40. case V4L2_PIX_FMT_RGB565:
  41. pixformat = COLOR_RGB565;
  42. @@ -120,11 +123,43 @@ static enum COLOR_FORMAT v4l2fmt_to_fbfmt(unsigned int format)
  43. pixformat = COLOR_YUV422_YVYU;
  44. break;
  45. default:
  46. - pixformat = COLOR_RGB565;
  47. + pixformat = COLOR_UNKOWN;
  48. break;
  49. }
  50. +}
  51. - return pixformat;
  52. +unsigned int FbPreview::getPixformat(void)
  53. +{
  54. + unsigned int format;
  55. +
  56. + switch (pixformat) {
  57. + case COLOR_RGB565:
  58. + format = V4L2_PIX_FMT_RGB565;
  59. + break;
  60. + case COLOR_RGB888_ARGB:
  61. + format = V4L2_PIX_FMT_RGB24;
  62. + break;
  63. + case COLOR_YUV420P:
  64. + format = V4L2_PIX_FMT_YUV420;
  65. + break;
  66. + case COLOR_YUV422_YUYV:
  67. + format = V4L2_PIX_FMT_YUYV;
  68. + break;
  69. + case COLOR_YUV420_NV21:
  70. + format = V4L2_PIX_FMT_NV21;
  71. + break;
  72. + case COLOR_YUV420_NV12:
  73. + format = V4L2_PIX_FMT_NV12;
  74. + break;
  75. + case COLOR_YUV422_YVYU:
  76. + format = V4L2_PIX_FMT_YVYU;
  77. + break;
  78. + default:
  79. + format = 0;
  80. + break;
  81. + }
  82. +
  83. + return format;
  84. }
  85. FbPreview::FbPreview(Options const *options) : Preview(options)
  86. @@ -140,10 +175,10 @@ FbPreview::FbPreview(Options const *options) : Preview(options)
  87. libcamera::PixelFormat pixelFormat =
  88. libcamera::PixelFormat::fromString(options_->pixelformat);
  89. - if (pixelFormat.fourcc() != V4L2_PIX_FMT_NV12)
  90. - throw std::runtime_error("FB onlu support NV12 display");
  91. + setPixformat(pixelFormat.fourcc());
  92. + if (pixformat == COLOR_UNKOWN)
  93. + throw std::runtime_error("FB unsupport format display.");
  94. - pixformat = v4l2fmt_to_fbfmt(pixelFormat.fourcc());
  95. if (-1 == ioctl(g_stfbc_fd, FBIOPAN_GET_PP_MODE, &pp_info[0]))
  96. throw std::runtime_error("Error reading variable information.");
  97. @@ -217,9 +252,6 @@ int FbPreview::NVResize(unsigned char *inBuf,
  98. int fb_Ypos, fb_Upos, fb_Vpos;
  99. int width, height;
  100. int x_offset, y_offset;
  101. - unsigned int start_timems;
  102. - unsigned int end_timems;
  103. - struct timeval ts_start, ts_end;
  104. width = imgWidth > g_vinfo.xres ? g_vinfo.xres : imgWidth;
  105. height = imgHeight > g_vinfo.yres ? g_vinfo.yres : imgHeight;
  106. @@ -264,15 +296,74 @@ int FbPreview::NVResize(unsigned char *inBuf,
  107. return 0;
  108. }
  109. +int FbPreview::YUYVResize(unsigned char *inBuf,
  110. + unsigned char *outBuf, int imgWidth, int imgHeight)
  111. +{
  112. + int rows, cols;
  113. + unsigned char *OutNVdata, *InNVdata;
  114. + int Ypos, fb_Ypos;
  115. + int width, height;
  116. + int x_offset, y_offset;
  117. +
  118. + width = imgWidth > g_vinfo.xres ? g_vinfo.xres : imgWidth;
  119. + height = imgHeight > g_vinfo.yres ? g_vinfo.yres : imgHeight;
  120. + x_offset = (g_vinfo.xres - width) / 2;
  121. + y_offset = (g_vinfo.yres - height) / 2;
  122. + x_offset &= ~0x1;
  123. +
  124. + InNVdata = inBuf;
  125. + OutNVdata = tmpBuf;
  126. +
  127. + if (imgWidth == g_vinfo.xres) {
  128. + fb_Ypos = y_offset * g_vinfo.xres + x_offset;
  129. + memcpy(&tmpBuf[fb_Ypos], inBuf, imgWidth * height * 2);
  130. + memcpy(&outBuf[fb_Ypos], &tmpBuf[fb_Ypos], imgWidth * height * 2);
  131. + return 0;
  132. + }
  133. +
  134. + /* two bytes for every pixels */
  135. + for(rows = 0; rows < height; rows++)
  136. + {
  137. + // g_vinfo.xres, g_vinfo.yres g_vinfo.bits_per_pixel
  138. + fb_Ypos = ((rows + y_offset) * g_vinfo.xres + x_offset) * 2;
  139. + Ypos = rows * imgWidth * 2;
  140. + memcpy(&OutNVdata[fb_Ypos], &InNVdata[Ypos], width * 2);
  141. + }
  142. +
  143. + memcpy(outBuf, tmpBuf, g_screensize);
  144. +
  145. + return 0;
  146. +}
  147. +
  148. void FbPreview::Show(int fd, libcamera::Span<uint8_t> span, int width, int height, int stride)
  149. {
  150. - int imgsize = stride * height + stride * height / 2;
  151. auto startTime = std::chrono::high_resolution_clock::now();
  152. + int size_valid = 0;
  153. + int imgsize;
  154. +
  155. + if (pixformat == COLOR_YUV420_NV21 || pixformat == COLOR_YUV420_NV12) {
  156. + imgsize = stride * height + stride * height / 2;
  157. + if (imgsize == span.size()) {
  158. + size_valid = 1;
  159. + NVResize(span.data(), g_fb_buf, width, height);
  160. + }
  161. + } else if (pixformat == COLOR_YUV422_YVYU || pixformat == COLOR_YUV422_YUYV) {
  162. + imgsize = stride * height;
  163. + if (imgsize == span.size()) {
  164. + size_valid = 1;
  165. + YUYVResize(span.data(), g_fb_buf, width, height);
  166. + }
  167. + }
  168. - if (pixformat == COLOR_YUV420_NV21 || pixformat == COLOR_YUV420_NV12)
  169. - NVResize(span.data(), g_fb_buf, width, height);
  170. - else
  171. - std::cout << "FbPreview unsupport pixformat: " << pixformat << std::endl;
  172. + if (!size_valid) {
  173. + std::cout << "FbPreview unsupport pixformat: " << pixformat
  174. + << " fb need size: " << imgsize
  175. + << " width: " << width
  176. + << " height: " << height
  177. + << " stride: " << stride
  178. + << " size: " << span.size() << std::endl;
  179. + throw std::runtime_error("Error FbPreview unsupport pixformat.");
  180. + }
  181. auto endTime = std::chrono::high_resolution_clock::now();
  182. diff --git a/preview/preview.cpp b/preview/preview.cpp
  183. index 0086d83..17118d4 100644
  184. --- a/preview/preview.cpp
  185. +++ b/preview/preview.cpp
  186. @@ -49,10 +49,17 @@ Preview *make_preview(Options const *options)
  187. }
  188. catch (std::exception const &e)
  189. {
  190. - std::cout << "FB Preview window." << std::endl;
  191. - return make_fb_preview(options);
  192. - // std::cout << "Preview window unavailable" << std::endl;
  193. - // return make_null_preview(options);
  194. + try {
  195. + std::cout << "FB Preview window." << std::endl;
  196. + return make_fb_preview(options);
  197. + if (options->verbose)
  198. + std::cout << "Made FB Preview window." << std::endl;
  199. + }
  200. + catch (std::exception const &e)
  201. + {
  202. + std::cout << "Preview window unavailable" << std::endl;
  203. + return make_null_preview(options);
  204. + }
  205. }
  206. }
  207. }
  208. --
  209. 2.17.1