JpegUtil.cpp
4.36 KB
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
67
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#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) {
LOG_ERROR("open output file error");
return 1;
}
fwrite(pcData, dataLen, 1, fd);
fflush(fd);
fclose(fd);
return 0;
}
bool 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);
if (ret != ACL_SUCCESS) {
LOG_ERROR("acldvppJpegPredictEncSize failed!");
return false;
}
void *encodeOutBufferDev_ = nullptr;
ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize);
if (ret != ACL_SUCCESS) {
LOG_ERROR("acldvppMalloc failed!");
return false;
}
bool bRet = false;
do {
// 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_);
if (ret != ACL_SUCCESS) {
LOG_ERROR("acldvppJpegEncodeAsync failed!");
break;
}
aclRet = aclrtSynchronizeStream(stream_);
if (ret != ACL_SUCCESS) {
LOG_ERROR("aclrtSynchronizeStream failed!");
break;
}
// 申请Host内存outputHostBuffer
void* outputHostBuffer = malloc(outBufferSize);
if(outputHostBuffer == nullptr) {
LOG_ERROR("malloc failed!");
break;
}
// 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != ACL_SUCCESS) {
free(outputHostBuffer);
outputHostBuffer = nullptr;
LOG_ERROR("aclrtMemcpy failed!");
break;
}
// 数据使用完成后,释放内存
ret = jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
free(outputHostBuffer);
outputHostBuffer = nullptr;
if(ret != 0) {
LOG_ERROR("jpege_save failed!");
break;
}
bRet = true;
} while (0);
// 释放掉输入输出的device内存
(void)acldvppFree(encodeOutBufferDev_);
encodeOutBufferDev_ = nullptr;
aclRet = aclrtResetDevice(deviceId_);
return bRet;
}