kmpp.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. /* SPDX-License-Identifier: Apache-2.0 OR MIT */
  2. /*
  3. * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
  4. */
  5. #define MODULE_TAG "kmpp"
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <sys/mman.h>
  11. #include <sys/ioctl.h>
  12. #include "rk_mpi.h"
  13. #include "mpp_log.h"
  14. #include "mpp_mem.h"
  15. #include "mpp_env.h"
  16. #include "mpp_time.h"
  17. #include "mpp_impl.h"
  18. #include "mpp_2str.h"
  19. #include "mpp_debug.h"
  20. #include "kmpp.h"
  21. #include "kmpp_obj.h"
  22. #include "mpp_soc.h"
  23. #include "mpp_buffer_impl.h"
  24. #include "mpp_frame_impl.h"
  25. #include "mpp_packet_impl.h"
  26. #include "mpp_vcodec_client.h"
  27. #include "mpp_enc_cfg_impl.h"
  28. typedef struct KmppFrameInfos_t {
  29. RK_U32 width;
  30. RK_U32 height;
  31. RK_U32 hor_stride;
  32. RK_U32 ver_stride;
  33. RK_U32 hor_stride_pixel;
  34. RK_U32 offset_x;
  35. RK_U32 offset_y;
  36. RK_U32 fmt;
  37. RK_U32 fd;
  38. RK_U64 pts;
  39. RK_S32 jpeg_chan_id;
  40. void *osd_buf;
  41. RK_S32 mpi_buf_id;
  42. void *jpg_combo_osd_buf;
  43. RK_U32 is_gray;
  44. RK_U32 is_full;
  45. RK_U32 phy_addr;
  46. RK_U64 dts;
  47. void *pp_info;
  48. RK_U32 pskip_num;
  49. union {
  50. RK_U32 val;
  51. struct {
  52. RK_U32 eos : 1;
  53. RK_U32 pskip : 1;
  54. RK_U32 isr_request : 1;
  55. };
  56. };
  57. } KmppFrameInfos;
  58. typedef struct KmppVencPacketInfo_t {
  59. RK_U32 flag;
  60. RK_U32 temporal_id;
  61. RK_U32 packet_offset;
  62. RK_U32 packet_len;
  63. } KmppVencPacketInfo;
  64. typedef struct VencPacket_t {
  65. RK_U64 u64priv_data;
  66. RK_U64 u64packet_addr;
  67. RK_U32 len;
  68. RK_U32 buf_size;
  69. RK_U64 u64pts;
  70. RK_U64 u64dts;
  71. RK_U32 flag;
  72. RK_U32 temporal_id;
  73. RK_U32 offset;
  74. RK_U32 data_num;
  75. KmppVencPacketInfo packet[8];
  76. } VencPacket;
  77. static void kmpp_release_venc_packet(void *ctx, void *arg)
  78. {
  79. Kmpp *p = (Kmpp *)ctx;
  80. VencPacket *pkt = (VencPacket *)arg;
  81. if (!ctx || !pkt) {
  82. mpp_err_f("invalid input ctx %p pkt %p\n", ctx, pkt);
  83. return;
  84. }
  85. mpp_vcodec_ioctl(p->mClientFd, VCODEC_CHAN_OUT_STRM_END, 0, sizeof(VencPacket), pkt);
  86. mpp_mem_pool_put(p->mVencPacketPool, pkt);
  87. }
  88. static MPP_RET init(Kmpp *ctx, MppCtxType type, MppCodingType coding)
  89. {
  90. MPP_RET ret = MPP_NOK;
  91. RK_U32 chan_id;
  92. void *hnd;
  93. RK_U32 size;
  94. if (!ctx)
  95. return MPP_ERR_VALUE;
  96. if (mpp_check_support_format(type, coding)) {
  97. mpp_err("unable to create %s %s for mpp unsupported\n",
  98. strof_ctx_type(type), strof_coding_type(coding));
  99. return MPP_NOK;
  100. }
  101. if (ctx->mClientFd < 0) {
  102. ctx->mClientFd = mpp_vcodec_open();
  103. if (ctx->mClientFd < 0) {
  104. mpp_err("mpp_vcodec dev open failed\n");
  105. return MPP_NOK;
  106. }
  107. }
  108. hnd = kmpp_obj_to_shm(ctx->mVencInitKcfg);
  109. size = kmpp_obj_to_shm_size(ctx->mVencInitKcfg);
  110. kmpp_obj_get_u32(ctx->mVencInitKcfg, "chan_dup", &ctx->mChanDup);
  111. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_CREATE, 0, size, hnd);
  112. if (ret) {
  113. mpp_err("chan %d VCODEC_CHAN_CREATE failed\n", ctx->mChanId);
  114. return ret;
  115. }
  116. if (!ctx->mChanDup) {
  117. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_START, 0, 0, 0);
  118. if (ret) {
  119. mpp_err("chan %d VCODEC_CHAN_START failed\n", ctx->mChanId);
  120. return ret;
  121. }
  122. }
  123. if (ctx->mPacketGroup == NULL)
  124. mpp_buffer_group_get_internal(&ctx->mPacketGroup, MPP_BUFFER_TYPE_ION);
  125. ctx->mVencPacketPool = mpp_mem_pool_init(sizeof(VencPacket));
  126. kmpp_obj_get_u32(ctx->mVencInitKcfg, "chan_id", &chan_id);
  127. mpp_log("client %d open chan_id %d ok", ctx->mClientFd, chan_id);
  128. ctx->mInitDone = 1;
  129. ctx->mChanId = chan_id;
  130. ctx->mType = type;
  131. ctx->mOutputTimeout = MPP_POLL_BLOCK;
  132. ctx->mTimeout.tv_sec = 2;
  133. ctx->mTimeout.tv_usec = 100000;
  134. return ret;
  135. }
  136. static MPP_RET open_client(Kmpp *ctx)
  137. {
  138. if (!ctx)
  139. return MPP_ERR_VALUE;
  140. ctx->mClientFd = mpp_vcodec_open();
  141. if (ctx->mClientFd < 0) {
  142. mpp_err("mpp_vcodec dev open failed\n");
  143. return MPP_NOK;
  144. }
  145. return MPP_OK;
  146. }
  147. static void clear(Kmpp *ctx)
  148. {
  149. if (!ctx)
  150. return;
  151. if (!ctx->mChanDup) {
  152. MPP_RET ret;
  153. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_DESTROY, 0, 0, 0);
  154. if (ret)
  155. mpp_err("chan %d VCODEC_CHAN_DESTROY failed\n", ctx->mChanId);
  156. }
  157. if (ctx->mClientFd >= 0)
  158. mpp_vcodec_close(ctx->mClientFd);
  159. ctx->mClientFd = -1;
  160. if (ctx->mPacketGroup) {
  161. mpp_buffer_group_put(ctx->mPacketGroup);
  162. ctx->mPacketGroup = NULL;
  163. }
  164. if (ctx->mVencPacketPool) {
  165. mpp_mem_pool_deinit(ctx->mVencPacketPool);
  166. ctx->mVencPacketPool = NULL;
  167. }
  168. }
  169. static MPP_RET start(Kmpp *ctx)
  170. {
  171. MPP_RET ret = MPP_OK;
  172. if (!ctx)
  173. return MPP_ERR_VALUE;
  174. if (ctx->mChanDup)
  175. return MPP_OK;
  176. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_START, 0, 0, 0);
  177. if (ret)
  178. mpp_err("chan %d VCODEC_CHAN_START failed\n", ctx->mChanId);
  179. return ret;
  180. }
  181. static MPP_RET stop(Kmpp *ctx)
  182. {
  183. MPP_RET ret = MPP_OK;
  184. if (!ctx)
  185. return MPP_ERR_VALUE;
  186. if (ctx->mChanDup)
  187. return MPP_OK;
  188. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_START, 0, 0, 0);
  189. if (ret)
  190. mpp_err("chan %d VCODEC_CHAN_START failed\n", ctx->mChanId);
  191. return ret;
  192. }
  193. static MPP_RET mpp_pause(Kmpp *ctx)
  194. {
  195. MPP_RET ret = MPP_OK;
  196. if (!ctx)
  197. return MPP_ERR_VALUE;
  198. if (ctx->mChanDup)
  199. return MPP_OK;
  200. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_PAUSE, 0, 0, 0);
  201. if (ret)
  202. mpp_err("chan %d VCODEC_CHAN_PAUSE failed\n", ctx->mChanId);
  203. return ret;
  204. }
  205. static MPP_RET resume(Kmpp *ctx)
  206. {
  207. MPP_RET ret = MPP_OK;
  208. if (!ctx)
  209. return MPP_ERR_VALUE;
  210. if (ctx->mChanDup)
  211. return MPP_OK;
  212. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_RESUME, 0, 0, 0);
  213. if (ret)
  214. mpp_err("chan %d VCODEC_CHAN_RESUME failed\n", ctx->mChanId);
  215. return ret;
  216. }
  217. static MPP_RET put_packet(Kmpp *ctx, MppPacket packet)
  218. {
  219. (void) packet;
  220. MPP_RET ret = MPP_OK;
  221. if (!ctx->mInitDone)
  222. return MPP_ERR_INIT;
  223. return ret;
  224. }
  225. static MPP_RET get_frame(Kmpp *ctx, MppFrame *frame)
  226. {
  227. (void)frame;
  228. if (!ctx->mInitDone)
  229. return MPP_ERR_INIT;
  230. return MPP_OK;
  231. }
  232. static MPP_RET put_frame(Kmpp *ctx, MppFrame frame)
  233. {
  234. KmppFrameInfos frame_info;
  235. MppBuffer buf = NULL;
  236. MPP_RET ret = MPP_OK;
  237. if (!ctx)
  238. return MPP_ERR_VALUE;
  239. if (!ctx->mInitDone)
  240. return MPP_ERR_INIT;
  241. buf = mpp_frame_get_buffer(frame);
  242. memset(&frame_info, 0, sizeof(frame_info));
  243. frame_info.width = mpp_frame_get_width(frame);
  244. frame_info.height = mpp_frame_get_height(frame);
  245. frame_info.hor_stride = mpp_frame_get_hor_stride(frame);
  246. frame_info.ver_stride = mpp_frame_get_ver_stride(frame);
  247. frame_info.hor_stride_pixel = mpp_frame_get_hor_stride_pixel(frame);
  248. frame_info.offset_x = mpp_frame_get_offset_x(frame);
  249. frame_info.offset_y = mpp_frame_get_offset_y(frame);
  250. frame_info.fmt = mpp_frame_get_fmt(frame);
  251. frame_info.fd = mpp_buffer_get_fd(buf);
  252. // frame_info.pts = mpp_frame_get_pts(frame);
  253. // frame_info.jpeg_chan_id = mpp_frame_get_jpege_chan_id(frame);
  254. // frame_info.eos = mpp_frame_get_eos(frame);
  255. // frame_info.pskip = mpp_frame_get_pskip_request(frame);
  256. // frame_info.pskip_num = mpp_frame_get_pskip_num(frame);
  257. if (mpp_frame_has_meta(frame)) {
  258. MppMeta meta = mpp_frame_get_meta(frame);
  259. MppPacket packet = NULL;
  260. mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet);
  261. ctx->mPacket = packet;
  262. /* set roi */
  263. {
  264. MppEncROICfg *roi_data = NULL;
  265. MppEncROICfgLegacy roi_data0;
  266. mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&roi_data);
  267. if (roi_data) {
  268. roi_data0.change = 1;
  269. roi_data0.number = roi_data->number;
  270. memcpy(roi_data0.regions, roi_data->regions, roi_data->number * sizeof(MppEncROIRegion));
  271. ctx->mApi->control(ctx, MPP_ENC_SET_ROI_CFG, &roi_data0);
  272. }
  273. }
  274. }
  275. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_IN_FRM_RDY, 0, sizeof(frame_info), &frame_info);
  276. if (ret)
  277. mpp_err("chan %d VCODEC_CHAN_IN_FRM_RDY failed\n", ctx->mChanId);
  278. return ret;
  279. }
  280. static MPP_RET get_packet(Kmpp *ctx, MppPacket *packet)
  281. {
  282. RK_S32 ret;
  283. if (!ctx)
  284. return MPP_ERR_VALUE;
  285. if (!ctx->mInitDone)
  286. return MPP_ERR_INIT;
  287. struct timeval timeout;
  288. fd_set read_fds;
  289. FD_ZERO(&read_fds);
  290. FD_SET(ctx->mClientFd, &read_fds);
  291. memcpy(&timeout, &ctx->mTimeout, sizeof(timeout));
  292. ret = select(ctx->mClientFd + 1, &read_fds, NULL, NULL, &timeout);
  293. if (ret <= 0) {
  294. mpp_err("get venc stream error %d\n", ret);
  295. return MPP_NOK;
  296. }
  297. if (FD_ISSET(ctx->mClientFd, &read_fds)) {
  298. VencPacket *venc_packet = mpp_mem_pool_get(ctx->mVencPacketPool);
  299. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_OUT_STRM_BUF_RDY, 0, sizeof(VencPacket), venc_packet);
  300. if (ret) {
  301. mpp_err("chan %d VCODEC_CHAN_OUT_STRM_BUF_RDY failed\n", ctx->mChanId);
  302. return MPP_NOK;
  303. }
  304. if (venc_packet->len) {
  305. MppPacket pkt = NULL;
  306. void *ptr = NULL;
  307. RK_U32 len = venc_packet->len;
  308. ptr = (void *)(intptr_t)(venc_packet->u64priv_data);
  309. if (ptr) {
  310. if (ctx->mPacket) {
  311. void *dst;
  312. pkt = ctx->mPacket;
  313. ctx->mPacket = NULL;
  314. dst = mpp_packet_get_pos(pkt);
  315. memcpy(dst, ptr + venc_packet->offset, len);
  316. mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_OUT_STRM_END, 0, sizeof(VencPacket), venc_packet);
  317. mpp_packet_set_length(pkt, len);
  318. mpp_mem_pool_put(ctx->mVencPacketPool, venc_packet);
  319. } else {
  320. mpp_packet_init(&pkt, ptr + venc_packet->offset, len);
  321. mpp_packet_set_release(pkt, kmpp_release_venc_packet, ctx, venc_packet);
  322. }
  323. mpp_packet_set_dts(pkt, venc_packet->u64dts);
  324. mpp_packet_set_pts(pkt, venc_packet->u64pts);
  325. mpp_packet_set_flag(pkt, venc_packet->flag);
  326. if (venc_packet->flag & MPP_PACKET_FLAG_INTRA) {
  327. MppMeta meta = mpp_packet_get_meta(pkt);
  328. mpp_meta_set_s32(meta, KEY_OUTPUT_INTRA, 1);
  329. }
  330. }
  331. *packet = pkt;
  332. }
  333. }
  334. return MPP_OK;
  335. }
  336. static MPP_RET release_packet(Kmpp *ctx, MppPacket *packet)
  337. {
  338. VencPacket *enc_packet = (VencPacket *) *packet;
  339. MPP_RET ret = MPP_OK;
  340. if (!ctx)
  341. return MPP_ERR_VALUE;
  342. if (!ctx->mInitDone)
  343. return MPP_ERR_INIT;
  344. if (*packet == NULL)
  345. return MPP_NOK;
  346. if (ctx->mClientFd < 0)
  347. return MPP_NOK;
  348. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_OUT_STRM_END, 0, sizeof(*enc_packet), enc_packet);
  349. if (ret)
  350. mpp_err("chan %d VCODEC_CHAN_OUT_STRM_END failed\n", ctx->mChanId);
  351. return ret;
  352. }
  353. static MPP_RET poll(Kmpp *ctx, MppPortType type, MppPollType timeout)
  354. {
  355. MPP_RET ret = MPP_NOK;
  356. (void)type;
  357. (void)timeout;
  358. if (!ctx->mInitDone)
  359. return MPP_ERR_INIT;
  360. return ret;
  361. }
  362. static MPP_RET dequeue(Kmpp *ctx, MppPortType type, MppTask *task)
  363. {
  364. MPP_RET ret = MPP_NOK;
  365. (void)type;
  366. (void)task;
  367. if (!ctx->mInitDone)
  368. return MPP_ERR_INIT;
  369. return ret;
  370. }
  371. static MPP_RET enqueue(Kmpp *ctx, MppPortType type, MppTask task)
  372. {
  373. MPP_RET ret = MPP_NOK;
  374. (void)type;
  375. (void)task;
  376. if (!ctx->mInitDone)
  377. return MPP_ERR_INIT;
  378. return ret;
  379. }
  380. static MPP_RET control(Kmpp *ctx, MpiCmd cmd, MppParam param)
  381. {
  382. MPP_RET ret = MPP_NOK;
  383. RK_U32 size = 0;
  384. void *arg = param;
  385. if (!ctx)
  386. return MPP_ERR_VALUE;
  387. switch (cmd) {
  388. case MPP_ENC_SET_CFG :
  389. case MPP_ENC_GET_CFG : {
  390. size = sizeof(MppEncCfgImpl);
  391. } break;
  392. case MPP_ENC_SET_HEADER_MODE :
  393. case MPP_ENC_SET_SEI_CFG : {
  394. size = sizeof(RK_U32);
  395. } break;
  396. case MPP_ENC_GET_REF_CFG :
  397. case MPP_ENC_SET_REF_CFG : {
  398. size = sizeof(MppEncRefParam);
  399. } break;
  400. case MPP_ENC_GET_ROI_CFG:
  401. case MPP_ENC_SET_ROI_CFG: {
  402. size = sizeof(MppEncROICfgLegacy);
  403. } break;
  404. // case MPP_ENC_SET_JPEG_ROI_CFG : {
  405. // size = sizeof(MppJpegROICfg);
  406. // } break;
  407. case MPP_ENC_SET_OSD_DATA_CFG: {
  408. size = sizeof(MppEncOSDData3);
  409. } break;
  410. case MPP_ENC_SET_USERDATA: {
  411. size = sizeof(MppEncUserData);
  412. } break;
  413. case MPP_SET_VENC_INIT_KCFG: {
  414. KmppObj obj = param;
  415. arg = kmpp_obj_to_shm(obj);
  416. size = kmpp_obj_to_shm_size(obj);
  417. } break;
  418. case MPP_SET_SELECT_TIMEOUT: {
  419. struct timeval *p = (struct timeval *)param;
  420. ctx->mTimeout.tv_sec = p->tv_sec;
  421. ctx->mTimeout.tv_usec = p->tv_usec;
  422. return MPP_OK;
  423. } break;
  424. case MPP_ENC_SET_IDR_FRAME: {
  425. size = 0;
  426. } break;
  427. default : {
  428. size = 0;
  429. return MPP_OK;
  430. } break;
  431. }
  432. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_CONTROL, cmd, size, arg);
  433. if (ret)
  434. mpp_err("chan %d VCODEC_CHAN_CONTROL failed\n", ctx->mChanId);
  435. return ret;
  436. }
  437. static MPP_RET reset(Kmpp *ctx)
  438. {
  439. MPP_RET ret = MPP_OK;
  440. if (!ctx)
  441. return MPP_ERR_VALUE;
  442. if (ctx->mChanDup)
  443. return MPP_OK;
  444. if (!ctx->mInitDone)
  445. return MPP_ERR_INIT;
  446. ret = mpp_vcodec_ioctl(ctx->mClientFd, VCODEC_CHAN_RESET, 0, 0, 0);
  447. if (ret)
  448. mpp_err("chan %d VCODEC_CHAN_RESET failed\n", ctx->mChanId);
  449. return ret;
  450. }
  451. static MPP_RET notify_flag(Kmpp *ctx, RK_U32 flag)
  452. {
  453. (void)flag;
  454. (void)ctx;
  455. return MPP_NOK;
  456. }
  457. static MPP_RET notify(Kmpp *ctx, MppBufferGroup group)
  458. {
  459. MPP_RET ret = MPP_OK;
  460. (void)group;
  461. switch (ctx->mType) {
  462. case MPP_CTX_DEC : {
  463. } break;
  464. default : {
  465. } break;
  466. }
  467. return ret;
  468. }
  469. static MPP_RET get_fd(Kmpp *ctx, RK_S32 *fd)
  470. {
  471. MPP_RET ret = MPP_OK;
  472. if (!ctx)
  473. return MPP_ERR_VALUE;
  474. if (ctx->mClientFd >= 0)
  475. *fd = fcntl(ctx->mClientFd, F_DUPFD_CLOEXEC, 3);
  476. else
  477. *fd = -1;
  478. if (*fd < 0)
  479. ret = MPP_NOK;
  480. return ret;
  481. }
  482. static MPP_RET close_fd(Kmpp *ctx, RK_S32 fd)
  483. {
  484. if (fd >= 0)
  485. close(fd);
  486. (void)ctx;
  487. return MPP_OK;
  488. }
  489. static KmppOps ops = {
  490. .open_client = open_client,
  491. .init = init,
  492. .start = start,
  493. .stop = stop,
  494. .pause = mpp_pause,
  495. .resume = resume,
  496. .put_packet = put_packet,
  497. .get_frame = get_frame,
  498. .put_frame = put_frame,
  499. .get_packet = get_packet,
  500. .release_packet = release_packet,
  501. .poll = poll,
  502. .dequeue = dequeue,
  503. .enqueue = enqueue,
  504. .reset = reset,
  505. .control = control,
  506. .notify_flag = notify_flag,
  507. .notify = notify,
  508. .get_fd = get_fd,
  509. .close_fd = close_fd,
  510. .clear = clear,
  511. };
  512. void mpp_get_api(Kmpp *ctx)
  513. {
  514. if (!ctx)
  515. return;
  516. ctx->mApi = &ops;
  517. }