mode.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include "mode.h"
  2. #include <glib.h>
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. static const char *pixel_format_names[MP_PIXEL_FMT_MAX] = {
  7. "unsupported", "BGGR8", "GBRG8", "GRBG8", "RGGB8", "BGGR10P",
  8. "GBRG10P", "GRBG10P", "RGGB10P", "UYVY", "YUYV",
  9. };
  10. const char *
  11. mp_pixel_format_to_str(uint32_t pixel_format)
  12. {
  13. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, "INVALID");
  14. return pixel_format_names[pixel_format];
  15. }
  16. MPPixelFormat
  17. mp_pixel_format_from_str(const char *name)
  18. {
  19. for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
  20. if (strcasecmp(pixel_format_names[i], name) == 0) {
  21. return i;
  22. }
  23. }
  24. g_return_val_if_reached(MP_PIXEL_FMT_UNSUPPORTED);
  25. }
  26. static const uint32_t pixel_format_v4l_pixel_formats[MP_PIXEL_FMT_MAX] = {
  27. 0,
  28. V4L2_PIX_FMT_SBGGR8,
  29. V4L2_PIX_FMT_SGBRG8,
  30. V4L2_PIX_FMT_SGRBG8,
  31. V4L2_PIX_FMT_SRGGB8,
  32. V4L2_PIX_FMT_SBGGR10P,
  33. V4L2_PIX_FMT_SGBRG10P,
  34. V4L2_PIX_FMT_SGRBG10P,
  35. V4L2_PIX_FMT_SRGGB10P,
  36. V4L2_PIX_FMT_UYVY,
  37. V4L2_PIX_FMT_YUYV,
  38. };
  39. uint32_t
  40. mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format)
  41. {
  42. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  43. return pixel_format_v4l_pixel_formats[pixel_format];
  44. }
  45. MPPixelFormat
  46. mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format)
  47. {
  48. for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
  49. if (pixel_format_v4l_pixel_formats[i] == v4l_pixel_format) {
  50. return i;
  51. }
  52. }
  53. return MP_PIXEL_FMT_UNSUPPORTED;
  54. }
  55. static const uint32_t pixel_format_v4l_bus_codes[MP_PIXEL_FMT_MAX] = {
  56. 0,
  57. MEDIA_BUS_FMT_SBGGR8_1X8,
  58. MEDIA_BUS_FMT_SGBRG8_1X8,
  59. MEDIA_BUS_FMT_SGRBG8_1X8,
  60. MEDIA_BUS_FMT_SRGGB8_1X8,
  61. MEDIA_BUS_FMT_SBGGR10_1X10,
  62. MEDIA_BUS_FMT_SGBRG10_1X10,
  63. MEDIA_BUS_FMT_SGRBG10_1X10,
  64. MEDIA_BUS_FMT_SRGGB10_1X10,
  65. MEDIA_BUS_FMT_UYVY8_2X8,
  66. MEDIA_BUS_FMT_YUYV8_2X8,
  67. };
  68. uint32_t
  69. mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format)
  70. {
  71. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  72. return pixel_format_v4l_bus_codes[pixel_format];
  73. }
  74. MPPixelFormat
  75. mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code)
  76. {
  77. for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
  78. if (pixel_format_v4l_bus_codes[i] == v4l_bus_code) {
  79. return i;
  80. }
  81. }
  82. return MP_PIXEL_FMT_UNSUPPORTED;
  83. }
  84. uint32_t
  85. mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format)
  86. {
  87. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  88. switch (pixel_format) {
  89. case MP_PIXEL_FMT_BGGR8:
  90. case MP_PIXEL_FMT_GBRG8:
  91. case MP_PIXEL_FMT_GRBG8:
  92. case MP_PIXEL_FMT_RGGB8:
  93. return 8;
  94. case MP_PIXEL_FMT_BGGR10P:
  95. case MP_PIXEL_FMT_GBRG10P:
  96. case MP_PIXEL_FMT_GRBG10P:
  97. case MP_PIXEL_FMT_RGGB10P:
  98. return 10;
  99. case MP_PIXEL_FMT_UYVY:
  100. case MP_PIXEL_FMT_YUYV:
  101. return 16;
  102. default:
  103. return 0;
  104. }
  105. }
  106. uint32_t
  107. mp_pixel_format_pixel_depth(MPPixelFormat pixel_format)
  108. {
  109. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  110. switch (pixel_format) {
  111. case MP_PIXEL_FMT_BGGR8:
  112. case MP_PIXEL_FMT_GBRG8:
  113. case MP_PIXEL_FMT_GRBG8:
  114. case MP_PIXEL_FMT_RGGB8:
  115. case MP_PIXEL_FMT_UYVY:
  116. case MP_PIXEL_FMT_YUYV:
  117. return 8;
  118. case MP_PIXEL_FMT_GBRG10P:
  119. case MP_PIXEL_FMT_GRBG10P:
  120. case MP_PIXEL_FMT_RGGB10P:
  121. case MP_PIXEL_FMT_BGGR10P:
  122. return 10;
  123. default:
  124. return 0;
  125. }
  126. }
  127. const char *
  128. mp_pixel_format_cfa(MPPixelFormat pixel_format)
  129. {
  130. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  131. switch (pixel_format) {
  132. case MP_PIXEL_FMT_BGGR8:
  133. case MP_PIXEL_FMT_BGGR10P:
  134. return "BGGR";
  135. break;
  136. case MP_PIXEL_FMT_GBRG8:
  137. case MP_PIXEL_FMT_GBRG10P:
  138. return "GBRG";
  139. break;
  140. case MP_PIXEL_FMT_GRBG8:
  141. case MP_PIXEL_FMT_GRBG10P:
  142. return "GRBG";
  143. break;
  144. case MP_PIXEL_FMT_RGGB8:
  145. case MP_PIXEL_FMT_RGGB10P:
  146. return "RGGB";
  147. break;
  148. case MP_PIXEL_FMT_UYVY:
  149. return "UYUV";
  150. break;
  151. case MP_PIXEL_FMT_YUYV:
  152. return "YUYV";
  153. break;
  154. default:
  155. return "unsupported";
  156. }
  157. }
  158. const char *
  159. mp_pixel_format_cfa_pattern(MPPixelFormat pixel_format)
  160. {
  161. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  162. switch (pixel_format) {
  163. case MP_PIXEL_FMT_BGGR8:
  164. case MP_PIXEL_FMT_BGGR10P:
  165. return "\002\001\001\000";
  166. break;
  167. case MP_PIXEL_FMT_GBRG8:
  168. case MP_PIXEL_FMT_GBRG10P:
  169. return "\001\002\000\001";
  170. break;
  171. case MP_PIXEL_FMT_GRBG8:
  172. case MP_PIXEL_FMT_GRBG10P:
  173. return "\001\000\002\001";
  174. break;
  175. case MP_PIXEL_FMT_RGGB8:
  176. case MP_PIXEL_FMT_RGGB10P:
  177. return "\000\001\001\002";
  178. break;
  179. default:
  180. return NULL;
  181. }
  182. }
  183. uint32_t
  184. mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width)
  185. {
  186. uint32_t bits_per_pixel = mp_pixel_format_bits_per_pixel(pixel_format);
  187. uint64_t bits_per_width = width * (uint64_t)bits_per_pixel;
  188. uint64_t remainder = bits_per_width % 8;
  189. if (remainder == 0)
  190. return bits_per_width / 8;
  191. return (bits_per_width + 8 - remainder) / 8;
  192. }
  193. uint32_t
  194. mp_pixel_format_width_to_padding(MPPixelFormat pixel_format, uint32_t width)
  195. {
  196. uint64_t bytes_per_width =
  197. mp_pixel_format_width_to_bytes(pixel_format, width);
  198. uint64_t remainder = bytes_per_width % 8;
  199. if (remainder == 0)
  200. return remainder;
  201. return 8 - remainder;
  202. }
  203. uint32_t
  204. mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width)
  205. {
  206. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  207. switch (pixel_format) {
  208. case MP_PIXEL_FMT_BGGR8:
  209. case MP_PIXEL_FMT_GBRG8:
  210. case MP_PIXEL_FMT_GRBG8:
  211. case MP_PIXEL_FMT_RGGB8:
  212. return width / 2;
  213. case MP_PIXEL_FMT_BGGR10P:
  214. case MP_PIXEL_FMT_GBRG10P:
  215. case MP_PIXEL_FMT_GRBG10P:
  216. case MP_PIXEL_FMT_RGGB10P:
  217. return width / 2 * 5;
  218. case MP_PIXEL_FMT_UYVY:
  219. case MP_PIXEL_FMT_YUYV:
  220. return width;
  221. default:
  222. return 0;
  223. }
  224. }
  225. uint32_t
  226. mp_pixel_format_height_to_colors(MPPixelFormat pixel_format, uint32_t height)
  227. {
  228. g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
  229. switch (pixel_format) {
  230. case MP_PIXEL_FMT_BGGR8:
  231. case MP_PIXEL_FMT_GBRG8:
  232. case MP_PIXEL_FMT_GRBG8:
  233. case MP_PIXEL_FMT_RGGB8:
  234. case MP_PIXEL_FMT_BGGR10P:
  235. case MP_PIXEL_FMT_GBRG10P:
  236. case MP_PIXEL_FMT_GRBG10P:
  237. case MP_PIXEL_FMT_RGGB10P:
  238. return height / 2;
  239. case MP_PIXEL_FMT_UYVY:
  240. case MP_PIXEL_FMT_YUYV:
  241. return height;
  242. default:
  243. return 0;
  244. }
  245. }
  246. bool
  247. mp_mode_is_equivalent(const MPMode *m1, const MPMode *m2)
  248. {
  249. return m1->pixel_format == m2->pixel_format &&
  250. m1->frame_interval.numerator == m2->frame_interval.numerator &&
  251. m1->frame_interval.denominator == m2->frame_interval.denominator &&
  252. m1->width == m2->width && m1->height == m2->height;
  253. }