msm_venc.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include <media/v4l2_vidc_extensions.h>
  6. #include "msm_media_info.h"
  7. #include "msm_venc.h"
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vidc_driver.h"
  11. #include "msm_vidc_internal.h"
  12. #include "msm_vidc_platform.h"
  13. #include "msm_vidc_control.h"
  14. #include "msm_vidc_debug.h"
  15. #include "msm_vidc_power.h"
  16. #include "venus_hfi.h"
  17. #include "hfi_packet.h"
  18. static const u32 msm_venc_input_set_prop[] = {
  19. HFI_PROP_COLOR_FORMAT,
  20. HFI_PROP_RAW_RESOLUTION,
  21. HFI_PROP_LINEAR_STRIDE_SCANLINE,
  22. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  23. HFI_PROP_SIGNAL_COLOR_INFO,
  24. };
  25. static const u32 msm_venc_output_set_prop[] = {
  26. HFI_PROP_BITSTREAM_RESOLUTION,
  27. HFI_PROP_CROP_OFFSETS,
  28. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  29. HFI_PROP_CSC,
  30. };
  31. static const u32 msm_venc_input_subscribe_for_properties[] = {
  32. HFI_PROP_NO_OUTPUT,
  33. };
  34. static const u32 msm_venc_output_subscribe_for_properties[] = {
  35. HFI_PROP_PICTURE_TYPE,
  36. HFI_PROP_BUFFER_MARK,
  37. HFI_PROP_WORST_COMPRESSION_RATIO,
  38. };
  39. static const u32 msm_venc_output_internal_buffer_type[] = {
  40. MSM_VIDC_BUF_BIN,
  41. MSM_VIDC_BUF_COMV,
  42. MSM_VIDC_BUF_NON_COMV,
  43. MSM_VIDC_BUF_LINE,
  44. MSM_VIDC_BUF_DPB,
  45. };
  46. static const u32 msm_venc_input_internal_buffer_type[] = {
  47. MSM_VIDC_BUF_VPSS,
  48. };
  49. struct msm_venc_prop_type_handle {
  50. u32 type;
  51. int (*handle)(struct msm_vidc_inst *inst, enum msm_vidc_port_type port);
  52. };
  53. static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 v4l2_codec)
  54. {
  55. int rc = 0;
  56. if (inst->codec && inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat == v4l2_codec)
  57. return 0;
  58. i_vpr_h(inst, "%s: codec changed from %#x to %#x\n",
  59. __func__, inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, v4l2_codec);
  60. inst->codec = v4l2_codec_to_driver(v4l2_codec, __func__);
  61. rc = msm_vidc_update_debug_str(inst);
  62. if (rc)
  63. goto exit;
  64. rc = msm_vidc_get_inst_capability(inst);
  65. if (rc)
  66. goto exit;
  67. rc = msm_vidc_ctrl_deinit(inst);
  68. if (rc)
  69. goto exit;
  70. rc = msm_vidc_ctrl_init(inst);
  71. if (rc)
  72. goto exit;
  73. exit:
  74. return rc;
  75. }
  76. /* todo: add logs for each property once finalised */
  77. static int msm_venc_set_colorformat(struct msm_vidc_inst *inst,
  78. enum msm_vidc_port_type port)
  79. {
  80. int rc = 0;
  81. u32 pixelformat;
  82. enum msm_vidc_colorformat_type colorformat;
  83. u32 hfi_colorformat;
  84. if (port != INPUT_PORT) {
  85. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  86. return -EINVAL;
  87. }
  88. pixelformat = inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat;
  89. colorformat = v4l2_colorformat_to_driver(pixelformat, __func__);
  90. if (!(colorformat & inst->capabilities->cap[PIX_FMTS].step_or_mask)) {
  91. i_vpr_e(inst, "%s: invalid pixelformat %#x\n",
  92. __func__, pixelformat);
  93. return -EINVAL;
  94. }
  95. hfi_colorformat = get_hfi_colorformat(inst, colorformat);
  96. i_vpr_h(inst, "%s: hfi colorformat: %#x", __func__,
  97. hfi_colorformat);
  98. rc = venus_hfi_session_property(inst,
  99. HFI_PROP_COLOR_FORMAT,
  100. HFI_HOST_FLAGS_NONE,
  101. get_hfi_port(inst, port),
  102. HFI_PAYLOAD_U32_ENUM,
  103. &hfi_colorformat,
  104. sizeof(u32));
  105. if (rc)
  106. return rc;
  107. return 0;
  108. }
  109. static int msm_venc_set_stride_scanline(struct msm_vidc_inst *inst,
  110. enum msm_vidc_port_type port)
  111. {
  112. int rc = 0;
  113. u32 color_format, stride_y, scanline_y;
  114. u32 stride_uv = 0, scanline_uv = 0;
  115. u32 payload[2];
  116. if (port != INPUT_PORT) {
  117. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  118. return -EINVAL;
  119. }
  120. color_format = inst->capabilities->cap[PIX_FMTS].value;
  121. if (!is_linear_colorformat(color_format)) {
  122. i_vpr_h(inst,
  123. "%s: not a linear color fmt, property is not set\n",
  124. __func__);
  125. return 0;
  126. }
  127. stride_y = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
  128. scanline_y = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
  129. if (color_format == MSM_VIDC_FMT_NV12 ||
  130. color_format == MSM_VIDC_FMT_P010) {
  131. stride_uv = stride_y;
  132. scanline_uv = scanline_y / 2;
  133. }
  134. payload[0] = stride_y << 16 | scanline_y;
  135. payload[1] = stride_uv << 16 | scanline_uv;
  136. i_vpr_h(inst, "%s: stride_y: %d scanline_y: %d "
  137. "stride_uv: %d, scanline_uv: %d", __func__,
  138. stride_y, scanline_y, stride_uv, scanline_uv);
  139. rc = venus_hfi_session_property(inst,
  140. HFI_PROP_LINEAR_STRIDE_SCANLINE,
  141. HFI_HOST_FLAGS_NONE,
  142. get_hfi_port(inst, port),
  143. HFI_PAYLOAD_64_PACKED,
  144. &payload,
  145. sizeof(u64));
  146. if (rc)
  147. return rc;
  148. return 0;
  149. }
  150. static int msm_venc_set_raw_resolution(struct msm_vidc_inst *inst,
  151. enum msm_vidc_port_type port)
  152. {
  153. int rc = 0;
  154. u32 resolution;
  155. if (port != INPUT_PORT) {
  156. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  157. return -EINVAL;
  158. }
  159. resolution = inst->crop.width << 16 | inst->crop.height;
  160. i_vpr_h(inst, "%s: width: %d height: %d\n", __func__,
  161. inst->crop.width, inst->crop.height);
  162. rc = venus_hfi_session_property(inst,
  163. HFI_PROP_RAW_RESOLUTION,
  164. HFI_HOST_FLAGS_NONE,
  165. get_hfi_port(inst, port),
  166. HFI_PAYLOAD_32_PACKED,
  167. &resolution,
  168. sizeof(u32));
  169. if (rc)
  170. return rc;
  171. return 0;
  172. }
  173. static int msm_venc_set_bitstream_resolution(struct msm_vidc_inst *inst,
  174. enum msm_vidc_port_type port)
  175. {
  176. int rc = 0;
  177. u32 resolution;
  178. if (port != OUTPUT_PORT) {
  179. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  180. return -EINVAL;
  181. }
  182. resolution = (inst->fmts[port].fmt.pix_mp.width << 16) |
  183. inst->fmts[port].fmt.pix_mp.height;
  184. i_vpr_h(inst, "%s: width: %d height: %d\n", __func__,
  185. inst->fmts[port].fmt.pix_mp.width,
  186. inst->fmts[port].fmt.pix_mp.height);
  187. rc = venus_hfi_session_property(inst,
  188. HFI_PROP_BITSTREAM_RESOLUTION,
  189. HFI_HOST_FLAGS_NONE,
  190. get_hfi_port(inst, port),
  191. HFI_PAYLOAD_32_PACKED,
  192. &resolution,
  193. sizeof(u32));
  194. if (rc)
  195. return rc;
  196. return 0;
  197. }
  198. static int msm_venc_set_crop_offsets(struct msm_vidc_inst *inst,
  199. enum msm_vidc_port_type port)
  200. {
  201. int rc = 0;
  202. u32 left_offset, top_offset, right_offset, bottom_offset;
  203. u32 crop[2] = {0};
  204. u32 width, height;
  205. if (port != OUTPUT_PORT) {
  206. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  207. return -EINVAL;
  208. }
  209. left_offset = inst->compose.left;
  210. top_offset = inst->compose.top;
  211. width = inst->compose.width;
  212. height = inst->compose.height;
  213. if (inst->capabilities->cap[ROTATION].value == 90 ||
  214. inst->capabilities->cap[ROTATION].value == 270) {
  215. width = inst->compose.height;
  216. height = inst->compose.width;
  217. }
  218. right_offset = (inst->fmts[port].fmt.pix_mp.width - width);
  219. bottom_offset = (inst->fmts[port].fmt.pix_mp.height - height);
  220. if (is_image_session(inst))
  221. right_offset = bottom_offset = 0;
  222. crop[0] = left_offset << 16 | top_offset;
  223. crop[1] = right_offset << 16 | bottom_offset;
  224. i_vpr_h(inst, "%s: left_offset: %d top_offset: %d "
  225. "right_offset: %d bottom_offset: %d", __func__,
  226. left_offset, top_offset, right_offset, bottom_offset);
  227. rc = venus_hfi_session_property(inst,
  228. HFI_PROP_CROP_OFFSETS,
  229. HFI_HOST_FLAGS_NONE,
  230. get_hfi_port(inst, port),
  231. HFI_PAYLOAD_64_PACKED,
  232. &crop,
  233. sizeof(u64));
  234. if (rc)
  235. return rc;
  236. return 0;
  237. }
  238. static int msm_venc_set_host_max_buf_count(struct msm_vidc_inst *inst,
  239. enum msm_vidc_port_type port)
  240. {
  241. int rc = 0;
  242. u32 count = DEFAULT_MAX_HOST_BUF_COUNT;
  243. if (msm_vidc_is_super_buffer(inst) || is_image_session(inst))
  244. count = DEFAULT_MAX_HOST_BURST_BUF_COUNT;
  245. i_vpr_h(inst, "%s: count: %u port: %u\n", __func__, count, port);
  246. rc = venus_hfi_session_property(inst,
  247. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  248. HFI_HOST_FLAGS_NONE,
  249. get_hfi_port(inst, port),
  250. HFI_PAYLOAD_U32,
  251. &count,
  252. sizeof(u32));
  253. if (rc)
  254. return rc;
  255. return 0;
  256. }
  257. static int msm_venc_set_colorspace(struct msm_vidc_inst* inst,
  258. enum msm_vidc_port_type port)
  259. {
  260. int rc = 0;
  261. u32 primaries = MSM_VIDC_PRIMARIES_RESERVED;
  262. u32 matrix_coeff = MSM_VIDC_MATRIX_COEFF_RESERVED;
  263. u32 transfer_char = MSM_VIDC_TRANSFER_RESERVED;
  264. u32 full_range = V4L2_QUANTIZATION_DEFAULT;
  265. u32 colour_description_present_flag = 0;
  266. u32 video_signal_type_present_flag = 0, payload = 0;
  267. /* Unspecified video format */
  268. u32 video_format = 5;
  269. if (port != INPUT_PORT) {
  270. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  271. return -EINVAL;
  272. }
  273. if (inst->fmts[port].fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT ||
  274. inst->fmts[port].fmt.pix_mp.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
  275. inst->fmts[port].fmt.pix_mp.xfer_func != V4L2_XFER_FUNC_DEFAULT) {
  276. colour_description_present_flag = 1;
  277. video_signal_type_present_flag = 1;
  278. primaries = v4l2_color_primaries_to_driver(inst,
  279. inst->fmts[port].fmt.pix_mp.colorspace, __func__);
  280. matrix_coeff = v4l2_matrix_coeff_to_driver(inst,
  281. inst->fmts[port].fmt.pix_mp.ycbcr_enc, __func__);
  282. transfer_char = v4l2_transfer_char_to_driver(inst,
  283. inst->fmts[port].fmt.pix_mp.xfer_func, __func__);
  284. }
  285. if (inst->fmts[port].fmt.pix_mp.quantization !=
  286. V4L2_QUANTIZATION_DEFAULT) {
  287. video_signal_type_present_flag = 1;
  288. full_range = inst->fmts[port].fmt.pix_mp.quantization ==
  289. V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
  290. }
  291. payload = (matrix_coeff & 0xFF) |
  292. ((transfer_char << 8) & 0xFF00) |
  293. ((primaries << 16) & 0xFF0000) |
  294. ((colour_description_present_flag << 24) & 0x1000000) |
  295. ((full_range << 25) & 0x2000000) |
  296. ((video_format << 26) & 0x1C000000) |
  297. ((video_signal_type_present_flag << 29) & 0x20000000);
  298. i_vpr_h(inst, "%s: color info: %#x\n", __func__, payload);
  299. rc = venus_hfi_session_property(inst,
  300. HFI_PROP_SIGNAL_COLOR_INFO,
  301. HFI_HOST_FLAGS_NONE,
  302. get_hfi_port(inst, port),
  303. HFI_PAYLOAD_32_PACKED,
  304. &payload,
  305. sizeof(u32));
  306. if (rc)
  307. return rc;
  308. return 0;
  309. }
  310. static bool msm_venc_csc_required(struct msm_vidc_inst* inst)
  311. {
  312. struct v4l2_format *in_fmt = &inst->fmts[INPUT_PORT];
  313. struct v4l2_format *out_fmt = &inst->fmts[OUTPUT_PORT];
  314. /* video hardware supports conversion to REC709 CSC only */
  315. if (in_fmt->fmt.pix_mp.colorspace != out_fmt->fmt.pix_mp.colorspace &&
  316. out_fmt->fmt.pix_mp.colorspace == V4L2_COLORSPACE_REC709)
  317. return true;
  318. return false;
  319. }
  320. static int msm_venc_set_csc(struct msm_vidc_inst* inst,
  321. enum msm_vidc_port_type port)
  322. {
  323. int rc = 0;
  324. u32 csc = 0;
  325. if (port != OUTPUT_PORT) {
  326. i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
  327. return -EINVAL;
  328. }
  329. msm_vidc_update_cap_value(inst, CSC,
  330. msm_venc_csc_required(inst) ? 1 : 0, __func__);
  331. csc = inst->capabilities->cap[CSC].value;
  332. i_vpr_h(inst, "%s: csc: %u\n", __func__, csc);
  333. rc = venus_hfi_session_property(inst,
  334. HFI_PROP_CSC,
  335. HFI_HOST_FLAGS_NONE,
  336. get_hfi_port(inst, port),
  337. HFI_PAYLOAD_U32,
  338. &csc,
  339. sizeof(u32));
  340. if (rc)
  341. return rc;
  342. return 0;
  343. }
  344. static int msm_venc_set_quality_mode(struct msm_vidc_inst *inst)
  345. {
  346. int rc = 0;
  347. struct msm_vidc_core* core = inst->core;
  348. struct msm_vidc_inst_capability *capability = inst->capabilities;
  349. u32 mode;
  350. rc = call_session_op(core, decide_quality_mode, inst);
  351. if (rc) {
  352. i_vpr_e(inst, "%s: decide_work_route failed\n",
  353. __func__);
  354. return -EINVAL;
  355. }
  356. mode = capability->cap[QUALITY_MODE].value;
  357. i_vpr_h(inst, "%s: quality_mode: %u\n", __func__, mode);
  358. rc = venus_hfi_session_property(inst,
  359. HFI_PROP_QUALITY_MODE,
  360. HFI_HOST_FLAGS_NONE,
  361. HFI_PORT_BITSTREAM,
  362. HFI_PAYLOAD_U32_ENUM,
  363. &mode,
  364. sizeof(u32));
  365. if (rc)
  366. return rc;
  367. return 0;
  368. }
  369. static int msm_venc_set_input_properties(struct msm_vidc_inst *inst)
  370. {
  371. int i, j, rc = 0;
  372. static const struct msm_venc_prop_type_handle prop_type_handle_arr[] = {
  373. {HFI_PROP_COLOR_FORMAT, msm_venc_set_colorformat },
  374. {HFI_PROP_RAW_RESOLUTION, msm_venc_set_raw_resolution },
  375. {HFI_PROP_LINEAR_STRIDE_SCANLINE, msm_venc_set_stride_scanline },
  376. {HFI_PROP_BUFFER_HOST_MAX_COUNT, msm_venc_set_host_max_buf_count },
  377. {HFI_PROP_SIGNAL_COLOR_INFO, msm_venc_set_colorspace },
  378. };
  379. if (!inst) {
  380. d_vpr_e("%s: invalid params\n", __func__);
  381. return -EINVAL;
  382. }
  383. i_vpr_h(inst, "%s()\n", __func__);
  384. for (i = 0; i < ARRAY_SIZE(msm_venc_input_set_prop); i++) {
  385. /* set session input properties */
  386. for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
  387. if (prop_type_handle_arr[j].type == msm_venc_input_set_prop[i]) {
  388. rc = prop_type_handle_arr[j].handle(inst, INPUT_PORT);
  389. if (rc)
  390. goto exit;
  391. break;
  392. }
  393. }
  394. /* is property type unknown ? */
  395. if (j == ARRAY_SIZE(prop_type_handle_arr))
  396. i_vpr_e(inst, "%s: unknown property %#x\n", __func__,
  397. msm_venc_input_set_prop[i]);
  398. }
  399. exit:
  400. return rc;
  401. }
  402. static int msm_venc_set_output_properties(struct msm_vidc_inst *inst)
  403. {
  404. int i, j, rc = 0;
  405. static const struct msm_venc_prop_type_handle prop_type_handle_arr[] = {
  406. {HFI_PROP_BITSTREAM_RESOLUTION, msm_venc_set_bitstream_resolution },
  407. {HFI_PROP_CROP_OFFSETS, msm_venc_set_crop_offsets },
  408. {HFI_PROP_BUFFER_HOST_MAX_COUNT, msm_venc_set_host_max_buf_count },
  409. {HFI_PROP_CSC, msm_venc_set_csc },
  410. };
  411. if (!inst) {
  412. d_vpr_e("%s: invalid params\n", __func__);
  413. return -EINVAL;
  414. }
  415. i_vpr_h(inst, "%s()\n", __func__);
  416. for (i = 0; i < ARRAY_SIZE(msm_venc_output_set_prop); i++) {
  417. /* set session output properties */
  418. for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
  419. if (prop_type_handle_arr[j].type == msm_venc_output_set_prop[i]) {
  420. rc = prop_type_handle_arr[j].handle(inst, OUTPUT_PORT);
  421. if (rc)
  422. goto exit;
  423. break;
  424. }
  425. }
  426. /* is property type unknown ? */
  427. if (j == ARRAY_SIZE(prop_type_handle_arr))
  428. i_vpr_e(inst, "%s: unknown property %#x\n", __func__,
  429. msm_venc_output_set_prop[i]);
  430. }
  431. exit:
  432. return rc;
  433. }
  434. static int msm_venc_set_internal_properties(struct msm_vidc_inst *inst)
  435. {
  436. int rc = 0;
  437. if (!inst) {
  438. d_vpr_e("%s: invalid params\n", __func__);
  439. return -EINVAL;
  440. }
  441. i_vpr_h(inst, "%s()\n", __func__);
  442. rc = msm_venc_set_quality_mode(inst);
  443. if (rc)
  444. return rc;
  445. return rc;
  446. }
  447. static int msm_venc_get_input_internal_buffers(struct msm_vidc_inst *inst)
  448. {
  449. int i, rc = 0;
  450. struct msm_vidc_core *core;
  451. if (!inst || !inst->core) {
  452. d_vpr_e("%s: invalid params\n", __func__);
  453. return -EINVAL;
  454. }
  455. core = inst->core;
  456. for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) {
  457. rc = msm_vidc_get_internal_buffers(inst,
  458. msm_venc_input_internal_buffer_type[i]);
  459. if (rc)
  460. return rc;
  461. }
  462. return rc;
  463. }
  464. static int msm_venc_create_input_internal_buffers(struct msm_vidc_inst *inst)
  465. {
  466. int i, rc = 0;
  467. if (!inst || !inst->core) {
  468. d_vpr_e("%s: invalid params\n", __func__);
  469. return -EINVAL;
  470. }
  471. for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) {
  472. rc = msm_vidc_create_internal_buffers(inst,
  473. msm_venc_input_internal_buffer_type[i]);
  474. if (rc)
  475. return rc;
  476. }
  477. return rc;
  478. }
  479. static int msm_venc_queue_input_internal_buffers(struct msm_vidc_inst *inst)
  480. {
  481. int i, rc = 0;
  482. if (!inst || !inst->core) {
  483. d_vpr_e("%s: invalid params\n", __func__);
  484. return -EINVAL;
  485. }
  486. for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) {
  487. rc = msm_vidc_queue_internal_buffers(inst,
  488. msm_venc_input_internal_buffer_type[i]);
  489. if (rc)
  490. return rc;
  491. }
  492. return rc;
  493. }
  494. static int msm_venc_get_output_internal_buffers(struct msm_vidc_inst *inst)
  495. {
  496. int i, rc = 0;
  497. struct msm_vidc_core *core;
  498. if (!inst || !inst->core) {
  499. d_vpr_e("%s: invalid params\n", __func__);
  500. return -EINVAL;
  501. }
  502. core = inst->core;
  503. for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) {
  504. rc = msm_vidc_get_internal_buffers(inst,
  505. msm_venc_output_internal_buffer_type[i]);
  506. if (rc)
  507. return rc;
  508. }
  509. return rc;
  510. }
  511. static int msm_venc_create_output_internal_buffers(struct msm_vidc_inst *inst)
  512. {
  513. int i, rc = 0;
  514. if (!inst || !inst->core) {
  515. d_vpr_e("%s: invalid params\n", __func__);
  516. return -EINVAL;
  517. }
  518. for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) {
  519. rc = msm_vidc_create_internal_buffers(inst,
  520. msm_venc_output_internal_buffer_type[i]);
  521. if (rc)
  522. return rc;
  523. }
  524. return 0;
  525. }
  526. static int msm_venc_queue_output_internal_buffers(struct msm_vidc_inst *inst)
  527. {
  528. int i, rc = 0;
  529. if (!inst || !inst->core) {
  530. d_vpr_e("%s: invalid params\n", __func__);
  531. return -EINVAL;
  532. }
  533. for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) {
  534. rc = msm_vidc_queue_internal_buffers(inst,
  535. msm_venc_output_internal_buffer_type[i]);
  536. if (rc)
  537. return rc;
  538. }
  539. return 0;
  540. }
  541. static int msm_venc_property_subscription(struct msm_vidc_inst *inst,
  542. enum msm_vidc_port_type port)
  543. {
  544. int rc = 0;
  545. struct msm_vidc_core *core;
  546. u32 payload[32] = {0};
  547. u32 i;
  548. u32 payload_size = 0;
  549. if (!inst || !inst->core) {
  550. d_vpr_e("%s: invalid params\n", __func__);
  551. return -EINVAL;
  552. }
  553. core = inst->core;
  554. i_vpr_h(inst, "%s()\n", __func__);
  555. payload[0] = HFI_MODE_PROPERTY;
  556. if (port == INPUT_PORT) {
  557. for (i = 0; i < ARRAY_SIZE(msm_venc_input_subscribe_for_properties); i++)
  558. payload[i + 1] = msm_venc_input_subscribe_for_properties[i];
  559. payload_size = (ARRAY_SIZE(msm_venc_input_subscribe_for_properties) + 1) *
  560. sizeof(u32);
  561. } else if (port == OUTPUT_PORT) {
  562. for (i = 0; i < ARRAY_SIZE(msm_venc_output_subscribe_for_properties); i++)
  563. payload[i + 1] = msm_venc_output_subscribe_for_properties[i];
  564. payload_size = (ARRAY_SIZE(msm_venc_output_subscribe_for_properties) + 1) *
  565. sizeof(u32);
  566. } else {
  567. i_vpr_e(inst, "%s: invalid port: %d\n", __func__, port);
  568. return -EINVAL;
  569. }
  570. rc = venus_hfi_session_command(inst,
  571. HFI_CMD_SUBSCRIBE_MODE,
  572. port,
  573. HFI_PAYLOAD_U32_ARRAY,
  574. &payload[0],
  575. payload_size);
  576. return rc;
  577. }
  578. static int msm_venc_metadata_delivery(struct msm_vidc_inst *inst,
  579. enum msm_vidc_port_type port)
  580. {
  581. int rc = 0;
  582. struct msm_vidc_core *core;
  583. u32 payload[32] = {0};
  584. u32 i, count = 0;
  585. struct msm_vidc_inst_capability *capability;
  586. static const u32 metadata_list[] = {
  587. META_SEI_MASTERING_DISP,
  588. META_SEI_CLL,
  589. META_HDR10PLUS,
  590. META_EVA_STATS,
  591. META_BUF_TAG,
  592. META_ROI_INFO,
  593. };
  594. if (!inst || !inst->core) {
  595. d_vpr_e("%s: invalid params\n", __func__);
  596. return -EINVAL;
  597. }
  598. core = inst->core;
  599. i_vpr_h(inst, "%s()\n", __func__);
  600. capability = inst->capabilities;
  601. payload[0] = HFI_MODE_METADATA;
  602. for (i = 0; i < ARRAY_SIZE(metadata_list); i++) {
  603. if (capability->cap[metadata_list[i]].value) {
  604. payload[count + 1] =
  605. capability->cap[metadata_list[i]].hfi_id;
  606. count++;
  607. }
  608. };
  609. // TODO: remove below check later
  610. if (!count)
  611. return 0;
  612. rc = venus_hfi_session_command(inst,
  613. HFI_CMD_DELIVERY_MODE,
  614. port,
  615. HFI_PAYLOAD_U32_ARRAY,
  616. &payload[0],
  617. (count + 1) * sizeof(u32));
  618. return rc;
  619. }
  620. static int msm_venc_metadata_subscription(struct msm_vidc_inst *inst,
  621. enum msm_vidc_port_type port)
  622. {
  623. int rc = 0;
  624. struct msm_vidc_core *core;
  625. u32 payload[32] = {0};
  626. u32 i, count = 0;
  627. struct msm_vidc_inst_capability *capability;
  628. static const u32 metadata_list[] = {
  629. META_LTR_MARK_USE,
  630. META_SEQ_HDR_NAL,
  631. META_TIMESTAMP,
  632. META_BUF_TAG,
  633. META_SUBFRAME_OUTPUT,
  634. META_ENC_QP_METADATA,
  635. };
  636. if (!inst || !inst->core) {
  637. d_vpr_e("%s: invalid params\n", __func__);
  638. return -EINVAL;
  639. }
  640. core = inst->core;
  641. i_vpr_h(inst, "%s()\n", __func__);
  642. capability = inst->capabilities;
  643. payload[0] = HFI_MODE_METADATA;
  644. for (i = 0; i < ARRAY_SIZE(metadata_list); i++) {
  645. if (capability->cap[metadata_list[i]].value) {
  646. payload[count + 1] =
  647. capability->cap[metadata_list[i]].hfi_id;
  648. count++;
  649. }
  650. };
  651. // TODO: remove below check later
  652. if (!count)
  653. return 0;
  654. rc = venus_hfi_session_command(inst,
  655. HFI_CMD_SUBSCRIBE_MODE,
  656. port,
  657. HFI_PAYLOAD_U32_ARRAY,
  658. &payload[0],
  659. (count + 1) * sizeof(u32));
  660. return rc;
  661. }
  662. int msm_venc_streamoff_input(struct msm_vidc_inst *inst)
  663. {
  664. int rc = 0;
  665. if (!inst || !inst->core || !inst->capabilities) {
  666. d_vpr_e("%s: invalid params\n", __func__);
  667. return -EINVAL;
  668. }
  669. rc = msm_vidc_session_streamoff(inst, INPUT_PORT);
  670. if (rc)
  671. return rc;
  672. return 0;
  673. }
  674. int msm_venc_streamon_input(struct msm_vidc_inst *inst)
  675. {
  676. int rc = 0;
  677. if (!inst || !inst->core || !inst->capabilities) {
  678. d_vpr_e("%s: invalid params\n", __func__);
  679. return -EINVAL;
  680. }
  681. if (is_input_meta_enabled(inst) &&
  682. !inst->vb2q[INPUT_META_PORT].streaming) {
  683. i_vpr_e(inst,
  684. "%s: Meta port must be streamed on before data port\n",
  685. __func__);
  686. return -EINVAL;
  687. }
  688. rc = msm_vidc_check_session_supported(inst);
  689. if (rc)
  690. goto error;
  691. rc = msm_vidc_check_scaling_supported(inst);
  692. if (rc)
  693. goto error;
  694. rc = msm_venc_set_input_properties(inst);
  695. if (rc)
  696. goto error;
  697. /* Decide bse vpp delay after work mode */
  698. //msm_vidc_set_bse_vpp_delay(inst);
  699. rc = msm_venc_get_input_internal_buffers(inst);
  700. if (rc)
  701. goto error;
  702. rc = msm_venc_create_input_internal_buffers(inst);
  703. if (rc)
  704. goto error;
  705. rc = msm_venc_queue_input_internal_buffers(inst);
  706. if (rc)
  707. goto error;
  708. rc = msm_venc_property_subscription(inst, INPUT_PORT);
  709. if (rc)
  710. return rc;
  711. rc = msm_venc_metadata_delivery(inst, INPUT_PORT);
  712. if (rc)
  713. return rc;
  714. rc = msm_vidc_session_streamon(inst, INPUT_PORT);
  715. if (rc)
  716. goto error;
  717. return 0;
  718. error:
  719. i_vpr_e(inst, "%s: failed\n", __func__);
  720. msm_venc_streamoff_input(inst);
  721. return rc;
  722. }
  723. int msm_venc_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
  724. {
  725. int rc = 0;
  726. rc = msm_vidc_queue_buffer_single(inst, vb2);
  727. if (rc)
  728. return rc;
  729. return rc;
  730. }
  731. int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
  732. {
  733. int rc = 0;
  734. enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
  735. if (!inst || !inst->core) {
  736. d_vpr_e("%s: invalid params\n", __func__);
  737. return -EINVAL;
  738. }
  739. if (cmd == V4L2_ENC_CMD_STOP) {
  740. i_vpr_h(inst, "received cmd: drain\n");
  741. allow = msm_vidc_allow_stop(inst);
  742. if (allow == MSM_VIDC_DISALLOW)
  743. return -EBUSY;
  744. else if (allow == MSM_VIDC_IGNORE)
  745. return 0;
  746. else if (allow != MSM_VIDC_ALLOW)
  747. return -EINVAL;
  748. rc = venus_hfi_session_command(inst,
  749. HFI_CMD_DRAIN,
  750. INPUT_PORT,
  751. HFI_PAYLOAD_NONE,
  752. NULL,
  753. 0);
  754. if (rc)
  755. return rc;
  756. rc = msm_vidc_state_change_stop(inst);
  757. if (rc)
  758. return rc;
  759. } else if (cmd == V4L2_ENC_CMD_START) {
  760. i_vpr_h(inst, "received cmd: resume\n");
  761. if (!msm_vidc_allow_start(inst))
  762. return -EBUSY;
  763. vb2_clear_last_buffer_dequeued(&inst->vb2q[OUTPUT_META_PORT]);
  764. vb2_clear_last_buffer_dequeued(&inst->vb2q[OUTPUT_PORT]);
  765. rc = msm_vidc_state_change_start(inst);
  766. if (rc)
  767. return rc;
  768. /* tune power features */
  769. msm_vidc_allow_dcvs(inst);
  770. msm_vidc_power_data_reset(inst);
  771. /* print final buffer counts & size details */
  772. msm_vidc_print_buffer_info(inst);
  773. rc = venus_hfi_session_command(inst,
  774. HFI_CMD_RESUME,
  775. INPUT_PORT,
  776. HFI_PAYLOAD_NONE,
  777. NULL,
  778. 0);
  779. if (rc)
  780. return rc;
  781. } else {
  782. i_vpr_e(inst, "%s: unknown cmd %d\n", __func__, cmd);
  783. return -EINVAL;
  784. }
  785. return 0;
  786. }
  787. int msm_venc_streamoff_output(struct msm_vidc_inst *inst)
  788. {
  789. int rc = 0;
  790. struct msm_vidc_core *core;
  791. if (!inst || !inst->core || !inst->capabilities) {
  792. d_vpr_e("%s: invalid params\n", __func__);
  793. return -EINVAL;
  794. }
  795. core = inst->core;
  796. if (!core->capabilities) {
  797. i_vpr_e(inst, "%s: core capabilities is NULL\n", __func__);
  798. return -EINVAL;
  799. }
  800. /* restore LAYER_COUNT max allowed value */
  801. inst->capabilities->cap[ENH_LAYER_COUNT].max =
  802. core->capabilities[MAX_ENH_LAYER_COUNT].value;
  803. rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
  804. if (rc)
  805. return rc;
  806. return 0;
  807. }
  808. int msm_venc_streamon_output(struct msm_vidc_inst *inst)
  809. {
  810. int rc = 0;
  811. if (!inst || !inst->core || !inst->capabilities) {
  812. d_vpr_e("%s: invalid params\n", __func__);
  813. return -EINVAL;
  814. }
  815. if (is_output_meta_enabled(inst) &&
  816. !inst->vb2q[OUTPUT_META_PORT].streaming) {
  817. i_vpr_e(inst,
  818. "%s: Meta port must be streamed on before data port\n",
  819. __func__);
  820. return -EINVAL;
  821. }
  822. rc = msm_vidc_adjust_v4l2_properties(inst);
  823. if (rc)
  824. goto error;
  825. rc = msm_venc_set_output_properties(inst);
  826. if (rc)
  827. goto error;
  828. rc = msm_vidc_set_v4l2_properties(inst);
  829. if (rc)
  830. goto error;
  831. rc = msm_venc_get_output_internal_buffers(inst);
  832. if (rc)
  833. goto error;
  834. rc = msm_venc_create_output_internal_buffers(inst);
  835. if (rc)
  836. goto error;
  837. rc = msm_venc_queue_output_internal_buffers(inst);
  838. if (rc)
  839. goto error;
  840. rc = msm_venc_set_internal_properties(inst);
  841. if (rc)
  842. goto error;
  843. rc = msm_venc_property_subscription(inst, OUTPUT_PORT);
  844. if (rc)
  845. goto error;
  846. rc = msm_venc_metadata_subscription(inst, OUTPUT_PORT);
  847. if (rc)
  848. goto error;
  849. rc = msm_vidc_session_streamon(inst, OUTPUT_PORT);
  850. if (rc)
  851. goto error;
  852. return 0;
  853. error:
  854. i_vpr_e(inst, "%s: failed\n", __func__);
  855. msm_venc_streamoff_output(inst);
  856. return rc;
  857. }
  858. int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f)
  859. {
  860. int rc = 0;
  861. struct v4l2_format *fmt;
  862. struct msm_vidc_core *core;
  863. u32 codec_align;
  864. u32 width, height;
  865. if (!inst || !inst->core || !f) {
  866. d_vpr_e("%s: invalid params\n", __func__);
  867. return -EINVAL;
  868. }
  869. core = inst->core;
  870. fmt = &inst->fmts[OUTPUT_PORT];
  871. if (fmt->fmt.pix_mp.pixelformat != f->fmt.pix_mp.pixelformat) {
  872. i_vpr_h(inst,
  873. "%s: codec changed from %#x to %#x\n", __func__,
  874. fmt->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat);
  875. rc = msm_venc_codec_change(inst, f->fmt.pix_mp.pixelformat);
  876. if (rc)
  877. return rc;
  878. }
  879. fmt->type = OUTPUT_MPLANE;
  880. codec_align = (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC ||
  881. f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEIC) ? 32 : 16;
  882. /* use rotated width height if rotation is enabled */
  883. width = inst->compose.width;
  884. height = inst->compose.height;
  885. if (inst->capabilities->cap[ROTATION].value == 90 ||
  886. inst->capabilities->cap[ROTATION].value == 270) {
  887. width = inst->compose.height;
  888. height = inst->compose.width;
  889. }
  890. /* width, height is readonly for client */
  891. fmt->fmt.pix_mp.width = ALIGN(width, codec_align);
  892. fmt->fmt.pix_mp.height = ALIGN(height, codec_align);
  893. /* use grid dimension for image session */
  894. if (is_image_session(inst))
  895. fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.height = HEIC_GRID_DIMENSION;
  896. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  897. fmt->fmt.pix_mp.num_planes = 1;
  898. fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  899. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  900. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  901. /* video hw supports conversion to V4L2_COLORSPACE_REC709 only */
  902. if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT &&
  903. f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709)
  904. f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
  905. fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
  906. fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
  907. fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
  908. fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
  909. inst->buffers.output.min_count = call_session_op(core,
  910. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  911. inst->buffers.output.extra_count = call_session_op(core,
  912. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  913. if (inst->buffers.output.actual_count <
  914. inst->buffers.output.min_count +
  915. inst->buffers.output.extra_count) {
  916. inst->buffers.output.actual_count =
  917. inst->buffers.output.min_count +
  918. inst->buffers.output.extra_count;
  919. }
  920. inst->buffers.output.size =
  921. fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
  922. memcpy(f, fmt, sizeof(struct v4l2_format));
  923. return rc;
  924. }
  925. static int msm_venc_s_fmt_output_meta(struct msm_vidc_inst *inst, struct v4l2_format *f)
  926. {
  927. int rc = 0;
  928. struct v4l2_format *fmt;
  929. struct msm_vidc_core *core;
  930. if (!inst || !inst->core) {
  931. d_vpr_e("%s: invalid params\n", __func__);
  932. return -EINVAL;
  933. }
  934. core = inst->core;
  935. fmt = &inst->fmts[OUTPUT_META_PORT];
  936. fmt->type = OUTPUT_META_PLANE;
  937. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  938. if (is_output_meta_enabled(inst)) {
  939. fmt->fmt.meta.buffersize = call_session_op(core,
  940. buffer_size, inst, MSM_VIDC_BUF_OUTPUT_META);
  941. inst->buffers.output_meta.min_count =
  942. inst->buffers.output.min_count;
  943. inst->buffers.output_meta.extra_count =
  944. inst->buffers.output.extra_count;
  945. inst->buffers.output_meta.actual_count =
  946. inst->buffers.output.actual_count;
  947. inst->buffers.output_meta.size = fmt->fmt.meta.buffersize;
  948. } else {
  949. fmt->fmt.meta.buffersize = 0;
  950. inst->buffers.output_meta.min_count = 0;
  951. inst->buffers.output_meta.extra_count = 0;
  952. inst->buffers.output_meta.actual_count = 0;
  953. inst->buffers.output_meta.size = 0;
  954. }
  955. memcpy(f, fmt, sizeof(struct v4l2_format));
  956. return rc;
  957. }
  958. static int msm_venc_s_fmt_input(struct msm_vidc_inst *inst, struct v4l2_format *f)
  959. {
  960. int rc = 0;
  961. struct v4l2_format *fmt;
  962. struct msm_vidc_core *core;
  963. u32 pix_fmt, width, height, size, bytesperline,
  964. crop_width, crop_height;
  965. if (!inst || !inst->core || !inst->capabilities) {
  966. d_vpr_e("%s: invalid params\n", __func__);
  967. return -EINVAL;
  968. }
  969. core = inst->core;
  970. pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
  971. msm_vidc_update_cap_value(inst, PIX_FMTS, pix_fmt, __func__);
  972. if (is_rgba_colorformat(pix_fmt)) {
  973. width = VIDEO_RGB_STRIDE_PIX(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width);
  974. height = VIDEO_RGB_SCANLINES(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.height);
  975. crop_width = VIDEO_RGB_STRIDE_PIX(f->fmt.pix_mp.pixelformat, inst->crop.width);
  976. crop_height = VIDEO_RGB_SCANLINES(f->fmt.pix_mp.pixelformat, inst->crop.height);
  977. bytesperline =
  978. VIDEO_RGB_STRIDE_BYTES(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width);
  979. } else if (is_image_session(inst)) {
  980. width = ALIGN(f->fmt.pix_mp.width, HEIC_GRID_DIMENSION);
  981. height = ALIGN(f->fmt.pix_mp.height, HEIC_GRID_DIMENSION);
  982. crop_width = ALIGN(inst->crop.width, HEIC_GRID_DIMENSION);
  983. crop_height = ALIGN(inst->crop.height, HEIC_GRID_DIMENSION);
  984. bytesperline = width * (is_10bit_colorformat(pix_fmt) ? 2 : 1);
  985. } else {
  986. width = VIDEO_Y_STRIDE_PIX(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width);
  987. height = VIDEO_Y_SCANLINES(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.height);
  988. crop_width = VIDEO_Y_STRIDE_PIX(f->fmt.pix_mp.pixelformat, inst->crop.width);
  989. crop_height = VIDEO_Y_SCANLINES(f->fmt.pix_mp.pixelformat, inst->crop.height);
  990. bytesperline = VIDEO_Y_STRIDE_BYTES(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width);
  991. }
  992. fmt = &inst->fmts[INPUT_PORT];
  993. fmt->type = INPUT_MPLANE;
  994. fmt->fmt.pix_mp.width = width;
  995. fmt->fmt.pix_mp.height = height;
  996. fmt->fmt.pix_mp.num_planes = 1;
  997. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  998. fmt->fmt.pix_mp.plane_fmt[0].bytesperline = bytesperline;
  999. if (is_image_session(inst))
  1000. size = bytesperline * height * 3 / 2;
  1001. else
  1002. size = call_session_op(core, buffer_size, inst, MSM_VIDC_BUF_INPUT);
  1003. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = size;
  1004. fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
  1005. fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
  1006. fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
  1007. fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
  1008. inst->buffers.input.min_count = call_session_op(core,
  1009. min_count, inst, MSM_VIDC_BUF_INPUT);
  1010. inst->buffers.input.extra_count = call_session_op(core,
  1011. extra_count, inst, MSM_VIDC_BUF_INPUT);
  1012. if (inst->buffers.input.actual_count <
  1013. inst->buffers.input.min_count +
  1014. inst->buffers.input.extra_count) {
  1015. inst->buffers.input.actual_count =
  1016. inst->buffers.input.min_count +
  1017. inst->buffers.input.extra_count;
  1018. }
  1019. inst->buffers.input.size = size;
  1020. if (fmt->fmt.pix_mp.width != crop_width ||
  1021. fmt->fmt.pix_mp.height != crop_height) {
  1022. struct v4l2_format *output_fmt;
  1023. /* reset crop dimensions with updated resolution */
  1024. inst->crop.top = inst->crop.left = 0;
  1025. inst->crop.width = f->fmt.pix_mp.width;
  1026. inst->crop.height = f->fmt.pix_mp.height;
  1027. /* reset compose dimensions with updated resolution */
  1028. inst->compose.top = inst->compose.left = 0;
  1029. inst->compose.width = f->fmt.pix_mp.width;
  1030. inst->compose.height = f->fmt.pix_mp.height;
  1031. output_fmt = &inst->fmts[OUTPUT_PORT];
  1032. rc = msm_venc_s_fmt_output(inst, output_fmt);
  1033. if (rc)
  1034. return rc;
  1035. i_vpr_h(inst,
  1036. "%s: type %d: format %#x width %d height %d size %d\n",
  1037. __func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat,
  1038. output_fmt->fmt.pix_mp.width,
  1039. output_fmt->fmt.pix_mp.height,
  1040. output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
  1041. }
  1042. memcpy(f, fmt, sizeof(struct v4l2_format));
  1043. return rc;
  1044. }
  1045. static int msm_venc_s_fmt_input_meta(struct msm_vidc_inst *inst, struct v4l2_format *f)
  1046. {
  1047. int rc = 0;
  1048. struct v4l2_format *fmt;
  1049. struct msm_vidc_core *core;
  1050. if (!inst || !inst->core) {
  1051. d_vpr_e("%s: invalid params\n", __func__);
  1052. return -EINVAL;
  1053. }
  1054. core = inst->core;
  1055. fmt = &inst->fmts[INPUT_META_PORT];
  1056. fmt->type = INPUT_META_PLANE;
  1057. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1058. if (is_input_meta_enabled(inst)) {
  1059. fmt->fmt.meta.buffersize = call_session_op(core,
  1060. buffer_size, inst, MSM_VIDC_BUF_OUTPUT_META);
  1061. inst->buffers.input_meta.min_count =
  1062. inst->buffers.input.min_count;
  1063. inst->buffers.input_meta.extra_count =
  1064. inst->buffers.input.extra_count;
  1065. inst->buffers.input_meta.actual_count =
  1066. inst->buffers.input.actual_count;
  1067. inst->buffers.input_meta.size = fmt->fmt.meta.buffersize;
  1068. } else {
  1069. fmt->fmt.meta.buffersize = 0;
  1070. inst->buffers.input_meta.min_count = 0;
  1071. inst->buffers.input_meta.extra_count = 0;
  1072. inst->buffers.input_meta.actual_count = 0;
  1073. inst->buffers.input_meta.size = 0;
  1074. }
  1075. memcpy(f, fmt, sizeof(struct v4l2_format));
  1076. return rc;
  1077. }
  1078. // TODO: use PIX_FMTS caps to check supported color format
  1079. int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  1080. {
  1081. int rc = 0;
  1082. struct v4l2_format *fmt = NULL;
  1083. if (!inst) {
  1084. d_vpr_e("%s: invalid params\n", __func__);
  1085. return -EINVAL;
  1086. }
  1087. if (f->type == INPUT_MPLANE) {
  1088. fmt = &inst->fmts[INPUT_PORT];
  1089. rc = msm_venc_s_fmt_input(inst, f);
  1090. if (rc)
  1091. return rc;
  1092. } else if (f->type == INPUT_META_PLANE) {
  1093. fmt = &inst->fmts[INPUT_META_PORT];
  1094. rc = msm_venc_s_fmt_input_meta(inst, f);
  1095. if (rc)
  1096. return rc;
  1097. } else if (f->type == OUTPUT_MPLANE) {
  1098. fmt = &inst->fmts[OUTPUT_PORT];
  1099. rc = msm_venc_s_fmt_output(inst, f);
  1100. if (rc)
  1101. return rc;
  1102. } else if (f->type == OUTPUT_META_PLANE) {
  1103. fmt = &inst->fmts[OUTPUT_META_PORT];
  1104. rc = msm_venc_s_fmt_output_meta(inst, f);
  1105. if (rc)
  1106. return rc;
  1107. } else {
  1108. i_vpr_e(inst, "%s: invalid type %d\n", __func__, f->type);
  1109. return rc;
  1110. }
  1111. if (f->type == INPUT_MPLANE || f->type == OUTPUT_MPLANE) {
  1112. i_vpr_h(inst,
  1113. "%s: type %d: format %#x width %d height %d size %d\n",
  1114. __func__, f->type, fmt->fmt.pix_mp.pixelformat,
  1115. fmt->fmt.pix_mp.width,
  1116. fmt->fmt.pix_mp.height,
  1117. fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
  1118. } else {
  1119. i_vpr_h(inst, "%s: type %d: size %d\n",
  1120. __func__, f->type, fmt->fmt.meta.buffersize);
  1121. }
  1122. return rc;
  1123. }
  1124. int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  1125. {
  1126. int rc = 0;
  1127. int port;
  1128. if (!inst) {
  1129. d_vpr_e("%s: invalid params\n", __func__);
  1130. return -EINVAL;
  1131. }
  1132. port = v4l2_type_to_driver_port(inst, f->type, __func__);
  1133. if (port < 0)
  1134. return -EINVAL;
  1135. memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
  1136. return rc;
  1137. }
  1138. int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
  1139. {
  1140. int rc = 0;
  1141. struct v4l2_format *output_fmt;
  1142. if (!inst || !s) {
  1143. d_vpr_e("%s: invalid params\n", __func__);
  1144. return -EINVAL;
  1145. }
  1146. if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
  1147. i_vpr_e(inst, "%s: invalid type %d\n", __func__, s->type);
  1148. return -EINVAL;
  1149. }
  1150. switch (s->target) {
  1151. case V4L2_SEL_TGT_CROP_BOUNDS:
  1152. case V4L2_SEL_TGT_CROP_DEFAULT:
  1153. case V4L2_SEL_TGT_CROP:
  1154. if (s->r.left || s->r.top) {
  1155. i_vpr_h(inst, "%s: unsupported top %d or left %d\n",
  1156. __func__, s->r.left, s->r.top);
  1157. s->r.left = s->r.top = 0;
  1158. }
  1159. if (s->r.width > inst->fmts[INPUT_PORT].fmt.pix_mp.width) {
  1160. i_vpr_h(inst, "%s: unsupported width %d, fmt width %d\n",
  1161. __func__, s->r.width,
  1162. inst->fmts[INPUT_PORT].fmt.pix_mp.width);
  1163. s->r.width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
  1164. }
  1165. if (s->r.height > inst->fmts[INPUT_PORT].fmt.pix_mp.height) {
  1166. i_vpr_h(inst, "%s: unsupported height %d, fmt height %d\n",
  1167. __func__, s->r.height,
  1168. inst->fmts[INPUT_PORT].fmt.pix_mp.height);
  1169. s->r.height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
  1170. }
  1171. inst->crop.left = s->r.left;
  1172. inst->crop.top = s->r.top;
  1173. inst->crop.width = s->r.width;
  1174. inst->crop.height = s->r.height;
  1175. /* adjust compose such that it is within crop */
  1176. inst->compose.left = inst->crop.left;
  1177. inst->compose.top = inst->crop.top;
  1178. inst->compose.width = inst->crop.width;
  1179. inst->compose.height = inst->crop.height;
  1180. /* update output format based on new crop dimensions */
  1181. output_fmt = &inst->fmts[OUTPUT_PORT];
  1182. rc = msm_venc_s_fmt_output(inst, output_fmt);
  1183. if (rc)
  1184. return rc;
  1185. i_vpr_h(inst,
  1186. "%s: type %d: format %#x width %d height %d size %d\n",
  1187. __func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat,
  1188. output_fmt->fmt.pix_mp.width,
  1189. output_fmt->fmt.pix_mp.height,
  1190. output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
  1191. break;
  1192. case V4L2_SEL_TGT_COMPOSE_BOUNDS:
  1193. case V4L2_SEL_TGT_COMPOSE_PADDED:
  1194. case V4L2_SEL_TGT_COMPOSE_DEFAULT:
  1195. case V4L2_SEL_TGT_COMPOSE:
  1196. if (s->r.left < inst->crop.left) {
  1197. i_vpr_e(inst,
  1198. "%s: compose left (%d) less than crop left (%d)\n",
  1199. __func__, s->r.left, inst->crop.left);
  1200. s->r.left = inst->crop.left;
  1201. }
  1202. if (s->r.top < inst->crop.top) {
  1203. i_vpr_e(inst,
  1204. "%s: compose top (%d) less than crop top (%d)\n",
  1205. __func__, s->r.top, inst->crop.top);
  1206. s->r.top = inst->crop.top;
  1207. }
  1208. if (s->r.width > inst->crop.width) {
  1209. i_vpr_e(inst,
  1210. "%s: compose width (%d) greate than crop width (%d)\n",
  1211. __func__, s->r.width, inst->crop.width);
  1212. s->r.width = inst->crop.width;
  1213. }
  1214. if (s->r.height > inst->crop.height) {
  1215. i_vpr_e(inst,
  1216. "%s: compose height (%d) greate than crop height (%d)\n",
  1217. __func__, s->r.height, inst->crop.height);
  1218. s->r.height = inst->crop.height;
  1219. }
  1220. inst->compose.left = s->r.left;
  1221. inst->compose.top = s->r.top;
  1222. inst->compose.width = s->r.width;
  1223. inst->compose.height= s->r.height;
  1224. if (inst->crop.left != inst->compose.left ||
  1225. inst->crop.top != inst->compose.top ||
  1226. inst->crop.width != inst->compose.width ||
  1227. inst->crop.height != inst->compose.height) {
  1228. i_vpr_h(inst,
  1229. "%s: scaling enabled, crop: l %d t %d w %d h %d compose: l %d t %d w %d h %d\n",
  1230. __func__, inst->crop.left, inst->crop.top,
  1231. inst->crop.width, inst->crop.height,
  1232. inst->compose.left, inst->compose.top,
  1233. inst->compose.width, inst->compose.height);
  1234. }
  1235. /* update output format based on new compose dimensions */
  1236. output_fmt = &inst->fmts[OUTPUT_PORT];
  1237. rc = msm_venc_s_fmt_output(inst, output_fmt);
  1238. if (rc)
  1239. return rc;
  1240. i_vpr_h(inst,
  1241. "%s: type %d: format %#x width %d height %d size %d\n",
  1242. __func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat,
  1243. output_fmt->fmt.pix_mp.width,
  1244. output_fmt->fmt.pix_mp.height,
  1245. output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
  1246. break;
  1247. default:
  1248. i_vpr_e(inst, "%s: invalid target %d\n",
  1249. __func__, s->target);
  1250. rc = -EINVAL;
  1251. break;
  1252. }
  1253. if (!rc)
  1254. i_vpr_h(inst, "%s: target %d, r [%d, %d, %d, %d]\n",
  1255. __func__, s->target, s->r.top, s->r.left,
  1256. s->r.width, s->r.height);
  1257. return rc;
  1258. }
  1259. int msm_venc_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
  1260. {
  1261. int rc = 0;
  1262. if (!inst || !s) {
  1263. d_vpr_e("%s: invalid params\n", __func__);
  1264. return -EINVAL;
  1265. }
  1266. if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
  1267. i_vpr_e(inst, "%s: invalid type %d\n", __func__, s->type);
  1268. return -EINVAL;
  1269. }
  1270. switch (s->target) {
  1271. case V4L2_SEL_TGT_CROP_BOUNDS:
  1272. case V4L2_SEL_TGT_CROP_DEFAULT:
  1273. case V4L2_SEL_TGT_CROP:
  1274. s->r.left = inst->crop.left;
  1275. s->r.top = inst->crop.top;
  1276. s->r.width = inst->crop.width;
  1277. s->r.height = inst->crop.height;
  1278. break;
  1279. case V4L2_SEL_TGT_COMPOSE_BOUNDS:
  1280. case V4L2_SEL_TGT_COMPOSE_PADDED:
  1281. case V4L2_SEL_TGT_COMPOSE_DEFAULT:
  1282. case V4L2_SEL_TGT_COMPOSE:
  1283. s->r.left = inst->compose.left;
  1284. s->r.top = inst->compose.top;
  1285. s->r.width = inst->compose.width;
  1286. s->r.height = inst->compose.height;
  1287. break;
  1288. default:
  1289. i_vpr_e(inst, "%s: invalid target %d\n",
  1290. __func__, s->target);
  1291. rc = -EINVAL;
  1292. break;
  1293. }
  1294. if (!rc)
  1295. i_vpr_h(inst, "%s: target %d, r [%d, %d, %d, %d]\n",
  1296. __func__, s->target, s->r.top, s->r.left,
  1297. s->r.width, s->r.height);
  1298. return rc;
  1299. }
  1300. int msm_venc_s_param(struct msm_vidc_inst *inst,
  1301. struct v4l2_streamparm *s_parm)
  1302. {
  1303. int rc = 0;
  1304. struct msm_vidc_inst_capability *capability = NULL;
  1305. struct v4l2_fract *timeperframe = NULL;
  1306. u32 q16_rate, max_rate, default_rate;
  1307. u64 us_per_frame = 0, input_rate = 0;
  1308. bool is_frame_rate = false;
  1309. if (!inst || !s_parm) {
  1310. d_vpr_e("%s: invalid params\n", __func__);
  1311. return -EINVAL;
  1312. }
  1313. capability = inst->capabilities;
  1314. if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
  1315. timeperframe = &s_parm->parm.output.timeperframe;
  1316. max_rate = capability->cap[OPERATING_RATE].max;
  1317. default_rate = capability->cap[OPERATING_RATE].value >> 16;
  1318. } else {
  1319. timeperframe = &s_parm->parm.capture.timeperframe;
  1320. is_frame_rate = true;
  1321. max_rate = capability->cap[FRAME_RATE].max >> 16;
  1322. default_rate = capability->cap[FRAME_RATE].value >> 16;
  1323. }
  1324. if (!timeperframe->denominator || !timeperframe->numerator) {
  1325. i_vpr_e(inst,
  1326. "%s: invalid rate for type %u\n",
  1327. __func__, s_parm->type);
  1328. input_rate = default_rate;
  1329. goto set_default;
  1330. }
  1331. us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
  1332. do_div(us_per_frame, timeperframe->denominator);
  1333. if (!us_per_frame) {
  1334. i_vpr_e(inst, "%s: us_per_frame is zero\n",
  1335. __func__);
  1336. rc = -EINVAL;
  1337. goto exit;
  1338. }
  1339. input_rate = (u64)USEC_PER_SEC;
  1340. do_div(input_rate, us_per_frame);
  1341. /* Check max allowed rate */
  1342. if (input_rate > max_rate) {
  1343. i_vpr_e(inst,
  1344. "%s: Unsupported rate %llu, max_fps %u, type: %u\n",
  1345. __func__, input_rate, max_rate, s_parm->type);
  1346. rc = -ENOTSUPP;
  1347. goto exit;
  1348. }
  1349. set_default:
  1350. q16_rate = (u32)input_rate << 16;
  1351. i_vpr_h(inst, "%s: type %u value %#x\n",
  1352. __func__, s_parm->type, q16_rate);
  1353. msm_vidc_update_cap_value(inst,
  1354. is_frame_rate ? FRAME_RATE : OPERATING_RATE,
  1355. q16_rate, __func__);
  1356. if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
  1357. inst->vb2q[INPUT_PORT].streaming) ||
  1358. (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
  1359. inst->vb2q[OUTPUT_PORT].streaming)) {
  1360. if (msm_vidc_check_core_mbps(inst)) {
  1361. i_vpr_e(inst,
  1362. "%s: Unsupported load with rate %d, setting default rate %d\n",
  1363. __func__, input_rate, default_rate);
  1364. msm_vidc_update_cap_value(inst,
  1365. is_frame_rate ? FRAME_RATE : OPERATING_RATE,
  1366. default_rate << 16, __func__);
  1367. return -ENOMEM;
  1368. }
  1369. }
  1370. if (!is_realtime_session(inst))
  1371. inst->priority_level = MSM_VIDC_PRIORITY_HIGH;
  1372. if (is_frame_rate)
  1373. capability->cap[FRAME_RATE].flags |= CAP_FLAG_CLIENT_SET;
  1374. else
  1375. capability->cap[OPERATING_RATE].flags |= CAP_FLAG_CLIENT_SET;
  1376. /*
  1377. * In static case, frame rate is set via
  1378. * inst database set function mentioned in
  1379. * FRAME_RATE cap id.
  1380. * In dynamic case, frame rate is set like below.
  1381. */
  1382. if (inst->vb2q[OUTPUT_PORT].streaming) {
  1383. rc = venus_hfi_session_property(inst,
  1384. HFI_PROP_FRAME_RATE,
  1385. HFI_HOST_FLAGS_NONE,
  1386. HFI_PORT_BITSTREAM,
  1387. HFI_PAYLOAD_Q16,
  1388. &q16_rate,
  1389. sizeof(u32));
  1390. if (rc) {
  1391. i_vpr_e(inst,
  1392. "%s: failed to set frame rate to fw\n",
  1393. __func__);
  1394. goto exit;
  1395. }
  1396. }
  1397. exit:
  1398. return rc;
  1399. }
  1400. int msm_venc_g_param(struct msm_vidc_inst *inst,
  1401. struct v4l2_streamparm *s_parm)
  1402. {
  1403. struct msm_vidc_inst_capability *capability = NULL;
  1404. struct v4l2_fract *timeperframe = NULL;
  1405. if (!inst || !s_parm) {
  1406. d_vpr_e("%s: invalid params\n", __func__);
  1407. return -EINVAL;
  1408. }
  1409. capability = inst->capabilities;
  1410. if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
  1411. timeperframe = &s_parm->parm.output.timeperframe;
  1412. timeperframe->numerator = 1;
  1413. timeperframe->denominator =
  1414. capability->cap[OPERATING_RATE].value >> 16;
  1415. } else {
  1416. timeperframe = &s_parm->parm.capture.timeperframe;
  1417. timeperframe->numerator = 1;
  1418. timeperframe->denominator =
  1419. capability->cap[FRAME_RATE].value >> 16;
  1420. }
  1421. i_vpr_h(inst, "%s: type %u, num %u denom %u\n",
  1422. __func__, s_parm->type, timeperframe->numerator,
  1423. timeperframe->denominator);
  1424. return 0;
  1425. }
  1426. int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
  1427. {
  1428. int rc = 0;
  1429. struct msm_vidc_core *core;
  1430. u32 array[32] = {0};
  1431. u32 i = 0;
  1432. if (!inst || !inst->core || !inst->capabilities || !f ||
  1433. f->index >= ARRAY_SIZE(array)) {
  1434. d_vpr_e("%s: invalid params\n", __func__);
  1435. return -EINVAL;
  1436. }
  1437. core = inst->core;
  1438. if (f->type == OUTPUT_MPLANE) {
  1439. u32 codecs = core->capabilities[ENC_CODECS].value;
  1440. u32 idx = 0;
  1441. for (i = 0; i <= 31; i++) {
  1442. if (codecs & BIT(i)) {
  1443. if (idx >= ARRAY_SIZE(array))
  1444. break;
  1445. array[idx] = codecs & BIT(i);
  1446. idx++;
  1447. }
  1448. }
  1449. if (!array[f->index])
  1450. return -EINVAL;
  1451. f->pixelformat = v4l2_codec_from_driver(array[f->index],
  1452. __func__);
  1453. if (!f->pixelformat)
  1454. return -EINVAL;
  1455. f->flags = V4L2_FMT_FLAG_COMPRESSED;
  1456. strlcpy(f->description, "codec", sizeof(f->description));
  1457. } else if (f->type == INPUT_MPLANE) {
  1458. u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask;
  1459. u32 idx = 0;
  1460. for (i = 0; i <= 31; i++) {
  1461. if (formats & BIT(i)) {
  1462. if (idx >= ARRAY_SIZE(array))
  1463. break;
  1464. array[idx] = formats & BIT(i);
  1465. idx++;
  1466. }
  1467. }
  1468. if (!array[f->index])
  1469. return -EINVAL;
  1470. f->pixelformat = v4l2_colorformat_from_driver(array[f->index],
  1471. __func__);
  1472. if (!f->pixelformat)
  1473. return -EINVAL;
  1474. strlcpy(f->description, "colorformat", sizeof(f->description));
  1475. } else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
  1476. if (!f->index) {
  1477. f->pixelformat = V4L2_META_FMT_VIDC;
  1478. strlcpy(f->description, "metadata", sizeof(f->description));
  1479. } else {
  1480. return -EINVAL;
  1481. }
  1482. }
  1483. memset(f->reserved, 0, sizeof(f->reserved));
  1484. i_vpr_h(inst, "%s: index %d, %s : %#x, flags %#x, driver colorfmt %#x\n",
  1485. __func__, f->index, f->description, f->pixelformat, f->flags,
  1486. v4l2_colorformat_to_driver(f->pixelformat, __func__));
  1487. return rc;
  1488. }
  1489. int msm_venc_inst_init(struct msm_vidc_inst *inst)
  1490. {
  1491. int rc = 0;
  1492. struct msm_vidc_core *core;
  1493. struct v4l2_format *f;
  1494. if (!inst || !inst->core) {
  1495. d_vpr_e("%s: invalid params\n", __func__);
  1496. return -EINVAL;
  1497. }
  1498. i_vpr_h(inst, "%s()\n", __func__);
  1499. core = inst->core;
  1500. if (core->capabilities[DCVS].value)
  1501. inst->power.dcvs_mode = true;
  1502. f = &inst->fmts[OUTPUT_PORT];
  1503. f->type = OUTPUT_MPLANE;
  1504. f->fmt.pix_mp.width = DEFAULT_WIDTH;
  1505. f->fmt.pix_mp.height = DEFAULT_HEIGHT;
  1506. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
  1507. f->fmt.pix_mp.num_planes = 1;
  1508. f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  1509. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1510. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  1511. f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
  1512. f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
  1513. f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
  1514. f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
  1515. inst->buffers.output.min_count = call_session_op(core,
  1516. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  1517. inst->buffers.output.extra_count = call_session_op(core,
  1518. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  1519. inst->buffers.output.actual_count =
  1520. inst->buffers.output.min_count +
  1521. inst->buffers.output.extra_count;
  1522. inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1523. inst->crop.left = inst->crop.top = 0;
  1524. inst->crop.width = f->fmt.pix_mp.width;
  1525. inst->crop.height = f->fmt.pix_mp.height;
  1526. inst->compose.left = inst->compose.top = 0;
  1527. inst->compose.width = f->fmt.pix_mp.width;
  1528. inst->compose.height = f->fmt.pix_mp.height;
  1529. f = &inst->fmts[OUTPUT_META_PORT];
  1530. f->type = OUTPUT_META_PLANE;
  1531. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1532. f->fmt.meta.buffersize = 0;
  1533. inst->buffers.output_meta.min_count = 0;
  1534. inst->buffers.output_meta.extra_count = 0;
  1535. inst->buffers.output_meta.actual_count = 0;
  1536. inst->buffers.output_meta.size = 0;
  1537. f = &inst->fmts[INPUT_PORT];
  1538. f->type = INPUT_MPLANE;
  1539. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VIDC_NV12C;
  1540. f->fmt.pix_mp.width = VIDEO_Y_STRIDE_PIX(f->fmt.pix_mp.pixelformat,
  1541. DEFAULT_WIDTH);
  1542. f->fmt.pix_mp.height = VIDEO_Y_SCANLINES(f->fmt.pix_mp.pixelformat,
  1543. DEFAULT_HEIGHT);
  1544. f->fmt.pix_mp.num_planes = 1;
  1545. f->fmt.pix_mp.plane_fmt[0].bytesperline =
  1546. VIDEO_Y_STRIDE_BYTES(f->fmt.pix_mp.pixelformat,
  1547. DEFAULT_WIDTH);
  1548. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1549. buffer_size, inst, MSM_VIDC_BUF_INPUT);
  1550. f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
  1551. f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
  1552. f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
  1553. f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
  1554. inst->buffers.input.min_count = call_session_op(core,
  1555. min_count, inst, MSM_VIDC_BUF_INPUT);
  1556. inst->buffers.input.extra_count = call_session_op(core,
  1557. extra_count, inst, MSM_VIDC_BUF_INPUT);
  1558. inst->buffers.input.actual_count =
  1559. inst->buffers.input.min_count +
  1560. inst->buffers.input.extra_count;
  1561. inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1562. f = &inst->fmts[INPUT_META_PORT];
  1563. f->type = INPUT_META_PLANE;
  1564. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1565. f->fmt.meta.buffersize = 0;
  1566. inst->buffers.input_meta.min_count = 0;
  1567. inst->buffers.input_meta.extra_count = 0;
  1568. inst->buffers.input_meta.actual_count = 0;
  1569. inst->buffers.input_meta.size = 0;
  1570. inst->hfi_rc_type = HFI_RC_VBR_CFR;
  1571. inst->hfi_layer_type = HFI_HIER_P_SLIDING_WINDOW;
  1572. rc = msm_venc_codec_change(inst,
  1573. inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat);
  1574. return rc;
  1575. }
  1576. int msm_venc_inst_deinit(struct msm_vidc_inst *inst)
  1577. {
  1578. int rc = 0;
  1579. if (!inst) {
  1580. d_vpr_e("%s: invalid params\n", __func__);
  1581. return -EINVAL;
  1582. }
  1583. rc = msm_vidc_ctrl_deinit(inst);
  1584. return rc;
  1585. }