Blame view

src/util/JpegUtil.cpp 3.48 KB
09c2d08c   Hu Chunming   arm交付版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  #include <cstdio>
  #include <cstdlib>
  #include <memory>
  #include "JpegUtil.h"
  #include "../common/logger.hpp"
  
  using namespace std;
  
  
  int JpegUtil::jpeg_init(int32_t devId){
      deviceId_ = devId;
  
      aclError ret;
      /* 2.Run the management resource application, including Device, Context, Stream */
      aclrtSetDevice(deviceId_);
      aclrtCreateContext(&context_, deviceId_);
      aclrtCreateStream(&stream_);
  
      // channel  准备
      dvppChannelDesc_ = acldvppCreateChannelDesc();
      ret = acldvppCreateChannel(dvppChannelDesc_);
  
      // 创建图片编码配置数据,设置编码质量
      // 编码质量范围[0, 100],其中level 0编码质量与level 100差不多,而在[1, 100]内数值越小输出图片质量越差。
      jpegeConfig_ = acldvppCreateJpegeConfig();
      acldvppSetJpegeConfigLevel(jpegeConfig_, 100);
  }
  
  void JpegUtil::jpeg_release(){
      aclError ret;
      ret = aclrtSetDevice(deviceId_);
      aclrtSetCurrentContext(context_);
  
      ret = acldvppDestroyChannel(dvppChannelDesc_);
      ret = acldvppDestroyChannelDesc(dvppChannelDesc_);
      dvppChannelDesc_ = nullptr;
  
      if (stream_ != nullptr) {
          ret = aclrtDestroyStream(stream_);
          if (ret != ACL_SUCCESS) {
              LOG_ERROR("destroy stream failed");
          }
          stream_ = nullptr;
      }
  
      acldvppDestroyJpegeConfig(jpegeConfig_);
  
      if (context_ != nullptr) {
          ret = aclrtDestroyContext(context_);
          if (ret != ACL_SUCCESS) {
              LOG_ERROR("destroy context failed");
          }
          context_ = nullptr;
      }
  
      ret = aclrtResetDevice(deviceId_);
      if (ret != ACL_SUCCESS) {
          LOG_ERROR("reset device failed");
      }
  }
  
  int32_t JpegUtil::jpege_save(char* pcData , uint32_t dataLen, string out_file_name)
  {
      FILE* fd = nullptr;
      fd = fopen(out_file_name.c_str(), "wb");
      if (fd == nullptr) {
2c2868df   Zhao Shuaihua   结果整理,推送抓拍图
67
          LOG_ERROR("open output file err");
09c2d08c   Hu Chunming   arm交付版
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
          return 1;
      }
  
      fwrite(pcData, dataLen, 1, fd);
      fflush(fd);
  
      fclose(fd);
      return 0;
  }
  
  void JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name) {
  
      aclError aclRet ;
      aclRet = aclrtSetDevice(deviceId_);
      aclrtSetCurrentContext(context_);
  
      // 8. 申请输出内存,申请Device内存encodeOutBufferDev_,存放编码后的输出数据
      uint32_t outBufferSize= 0;
      int ret = acldvppJpegPredictEncSize(encodeInputDesc_, jpegeConfig_, &outBufferSize);
      void *encodeOutBufferDev_ = nullptr;
      ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize);
  
      // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
      aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_);
      aclRet = aclrtSynchronizeStream(stream_);
  
      // 该模式下,由于处理结果在Device侧,因此需要调用内存复制接口传输结果数据后,再释放Device侧内存
      // 申请Host内存outputHostBuffer 
      void* outputHostBuffer = malloc(outBufferSize);
      // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
      aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
      // 释放掉输入输出的device内存
      (void)acldvppFree(encodeOutBufferDev_);
      encodeOutBufferDev_ = nullptr;
      // 数据使用完成后,释放内存
      jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
      free(outputHostBuffer);
      outputHostBuffer = nullptr;
  }