msm_venc.c 50 KB

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