ark_video.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <linux/ioctl.h>
  4. #include <sys/ioctl.h>
  5. #include <errno.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <sys/mman.h>
  9. #include <string.h>
  10. #include <sys/syscall.h>
  11. #include <sys/time.h>
  12. #include <sys/shm.h>
  13. #include <sys/ipc.h>
  14. #include <signal.h>
  15. #include "ark_common.h"
  16. #include "ark_video.h"
  17. #include "mfcapi.h"
  18. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  19. #include "ark_2d.h"
  20. #endif
  21. struct display_data *pdd = NULL;
  22. //#define DECODE_SCALE_PARALLEL
  23. static int get_shared_display_data(void)
  24. {
  25. if (pdd == NULL) {
  26. int shmid;
  27. shmid = shmget(DISPLAY_DATA_ID, sizeof(struct display_data), IPC_CREAT | 0666);
  28. if (shmid == -1) {
  29. perror("shmget err");
  30. return errno;
  31. }
  32. struct display_data *p = NULL;
  33. p = shmat(shmid, NULL, 0);
  34. if (p == (void *)-1 ) {
  35. perror("shmat err");
  36. return errno;
  37. }
  38. if (p->init == 0) {
  39. if (sem_init(&p->sem, 1, 1) < 0) {
  40. printf("sem_init fail, err is %d-%s.\n", errno, strerror(errno));
  41. return errno;
  42. }
  43. p->kernel_used = 0;
  44. p->display_mode = DISP_NONE;
  45. p->active_handle = NULL;
  46. p->init = 1;
  47. arkapi_display_get_screen_info(&p->screen);
  48. ark_dbg("%s %s-%s.\n", __FUNCTION__, __DATE__, __TIME__);
  49. }
  50. pdd = p;
  51. }
  52. return 0;
  53. }
  54. static int display_lock(void)
  55. {
  56. if (pdd) {
  57. if (sem_wait(&pdd->sem) < 0 ) {
  58. printf("sem_wait fail.\n");
  59. return -1;
  60. }
  61. }
  62. return 0;
  63. }
  64. static int display_unlock(void)
  65. {
  66. if (pdd) {
  67. if (sem_post(&pdd->sem) < 0 ) {
  68. printf("sem_post fail.\n");
  69. return -1;
  70. }
  71. }
  72. return 0;
  73. }
  74. static void video_handle_default(video_handle *handle)
  75. {
  76. int i;
  77. if(!handle){
  78. printf("%s: handle null, error.\n", __func__);
  79. return;
  80. }
  81. memset(handle, 0 ,sizeof(video_handle));
  82. handle->handle_disp = NULL;
  83. handle->last_display_addr = 0;
  84. handle->last_render_yaddr = 0;
  85. handle->last_render_uaddr = 0;
  86. handle->last_render_vaddr = 0;
  87. handle->first_show = 1;
  88. handle->dec_first_frame = 1;
  89. handle->rotate_buffer_index= 0;
  90. handle->cur_direction = VERTICAL;
  91. handle->in_buffer.virtualAddress = (unsigned int *)MAP_FAILED;
  92. handle->in_buffer.busAddress = 0;
  93. for (i = 0; i < ROTATE_BUF_MAX; i++) {
  94. handle->rotate_buffer[i].virtualAddress = (unsigned int *)MAP_FAILED;
  95. handle->rotate_buffer[i].busAddress = 0;
  96. }
  97. handle->cfg_vid.win_src_x = 0;
  98. handle->cfg_vid.win_src_y = 0;
  99. handle->cfg_vid.win_src_width = 0;
  100. handle->cfg_vid.win_src_height = 0;
  101. handle->cfg_vid.disp_x = 0;
  102. handle->cfg_vid.disp_y = 0;
  103. handle->cfg_vid.disp_width = pdd->screen.width;
  104. handle->cfg_vid.disp_height = pdd->screen.height;
  105. handle->cfg_vid.direction = VERTICAL;
  106. handle->cfg_vid.keep_aspect_ratio = 0;
  107. }
  108. int video_alloc_buffer(video_handle *handle)
  109. {
  110. reqbuf_info *reqbuf;
  111. int ret, i;
  112. if(!handle){
  113. printf("%s: handle null, error.\n", __func__);
  114. return -EINVAL;
  115. }
  116. reqbuf = arkapi_memalloc_reqbuf(handle->handle_mem, MAX_STREAM_BUFFER_SIZE, 1);
  117. if (!reqbuf) {
  118. printf("memalloc: get buffer failure 1.\n");
  119. return -1;
  120. }
  121. handle->in_buffer.size = reqbuf->size;
  122. handle->in_buffer.busAddress = reqbuf->phy_addr[0];
  123. handle->in_buffer.virtualAddress = (unsigned int *)reqbuf->virt_addr[0];
  124. reqbuf = arkapi_memalloc_reqbuf(handle->handle_mem,
  125. handle->cfg_vid.disp_width * handle->cfg_vid.disp_height * 2, ROTATE_BUF_MAX);
  126. if (!reqbuf) {
  127. printf("memalloc: get buffer failure.\n");
  128. return -1;
  129. }
  130. for(i = 0; i < reqbuf->count; i++){
  131. handle->rotate_buffer[i].size = reqbuf->size;
  132. handle->rotate_buffer[i].busAddress = reqbuf->phy_addr[i];
  133. handle->rotate_buffer[i].virtualAddress = (unsigned int *)reqbuf->virt_addr[i];
  134. }
  135. ark_dbg("%s: <---success.\n", __func__);
  136. return 0;
  137. }
  138. static void video_display_process(video_handle *handle, unsigned int yaddr, unsigned int uaddr, unsigned int vaddr)
  139. {
  140. int off_x, off_y;
  141. int out_w, out_h;
  142. int winx = 0, winy = 0, winwidth = 0, winheight = 0;
  143. unsigned int dst_phyaddr, read_addr = 0;
  144. int ret;
  145. if(!handle || !handle->handle_disp){
  146. printf("%s: handle null, error.\n", __func__);
  147. return;
  148. }
  149. if (!handle->active) {
  150. printf("%s not active.\n", __func__);
  151. return;
  152. }
  153. display_lock();
  154. if (pdd->active_handle != handle) {
  155. ark_dbg("%s: active_handle=0x%p != handle=0x%p, exit.\n", __func__, pdd->active_handle, handle);
  156. display_unlock();
  157. return;
  158. }
  159. if (pdd->kernel_used) {
  160. ark_dbg("%s display used by kernel.\n", __func__);
  161. display_unlock();
  162. return;
  163. }
  164. display_unlock();
  165. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  166. if (yaddr == 0)
  167. return;
  168. dst_phyaddr = handle->rotate_buffer[handle->rotate_buffer_index].busAddress;
  169. handle->rotate_buffer_index = (handle->rotate_buffer_index + 1) % ROTATE_BUF_MAX;
  170. arkapi_display_get_layer_addr(handle->handle_disp, &read_addr, NULL, NULL);
  171. if (read_addr == dst_phyaddr)
  172. arkapi_display_wait_for_vsync(handle->handle_disp);
  173. arkapi_2d_process(handle->handle_2d, yaddr, dst_phyaddr);
  174. handle->last_display_addr = dst_phyaddr;
  175. out_w = handle->handle_2d->out_width;
  176. out_h = handle->handle_2d->out_height;
  177. if(handle->cfg_vid.disp_x == 0 && handle->cfg_vid.disp_y == 0){
  178. off_x = (handle->cfg_vid.disp_width - out_w) / 2;
  179. off_y = (handle->cfg_vid.disp_height - out_h) / 2;
  180. }else{
  181. off_x = handle->cfg_vid.disp_x;
  182. off_y = handle->cfg_vid.disp_y;
  183. }
  184. #else
  185. off_x = handle->cfg_vid.disp_x;
  186. off_y = handle->cfg_vid.disp_y;
  187. out_w = handle->cfg_vid.disp_width;
  188. out_h = handle->cfg_vid.disp_height;
  189. #ifndef DECODE_SCALE_PARALLEL
  190. if (yaddr == 0)
  191. return;
  192. if(handle->cfg_vid.win_src_width && handle->cfg_vid.win_src_height){
  193. winx = handle->cfg_vid.win_src_x;
  194. winy = handle->cfg_vid.win_src_y;
  195. winwidth = handle->cfg_vid.win_src_width;
  196. winheight = handle->cfg_vid.win_src_height;
  197. }else{
  198. winwidth = handle->out_buffer.codedWidth;
  199. winheight = handle->out_buffer.codedHeight;
  200. }
  201. dst_phyaddr = handle->rotate_buffer[handle->rotate_buffer_index].busAddress;
  202. handle->rotate_buffer_index = (handle->rotate_buffer_index + 1) % ROTATE_BUF_MAX;
  203. arkapi_display_get_layer_addr(handle->handle_disp, &read_addr, NULL, NULL);
  204. if (read_addr == dst_phyaddr)
  205. arkapi_display_wait_for_vsync(handle->handle_disp);
  206. ret = arkapi_scalar(yaddr, uaddr, vaddr,
  207. ARK_SCALE_FORMAT_Y_UV420,
  208. handle->out_buffer.frameWidth, handle->out_buffer.frameHeight,
  209. winx, winy, winwidth, winheight,
  210. 0, 0, 0, 0,
  211. handle->cfg_vid.disp_width, handle->cfg_vid.disp_height,
  212. dst_phyaddr, dst_phyaddr + out_w * out_h, 0,
  213. ARK_SCALE_OUT_FORMAT_Y_UV420,
  214. SCALE_ROTATE_0);
  215. if (ret) {
  216. printf("arkapi_scalar fail.\n");
  217. handle->last_display_addr = 0;
  218. } else {
  219. handle->last_display_addr = dst_phyaddr;
  220. }
  221. #endif
  222. #endif
  223. if (handle->last_display_addr) {
  224. unsigned int display_addr = handle->last_display_addr;
  225. if (handle->first_show) {
  226. arkapi_display_set_layer_pos_atomic(handle->handle_disp, off_x, off_y);
  227. arkapi_display_set_layer_size_atomic(handle->handle_disp, out_w, out_h);
  228. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  229. arkapi_display_set_layer_format_atomic(handle->handle_disp, ARK_LCDC_FORMAT_R5G6B5);
  230. arkapi_display_set_layer_addr_atomic(handle->handle_disp, display_addr, 0, 0);
  231. #else
  232. arkapi_display_set_layer_format_atomic(handle->handle_disp, ARK_LCDC_FORMAT_Y_UV420);
  233. arkapi_display_set_layer_addr_atomic(handle->handle_disp, display_addr,
  234. display_addr + out_w * out_h, 0);
  235. #endif
  236. arkapi_display_layer_update_commit(handle->handle_disp);
  237. usleep(20000);
  238. arkapi_display_show_layer(handle->handle_disp);
  239. handle->first_show = 0;
  240. } else {
  241. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  242. arkapi_display_set_layer_addr(handle->handle_disp, display_addr, 0, 0);
  243. #else
  244. arkapi_display_set_layer_addr(handle->handle_disp, display_addr,
  245. display_addr + out_w * out_h, 0);
  246. #endif
  247. }
  248. handle->last_display_addr = 0;
  249. }
  250. #ifdef DECODE_SCALE_PARALLEL
  251. #if LIBARKAPI_PLATFORM != LIBARKAPI_ARK1668
  252. if (yaddr == 0)
  253. return;
  254. if(handle->cfg_vid.win_src_width && handle->cfg_vid.win_src_height){
  255. winx = handle->cfg_vid.win_src_x;
  256. winy = handle->cfg_vid.win_src_y;
  257. winwidth = handle->cfg_vid.win_src_width;
  258. winheight = handle->cfg_vid.win_src_height;
  259. }else{
  260. winwidth = handle->out_buffer.codedWidth;
  261. winheight = handle->out_buffer.codedHeight;
  262. }
  263. ret = arkapi_scalar_wait_idle();
  264. if (ret) {
  265. printf("arkapi_scalar_wait_idle fail.\n");
  266. } else {
  267. dst_phyaddr = handle->rotate_buffer[handle->rotate_buffer_index].busAddress;
  268. handle->rotate_buffer_index = (handle->rotate_buffer_index + 1) % ROTATE_BUF_MAX;
  269. arkapi_display_get_layer_addr(handle->handle_disp, &read_addr, NULL, NULL);
  270. if (read_addr == dst_phyaddr)
  271. arkapi_display_wait_for_vsync(handle->handle_disp);
  272. ret = arkapi_scalar_nowait(yaddr, uaddr, vaddr,
  273. ARK_SCALE_FORMAT_Y_UV420,
  274. handle->out_buffer.frameWidth, handle->out_buffer.frameHeight,
  275. winx, winy, winwidth, winheight,
  276. 0, 0, 0, 0,
  277. handle->cfg_vid.disp_width, handle->cfg_vid.disp_height,
  278. dst_phyaddr, dst_phyaddr + out_w * out_h, 0,
  279. ARK_SCALE_OUT_FORMAT_Y_UV420,
  280. SCALE_ROTATE_0);
  281. if (!ret)
  282. handle->last_display_addr = dst_phyaddr;
  283. else
  284. printf("arkapi_scalar_nowait fail.\n");
  285. }
  286. #endif
  287. #endif
  288. //ark_dbg("%s: <---end.\n", __func__);
  289. }
  290. void sig_handler(int sigio)
  291. {
  292. video_handle *handle;
  293. display_lock();
  294. handle = pdd->active_handle;
  295. display_unlock();
  296. if (sigio == SIGUSR1) {
  297. ark_dbg("rev SIGUSR1\n");
  298. if (handle && handle->handle_disp)
  299. arkapi_display_hide_layer(handle->handle_disp);
  300. } else if (sigio == SIGUSR2) {
  301. ark_dbg("rev SIGUSR2\n");
  302. handle->first_show = 1;
  303. if (handle)
  304. video_display_process(handle, handle->last_render_yaddr, handle->last_render_uaddr,
  305. handle->last_render_vaddr);
  306. #if LIBARKAPI_PLATFORM != LIBARKAPI_ARK1668 && defined(DECODE_SCALE_PARALLEL)
  307. video_display_process(handle, 0, 0, 0);
  308. #endif
  309. }
  310. }
  311. video_handle *arkapi_video_init(int stream_type)
  312. {
  313. memalloc_handle *handle_mem = NULL;
  314. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  315. ark2d_handle *handle_2d = NULL;
  316. #endif
  317. disp_handle *handle_disp= NULL;
  318. video_handle *handle = NULL;
  319. struct list_head *list;
  320. int ret;
  321. ark_dbg("%s: stream_type=%d.\n", __func__, stream_type);
  322. printf("arkapi_video_init -20220406\n");
  323. if(stream_type < RAW_STRM_TYPE_H264 || (stream_type > RAW_STRM_TYPE_MP4_CUSTOM && \
  324. stream_type != RAW_STRM_TYPE_H264_NOREORDER)){
  325. printf("stream_type, error.\n");
  326. return NULL;
  327. }
  328. get_shared_display_data();
  329. handle = (video_handle *)malloc(sizeof(video_handle));
  330. if(!handle){
  331. printf("%s: malloc video handle error.\n", __func__);
  332. goto err;
  333. }
  334. memset(handle, 0, sizeof(video_handle));
  335. video_handle_default(handle);
  336. handle_disp = arkapi_display_open_layer(VIDEO_LAYER);
  337. if (!handle_disp) {
  338. printf("open VIDEO_LAYER fail.\n");
  339. goto err;
  340. }
  341. handle->handle_disp = handle_disp;
  342. handle_mem = arkapi_memalloc_init();
  343. if (!handle_mem) {
  344. goto err1;
  345. }
  346. handle->handle_mem = handle_mem;
  347. if(video_alloc_buffer(handle) < 0){
  348. goto err1;
  349. }
  350. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  351. handle->handle_2d = arkapi_2d_init();
  352. if(!handle->handle_2d){
  353. printf("%s: 2d init fail.\n", __func__);
  354. goto err1;
  355. }
  356. #endif
  357. handle->handle_mfc = mfc_init(stream_type);
  358. if(!handle->handle_mfc){
  359. printf("%s: mfc init fail.\n", __func__);
  360. goto err2;
  361. }
  362. if (sem_init(&handle->sem_lock, 1, 1) < 0) {
  363. printf("%s sem_init fail\n", __func__);
  364. goto err2;
  365. }
  366. signal(SIGUSR1, sig_handler);
  367. signal(SIGUSR2, sig_handler);
  368. ark_dbg("%s: success.\n", __func__);
  369. return handle;
  370. err2:
  371. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  372. arkapi_2d_release(handle->handle_2d);
  373. #endif
  374. err1:
  375. arkapi_memalloc_release(handle->handle_mem);
  376. err:
  377. if(handle) free(handle);
  378. return NULL;
  379. }
  380. static int arkapi_video_lock(video_handle *handle)
  381. {
  382. int ret = 0;
  383. ret = sem_wait(&handle->sem_lock);
  384. if (ret < 0 ) {
  385. printf("%s sem_wait fail, error=%d.\n", __func__, ret);
  386. }
  387. return ret;
  388. }
  389. static int arkapi_video_unlock(video_handle *handle)
  390. {
  391. int ret = 0;
  392. ret = sem_post(&handle->sem_lock);
  393. if (ret < 0) {
  394. printf("%s sem_post fail, error=%d.\n", __func__, ret);
  395. }
  396. return ret;
  397. }
  398. int arkapi_video_set_config(video_handle *handle, video_cfg *cfg_vid)
  399. {
  400. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  401. ark2d_cfg cfg_2d;
  402. #endif
  403. if(!handle || !cfg_vid){
  404. printf("%s: handle=0x%p, cfg_vid=0x%p, error.\n", __func__, handle, cfg_vid);
  405. return -EINVAL;
  406. }
  407. arkapi_video_lock(handle);
  408. memcpy(&handle->cfg_vid, cfg_vid, sizeof(video_cfg));
  409. if (handle->cfg_vid.direction != handle->cur_direction) {
  410. handle->first_show = 1;
  411. handle->cur_direction = handle->cfg_vid.direction;
  412. }
  413. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  414. arkapi_2d_get_config(handle->handle_2d, &cfg_2d);
  415. cfg_2d.dst_width = cfg_2d.win_dst_width = cfg_vid->disp_width;
  416. cfg_2d.dst_height= cfg_2d.win_dst_height= cfg_vid->disp_height;
  417. cfg_2d.direction = cfg_vid->direction;
  418. cfg_2d.keep_aspect_ratio = cfg_vid->keep_aspect_ratio;
  419. arkapi_2d_set_config(handle->handle_2d, &cfg_2d);
  420. #endif
  421. arkapi_video_unlock(handle);
  422. ark_dbg("%s: disp_x=%d, disp_y=%d, disp_width=%d, disp_height=%d, direction=%d.\n", \
  423. __func__, cfg_vid->disp_x, cfg_vid->disp_y, cfg_vid->disp_width, cfg_vid->disp_height, cfg_vid->direction);
  424. return SUCCESS;
  425. }
  426. int arkapi_video_get_config(video_handle *handle, video_cfg *cfg_vid)
  427. {
  428. if(!handle || !cfg_vid){
  429. printf("%s: handle=0x%p, cfg_vid=0x%p, error.\n", __func__, handle, cfg_vid);
  430. return -EINVAL;
  431. }
  432. arkapi_video_lock(handle);
  433. memcpy(cfg_vid, &handle->cfg_vid, sizeof(video_cfg));
  434. arkapi_video_unlock(handle);
  435. //ark_dbg("%s: disp_x=%d, disp_y=%d, disp_width=%d, disp_height=%d, direction=%d.\n", \
  436. //__func__, cfg_vid->disp_x, cfg_vid->disp_y, cfg_vid->disp_width, cfg_vid->disp_height, cfg_vid->direction);
  437. return SUCCESS;
  438. }
  439. int arkapi_video_set_display_mode(int mode)
  440. {
  441. if (mode < DISP_NONE || mode >= DISP_MODE_NUM) {
  442. printf("Ivalid parameter mode(%d).\n", mode);
  443. return -1;
  444. }
  445. get_shared_display_data();
  446. display_lock();
  447. pdd->display_mode = mode;
  448. display_unlock();
  449. return 0;
  450. }
  451. int arkapi_video_show(video_handle *handle, int enable)
  452. {
  453. int ret = 0;
  454. if(!handle || !handle->handle_disp){
  455. printf("%s: handle=0x%p, handle->0x%p, error.\n", __func__, handle, handle->handle_disp);
  456. return -EINVAL;
  457. }
  458. arkapi_video_lock(handle);
  459. if(enable){
  460. handle->active = 1;
  461. printf("%s: set video handle=0x%p active=1.\n", __func__, handle);
  462. if (!handle->first_show)
  463. ret = arkapi_display_show_layer(handle->handle_disp);
  464. display_lock();
  465. pdd->active_handle = handle;
  466. pdd->active_pid = getpid();
  467. display_unlock();
  468. }else{
  469. handle->active = 0;
  470. display_lock();
  471. if(pdd->active_handle == handle)
  472. pdd->active_handle = NULL;
  473. display_unlock();
  474. ret = arkapi_display_hide_layer(handle->handle_disp);
  475. }
  476. arkapi_video_unlock(handle);
  477. ark_dbg("%s: enable=%d, ret=%d.\n", __func__, enable, ret);
  478. return ret;
  479. }
  480. int arkapi_video_show_mode(video_handle *handle, int mode, int enable)
  481. {
  482. int ret = 0;
  483. if(!handle || !handle->handle_disp){
  484. printf("%s: handle=0x%p, handle->0x%p, error.\n", __func__, handle, handle->handle_disp);
  485. return -EINVAL;
  486. }
  487. display_lock();
  488. if (pdd->display_mode != mode) {
  489. printf("%s: unmatch display mode %d:%d.\n", __func__, pdd->display_mode, mode);
  490. display_unlock();
  491. return -1;
  492. }
  493. display_unlock();
  494. arkapi_video_show(handle, enable);
  495. }
  496. void arkapi_video_release(video_handle *handle)
  497. {
  498. struct list_head *pos;
  499. struct list_head *del_tmp;
  500. video_handle *vid_tmp;
  501. if(!handle){
  502. printf("%s: handle null, error.\n", __func__);
  503. return;
  504. }
  505. display_lock();
  506. if(pdd->active_handle == handle)
  507. pdd->active_handle = NULL;
  508. display_unlock();
  509. arkapi_video_lock(handle);
  510. arkapi_display_hide_layer(handle->handle_disp);
  511. if (handle->handle_disp)
  512. arkapi_display_close_layer(handle->handle_disp);
  513. if (handle->handle_mem)
  514. arkapi_memalloc_release(handle->handle_mem);
  515. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  516. if (handle->handle_2d)
  517. arkapi_2d_release(handle->handle_2d);
  518. #endif
  519. if (handle->handle_mfc)
  520. mfc_uninit(handle->handle_mfc);
  521. arkapi_video_unlock(handle);
  522. sem_destroy(&handle->sem_lock);
  523. free(handle);
  524. ark_dbg("%s: <---sucess.\n", __func__);
  525. return;
  526. }
  527. int arkapi_video_play(video_handle *handle, const void *src_addr, int len, int fps)
  528. {
  529. static int mirror_w = 0, mirror_h = 0;
  530. int count = ROTATE_BUF_MAX;
  531. ark2d_cfg cfg_2d;
  532. int i, time_delay = 0;
  533. struct timeval start, end;
  534. unsigned long usetime = 0;
  535. int ret;
  536. if(!handle){
  537. printf("%s: handle null, error.\n", __func__);
  538. return -EINVAL;
  539. }
  540. if(!handle->handle_mfc || !handle->handle_mem
  541. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  542. || !handle->handle_2d
  543. #endif
  544. ) {
  545. printf("%s: handle_mfc=0x%p, handle_2d=0x%p,handle_mfc=0x%p, error.\n",
  546. __func__, handle->handle_mfc, handle->handle_2d, handle->handle_mem);
  547. return -EINVAL;
  548. }
  549. arkapi_video_lock(handle);
  550. memcpy(handle->in_buffer.virtualAddress, src_addr, len);
  551. //ark_dbg("%s: src_addr=0x%p, len=%d.\n", __func__, src_addr, len);
  552. if (len > MAX_STREAM_BUFFER_SIZE)
  553. len = MAX_STREAM_BUFFER_SIZE;
  554. handle->in_buffer.size = len;
  555. handle->out_buffer.num = 0;
  556. ret = mfc_decode(handle->handle_mfc, &handle->in_buffer, &handle->out_buffer);
  557. if (ret) {
  558. printf("mfc_decode fail, ret=%d.\n", ret);
  559. arkapi_video_unlock(handle);
  560. return ret;
  561. }
  562. if (handle->dec_first_frame)
  563. handle->dec_first_frame = 0;
  564. if(mirror_w != handle->out_buffer.frameWidth || mirror_h != handle->out_buffer.frameHeight){
  565. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  566. arkapi_2d_get_config(handle->handle_2d, &cfg_2d);
  567. cfg_2d.src_width = mirror_w = handle->out_buffer.frameWidth;
  568. cfg_2d.src_height = mirror_h = handle->out_buffer.frameHeight;
  569. cfg_2d.win_src_width = handle->out_buffer.codedWidth;
  570. cfg_2d.win_src_height = handle->out_buffer.codedHeight;
  571. arkapi_2d_set_config(handle->handle_2d, &cfg_2d);
  572. #endif
  573. }
  574. if (fps)
  575. gettimeofday(&start, NULL);
  576. for (i = 0; i < handle->out_buffer.num; i++) {
  577. if (fps && i > 0) {
  578. gettimeofday(&end, NULL);
  579. usetime = ((end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec)/1000;
  580. time_delay = 1000 / fps * i - usetime;
  581. if (time_delay > 0)
  582. usleep(time_delay * 1000);
  583. }
  584. handle->last_render_yaddr = handle->out_buffer.buffer[i].yBusAddress;
  585. handle->last_render_uaddr = handle->last_render_yaddr + handle->out_buffer.frameWidth * handle->out_buffer.frameHeight;
  586. video_display_process(handle, handle->last_render_yaddr, handle->last_render_uaddr, 0);
  587. }
  588. arkapi_video_unlock(handle);
  589. //ark_dbg("%s: <---end.\n", __func__);
  590. return handle->out_buffer.num;
  591. }
  592. int arkapi_video_play_eof(video_handle *handle, int fps)
  593. {
  594. unsigned int src_phyaddr;
  595. int time_delay;
  596. struct timeval start, end;
  597. unsigned long usetime = 0;
  598. if(!handle->handle_mfc || !handle->handle_mem
  599. #if LIBARKAPI_PLATFORM == LIBARKAPI_ARK1668
  600. || !handle->handle_2d
  601. #endif
  602. ) {
  603. printf("%s: handle_mfc=0x%p, handle_2d=0x%p,handle_mfc=0x%p, error.\n",
  604. __func__, handle->handle_mfc, handle->handle_2d, handle->handle_mem);
  605. return -EINVAL;
  606. }
  607. arkapi_video_lock(handle);
  608. #if LIBARKAPI_PLATFORM != LIBARKAPI_ARK1668 && defined(DECODE_SCALE_PARALLEL)
  609. video_display_process(handle, 0, 0, 0);
  610. #endif
  611. while (mfc_decode_eof(handle->handle_mfc, &handle->out_buffer))
  612. {
  613. if (fps)
  614. gettimeofday(&start, NULL);
  615. handle->last_render_yaddr = handle->out_buffer.buffer[0].yBusAddress;
  616. handle->last_render_uaddr = handle->last_render_yaddr + handle->out_buffer.frameWidth * handle->out_buffer.frameHeight;
  617. video_display_process(handle, handle->last_render_yaddr, handle->last_render_uaddr, 0);
  618. if (fps) {
  619. gettimeofday(&end, NULL);
  620. usetime = ((end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec)/1000;
  621. time_delay = 1000 / fps - usetime;
  622. if (time_delay > 0)
  623. usleep(time_delay * 1000);
  624. }
  625. }
  626. #if LIBARKAPI_PLATFORM != LIBARKAPI_ARK1668 && defined(DECODE_SCALE_PARALLEL)
  627. video_display_process(handle, 0, 0, 0);
  628. #endif
  629. arkapi_video_unlock(handle);
  630. return 0;
  631. }
  632. int arkapi_enter_carback(void)
  633. {
  634. get_shared_display_data();
  635. display_lock();
  636. if (pdd->active_handle == NULL) {
  637. pdd->kernel_used = 1;
  638. display_unlock();
  639. return 0;
  640. }
  641. if (pdd->active_pid > 0)
  642. kill(pdd->active_pid, SIGUSR1);
  643. pdd->kernel_used = 1;
  644. ark_dbg("%s enter.\n", __FUNCTION__);
  645. display_unlock();
  646. return 0;
  647. }
  648. int arkapi_exit_carback(void)
  649. {
  650. get_shared_display_data();
  651. display_lock();
  652. pdd->kernel_used = 0;
  653. if (pdd->active_handle && pdd->active_pid > 0)
  654. kill(pdd->active_pid, SIGUSR2);
  655. display_unlock();
  656. return 0;
  657. }
  658. int arkapi_set_vin_start(int start)
  659. {
  660. get_shared_display_data();
  661. display_lock();
  662. if (start){
  663. if (pdd->active_handle == NULL) {
  664. pdd->kernel_used = 1;
  665. display_unlock();
  666. return 0;
  667. }
  668. if (pdd->active_pid > 0)
  669. kill(pdd->active_pid, SIGUSR1);
  670. pdd->kernel_used = 1;
  671. }else{
  672. pdd->kernel_used = 0;
  673. if (pdd->active_handle && pdd->active_pid > 0)
  674. kill(pdd->active_pid, SIGUSR2);
  675. }
  676. display_unlock();
  677. return 0;
  678. }