mode.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #include <stdlib.h>
  2. #include <linux/v4l2-subdev.h>
  3. #include <strings.h>
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include "mode.h"
  7. #include "libmegapixels.h"
  8. // TODO: The 16 bit formats are imported from millipixels and seem broken
  9. static struct libmegapixels_modename mode_lut[] = {
  10. {
  11. .name = "unsupported",
  12. .v4l_pixel_format = 0,
  13. .media_bus_format = 0,
  14. .bpc = 0,
  15. .bpp = 0,
  16. .cfa = LIBMEGAPIXELS_CFA_NONE,
  17. },
  18. {
  19. .name = "BGGR8",
  20. .v4l_pixel_format = V4L2_PIX_FMT_SBGGR8,
  21. .media_bus_format = MEDIA_BUS_FMT_SBGGR8_1X8,
  22. .bpc = 8,
  23. .bpp = 8,
  24. .cfa = LIBMEGAPIXELS_CFA_BGGR,
  25. },
  26. {
  27. .name = "GBRG8",
  28. .v4l_pixel_format = V4L2_PIX_FMT_SGBRG8,
  29. .media_bus_format = MEDIA_BUS_FMT_SGBRG8_1X8,
  30. .bpc = 8,
  31. .bpp = 8,
  32. .cfa = LIBMEGAPIXELS_CFA_GBRG,
  33. },
  34. {
  35. .name = "GRBG8",
  36. .v4l_pixel_format = V4L2_PIX_FMT_SGRBG8,
  37. .media_bus_format = MEDIA_BUS_FMT_SGRBG8_1X8,
  38. .bpc = 8,
  39. .bpp = 8,
  40. .cfa = LIBMEGAPIXELS_CFA_GRBG,
  41. },
  42. {
  43. .name = "RGGB8",
  44. .v4l_pixel_format = V4L2_PIX_FMT_SRGGB8,
  45. .media_bus_format = MEDIA_BUS_FMT_SRGGB8_1X8,
  46. .bpc = 8,
  47. .bpp = 8,
  48. .cfa = LIBMEGAPIXELS_CFA_RGGB,
  49. },
  50. {
  51. .name = "BGGR10P",
  52. .v4l_pixel_format = V4L2_PIX_FMT_SBGGR10P,
  53. .media_bus_format = MEDIA_BUS_FMT_SBGGR10_1X10,
  54. .bpc = 10,
  55. .bpp = 10,
  56. .cfa = LIBMEGAPIXELS_CFA_BGGR,
  57. },
  58. {
  59. .name = "GBRG10P",
  60. .v4l_pixel_format = V4L2_PIX_FMT_SGBRG10P,
  61. .media_bus_format = MEDIA_BUS_FMT_SGBRG10_1X10,
  62. .bpc = 10,
  63. .bpp = 10,
  64. .cfa = LIBMEGAPIXELS_CFA_GBRG,
  65. },
  66. {
  67. .name = "GRBG10P",
  68. .v4l_pixel_format = V4L2_PIX_FMT_SGRBG10P,
  69. .media_bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
  70. .bpc = 10,
  71. .bpp = 10,
  72. .cfa = LIBMEGAPIXELS_CFA_GRBG,
  73. },
  74. {
  75. .name = "RGGB10P",
  76. .v4l_pixel_format = V4L2_PIX_FMT_SRGGB10P,
  77. .media_bus_format = MEDIA_BUS_FMT_SRGGB10_1X10,
  78. .bpc = 10,
  79. .bpp = 10,
  80. .cfa = LIBMEGAPIXELS_CFA_RGGB,
  81. },
  82. {
  83. .name = "BGGR10",
  84. .v4l_pixel_format = V4L2_PIX_FMT_SBGGR10,
  85. .media_bus_format = MEDIA_BUS_FMT_SBGGR10_1X10,
  86. .bpc = 10,
  87. .bpp = 10,
  88. .cfa = LIBMEGAPIXELS_CFA_BGGR,
  89. },
  90. {
  91. .name = "GBRG10",
  92. .v4l_pixel_format = V4L2_PIX_FMT_SGBRG10,
  93. .media_bus_format = MEDIA_BUS_FMT_SGBRG10_1X10,
  94. .bpc = 10,
  95. .bpp = 10,
  96. .cfa = LIBMEGAPIXELS_CFA_GBRG,
  97. },
  98. {
  99. .name = "GRBG10",
  100. .v4l_pixel_format = V4L2_PIX_FMT_SGRBG10,
  101. .media_bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
  102. .bpc = 10,
  103. .bpp = 10,
  104. .cfa = LIBMEGAPIXELS_CFA_GRBG,
  105. },
  106. {
  107. .name = "RGGB10",
  108. .v4l_pixel_format = V4L2_PIX_FMT_SRGGB10,
  109. .media_bus_format = MEDIA_BUS_FMT_SRGGB10_1X10,
  110. .bpc = 10,
  111. .bpp = 10,
  112. .cfa = LIBMEGAPIXELS_CFA_RGGB,
  113. },
  114. {
  115. .name = "BGGR16",
  116. .v4l_pixel_format = V4L2_PIX_FMT_SBGGR16,
  117. .media_bus_format = MEDIA_BUS_FMT_SBGGR10_1X10,
  118. .bpc = 10,
  119. .bpp = 10,
  120. .cfa = LIBMEGAPIXELS_CFA_BGGR,
  121. },
  122. {
  123. .name = "GBRG16",
  124. .v4l_pixel_format = V4L2_PIX_FMT_SGBRG16,
  125. .media_bus_format = MEDIA_BUS_FMT_SGBRG10_1X10,
  126. .bpc = 10,
  127. .bpp = 10,
  128. .cfa = LIBMEGAPIXELS_CFA_GBRG,
  129. },
  130. {
  131. .name = "GRBG16",
  132. .v4l_pixel_format = V4L2_PIX_FMT_SGRBG16,
  133. .media_bus_format =MEDIA_BUS_FMT_SGRBG10_1X10,
  134. .bpc = 10,
  135. .bpp = 10,
  136. .cfa = LIBMEGAPIXELS_CFA_GRBG,
  137. },
  138. {
  139. .name = "RGGB16",
  140. .v4l_pixel_format = V4L2_PIX_FMT_SRGGB16,
  141. .media_bus_format = MEDIA_BUS_FMT_SRGGB10_1X10,
  142. .bpc = 10,
  143. .bpp = 10,
  144. .cfa = LIBMEGAPIXELS_CFA_RGGB,
  145. },
  146. {
  147. .name = "UYVY",
  148. .v4l_pixel_format = V4L2_PIX_FMT_UYVY,
  149. .media_bus_format = MEDIA_BUS_FMT_UYVY8_2X8,
  150. .bpc = 8,
  151. .bpp = 16,
  152. .cfa = LIBMEGAPIXELS_CFA_NONE,
  153. },
  154. {
  155. .name = "YUYV",
  156. .v4l_pixel_format = V4L2_PIX_FMT_YUYV,
  157. .media_bus_format = MEDIA_BUS_FMT_YUYV8_2X8,
  158. .bpc = 8,
  159. .bpp = 16,
  160. .cfa = LIBMEGAPIXELS_CFA_NONE,
  161. },
  162. {
  163. .name = "VYUY",
  164. .v4l_pixel_format = V4L2_PIX_FMT_VYUY,
  165. .media_bus_format = MEDIA_BUS_FMT_VYUY8_2X8,
  166. .bpc = 8,
  167. .bpp = 16,
  168. .cfa = LIBMEGAPIXELS_CFA_NONE,
  169. },
  170. {
  171. .name = "YVYU",
  172. .v4l_pixel_format = V4L2_PIX_FMT_YVYU,
  173. .media_bus_format = MEDIA_BUS_FMT_YVYU8_2X8,
  174. .bpc = 8,
  175. .bpp = 16,
  176. .cfa = LIBMEGAPIXELS_CFA_NONE,
  177. },
  178. };
  179. int
  180. libmegapixels_format_name_to_index(const char *name)
  181. {
  182. int count = sizeof(mode_lut) / sizeof(mode_lut[0]);
  183. for (int i = 0; i < count; i++) {
  184. if (strcasecmp(mode_lut[i].name, name) == 0) {
  185. return i;
  186. }
  187. }
  188. return 0;
  189. }
  190. uint32_t
  191. libmegapixels_format_to_v4l_pixfmt(int index)
  192. {
  193. return mode_lut[index].v4l_pixel_format;
  194. }
  195. uint32_t
  196. libmegapixels_format_to_media_busfmt(int index)
  197. {
  198. return mode_lut[index].media_bus_format;
  199. }
  200. int
  201. libmegapixels_v4l_pixfmt_to_index(uint32_t pixfmt)
  202. {
  203. int count = sizeof(mode_lut) / sizeof(mode_lut[0]);
  204. for (int i = 0; i < count; i++) {
  205. if (mode_lut[i].v4l_pixel_format == pixfmt) {
  206. return i;
  207. }
  208. }
  209. return 0;
  210. }
  211. char *
  212. libmegapixels_v4l_pixfmt_to_string(uint32_t pixfmt)
  213. {
  214. int count = sizeof(mode_lut) / sizeof(mode_lut[0]);
  215. for (int i = 0; i < count; i++) {
  216. if (mode_lut[i].v4l_pixel_format == pixfmt) {
  217. return mode_lut[i].name;
  218. }
  219. }
  220. return "unknown";
  221. }
  222. char *
  223. libmegapixels_format_name(int format)
  224. {
  225. return mode_lut[format].name;
  226. }
  227. // mp_pixel_format_bits_per_pixel
  228. uint32_t
  229. libmegapixels_format_bits_per_pixel(int format)
  230. {
  231. return mode_lut[format].bpp;
  232. }
  233. const char *
  234. libmegapixels_format_cfa(int format)
  235. {
  236. switch (mode_lut[format].cfa) {
  237. case LIBMEGAPIXELS_CFA_BGGR:
  238. return "BGGR";
  239. case LIBMEGAPIXELS_CFA_GBRG:
  240. return "GBRG";
  241. case LIBMEGAPIXELS_CFA_GRBG:
  242. return "GRBG";
  243. case LIBMEGAPIXELS_CFA_RGGB:
  244. return "RGGB";
  245. default:
  246. return NULL;
  247. }
  248. }
  249. const char *
  250. libmegapixels_format_cfa_pattern(int format)
  251. {
  252. switch (mode_lut[format].cfa) {
  253. case LIBMEGAPIXELS_CFA_BGGR:
  254. return "\002\001\001\000";
  255. case LIBMEGAPIXELS_CFA_GBRG:
  256. return "\001\002\000\001";
  257. case LIBMEGAPIXELS_CFA_GRBG:
  258. return "\001\000\002\001";
  259. case LIBMEGAPIXELS_CFA_RGGB:
  260. return "\000\001\001\002";
  261. default:
  262. return NULL;
  263. }
  264. }
  265. // mp_pixel_format_width_to_bytes
  266. uint32_t
  267. libmegapixels_mode_width_to_bytes(int index, uint32_t width)
  268. {
  269. uint32_t bits_per_pixel = mode_lut[index].bpp;
  270. uint64_t bits_per_width = width * (uint64_t) bits_per_pixel;
  271. uint64_t remainder = bits_per_width % 8;
  272. if (remainder == 0)
  273. return bits_per_width / 8;
  274. return (bits_per_width + 8 - remainder) / 8;
  275. }
  276. uint32_t
  277. libmegapixels_mode_width_to_padding(int index, uint32_t width)
  278. {
  279. if (mode_lut[index].bpp == 8) {
  280. return 0;
  281. }
  282. uint64_t bytes_per_width = libmegapixels_mode_width_to_bytes(index, width);
  283. uint64_t remainder = bytes_per_width % 8;
  284. if (remainder == 0)
  285. return remainder;
  286. return 8 - remainder;
  287. }
  288. uint32_t
  289. libmegapixels_mode_raw_width_to_width(int index, uint32_t width)
  290. {
  291. switch (mode_lut[index].v4l_pixel_format) {
  292. case V4L2_PIX_FMT_SBGGR8:
  293. case V4L2_PIX_FMT_SGBRG8:
  294. case V4L2_PIX_FMT_SGRBG8:
  295. case V4L2_PIX_FMT_SRGGB8:
  296. return width / 2;
  297. case V4L2_PIX_FMT_SBGGR10P:
  298. case V4L2_PIX_FMT_SGBRG10P:
  299. case V4L2_PIX_FMT_SGRBG10P:
  300. case V4L2_PIX_FMT_SRGGB10P:
  301. return width / 2 * 5;
  302. case V4L2_PIX_FMT_UYVY:
  303. case V4L2_PIX_FMT_YUYV:
  304. return width;
  305. default:
  306. return 0;
  307. }
  308. }
  309. uint32_t
  310. libmegapixels_mode_raw_height_to_height(int index, uint32_t height)
  311. {
  312. switch (mode_lut[index].v4l_pixel_format) {
  313. case V4L2_PIX_FMT_SBGGR8:
  314. case V4L2_PIX_FMT_SGBRG8:
  315. case V4L2_PIX_FMT_SGRBG8:
  316. case V4L2_PIX_FMT_SRGGB8:
  317. case V4L2_PIX_FMT_SBGGR10P:
  318. case V4L2_PIX_FMT_SGBRG10P:
  319. case V4L2_PIX_FMT_SGRBG10P:
  320. case V4L2_PIX_FMT_SRGGB10P:
  321. return height / 2;
  322. case V4L2_PIX_FMT_UYVY:
  323. case V4L2_PIX_FMT_YUYV:
  324. return height;
  325. default:
  326. return 0;
  327. }
  328. }
  329. int
  330. libmegapixels_mode_equals(libmegapixels_mode *a, libmegapixels_mode *b)
  331. {
  332. if (a == NULL || b == NULL) {
  333. return 0;
  334. }
  335. if (a->width != b->width) {
  336. return 0;
  337. }
  338. if (a->height != b->height) {
  339. return 0;
  340. }
  341. if (a->rate != b->rate) {
  342. return 0;
  343. }
  344. if (a->format != b->format) {
  345. return 0;
  346. }
  347. return 1;
  348. }
  349. int
  350. mode_snprintf(char *buf, size_t maxlen, libmegapixels_mode *mode)
  351. {
  352. return snprintf(buf, maxlen, "%dx%d@%d %s", mode->width, mode->height, mode->rate, mode_lut[mode->format].name);
  353. }