msm_venc.c 41 KB

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