vcodec_service.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /*
  2. * Copyright 2020 Rockchip Electronics Co. LTD
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define MODULE_TAG "vcodec_service"
  17. #include <sys/ioctl.h>
  18. #include <fcntl.h>
  19. #include <errno.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include "mpp_env.h"
  23. #include "mpp_mem.h"
  24. #include "mpp_time.h"
  25. #include "mpp_list.h"
  26. #include "mpp_debug.h"
  27. #include "mpp_common.h"
  28. #include "vpu.h"
  29. #include "mpp_soc.h"
  30. #include "mpp_platform.h"
  31. #include "vcodec_service.h"
  32. #include "vcodec_service_api.h"
  33. #define MAX_REGS_COUNT 3
  34. #define MPX_EXTRA_INFO_NUM 16
  35. #define MAX_INFO_COUNT 16
  36. #define INFO_FORMAT_TYPE 3
  37. typedef struct MppReq_t {
  38. RK_U32 *req;
  39. RK_U32 size;
  40. } MppReq;
  41. typedef struct VcodecExtraSlot_t {
  42. RK_U32 reg_idx;
  43. RK_U32 offset;
  44. } VcodecExtraSlot;
  45. typedef struct VcodecExtraInfo_t {
  46. RK_U32 magic; // Fix magic value 0x4C4A46
  47. RK_U32 count; // valid patch info count
  48. VcodecExtraSlot slots[MPX_EXTRA_INFO_NUM];
  49. } VcodecExtraInfo;
  50. typedef struct VcodecRegCfg_t {
  51. RK_U32 reg_size;
  52. VcodecExtraInfo extra_info;
  53. void *reg_set;
  54. void *reg_get;
  55. } VcodecRegCfg;
  56. typedef struct MppDevVcodecService_t {
  57. RK_S32 client_type;
  58. RK_U64 fmt;
  59. RK_S32 fd;
  60. RK_S32 max_regs;
  61. RK_U32 reg_size;
  62. RK_S32 reg_send_idx;
  63. RK_S32 reg_poll_idx;
  64. VcodecRegCfg regs[MAX_REGS_COUNT];
  65. RK_S32 info_count;
  66. MppDevInfoCfg info[MAX_INFO_COUNT];
  67. } MppDevVcodecService;
  68. /* For vpu1 / vpu2 */
  69. static const char *mpp_vpu_dev[] = {
  70. "/dev/vpu_service",
  71. "/dev/vpu-service",
  72. "/dev/mpp_service",
  73. };
  74. /* For hevc 4K decoder */
  75. static const char *mpp_hevc_dev[] = {
  76. "/dev/hevc_service",
  77. "/dev/hevc-service",
  78. "/dev/mpp_service",
  79. };
  80. /* For H.264/H.265/VP9 4K decoder */
  81. static const char *mpp_rkvdec_dev[] = {
  82. "/dev/rkvdec",
  83. "/dev/mpp_service",
  84. };
  85. /* For H.264 4K encoder */
  86. static const char *mpp_rkvenc_dev[] = {
  87. "/dev/rkvenc",
  88. "/dev/mpp_service",
  89. };
  90. /* For avs+ decoder */
  91. static const char *mpp_avsd_dev[] = {
  92. "/dev/avsd",
  93. "/dev/mpp_service",
  94. };
  95. /* For H.264 / jpeg encoder */
  96. static const char *mpp_vepu_dev[] = {
  97. "/dev/vepu",
  98. "/dev/mpp_service",
  99. };
  100. /* For H.265 encoder */
  101. static const char *mpp_h265e_dev[] = {
  102. "/dev/h265e",
  103. "/dev/mpp_service",
  104. };
  105. /* For jpeg decoder */
  106. static const char *mpp_jpegd_dev[] = {
  107. "/dev/mpp_service",
  108. };
  109. static const char *mpp_jpege_dev[] = {
  110. "/dev/mpp_service",
  111. };
  112. #define mpp_find_device(dev) _mpp_find_device(dev, MPP_ARRAY_ELEMS(dev))
  113. static const char *_mpp_find_device(const char **dev, RK_U32 size)
  114. {
  115. RK_U32 i;
  116. for (i = 0; i < size; i++)
  117. if (!access(dev[i], F_OK))
  118. return dev[i];
  119. return NULL;
  120. }
  121. const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform)
  122. {
  123. const char *dev = NULL;
  124. if ((platform & HAVE_RKVDEC) && (type == MPP_CTX_DEC) &&
  125. (coding == MPP_VIDEO_CodingAVC ||
  126. coding == MPP_VIDEO_CodingHEVC ||
  127. coding == MPP_VIDEO_CodingAVS2 ||
  128. coding == MPP_VIDEO_CodingVP9)) {
  129. dev = mpp_find_device(mpp_rkvdec_dev);
  130. } else if ((platform & HAVE_HEVC_DEC) && (type == MPP_CTX_DEC) &&
  131. (coding == MPP_VIDEO_CodingHEVC)) {
  132. dev = mpp_find_device(mpp_hevc_dev);
  133. } else if ((platform & HAVE_AVSDEC) && (type == MPP_CTX_DEC) &&
  134. (coding == MPP_VIDEO_CodingAVS)) {
  135. dev = mpp_find_device(mpp_avsd_dev);
  136. } else if ((platform & HAVE_RKVENC) && (type == MPP_CTX_ENC) &&
  137. (coding == MPP_VIDEO_CodingAVC)) {
  138. dev = mpp_find_device(mpp_rkvenc_dev);
  139. } else if ((platform & HAVE_VEPU22) && (type == MPP_CTX_ENC) &&
  140. (coding == MPP_VIDEO_CodingHEVC)) {
  141. dev = mpp_find_device(mpp_h265e_dev);
  142. } else {
  143. if (type == MPP_CTX_ENC)
  144. dev = mpp_find_device(mpp_vepu_dev);
  145. if (dev == NULL)
  146. dev = mpp_find_device(mpp_vpu_dev);
  147. }
  148. return dev;
  149. }
  150. const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding)
  151. {
  152. const char *dev = NULL;
  153. RockchipSocType soc_type = mpp_get_soc_type();
  154. switch (soc_type) {
  155. case ROCKCHIP_SOC_RK3036 : {
  156. /* rk3036 do NOT have encoder */
  157. if (type == MPP_CTX_ENC)
  158. dev = NULL;
  159. else if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
  160. dev = mpp_find_device(mpp_hevc_dev);
  161. else
  162. dev = mpp_find_device(mpp_vpu_dev);
  163. } break;
  164. case ROCKCHIP_SOC_RK3066 :
  165. case ROCKCHIP_SOC_RK3188 : {
  166. /* rk3066/rk3188 have vpu1 only */
  167. dev = mpp_find_device(mpp_vpu_dev);
  168. } break;
  169. case ROCKCHIP_SOC_RK3288 :
  170. case ROCKCHIP_SOC_RK312X :
  171. case ROCKCHIP_SOC_RK3368 :
  172. case ROCKCHIP_SOC_RK3326 :
  173. case ROCKCHIP_SOC_PX30 : {
  174. /*
  175. * rk3288/rk312x/rk3368 have codec:
  176. * 1 - vpu1
  177. * 2 - RK hevc decoder
  178. */
  179. if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
  180. dev = mpp_find_device(mpp_hevc_dev);
  181. else
  182. dev = mpp_find_device(mpp_vpu_dev);
  183. } break;
  184. case ROCKCHIP_SOC_RK3128H : {
  185. /*
  186. * rk3128H have codec:
  187. * 1 - vpu2
  188. * 2 - RK H.264/H.265 1080p@60fps decoder
  189. * NOTE: rk3128H do NOT have jpeg encoder
  190. */
  191. if (type == MPP_CTX_DEC &&
  192. (coding == MPP_VIDEO_CodingAVC ||
  193. coding == MPP_VIDEO_CodingHEVC))
  194. dev = mpp_find_device(mpp_rkvdec_dev);
  195. else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
  196. dev = NULL;
  197. else if (type == MPP_CTX_DEC && coding == MPP_VIDEO_CodingVP9)
  198. dev = NULL;
  199. else
  200. dev = mpp_find_device(mpp_vpu_dev);
  201. } break;
  202. case ROCKCHIP_SOC_RK3399 :
  203. case ROCKCHIP_SOC_RK3229 : {
  204. /*
  205. * rk3399/rk3229 have codec:
  206. * 1 - vpu2
  207. * 2 - RK H.264/H.265/VP9 4K decoder
  208. */
  209. if (type == MPP_CTX_DEC &&
  210. (coding == MPP_VIDEO_CodingAVC ||
  211. coding == MPP_VIDEO_CodingHEVC ||
  212. coding == MPP_VIDEO_CodingVP9))
  213. dev = mpp_find_device(mpp_rkvdec_dev);
  214. else
  215. dev = mpp_find_device(mpp_vpu_dev);
  216. } break;
  217. case ROCKCHIP_SOC_RK3228 : {
  218. /*
  219. * rk3228 have codec:
  220. * 1 - vpu2
  221. * 2 - RK H.264/H.265 4K decoder
  222. * NOTE: rk3228 do NOT have jpeg encoder
  223. */
  224. if (type == MPP_CTX_DEC &&
  225. (coding == MPP_VIDEO_CodingAVC ||
  226. coding == MPP_VIDEO_CodingHEVC))
  227. dev = mpp_find_device(mpp_rkvdec_dev);
  228. else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
  229. dev = NULL;
  230. else
  231. dev = mpp_find_device(mpp_vpu_dev);
  232. } break;
  233. case ROCKCHIP_SOC_RK3228H : {
  234. /*
  235. * rk3228h has codec:
  236. * 1 - vpu2
  237. * 2 - RK H.264/H.265 4K decoder
  238. * 3 - avs+ decoder
  239. * 4 - H.265 encoder
  240. */
  241. if (type == MPP_CTX_ENC) {
  242. if (coding == MPP_VIDEO_CodingHEVC)
  243. dev = mpp_find_device(mpp_h265e_dev);
  244. else
  245. dev = mpp_find_device(mpp_vepu_dev);
  246. } else if (type == MPP_CTX_DEC) {
  247. if (coding == MPP_VIDEO_CodingAVS)
  248. dev = mpp_find_device(mpp_avsd_dev);
  249. else if (coding == MPP_VIDEO_CodingAVC ||
  250. coding == MPP_VIDEO_CodingHEVC)
  251. dev = mpp_find_device(mpp_rkvdec_dev);
  252. else
  253. dev = mpp_find_device(mpp_vpu_dev);
  254. }
  255. } break;
  256. case ROCKCHIP_SOC_RK3328 : {
  257. /*
  258. * rk3228 has codec:
  259. * 1 - vpu2
  260. * 2 - RK H.264/H.265/VP9 4K decoder
  261. * 4 - H.265 encoder
  262. */
  263. if (type == MPP_CTX_ENC) {
  264. if (coding == MPP_VIDEO_CodingHEVC)
  265. dev = mpp_find_device(mpp_h265e_dev);
  266. else
  267. dev = mpp_find_device(mpp_vepu_dev);
  268. } else if (type == MPP_CTX_DEC) {
  269. if (coding == MPP_VIDEO_CodingAVC ||
  270. coding == MPP_VIDEO_CodingHEVC ||
  271. coding == MPP_VIDEO_CodingVP9) {
  272. dev = mpp_find_device(mpp_rkvdec_dev);
  273. } else
  274. dev = mpp_find_device(mpp_vpu_dev);
  275. }
  276. } break;
  277. case ROCKCHIP_SOC_RV1108 : {
  278. /*
  279. * rv1108 has codec:
  280. * 1 - vpu2
  281. * 2 - RK H.264 4K decoder
  282. * 3 - RK H.264 4K encoder
  283. */
  284. if (coding == MPP_VIDEO_CodingAVC) {
  285. if (type == MPP_CTX_ENC)
  286. dev = mpp_find_device(mpp_rkvenc_dev);
  287. else
  288. dev = mpp_find_device(mpp_rkvdec_dev);
  289. } else if (coding == MPP_VIDEO_CodingMJPEG)
  290. dev = mpp_find_device(mpp_vpu_dev);
  291. } break;
  292. case ROCKCHIP_SOC_RV1109 :
  293. case ROCKCHIP_SOC_RV1126 : {
  294. /*
  295. * rv1108 has codec:
  296. * 1 - vpu2 for jpeg encoder and decoder
  297. * 2 - RK H.264/H.265 4K decoder
  298. * 3 - RK H.264/H.265 4K encoder
  299. */
  300. if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) {
  301. if (type == MPP_CTX_ENC)
  302. dev = mpp_find_device(mpp_rkvenc_dev);
  303. else
  304. dev = mpp_find_device(mpp_rkvdec_dev);
  305. } else if (coding == MPP_VIDEO_CodingMJPEG)
  306. dev = mpp_find_device(mpp_vpu_dev);
  307. } break;
  308. case ROCKCHIP_SOC_RK3566 :
  309. case ROCKCHIP_SOC_RK3567 :
  310. case ROCKCHIP_SOC_RK3568 : {
  311. /*
  312. * rk3566/rk3568 has codec:
  313. * 1 - vpu2 for jpeg/vp8 encoder and decoder
  314. * 2 - RK H.264/H.265/VP9 4K decoder
  315. * 3 - RK H.264/H.265 4K encoder
  316. * 3 - RK jpeg decoder
  317. */
  318. if (type == MPP_CTX_DEC) {
  319. if (coding == MPP_VIDEO_CodingAVC ||
  320. coding == MPP_VIDEO_CodingHEVC ||
  321. coding == MPP_VIDEO_CodingVP9)
  322. dev = mpp_find_device(mpp_rkvdec_dev);
  323. else if (coding == MPP_VIDEO_CodingMJPEG)
  324. dev = mpp_find_device(mpp_jpegd_dev);
  325. else
  326. dev = mpp_find_device(mpp_vpu_dev);
  327. } else if (type == MPP_CTX_ENC) {
  328. if (coding == MPP_VIDEO_CodingAVC ||
  329. coding == MPP_VIDEO_CodingHEVC)
  330. dev = mpp_find_device(mpp_rkvenc_dev);
  331. else if (coding == MPP_VIDEO_CodingMJPEG ||
  332. coding == MPP_VIDEO_CodingVP8)
  333. dev = mpp_find_device(mpp_vpu_dev);
  334. else
  335. dev = NULL;
  336. }
  337. } break;
  338. case ROCKCHIP_SOC_RK3588 : {
  339. /*
  340. * rk3588 has codec:
  341. * 1 - RK H.264/H.265/VP9/AVS2 8K decoder
  342. * 2 - RK H.264/H.265 8K encoder
  343. * 3 - vpu2 for jpeg/vp8 encoder and decoder
  344. * 4 - RK jpeg decoder
  345. */
  346. if (type == MPP_CTX_DEC) {
  347. if (coding == MPP_VIDEO_CodingAVC ||
  348. coding == MPP_VIDEO_CodingHEVC ||
  349. coding == MPP_VIDEO_CodingAVS2 ||
  350. coding == MPP_VIDEO_CodingVP9)
  351. dev = mpp_find_device(mpp_rkvdec_dev);
  352. else if (coding == MPP_VIDEO_CodingMJPEG)
  353. dev = mpp_find_device(mpp_jpegd_dev);
  354. else
  355. dev = mpp_find_device(mpp_vpu_dev);
  356. } else if (type == MPP_CTX_ENC) {
  357. if (coding == MPP_VIDEO_CodingAVC ||
  358. coding == MPP_VIDEO_CodingHEVC)
  359. dev = mpp_find_device(mpp_rkvenc_dev);
  360. else if (coding == MPP_VIDEO_CodingMJPEG ||
  361. coding == MPP_VIDEO_CodingVP8)
  362. dev = mpp_find_device(mpp_vpu_dev);
  363. else
  364. dev = NULL;
  365. }
  366. } break;
  367. case ROCKCHIP_SOC_RK3576 :
  368. case ROCKCHIP_SOC_RV1126B : {
  369. if (type == MPP_CTX_DEC) {
  370. if (coding == MPP_VIDEO_CodingMJPEG)
  371. dev = mpp_find_device(mpp_jpegd_dev);
  372. else
  373. dev = mpp_find_device(mpp_rkvdec_dev);
  374. } else if (type == MPP_CTX_ENC) {
  375. if (coding == MPP_VIDEO_CodingMJPEG)
  376. dev = mpp_find_device(mpp_jpege_dev);
  377. else
  378. dev = mpp_find_device(mpp_rkvenc_dev);
  379. }
  380. } break;
  381. default : {
  382. /* default case for unknown compatible */
  383. RK_U32 vcodec_type = mpp_get_vcodec_type();
  384. dev = mpp_get_platform_dev_name(type, coding, vcodec_type);
  385. } break;
  386. }
  387. return dev;
  388. }
  389. static RK_S32 vcodec_service_ioctl(RK_S32 fd, RK_S32 cmd, void *regs, RK_S32 size)
  390. {
  391. MppReq req;
  392. req.req = regs;
  393. req.size = size;
  394. return (RK_S32)ioctl(fd, cmd, &req);
  395. }
  396. static void extra_info_init(VcodecExtraInfo *info)
  397. {
  398. info->magic = EXTRA_INFO_MAGIC;
  399. info->count = 0;
  400. }
  401. static void update_extra_info(VcodecExtraInfo *info, char* fmt, VcodecRegCfg* send_cfg)
  402. {
  403. void *reg_set = send_cfg->reg_set;
  404. RK_U32 reg_size = send_cfg->reg_size;
  405. if (info->count) {
  406. if (!strstr(fmt, "mjpeg")) {
  407. RK_U32 *reg = (RK_U32*)reg_set;
  408. RK_U32 i = 0;
  409. for (i = 0; i < info->count; i++) {
  410. VcodecExtraSlot *slot = &info->slots[i];
  411. reg[slot->reg_idx] |= (slot->offset << 10);
  412. }
  413. info->count = 0;
  414. } else {
  415. void *extra_data = reg_set + reg_size;
  416. RK_S32 extra_size = sizeof(send_cfg->extra_info);
  417. memcpy(extra_data, info, extra_size);
  418. send_cfg->reg_size += extra_size;
  419. extra_info_init(info);
  420. }
  421. }
  422. }
  423. MPP_RET vcodec_service_init(void *ctx, MppClientType type)
  424. {
  425. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  426. static RK_S32 vcodec_ioctl_version = -1;
  427. VPU_CLIENT_TYPE client_type;
  428. const char *name = NULL;
  429. RK_U32 reg_size = 0;
  430. RK_S32 max_regs = 2;
  431. MPP_RET ret = MPP_NOK;
  432. switch (type) {
  433. case VPU_CLIENT_VDPU1 : {
  434. name = mpp_find_device(mpp_vpu_dev);
  435. client_type = VPU_DEC;
  436. reg_size = VDPU1_REGISTERS;
  437. } break;
  438. case VPU_CLIENT_VDPU2 : {
  439. name = mpp_find_device(mpp_vpu_dev);
  440. client_type = VPU_DEC;
  441. reg_size = VDPU2_REGISTERS;
  442. } break;
  443. case VPU_CLIENT_VDPU1_PP : {
  444. name = mpp_find_device(mpp_vpu_dev);
  445. client_type = VPU_DEC_PP;
  446. if (ROCKCHIP_SOC_RK3036 == mpp_get_soc_type())
  447. reg_size = VDPU1_REGISTERS;
  448. else
  449. reg_size = VDPU1_PP_REGISTERS;
  450. } break;
  451. case VPU_CLIENT_VDPU2_PP : {
  452. name = mpp_find_device(mpp_vpu_dev);
  453. client_type = VPU_DEC_PP;
  454. reg_size = VDPU2_PP_REGISTERS;
  455. } break;
  456. case VPU_CLIENT_HEVC_DEC : {
  457. name = mpp_find_device(mpp_hevc_dev);
  458. client_type = VPU_DEC;
  459. reg_size = RKHEVC_REGISTERS;
  460. max_regs = 3;
  461. } break;
  462. case VPU_CLIENT_RKVDEC : {
  463. name = mpp_find_device(mpp_rkvdec_dev);
  464. client_type = VPU_DEC;
  465. reg_size = RKVDEC_REGISTERS;
  466. max_regs = 3;
  467. } break;
  468. case VPU_CLIENT_AVSPLUS_DEC : {
  469. name = mpp_find_device(mpp_avsd_dev);
  470. client_type = VPU_DEC;
  471. reg_size = AVSD_REGISTERS;
  472. } break;
  473. case VPU_CLIENT_RKVENC : {
  474. name = mpp_find_device(mpp_rkvenc_dev);
  475. client_type = VPU_ENC;
  476. reg_size = AVSD_REGISTERS;
  477. } break;
  478. case VPU_CLIENT_VEPU1 : {
  479. name = mpp_find_device(mpp_vpu_dev);
  480. client_type = VPU_ENC;
  481. reg_size = VEPU1_REGISTERS;
  482. } break;
  483. case VPU_CLIENT_VEPU2 : {
  484. name = mpp_find_device(mpp_vepu_dev);
  485. if (NULL == name)
  486. name = mpp_find_device(mpp_vpu_dev);
  487. client_type = VPU_ENC;
  488. reg_size = VEPU2_REGISTERS;
  489. } break;
  490. default : {
  491. mpp_err_f("unsupported client type %d\n", type);
  492. return ret;
  493. } break;
  494. }
  495. p->fd = open(name, O_RDWR | O_CLOEXEC);
  496. if (p->fd < 0) {
  497. mpp_err("open vcodec_service %s failed\n", name);
  498. return ret;
  499. }
  500. if (vcodec_ioctl_version < 0) {
  501. ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE, (unsigned long)client_type);
  502. if (!ret) {
  503. vcodec_ioctl_version = 0;
  504. } else {
  505. ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE_U32, (RK_U32)client_type);
  506. if (!ret)
  507. vcodec_ioctl_version = 1;
  508. }
  509. mpp_assert(ret == MPP_OK);
  510. } else {
  511. RK_U32 cmd = (vcodec_ioctl_version == 0) ?
  512. (VPU_IOC_SET_CLIENT_TYPE) :
  513. (VPU_IOC_SET_CLIENT_TYPE_U32);
  514. ret = (RK_S32)ioctl(p->fd, cmd, client_type);
  515. }
  516. p->max_regs = max_regs;
  517. p->reg_size = reg_size * sizeof(RK_U32);
  518. {
  519. RK_S32 i;
  520. for (i = 0; i < max_regs; i++) {
  521. VcodecRegCfg *reg = &p->regs[i];
  522. reg->reg_size = p->reg_size;
  523. extra_info_init(&reg->extra_info);
  524. }
  525. }
  526. return ret;
  527. }
  528. MPP_RET vcodec_service_deinit(void *ctx)
  529. {
  530. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  531. if (p->fd)
  532. close(p->fd);
  533. return MPP_OK;
  534. }
  535. MPP_RET vcodec_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
  536. {
  537. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  538. VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
  539. mpp_assert(cfg->offset == 0);
  540. send_cfg->reg_set = cfg->reg;
  541. send_cfg->reg_size = cfg->size;
  542. if (p->reg_size != cfg->size)
  543. mpp_err_f("reg size mismatch wr %d rd %d\n",
  544. p->reg_size, cfg->size);
  545. return MPP_OK;
  546. }
  547. MPP_RET vcodec_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
  548. {
  549. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  550. VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
  551. mpp_assert(cfg->offset == 0);
  552. send_cfg->reg_get = cfg->reg;
  553. if (send_cfg->reg_size != cfg->size)
  554. mpp_err_f("reg size mismatch rd %d rd %d\n",
  555. send_cfg->reg_size, cfg->size);
  556. return MPP_OK;
  557. }
  558. MPP_RET vcodec_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg)
  559. {
  560. if (cfg->offset) {
  561. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  562. VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
  563. VcodecExtraInfo *extra = &send_cfg->extra_info;
  564. VcodecExtraSlot *slot;
  565. RK_U32 i;
  566. for (i = 0; i < extra->count; i++) {
  567. slot = &extra->slots[i];
  568. if (slot->reg_idx == cfg->reg_idx) {
  569. mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
  570. slot->reg_idx, slot->offset, cfg->offset);
  571. slot->offset = cfg->offset;
  572. return MPP_OK;
  573. }
  574. }
  575. slot = &extra->slots[extra->count];
  576. slot->reg_idx = cfg->reg_idx;
  577. slot->offset = cfg->offset;
  578. extra->count++;
  579. }
  580. return MPP_OK;
  581. }
  582. MPP_RET vcodec_service_cmd_send(void *ctx)
  583. {
  584. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  585. VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
  586. VcodecExtraInfo *extra = &send_cfg->extra_info;
  587. void *reg_set = send_cfg->reg_set;
  588. char *fmt = (char*)&p->fmt;
  589. update_extra_info(extra, fmt, send_cfg);
  590. MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_SET_REG,
  591. reg_set, send_cfg->reg_size);
  592. if (ret) {
  593. mpp_err_f("ioctl VPU_IOC_SET_REG failed ret %d errno %d %s\n",
  594. ret, errno, strerror(errno));
  595. ret = errno;
  596. }
  597. p->reg_send_idx++;
  598. if (p->reg_send_idx >= p->max_regs)
  599. p->reg_send_idx = 0;
  600. p->info_count = 0;
  601. return ret;
  602. }
  603. MPP_RET vcodec_service_cmd_poll(void *ctx, MppDevPollCfg *cfg)
  604. {
  605. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  606. VcodecRegCfg *poll_cfg = &p->regs[p->reg_poll_idx];
  607. void *reg_get = poll_cfg->reg_get;
  608. RK_S32 reg_size = poll_cfg->reg_size;
  609. MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_GET_REG,
  610. reg_get, reg_size);
  611. if (ret) {
  612. mpp_err_f("ioctl VPU_IOC_GET_REG failed ret %d errno %d %s\n",
  613. ret, errno, strerror(errno));
  614. ret = errno;
  615. }
  616. p->reg_poll_idx++;
  617. if (p->reg_poll_idx >= p->max_regs)
  618. p->reg_poll_idx = 0;
  619. (void)cfg;
  620. return ret;
  621. }
  622. MPP_RET vcodec_service_set_info(void *ctx, MppDevInfoCfg *cfg)
  623. {
  624. MppDevVcodecService *p = (MppDevVcodecService *)ctx;
  625. if (!p->info_count)
  626. memset(p->info, 0, sizeof(p->info));
  627. if (p->info_count >= MAX_INFO_COUNT) {
  628. mpp_err("info count reach max\n");
  629. return MPP_NOK;
  630. }
  631. memcpy(&p->info[p->info_count], cfg, sizeof(MppDevInfoCfg));
  632. p->info_count++;
  633. if (cfg->type == INFO_FORMAT_TYPE) {
  634. p->fmt = cfg->data;
  635. }
  636. return MPP_OK;
  637. }
  638. const MppDevApi vcodec_service_api = {
  639. "vcodec_service",
  640. sizeof(MppDevVcodecService),
  641. vcodec_service_init,
  642. vcodec_service_deinit,
  643. NULL,
  644. NULL,
  645. NULL,
  646. NULL,
  647. vcodec_service_reg_wr,
  648. vcodec_service_reg_rd,
  649. vcodec_service_reg_offset,
  650. NULL,
  651. NULL,
  652. vcodec_service_set_info,
  653. NULL,
  654. NULL,
  655. NULL,
  656. NULL,
  657. NULL,
  658. vcodec_service_cmd_send,
  659. vcodec_service_cmd_poll,
  660. };