1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "av_trans_utils.h"
17
18 #include <cstddef>
19 #include <securec.h>
20
21 #include "av_trans_constants.h"
22 #include "av_trans_log.h"
23 #include "av_trans_meta.h"
24
25 #include "plugin/common/share_allocator.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 using HiSBufferMeta = OHOS::Media::Plugin::BufferMeta;
30 using TransBufferMeta = OHOS::DistributedHardware::BufferMeta;
31
32 const std::string KEY_OWNER_NAME = "ownerName";
33 const std::string KEY_PEER_DEVID = "peerDevId";
34
TransName2PkgName(const std::string & ownerName)35 std::string TransName2PkgName(const std::string &ownerName)
36 {
37 const static std::pair<std::string, std::string> mapArray[] = {
38 {OWNER_NAME_D_MIC, PKG_NAME_D_AUDIO},
39 {OWNER_NAME_D_VIRMODEM_MIC, PKG_NAME_D_CALL},
40 {OWNER_NAME_D_CAMERA, PKG_NAME_D_CAMERA},
41 {OWNER_NAME_D_SCREEN, PKG_NAME_D_SCREEN},
42 {OWNER_NAME_D_SPEAKER, PKG_NAME_D_AUDIO},
43 {OWNER_NAME_D_VIRMODEM_SPEAKER, PKG_NAME_D_CALL},
44 };
45 for (const auto& item : mapArray) {
46 if (item.first == ownerName) {
47 return item.second;
48 }
49 }
50 return EMPTY_STRING;
51 }
52
TransName2MediaType(const std::string & ownerName)53 OHOS::Media::Plugin::MediaType TransName2MediaType(const std::string &ownerName)
54 {
55 const static std::pair<std::string, OHOS::Media::Plugin::MediaType> mapArray[] = {
56 {OWNER_NAME_D_MIC, OHOS::Media::Plugin::MediaType::AUDIO},
57 {OWNER_NAME_D_VIRMODEM_MIC, OHOS::Media::Plugin::MediaType::AUDIO},
58 {OWNER_NAME_D_CAMERA, OHOS::Media::Plugin::MediaType::VIDEO},
59 {OWNER_NAME_D_SCREEN, OHOS::Media::Plugin::MediaType::VIDEO},
60 {OWNER_NAME_D_SPEAKER, OHOS::Media::Plugin::MediaType::AUDIO},
61 {OWNER_NAME_D_VIRMODEM_SPEAKER, OHOS::Media::Plugin::MediaType::AUDIO},
62 };
63 for (const auto& item : mapArray) {
64 if (item.first == ownerName) {
65 return item.second;
66 }
67 }
68 return OHOS::Media::Plugin::MediaType::UNKNOWN;
69 }
70
BuildChannelDescription(const std::string & ownerName,const std::string & peerDevId)71 std::string BuildChannelDescription(const std::string &ownerName, const std::string &peerDevId)
72 {
73 cJSON *descJson = cJSON_CreateObject();
74 if (descJson == nullptr) {
75 return "";
76 }
77 cJSON_AddStringToObject(descJson, KEY_OWNER_NAME.c_str(), ownerName.c_str());
78 cJSON_AddStringToObject(descJson, KEY_PEER_DEVID.c_str(), peerDevId.c_str());
79 char *data = cJSON_PrintUnformatted(descJson);
80 if (data == nullptr) {
81 cJSON_Delete(descJson);
82 return "";
83 }
84 std::string jsonstr(data);
85 cJSON_Delete(descJson);
86 cJSON_free(data);
87 return jsonstr;
88 }
89
ParseChannelDescription(const std::string & descJsonStr,std::string & ownerName,std::string & peerDevId)90 void ParseChannelDescription(const std::string &descJsonStr, std::string &ownerName, std::string &peerDevId)
91 {
92 cJSON *descJson = cJSON_Parse(descJsonStr.c_str());
93 if (descJson == nullptr) {
94 return ;
95 }
96 cJSON *nameObj = cJSON_GetObjectItemCaseSensitive(descJson, KEY_OWNER_NAME.c_str());
97 if (nameObj == nullptr || !IsString(descJson, KEY_OWNER_NAME)) {
98 cJSON_Delete(descJson);
99 return ;
100 }
101 cJSON *devObj = cJSON_GetObjectItemCaseSensitive(descJson, KEY_PEER_DEVID.c_str());
102 if (devObj == nullptr || !IsString(descJson, KEY_PEER_DEVID)) {
103 cJSON_Delete(descJson);
104 return ;
105 }
106 ownerName = nameObj->valuestring;
107 peerDevId = devObj->valuestring;
108 cJSON_Delete(descJson);
109 }
110
TransBuffer2HiSBuffer(const std::shared_ptr<AVTransBuffer> & transBuffer)111 std::shared_ptr<AVBuffer> TransBuffer2HiSBuffer(const std::shared_ptr<AVTransBuffer>& transBuffer)
112 {
113 if ((transBuffer == nullptr) || transBuffer->IsEmpty()) {
114 return nullptr;
115 }
116
117 auto data = transBuffer->GetBufferData();
118 if (data == nullptr) {
119 return nullptr;
120 }
121
122 auto hisBuffer = std::make_shared<AVBuffer>();
123 hisBuffer->WrapMemory(data->GetAddress(), data->GetCapacity(), data->GetSize());
124
125 Convert2HiSBufferMeta(transBuffer, hisBuffer);
126 return hisBuffer;
127 }
128
HiSBuffer2TransBuffer(const std::shared_ptr<AVBuffer> & hisBuffer)129 std::shared_ptr<AVTransBuffer> HiSBuffer2TransBuffer(const std::shared_ptr<AVBuffer>& hisBuffer)
130 {
131 if ((hisBuffer == nullptr) || hisBuffer->IsEmpty()) {
132 return nullptr;
133 }
134
135 auto memory = hisBuffer->GetMemory();
136 if (memory == nullptr) {
137 return nullptr;
138 }
139
140 auto transBuffer = std::make_shared<AVTransBuffer>();
141 transBuffer->WrapBufferData(memory->GetReadOnlyData(), memory->GetCapacity(), memory->GetSize());
142
143 Convert2TransBufferMeta(hisBuffer, transBuffer);
144 return transBuffer;
145 }
146
Convert2HiSBufferMeta(std::shared_ptr<AVTransBuffer> transBuffer,std::shared_ptr<AVBuffer> hisBuffer)147 void Convert2HiSBufferMeta(std::shared_ptr<AVTransBuffer> transBuffer, std::shared_ptr<AVBuffer> hisBuffer)
148 {
149 std::shared_ptr<TransBufferMeta> transMeta = transBuffer->GetBufferMeta();
150 if ((transMeta->GetMetaType() == MetaType::AUDIO)) {
151 auto hisAMeta = std::make_shared<AVTransAudioBufferMeta>();
152
153 std::string value;
154 transMeta->GetMetaItem(AVTransTag::BUFFER_DATA_TYPE, value);
155 uint32_t dataType = static_cast<uint32_t>(std::atoi(value.c_str()));
156 hisAMeta->dataType_ = (BufferDataType)dataType;
157
158 transMeta->GetMetaItem(AVTransTag::AUDIO_SAMPLE_FORMAT, value);
159 uint32_t format = static_cast<uint32_t>(std::atoi(value.c_str()));
160 hisAMeta->format_ = (AudioSampleFormat)format;
161
162 transMeta->GetMetaItem(AVTransTag::AUDIO_SAMPLE_RATE, value);
163 hisAMeta->sampleRate_ = static_cast<uint32_t>(std::atoi(value.c_str()));
164
165 hisBuffer->UpdateBufferMeta(*hisAMeta);
166 } else {
167 auto hisVMeta = std::make_shared<AVTransVideoBufferMeta>();
168
169 std::string value;
170 transMeta->GetMetaItem(AVTransTag::BUFFER_DATA_TYPE, value);
171 uint32_t dataType = static_cast<uint32_t>(std::atoi(value.c_str()));
172 hisVMeta->dataType_ = (BufferDataType)dataType;
173
174 transMeta->GetMetaItem(AVTransTag::VIDEO_PIXEL_FORMAT, value);
175 uint32_t format = static_cast<uint32_t>(std::atoi(value.c_str()));
176 hisVMeta->format_ = (VideoPixelFormat)format;
177
178 transMeta->GetMetaItem(AVTransTag::VIDEO_WIDTH, value);
179 hisVMeta->width_ = static_cast<uint32_t>(std::atoi(value.c_str()));
180
181 transMeta->GetMetaItem(AVTransTag::VIDEO_HEIGHT, value);
182 hisVMeta->height_ = static_cast<uint32_t>(std::atoi(value.c_str()));
183
184 TRUE_LOG_MSG(!transMeta->GetMetaItem(AVTransTag::PRE_TIMESTAMP, value), "get PRE_TIMESTAMP meta failed");
185 hisVMeta->pts_ = std::stoll(value.c_str());
186
187 hisBuffer->pts = std::stoll(value.c_str());
188 hisBuffer->UpdateBufferMeta(*hisVMeta);
189 }
190 }
191
Convert2TransBufferMeta(std::shared_ptr<AVBuffer> hisBuffer,std::shared_ptr<AVTransBuffer> transBuffer)192 void Convert2TransBufferMeta(std::shared_ptr<AVBuffer> hisBuffer, std::shared_ptr<AVTransBuffer> transBuffer)
193 {
194 std::shared_ptr<HiSBufferMeta> hisMeta = hisBuffer->GetBufferMeta();
195 if ((hisMeta->GetType() == BufferMetaType::AUDIO)) {
196 std::shared_ptr<AVTransAudioBufferMeta> hisAMeta = ReinterpretCastPointer<AVTransAudioBufferMeta>(hisMeta);
197 TRUE_RETURN(hisAMeta == nullptr, "hisAMeta is null");
198
199 auto transAMeta = std::make_shared<TransBufferMeta>(MetaType::AUDIO);
200 transAMeta->SetMetaItem(AVTransTag::BUFFER_DATA_TYPE, std::to_string((uint32_t)(hisAMeta->dataType_)));
201 transAMeta->SetMetaItem(AVTransTag::AUDIO_SAMPLE_FORMAT, std::to_string((uint32_t)(hisAMeta->format_)));
202 transAMeta->SetMetaItem(AVTransTag::AUDIO_SAMPLE_RATE, std::to_string(hisAMeta->sampleRate_));
203
204 transBuffer->UpdateBufferMeta(transAMeta);
205 } else {
206 std::shared_ptr<AVTransVideoBufferMeta> hisVMeta = ReinterpretCastPointer<AVTransVideoBufferMeta>(hisMeta);
207 TRUE_RETURN(hisVMeta == nullptr, "hisAMeta is null");
208
209 auto transVMeta = std::make_shared<TransBufferMeta>(MetaType::VIDEO);
210 transVMeta->SetMetaItem(AVTransTag::BUFFER_DATA_TYPE, std::to_string((uint32_t)(hisVMeta->dataType_)));
211 transVMeta->SetMetaItem(AVTransTag::VIDEO_PIXEL_FORMAT, std::to_string((uint32_t)(hisVMeta->format_)));
212 transVMeta->SetMetaItem(AVTransTag::VIDEO_WIDTH, std::to_string(hisVMeta->width_));
213 transVMeta->SetMetaItem(AVTransTag::VIDEO_HEIGHT, std::to_string(hisVMeta->height_));
214 transVMeta->SetMetaItem(AVTransTag::PRE_TIMESTAMP, std::to_string(hisVMeta->pts_));
215
216 transBuffer->UpdateBufferMeta(transVMeta);
217 }
218 }
219
CastEventType(Plugin::PluginEventType type,bool isAbnormal)220 EventType CastEventType(Plugin::PluginEventType type, bool isAbnormal)
221 {
222 switch (type) {
223 case Plugin::PluginEventType::EVENT_CHANNEL_OPENED:
224 return EventType::EVENT_START_SUCCESS;
225 case Plugin::PluginEventType::EVENT_CHANNEL_OPEN_FAIL:
226 return EventType::EVENT_START_FAIL;
227 case Plugin::PluginEventType::EVENT_CHANNEL_CLOSED:
228 return isAbnormal ? EventType::EVENT_ENGINE_ERROR : EventType::EVENT_STOP_SUCCESS;
229 default:
230 AVTRANS_LOGE("unsupport plugin event type.");
231 }
232 return EventType::EVENT_ENGINE_ERROR;
233 }
234
DumpBufferToFile(const std::string fileName,uint8_t * buffer,int32_t bufSize)235 void DumpBufferToFile(const std::string fileName, uint8_t *buffer, int32_t bufSize)
236 {
237 if (fileName.empty()) {
238 AVTRANS_LOGE("input fileName is empty.");
239 return;
240 }
241 char path[PATH_MAX + 1] = {0x00};
242 if (fileName.length() > PATH_MAX || realpath(fileName.c_str(), path) == nullptr) {
243 return;
244 }
245 std::ofstream ofs(path, std::ios::binary | std::ios::out | std::ios::app);
246 if (!ofs.is_open()) {
247 AVTRANS_LOGE("open file failed.");
248 return;
249 }
250 ofs.write((const char*)(buffer), bufSize);
251 ofs.close();
252 }
253
IsUInt32(const cJSON * jsonObj,const std::string & key)254 bool IsUInt32(const cJSON *jsonObj, const std::string &key)
255 {
256 cJSON *keyObj = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
257 return (keyObj != nullptr) && cJSON_IsNumber(keyObj) &&
258 static_cast<uint32_t>(keyObj->valueint) <= UINT32_MAX;
259 }
260
IsInt64(const cJSON * jsonObj,const std::string & key)261 bool IsInt64(const cJSON *jsonObj, const std::string &key)
262 {
263 cJSON *keyObj = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
264 return (keyObj != nullptr) && cJSON_IsNumber(keyObj) &&
265 static_cast<int64_t>(keyObj->valueint) <= INT64_MAX &&
266 static_cast<int64_t>(keyObj->valueint) >= INT64_MIN;
267 }
268
IsString(const cJSON * jsonObj,const std::string & key)269 bool IsString(const cJSON *jsonObj, const std::string &key)
270 {
271 cJSON *keyObj = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
272 return (keyObj != nullptr) && cJSON_IsString(keyObj) &&
273 strlen(cJSON_GetStringValue(keyObj)) <= MAX_MESSAGES_LEN;
274 }
275
GetCurrentTime()276 int64_t GetCurrentTime()
277 {
278 struct timespec time = { 0, 0 };
279 clock_gettime(CLOCK_MONOTONIC, &time);
280 return time.tv_sec * NS_ONE_S + time.tv_nsec;
281 }
282
GenerateAdtsHeader(unsigned char * adtsHeader,uint32_t packetLen,uint32_t profile,uint32_t sampleRate,uint32_t channels)283 void GenerateAdtsHeader(unsigned char* adtsHeader, uint32_t packetLen, uint32_t profile, uint32_t sampleRate,
284 uint32_t channels)
285 {
286 static std::map<int, uint32_t> mapSampleRateToFreIndex {
287 {96000, 0},
288 {88200, 1},
289 {64000, 2},
290 {48000, 3},
291 {44100, 4},
292 {32000, 5},
293 {24000, 6},
294 {16000, 8},
295 {12000, 9},
296 {11025, 10},
297 {8000, 11},
298 {7350, 12},
299 };
300 // profile only support AAC LC: 1
301 uint32_t freqIdx = mapSampleRateToFreIndex[sampleRate]; // 48KHz : 3
302 int8_t arrZero = 0;
303 int8_t arrOne = 1;
304 int8_t arrTwo = 2;
305 int8_t arrThree = 3;
306 int8_t arrFour = 4;
307 int8_t arrFive = 5;
308 int8_t arrSix = 6;
309 uint8_t calSix = 6;
310 uint8_t calThree = 3;
311 uint8_t calSeven = 7;
312 uint8_t calFive = 5;
313 uint8_t calEleven = 11;
314 uint8_t calTwo = 2;
315 adtsHeader[arrZero] = (unsigned char) 0xFF;
316 adtsHeader[arrOne] = (unsigned char) 0xF9;
317 if (profile < 1) {
318 return;
319 }
320 adtsHeader[arrTwo] = (unsigned char) (((profile - 1) << calSix) + (freqIdx << calTwo) + (channels >> calTwo));
321 adtsHeader[arrThree] = (unsigned char) (((channels & calThree) << calSix) + (packetLen >> calEleven));
322 adtsHeader[arrFour] = (unsigned char) ((packetLen & 0x7FF) >> calThree);
323 adtsHeader[arrFive] = (unsigned char) (((packetLen & calSeven) << calFive) + 0x1F);
324 adtsHeader[arrSix] = (unsigned char) 0xFC;
325 }
326 } // namespace DistributedHardware
327 } // namespace OHOS