msm_media_info.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef __MSM_MEDIA_INFO_H__
  7. #define __MSM_MEDIA_INFO_H__
  8. #include "msm_vidc_internal.h"
  9. /* Width and Height should be multiple of 16 */
  10. #define INTERLACE_WIDTH_MAX 1920
  11. #define INTERLACE_HEIGHT_MAX 1920
  12. #define INTERLACE_MB_PER_FRAME_MAX ((1920 * 1088) / 256)
  13. #ifndef MSM_MEDIA_ALIGN
  14. #define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\
  15. ((((__sz) + (__align) - 1) / (__align)) * (__align)) :\
  16. (((__sz) + (__align) - 1) & (~((__align) - 1))))
  17. #endif
  18. #ifndef MSM_MEDIA_ROUNDUP
  19. #define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r))
  20. #endif
  21. /*
  22. * Function arguments:
  23. * @v4l2_fmt
  24. * @width
  25. * Progressive: width
  26. * Interlaced: width
  27. */
  28. static inline unsigned int video_y_stride_bytes(unsigned int colorformat,
  29. unsigned int width)
  30. {
  31. unsigned int alignment, stride = 0;
  32. if (!width)
  33. goto invalid_input;
  34. switch (colorformat) {
  35. case MSM_VIDC_FMT_NV12:
  36. case MSM_VIDC_FMT_NV21:
  37. case MSM_VIDC_FMT_NV12C:
  38. alignment = 128;
  39. stride = MSM_MEDIA_ALIGN(width, alignment);
  40. break;
  41. case MSM_VIDC_FMT_TP10C:
  42. alignment = 256;
  43. stride = MSM_MEDIA_ALIGN(width, 192);
  44. stride = MSM_MEDIA_ALIGN(stride * 4 / 3, alignment);
  45. break;
  46. case MSM_VIDC_FMT_P010:
  47. alignment = 256;
  48. stride = MSM_MEDIA_ALIGN(width * 2, alignment);
  49. break;
  50. default:
  51. break;
  52. }
  53. invalid_input:
  54. return stride;
  55. }
  56. /*
  57. * Function arguments:
  58. * @v4l2_fmt
  59. * @width
  60. * Progressive: width
  61. * Interlaced: width
  62. */
  63. static inline unsigned int video_y_stride_pix(unsigned int colorformat,
  64. unsigned int width)
  65. {
  66. unsigned int alignment, stride = 0;
  67. if (!width)
  68. goto invalid_input;
  69. switch (colorformat) {
  70. case MSM_VIDC_FMT_NV12:
  71. case MSM_VIDC_FMT_NV21:
  72. case MSM_VIDC_FMT_NV12C:
  73. case MSM_VIDC_FMT_P010:
  74. alignment = 128;
  75. stride = MSM_MEDIA_ALIGN(width, alignment);
  76. break;
  77. case MSM_VIDC_FMT_TP10C:
  78. alignment = 192;
  79. stride = MSM_MEDIA_ALIGN(width, alignment);
  80. break;
  81. default:
  82. break;
  83. }
  84. invalid_input:
  85. return stride;
  86. }
  87. /*
  88. * Function arguments:
  89. * @v4l2_fmt
  90. * @width
  91. * Progressive: width
  92. * Interlaced: width
  93. */
  94. static inline unsigned int video_uv_stride_bytes(unsigned int colorformat,
  95. unsigned int width)
  96. {
  97. unsigned int alignment, stride = 0;
  98. if (!width)
  99. goto invalid_input;
  100. switch (colorformat) {
  101. case MSM_VIDC_FMT_NV21:
  102. case MSM_VIDC_FMT_NV12:
  103. case MSM_VIDC_FMT_NV12C:
  104. alignment = 128;
  105. stride = MSM_MEDIA_ALIGN(width, alignment);
  106. break;
  107. case MSM_VIDC_FMT_TP10C:
  108. alignment = 256;
  109. stride = MSM_MEDIA_ALIGN(width, 192);
  110. stride = MSM_MEDIA_ALIGN(stride * 4 / 3, alignment);
  111. break;
  112. case MSM_VIDC_FMT_P010:
  113. alignment = 256;
  114. stride = MSM_MEDIA_ALIGN(width * 2, alignment);
  115. break;
  116. default:
  117. break;
  118. }
  119. invalid_input:
  120. return stride;
  121. }
  122. /*
  123. * Function arguments:
  124. * @v4l2_fmt
  125. * @width
  126. * Progressive: width
  127. * Interlaced: width
  128. */
  129. static inline unsigned int video_uv_stride_pix(unsigned int colorformat,
  130. unsigned int width)
  131. {
  132. unsigned int alignment, stride = 0;
  133. if (!width)
  134. goto invalid_input;
  135. switch (colorformat) {
  136. case MSM_VIDC_FMT_NV21:
  137. case MSM_VIDC_FMT_NV12:
  138. case MSM_VIDC_FMT_NV12C:
  139. case MSM_VIDC_FMT_P010:
  140. alignment = 128;
  141. stride = MSM_MEDIA_ALIGN(width, alignment);
  142. break;
  143. case MSM_VIDC_FMT_TP10C:
  144. alignment = 192;
  145. stride = MSM_MEDIA_ALIGN(width, alignment);
  146. break;
  147. default:
  148. break;
  149. }
  150. invalid_input:
  151. return stride;
  152. }
  153. /*
  154. * Function arguments:
  155. * @v4l2_fmt
  156. * @height
  157. * Progressive: height
  158. * Interlaced: (height+1)>>1
  159. */
  160. static inline unsigned int video_y_scanlines(unsigned int colorformat,
  161. unsigned int height)
  162. {
  163. unsigned int alignment, sclines = 0;
  164. if (!height)
  165. goto invalid_input;
  166. switch (colorformat) {
  167. case MSM_VIDC_FMT_NV12:
  168. case MSM_VIDC_FMT_NV21:
  169. case MSM_VIDC_FMT_NV12C:
  170. case MSM_VIDC_FMT_P010:
  171. alignment = 32;
  172. break;
  173. case MSM_VIDC_FMT_TP10C:
  174. alignment = 16;
  175. break;
  176. default:
  177. return 0;
  178. }
  179. sclines = MSM_MEDIA_ALIGN(height, alignment);
  180. invalid_input:
  181. return sclines;
  182. }
  183. /*
  184. * Function arguments:
  185. * @v4l2_fmt
  186. * @height
  187. * Progressive: height
  188. * Interlaced: (height+1)>>1
  189. */
  190. static inline unsigned int video_uv_scanlines(unsigned int colorformat,
  191. unsigned int height)
  192. {
  193. unsigned int alignment, sclines = 0;
  194. if (!height)
  195. goto invalid_input;
  196. switch (colorformat) {
  197. case MSM_VIDC_FMT_NV21:
  198. case MSM_VIDC_FMT_NV12:
  199. case MSM_VIDC_FMT_TP10C:
  200. case MSM_VIDC_FMT_P010:
  201. alignment = 16;
  202. break;
  203. case MSM_VIDC_FMT_NV12C:
  204. alignment = 32;
  205. break;
  206. default:
  207. goto invalid_input;
  208. }
  209. sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, alignment);
  210. invalid_input:
  211. return sclines;
  212. }
  213. /*
  214. * Function arguments:
  215. * @v4l2_fmt
  216. * @width
  217. * Progressive: width
  218. * Interlaced: width
  219. */
  220. static inline unsigned int video_y_meta_stride(unsigned int colorformat,
  221. unsigned int width)
  222. {
  223. int y_tile_width = 0, y_meta_stride = 0;
  224. if (!width)
  225. goto invalid_input;
  226. switch (colorformat) {
  227. case MSM_VIDC_FMT_NV12C:
  228. y_tile_width = 32;
  229. break;
  230. case MSM_VIDC_FMT_TP10C:
  231. y_tile_width = 48;
  232. break;
  233. default:
  234. goto invalid_input;
  235. }
  236. y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width);
  237. y_meta_stride = MSM_MEDIA_ALIGN(y_meta_stride, 64);
  238. invalid_input:
  239. return y_meta_stride;
  240. }
  241. /*
  242. * Function arguments:
  243. * @v4l2_fmt
  244. * @height
  245. * Progressive: height
  246. * Interlaced: (height+1)>>1
  247. */
  248. static inline unsigned int video_y_meta_scanlines(unsigned int colorformat,
  249. unsigned int height)
  250. {
  251. int y_tile_height = 0, y_meta_scanlines = 0;
  252. if (!height)
  253. goto invalid_input;
  254. switch (colorformat) {
  255. case MSM_VIDC_FMT_NV12C:
  256. y_tile_height = 8;
  257. break;
  258. case MSM_VIDC_FMT_TP10C:
  259. y_tile_height = 4;
  260. break;
  261. default:
  262. goto invalid_input;
  263. }
  264. y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height);
  265. y_meta_scanlines = MSM_MEDIA_ALIGN(y_meta_scanlines, 16);
  266. invalid_input:
  267. return y_meta_scanlines;
  268. }
  269. /*
  270. * Function arguments:
  271. * @v4l2_fmt
  272. * @width
  273. * Progressive: width
  274. * Interlaced: width
  275. */
  276. static inline unsigned int video_uv_meta_stride(unsigned int colorformat,
  277. unsigned int width)
  278. {
  279. int uv_tile_width = 0, uv_meta_stride = 0;
  280. if (!width)
  281. goto invalid_input;
  282. switch (colorformat) {
  283. case MSM_VIDC_FMT_NV12C:
  284. uv_tile_width = 16;
  285. break;
  286. case MSM_VIDC_FMT_TP10C:
  287. uv_tile_width = 24;
  288. break;
  289. default:
  290. goto invalid_input;
  291. }
  292. uv_meta_stride = MSM_MEDIA_ROUNDUP((width + 1) >> 1, uv_tile_width);
  293. uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64);
  294. invalid_input:
  295. return uv_meta_stride;
  296. }
  297. /*
  298. * Function arguments:
  299. * @v4l2_fmt
  300. * @height
  301. * Progressive: height
  302. * Interlaced: (height+1)>>1
  303. */
  304. static inline unsigned int video_uv_meta_scanlines(unsigned int colorformat,
  305. unsigned int height)
  306. {
  307. int uv_tile_height = 0, uv_meta_scanlines = 0;
  308. if (!height)
  309. goto invalid_input;
  310. switch (colorformat) {
  311. case MSM_VIDC_FMT_NV12C:
  312. uv_tile_height = 8;
  313. break;
  314. case MSM_VIDC_FMT_TP10C:
  315. uv_tile_height = 4;
  316. break;
  317. default:
  318. goto invalid_input;
  319. }
  320. uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height + 1) >> 1, uv_tile_height);
  321. uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16);
  322. invalid_input:
  323. return uv_meta_scanlines;
  324. }
  325. static inline unsigned int video_rgb_stride_bytes(unsigned int colorformat,
  326. unsigned int width)
  327. {
  328. unsigned int alignment = 0, stride = 0, bpp = 4;
  329. if (!width)
  330. goto invalid_input;
  331. switch (colorformat) {
  332. case MSM_VIDC_FMT_RGBA8888C:
  333. case MSM_VIDC_FMT_RGBA8888:
  334. alignment = 256;
  335. break;
  336. default:
  337. goto invalid_input;
  338. }
  339. stride = MSM_MEDIA_ALIGN(width * bpp, alignment);
  340. invalid_input:
  341. return stride;
  342. }
  343. static inline unsigned int video_rgb_stride_pix(unsigned int colorformat,
  344. unsigned int width)
  345. {
  346. unsigned int bpp = 4;
  347. return video_rgb_stride_bytes(colorformat, width) / bpp;
  348. }
  349. static inline unsigned int video_rgb_scanlines(unsigned int colorformat,
  350. unsigned int height)
  351. {
  352. unsigned int alignment = 0, scanlines = 0;
  353. if (!height)
  354. goto invalid_input;
  355. switch (colorformat) {
  356. case MSM_VIDC_FMT_RGBA8888C:
  357. alignment = 16;
  358. break;
  359. case MSM_VIDC_FMT_RGBA8888:
  360. alignment = 32;
  361. break;
  362. default:
  363. goto invalid_input;
  364. }
  365. scanlines = MSM_MEDIA_ALIGN(height, alignment);
  366. invalid_input:
  367. return scanlines;
  368. }
  369. static inline unsigned int video_rgb_meta_stride(unsigned int colorformat,
  370. unsigned int width)
  371. {
  372. int rgb_tile_width = 0, rgb_meta_stride = 0;
  373. if (!width)
  374. goto invalid_input;
  375. switch (colorformat) {
  376. case MSM_VIDC_FMT_RGBA8888C:
  377. case MSM_VIDC_FMT_RGBA8888:
  378. rgb_tile_width = 16;
  379. break;
  380. default:
  381. goto invalid_input;
  382. }
  383. rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, rgb_tile_width);
  384. rgb_meta_stride = MSM_MEDIA_ALIGN(rgb_meta_stride, 64);
  385. invalid_input:
  386. return rgb_meta_stride;
  387. }
  388. static inline unsigned int video_rgb_meta_scanlines(unsigned int colorformat,
  389. unsigned int height)
  390. {
  391. int rgb_tile_height = 0, rgb_meta_scanlines = 0;
  392. if (!height)
  393. goto invalid_input;
  394. switch (colorformat) {
  395. case MSM_VIDC_FMT_RGBA8888C:
  396. case MSM_VIDC_FMT_RGBA8888:
  397. rgb_tile_height = 4;
  398. break;
  399. default:
  400. goto invalid_input;
  401. }
  402. rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, rgb_tile_height);
  403. rgb_meta_scanlines = MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16);
  404. invalid_input:
  405. return rgb_meta_scanlines;
  406. }
  407. static inline unsigned int video_buffer_size(unsigned int colorformat,
  408. unsigned int pix_width,
  409. unsigned int pix_height,
  410. unsigned int interlace)
  411. {
  412. unsigned int size = 0;
  413. unsigned int y_plane, uv_plane, y_stride,
  414. uv_stride, y_sclines, uv_sclines;
  415. unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0;
  416. unsigned int y_meta_stride = 0, y_meta_scanlines = 0;
  417. unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0;
  418. unsigned int y_meta_plane = 0, uv_meta_plane = 0;
  419. unsigned int rgb_stride = 0, rgb_scanlines = 0;
  420. unsigned int rgb_plane = 0, rgb_ubwc_plane = 0, rgb_meta_plane = 0;
  421. unsigned int rgb_meta_stride = 0, rgb_meta_scanlines = 0;
  422. if (!pix_width || !pix_height)
  423. goto invalid_input;
  424. y_stride = video_y_stride_bytes(colorformat, pix_width);
  425. uv_stride = video_uv_stride_bytes(colorformat, pix_width);
  426. y_sclines = video_y_scanlines(colorformat, pix_height);
  427. uv_sclines = video_uv_scanlines(colorformat, pix_height);
  428. rgb_stride = video_rgb_stride_bytes(colorformat, pix_width);
  429. rgb_scanlines = video_rgb_scanlines(colorformat, pix_height);
  430. switch (colorformat) {
  431. case MSM_VIDC_FMT_NV21:
  432. case MSM_VIDC_FMT_NV12:
  433. case MSM_VIDC_FMT_P010:
  434. y_plane = y_stride * y_sclines;
  435. uv_plane = uv_stride * uv_sclines;
  436. size = y_plane + uv_plane;
  437. break;
  438. case MSM_VIDC_FMT_NV12C:
  439. y_meta_stride = video_y_meta_stride(colorformat, pix_width);
  440. uv_meta_stride = video_uv_meta_stride(colorformat, pix_width);
  441. if (!interlace && colorformat == MSM_VIDC_FMT_NV12C) {
  442. y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
  443. uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
  444. y_meta_scanlines =
  445. video_y_meta_scanlines(colorformat, pix_height);
  446. y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride *
  447. y_meta_scanlines, 4096);
  448. uv_meta_scanlines =
  449. video_uv_meta_scanlines(colorformat, pix_height);
  450. uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
  451. uv_meta_scanlines,
  452. 4096);
  453. size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
  454. uv_meta_plane);
  455. } else {
  456. if (pix_width <= INTERLACE_WIDTH_MAX &&
  457. pix_height <= INTERLACE_HEIGHT_MAX &&
  458. (pix_height * pix_width) / 256 <= INTERLACE_MB_PER_FRAME_MAX) {
  459. y_sclines =
  460. video_y_scanlines(colorformat, (pix_height + 1) >> 1);
  461. y_ubwc_plane =
  462. MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
  463. uv_sclines =
  464. video_uv_scanlines(colorformat, (pix_height + 1) >> 1);
  465. uv_ubwc_plane =
  466. MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
  467. y_meta_scanlines =
  468. video_y_meta_scanlines(colorformat, (pix_height + 1) >> 1);
  469. y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride *
  470. y_meta_scanlines,
  471. 4096);
  472. uv_meta_scanlines =
  473. video_uv_meta_scanlines(colorformat, (pix_height + 1) >> 1);
  474. uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
  475. uv_meta_scanlines,
  476. 4096);
  477. size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
  478. uv_meta_plane)*2;
  479. } else {
  480. y_sclines = video_y_scanlines(colorformat, pix_height);
  481. y_ubwc_plane =
  482. MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
  483. uv_sclines = video_uv_scanlines(colorformat, pix_height);
  484. uv_ubwc_plane =
  485. MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
  486. y_meta_scanlines =
  487. video_y_meta_scanlines(colorformat, pix_height);
  488. y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride *
  489. y_meta_scanlines,
  490. 4096);
  491. uv_meta_scanlines =
  492. video_uv_meta_scanlines(colorformat, pix_height);
  493. uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
  494. uv_meta_scanlines,
  495. 4096);
  496. size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
  497. uv_meta_plane);
  498. }
  499. }
  500. break;
  501. case MSM_VIDC_FMT_TP10C:
  502. y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
  503. uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
  504. y_meta_stride = video_y_meta_stride(colorformat, pix_width);
  505. y_meta_scanlines = video_y_meta_scanlines(colorformat, pix_height);
  506. y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride *
  507. y_meta_scanlines, 4096);
  508. uv_meta_stride = video_uv_meta_stride(colorformat, pix_width);
  509. uv_meta_scanlines = video_uv_meta_scanlines(colorformat, pix_height);
  510. uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
  511. uv_meta_scanlines,
  512. 4096);
  513. size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
  514. uv_meta_plane;
  515. break;
  516. case MSM_VIDC_FMT_RGBA8888C:
  517. rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines,
  518. 4096);
  519. rgb_meta_stride = video_rgb_meta_stride(colorformat, pix_width);
  520. rgb_meta_scanlines = video_rgb_meta_scanlines(colorformat,
  521. pix_height);
  522. rgb_meta_plane = MSM_MEDIA_ALIGN(rgb_meta_stride *
  523. rgb_meta_scanlines, 4096);
  524. size = rgb_ubwc_plane + rgb_meta_plane;
  525. break;
  526. case MSM_VIDC_FMT_RGBA8888:
  527. rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096);
  528. size = rgb_plane;
  529. break;
  530. default:
  531. break;
  532. }
  533. invalid_input:
  534. size = MSM_MEDIA_ALIGN(size, 4096);
  535. return size;
  536. }
  537. #endif