vdec_demo1.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2021 Alibaba Group Holding Limited
  3. * Author: LuChongzhi <chongzhi.lcz@alibaba-inc.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #define LOG_LEVEL 3
  13. #define LOG_PREFIX "vdec_demo1"
  14. #include <syslog.h>
  15. #include <csi_vdec.h>
  16. #include <csi_allocator.h>
  17. #define TEST_MODULE_NAME "simulator_vdec0"
  18. int main(int argc, char *argv[])
  19. {
  20. int ret;
  21. csi_vdec_info_t vdec_info;
  22. csi_vdec_dev_t decoder;
  23. csi_vdec_chn_t channel;
  24. // 打印HAL接口版本号
  25. csi_api_version_u version;
  26. csi_vdec_get_version(&version);
  27. printf("Video Decoder HAL version: %d.%d\n", version.major, version.minor);
  28. // 获取设备中,所有的Video Decoder
  29. struct csi_vdec_infos vdec_infos;
  30. csi_vdec_query_list(&vdec_infos);
  31. // 打印所有设备所支持的Video Decoder
  32. bool found_module = false;
  33. for (int i = 0; i < vdec_infos.count; i++) {
  34. csi_vdec_info_t *info;
  35. info = &(vdec_infos.info[i]);
  36. printf("decoder[%d]: module_name='%s', device_name='%s', capabilities=0x%lx\n",
  37. i, info->module_name, info->device_name, info->capabilities);
  38. if (strcmp(info->module_name, TEST_MODULE_NAME) == 0) {
  39. vdec_info = *info;
  40. found_module = true;
  41. }
  42. }
  43. if (!found_module) {
  44. LOG_E("Can't find module_name:'%s'\n", TEST_MODULE_NAME);
  45. exit(-1);
  46. }
  47. // 打开设备获取句柄,作为后续操对象
  48. csi_vdec_open(&decoder, vdec_info.device_name);
  49. // 创建视频解码通道
  50. csi_vdec_config_s dec_cfg;
  51. dec_cfg.input_mode = CSI_VDEC_INPUT_MODE_FRAME;
  52. dec_cfg.input_stream_buf_size = 1*1024*1024;
  53. dec_cfg.output_format = CSI_PIX_FMT_I420;
  54. dec_cfg.output_width = 1920;
  55. dec_cfg.output_height = 1080;
  56. dec_cfg.output_order = CSI_VDEC_OUTPUT_ORDER_DISP;
  57. dec_cfg.dec_vcodec_id = CSI_VCODEC_ID_H264;
  58. dec_cfg.output_img_type = CSI_VDEC_MODE_IPB;
  59. dec_cfg.dec_frame_buf_cnt = 8;
  60. csi_vdec_create_channel(&channel, decoder, &dec_cfg);
  61. // 配置内存分配器
  62. if (1) {
  63. //csi_allocator_s *allocator = csi_allocator_get(CSI_ALLOCATOR_TYPE_DMA);
  64. //csi_vdec_set_memory_allocator(channel, allocator);
  65. } else {
  66. csi_frame_s *allocated_frames[8]; // TODO: allocate frames first
  67. csi_vdec_register_frames(channel, allocated_frames, 8);
  68. }
  69. // 配置解码通道模式
  70. csi_vdec_mode_s vdec_mode;
  71. vdec_mode.fb_source = CSI_FB_SOURCE_DMABUF;
  72. vdec_mode.low_latency_mode = false;
  73. vdec_mode.mini_buf_mode = false;
  74. csi_vdec_set_mode(channel, &vdec_mode);
  75. // 获取和重新配置解码通道属性
  76. csi_vdec_get_chn_config(channel, &dec_cfg);
  77. dec_cfg.dec_frame_buf_cnt = 16;
  78. csi_vdec_set_chn_config(channel, &dec_cfg);
  79. // 订阅事件
  80. csi_vdec_event_handle_t event_handle;
  81. csi_vdec_create_event_handle(&event_handle, decoder);
  82. csi_vdec_event_subscription_t subscribe_dec, subscribe_chn;
  83. subscribe_dec.type = CSI_VDEC_EVENT_TYPE_DECODER; // 订阅Decoder事件
  84. subscribe_dec.id = CSI_VDEC_EVENT_ID_ERROR;
  85. csi_vdec_subscribe_event(event_handle, &subscribe_dec);
  86. subscribe_chn.type = CSI_VDEC_EVENT_TYPE_CHANNEL; // 订阅Channel事件
  87. subscribe_chn.id = CSI_VDEC_CHANNEL_EVENT_ID_FRAME_READY;
  88. csi_vdec_subscribe_event(event_handle, &subscribe_chn);
  89. // 传送视频码流
  90. csi_vdec_start(channel);
  91. const int send_count = 25;
  92. const int stream_packet_len = 1024;
  93. csi_vdec_stream_s stream;
  94. stream.data = malloc(stream_packet_len);
  95. for (int i = 0; i < send_count; i++) {
  96. stream.length = stream_packet_len;
  97. stream.pts = 40 * i;
  98. stream.eos = (i < (send_count - 1)) ? false : true;
  99. if (i == 10) {
  100. // Just for testing
  101. csi_vdec_reset(channel);
  102. }
  103. csi_vdec_send_stream_buf(channel, &stream, 1000);
  104. }
  105. free(stream.data);
  106. stream.data = NULL;
  107. // 收取解码结果
  108. csi_frame_s *frame;
  109. struct csi_vdec_event event;
  110. int get_count = 0;
  111. csi_vdec_chn_status_s status;
  112. while (get_count < send_count) {
  113. // timeout unit: ms, -1 means wait forever, or until error occurs
  114. csi_vdec_get_event(event_handle, &event, -1);
  115. switch (event.type) {
  116. case CSI_VDEC_EVENT_TYPE_DECODER:
  117. csi_vdec_query_status(channel, &status);
  118. // Dump Status
  119. break;
  120. case CSI_VDEC_EVENT_TYPE_CHANNEL:
  121. switch (event.id) {
  122. case CSI_VDEC_CHANNEL_EVENT_ID_FRAME_READY:
  123. csi_vdec_get_frame(channel, &frame, 1000);
  124. get_count++;
  125. // display frame
  126. // release frame: frame.release();
  127. }
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. // 关闭与回收资源
  134. csi_vdec_stop(channel);
  135. csi_vdec_unsubscribe_event(event_handle, &subscribe_dec);
  136. csi_vdec_unsubscribe_event(event_handle, &subscribe_chn);
  137. csi_vdec_destory_channel(channel);
  138. csi_vdec_close(decoder);
  139. return 0;
  140. }