1 /*
2  * Copyright (c) 2021-2021 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 #define HST_LOG_TAG "Pip_Plugin_Utils"
17 
18 #include "plugin_utils.h"
19 #include <cstdarg>
20 #include <sstream>
21 #include "foundation/log.h"
22 #include "foundation/pre_defines.h"
23 #include "plugin/common/plugin_attr_desc.h"
24 
25 namespace {
26 constexpr int32_t MAX_BUF_LEN = 512; // 512 buffer size
27 #define RETURN_IF_FAILED(exec, errVal, retVal) \
28 do { \
29     auto res = exec; \
30     if (res == (errVal)) { \
31         return errVal; \
32     } else { \
33         (retVal) = res; \
34     } \
35 } while (0)
36 
37 #define RETURN_IF_SNPRI_FAILED(exec, snPrintRet, retVal) \
38 do { \
39     snPrintRet = exec; \
40     if ((snPrintRet) == -1) { \
41         MEDIA_LOG_W("stringiness failed due to " PUBLIC_LOG_S " or truncated.", strerror(errno)); \
42         return retVal; \
43     } \
44 } while (0)
45 
46 using namespace OHOS::Media;
47 
48 template <typename T>
Stringiness(char * buf,size_t maxLen,const char * name,const T & val)49 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const T& val)
50 {
51     MEDIA_LOG_I("no cap trans function for " PUBLIC_LOG_S " may be update?", name);
52     return 0;
53 }
54 
55 template <typename T>
FixedCapKeyStringiness(char * buf,size_t maxLen,const char * name,const char * typeName,const Plugin::ValueType & val)56 int32_t FixedCapKeyStringiness(char* buf, size_t maxLen, const char* name, const char* typeName,
57                                const Plugin::ValueType& val)
58 {
59     int pos = 0;
60     auto ret = snprintf_truncated_s(buf, maxLen, "%s:(%s)", name, typeName);
61     if (ret == -1) {
62         return ret;
63     }
64     pos += ret;
65     auto item = Plugin::AnyCast<T>(&val);
66     if (item == nullptr) {
67         return -1;
68     }
69     RETURN_IF_FAILED(Stringiness(buf + pos, maxLen - pos, name, *item), -1, ret);
70     return pos + ret;
71 }
72 
73 template<typename T>
IntervalCapKeyStringiness(char * buf,size_t maxLen,const char * name,const char * typeName,const Plugin::ValueType & val)74 int32_t IntervalCapKeyStringiness(char* buf, size_t maxLen, const char* name, const char* typeName,
75                                   const Plugin::ValueType& val)
76 {
77     int pos = 0;
78     auto ret = snprintf_truncated_s(buf, maxLen, "%s:(%s)[", name, typeName);
79     if (ret == -1) {
80         return ret;
81     }
82     pos += ret;
83     auto item = Plugin::AnyCast<Plugin::IntervalCapability<T>>(&val);
84     if (item == nullptr) {
85         return -1;
86     }
87     RETURN_IF_FAILED(Stringiness(buf + pos, maxLen - pos, name, item->first), -1, ret);
88     pos += ret;
89     RETURN_IF_FAILED(snprintf_truncated_s(buf + pos, maxLen - pos, ", "), -1, ret);
90     pos += ret;
91     RETURN_IF_FAILED(Stringiness(buf + pos, maxLen - pos, name, item->second), -1, ret);
92     pos += ret;
93     RETURN_IF_FAILED(snprintf_truncated_s(buf + pos, maxLen - pos, "]"), -1, ret);
94     return pos + ret;
95 }
96 
97 template<typename T>
DiscreteCapKeyStringiness(char * buf,size_t maxLen,const char * name,const char * typeName,const Plugin::ValueType & val)98 int32_t DiscreteCapKeyStringiness(char* buf, size_t maxLen, const char* name, const char* typeName,
99                                   const Plugin::ValueType& val)
100 {
101     int pos = 0;
102     auto ret = snprintf_truncated_s(buf, maxLen, "%s:(%s){", name, typeName);
103     if (ret == -1) {
104         return ret;
105     }
106     pos += ret;
107     auto item = Plugin::AnyCast<Plugin::DiscreteCapability<T>>(&val);
108     if (item == nullptr) {
109         return -1;
110     }
111     int32_t i = 0;
112     int32_t length = item->size();
113     for (; i < length - 1; i++) {
114         RETURN_IF_FAILED(Stringiness<T>(buf + pos, maxLen - pos, name, item->at(i)), -1, ret);
115         pos += ret;
116         RETURN_IF_FAILED(snprintf_truncated_s(buf + pos, maxLen - pos, ", "), -1, ret);
117         pos += ret;
118     }
119     if (i == length - 1) {
120         RETURN_IF_FAILED(Stringiness<T>(buf + pos, maxLen - pos, name, item->at(i)), -1, ret);
121         pos += ret;
122     }
123     RETURN_IF_FAILED(snprintf_truncated_s(buf + pos, maxLen - pos, "}"), -1, ret);
124     return pos + ret;
125 }
126 
127 template<typename T>
CapKeyStringiness(char * buf,size_t maxLen,const char * name,const char * typeName,const Plugin::ValueType & val)128 int32_t CapKeyStringiness(char* buf, size_t maxLen, const char* name, const char* typeName,
129                           const Plugin::ValueType& val)
130 {
131     if (Plugin::Any::IsSameTypeWith<Plugin::FixedCapability<T>>(val)) {
132         return FixedCapKeyStringiness<T>(buf, maxLen, name, typeName, val);
133     } else if (Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(val)) {
134         return IntervalCapKeyStringiness<T>(buf, maxLen, name, typeName, val);
135     } else if (Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(val)) {
136         return DiscreteCapKeyStringiness<T>(buf, maxLen, name, typeName, val);
137     } else {
138         MEDIA_LOG_W("cap " PUBLIC_LOG_S "type mismatches when cast to string, which should be " PUBLIC_LOG_S,
139                     name, typeName);
140     }
141     return -1;
142 }
143 template <>
Stringiness(char * buf,size_t maxLen,const char * name,const int32_t & val)144 MEDIA_UNUSED int32_t Stringiness(char* buf, size_t maxLen, const char* name, const int32_t& val)
145 {
146     return snprintf_truncated_s(buf, maxLen, "%" PRIi32, val);
147 }
148 
149 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const uint32_t & val)150 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const uint32_t& val)
151 {
152     return snprintf_truncated_s(buf, maxLen, "%" PRIu32, val);
153 }
154 
155 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const std::string & val)156 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const std::string& val)
157 {
158     return snprintf_truncated_s(buf, maxLen, "%s", val.c_str());
159 }
160 
161 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const int64_t & val)162 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const int64_t& val)
163 {
164     return snprintf_truncated_s(buf, maxLen, "%" PRId64, val);
165 }
166 
167 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const uint64_t & val)168 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const uint64_t& val)
169 {
170     return snprintf_truncated_s(buf, maxLen, "%" PRIu64, val);
171 }
172 
173 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::AudioSampleFormat & val)174 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::AudioSampleFormat& val)
175 {
176     if (Plugin::g_auSampleFmtStrMap.count(val) == 0) {
177         MEDIA_LOG_W("audio sample format " PUBLIC_LOG_D32 " is unknown", static_cast<int32_t>(val));
178         return 0;
179     }
180     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_auSampleFmtStrMap.at(val));
181 }
182 
183 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::AudioChannelLayout & val)184 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::AudioChannelLayout& val)
185 {
186     if (Plugin::g_auChannelLayoutStrMap.count(val) == 0) {
187         MEDIA_LOG_W("audio channel layout " PUBLIC_LOG_U64 " is unknown", static_cast<uint64_t>(val));
188         return 0;
189     }
190     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_auChannelLayoutStrMap.at(val));
191 }
192 
193 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::VideoPixelFormat & val)194 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::VideoPixelFormat& val)
195 {
196     if (Plugin::g_videoPixelFormatStrMap.count(val) == 0) {
197         MEDIA_LOG_W("video pixel format " PUBLIC_LOG_U32 " is unknown", static_cast<uint32_t>(val));
198         return 0;
199     }
200     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_videoPixelFormatStrMap.at(val));
201 }
202 
203 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::VideoBitStreamFormat & val)204 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::VideoBitStreamFormat& val)
205 {
206     if (Plugin::g_vdBitStreamFormatStrMap.count(val) == 0) {
207         MEDIA_LOG_W("video bit stream format " PUBLIC_LOG_U32 " is unknown", static_cast<uint32_t>(val));
208         return 0;
209     }
210     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_vdBitStreamFormatStrMap.at(val));
211 }
212 
213 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::AudioAacProfile & val)214 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::AudioAacProfile& val)
215 {
216     if (Plugin::g_auAacProfileNameStrMap.count(val) == 0) {
217         MEDIA_LOG_W("audio aac profile name " PUBLIC_LOG_U8 " is unknown", static_cast<uint8_t>(val));
218         return 0;
219     }
220     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_auAacProfileNameStrMap.at(val));
221 }
222 
223 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::AudioAacStreamFormat & val)224 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::AudioAacStreamFormat& val)
225 {
226     if (Plugin::g_auAacStreamFormatNameStrMap.count(val) == 0) {
227         MEDIA_LOG_W("audio aac stream format name " PUBLIC_LOG_U8 " is unknown", static_cast<uint8_t>(val));
228         return 0;
229     }
230     return snprintf_truncated_s(buf, maxLen, "%s", Plugin::g_auAacStreamFormatNameStrMap.at(val));
231 }
232 
233 template<>
Stringiness(char * buf,size_t maxLen,const char * name,const Plugin::CodecConfig & val)234 int32_t Stringiness(char* buf, size_t maxLen, const char* name, const Plugin::CodecConfig& val)
235 {
236     return snprintf_truncated_s(buf, maxLen, "...");
237 }
238 
239 template<typename T>
MetaIDStringiness(char * buf,size_t maxLen,const char * name,const char * typeName,const Plugin::ValueType & val)240 int32_t MetaIDStringiness(char* buf, size_t maxLen, const char* name, const char* typeName,
241                           const Plugin::ValueType& val)
242 {
243     if (Plugin::Any::IsSameTypeWith<T>(val)) {
244         return FixedCapKeyStringiness<T>(buf, maxLen, name, typeName, val);
245     } else if (Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(val)) {
246         return DiscreteCapKeyStringiness<T>(buf, maxLen, name, typeName, val);
247     } else {
248         MEDIA_LOG_W("meta " PUBLIC_LOG_S " type mismatches when cast to string", name);
249     }
250     return -1;
251 }
252 using CapStrnessFunc = std::function<int32_t(char*, size_t, const char*, const char*, const Plugin::ValueType&)>;
253 
254 std::map<Plugin::Tag, CapStrnessFunc> g_metaStrnessMap = {
255     {Plugin::Tag::MIME, CapKeyStringiness<std::string>},
256     {Plugin::Tag::TRACK_ID, MetaIDStringiness<uint32_t>},
257     {Plugin::Tag::MEDIA_CODEC_CONFIG, MetaIDStringiness<std::vector<uint8_t>>},
258     {Plugin::Tag::AUDIO_CHANNELS, MetaIDStringiness<uint32_t>},
259     {Plugin::Tag::AUDIO_SAMPLE_RATE, MetaIDStringiness<uint32_t>},
260     {Plugin::Tag::AUDIO_SAMPLE_FORMAT, MetaIDStringiness<Plugin::AudioSampleFormat>},
261     {Plugin::Tag::AUDIO_SAMPLE_PER_FRAME, MetaIDStringiness<uint32_t>},
262     {Plugin::Tag::AUDIO_CHANNEL_LAYOUT, MetaIDStringiness<Plugin::AudioChannelLayout>},
263     {Plugin::Tag::AUDIO_OUTPUT_CHANNELS, MetaIDStringiness<uint32_t>},
264     {Plugin::Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT, MetaIDStringiness<Plugin::AudioChannelLayout>},
265     {Plugin::Tag::MEDIA_TITLE, MetaIDStringiness<std::string>},
266     {Plugin::Tag::MEDIA_ARTIST, MetaIDStringiness<std::string>},
267     {Plugin::Tag::MEDIA_LYRICIST, MetaIDStringiness<std::string>},
268     {Plugin::Tag::MEDIA_ALBUM, MetaIDStringiness<std::string>},
269     {Plugin::Tag::MEDIA_ALBUM_ARTIST, MetaIDStringiness<std::string>},
270     {Plugin::Tag::MEDIA_DATE, MetaIDStringiness<std::string>},
271     {Plugin::Tag::MEDIA_COMMENT, MetaIDStringiness<std::string>},
272     {Plugin::Tag::MEDIA_GENRE, MetaIDStringiness<std::string>},
273     {Plugin::Tag::MEDIA_DESCRIPTION, MetaIDStringiness<std::string>},
274     {Plugin::Tag::MEDIA_COPYRIGHT, MetaIDStringiness<std::string>},
275     {Plugin::Tag::MEDIA_LANGUAGE, MetaIDStringiness<std::string>},
276     {Plugin::Tag::MEDIA_LYRICS, MetaIDStringiness<std::string>},
277     {Plugin::Tag::MEDIA_DURATION, MetaIDStringiness<int64_t>},
278     {Plugin::Tag::MEDIA_BITRATE, MetaIDStringiness<int64_t>},
279     {Plugin::Tag::MEDIA_FILE_URI, MetaIDStringiness<std::string>},
280     {Plugin::Tag::MEDIA_FILE_SIZE, MetaIDStringiness<uint64_t>},
281     {Plugin::Tag::MEDIA_SEEKABLE, MetaIDStringiness<Plugin::Seekable>},
282     {Plugin::Tag::AUDIO_MPEG_VERSION, MetaIDStringiness<uint32_t>},
283     {Plugin::Tag::AUDIO_MPEG_LAYER, MetaIDStringiness<uint32_t>},
284     {Plugin::Tag::AUDIO_AAC_PROFILE, MetaIDStringiness<Plugin::AudioAacProfile>},
285     {Plugin::Tag::AUDIO_AAC_LEVEL, MetaIDStringiness<uint32_t>},
286     {Plugin::Tag::AUDIO_AAC_STREAM_FORMAT, MetaIDStringiness<Plugin::AudioAacStreamFormat>},
287     {Plugin::Tag::VIDEO_WIDTH, MetaIDStringiness<uint32_t>},
288     {Plugin::Tag::VIDEO_HEIGHT, MetaIDStringiness<uint32_t>},
289     {Plugin::Tag::VIDEO_FRAME_RATE, MetaIDStringiness<uint32_t>},
290     {Plugin::Tag::VIDEO_PIXEL_FORMAT, MetaIDStringiness<Plugin::VideoPixelFormat>},
291     {Plugin::Tag::VIDEO_BIT_STREAM_FORMAT, MetaIDStringiness<Plugin::VideoBitStreamFormat>},
292     {Plugin::Tag::BITS_PER_CODED_SAMPLE, MetaIDStringiness<uint32_t>},
293 };
294 }
295 
296 namespace OHOS {
297 namespace Media {
298 namespace Pipeline {
299 template<typename T>
AssignParameterIfMatch(Tag tag,T & ret,const Plugin::ValueType & val)300 bool AssignParameterIfMatch(Tag tag, T& ret, const Plugin::ValueType& val)
301 {
302     if (Plugin::HasTagInfo(tag)) {
303         auto defaultValue = Plugin::GetTagDefValue(tag);
304         if (defaultValue == nullptr) {
305             return false;
306         }
307         if (val.SameTypeWith(*defaultValue) && Plugin::Any::IsSameTypeWith<T>(val)) {
308             ret = Plugin::AnyCast<T>(val);
309             return true;
310         } else {
311             MEDIA_LOG_I("type of " PUBLIC_LOG_S " mismatch, should be " PUBLIC_LOG_S,
312                         Plugin::GetTagStrName(tag), Plugin::GetTagTypeStrName(tag));
313         }
314     } else {
315         MEDIA_LOG_I("tag " PUBLIC_LOG_D32 " is not in map, may be update it?", tag);
316     }
317     return false;
318 }
319 
320 template bool AssignParameterIfMatch(Tag tag, Plugin::SrcInputType& ret, const Plugin::ValueType& val);
321 template bool AssignParameterIfMatch(Tag tag, uint32_t& ret, const Plugin::ValueType& val);
322 template bool AssignParameterIfMatch(Tag tag, uint64_t& ret, const Plugin::ValueType& val);
323 template bool AssignParameterIfMatch(Tag tag, int32_t& ret, const Plugin::ValueType& val);
324 template bool AssignParameterIfMatch(Tag tag, int64_t& ret, const Plugin::ValueType& val);
325 template bool AssignParameterIfMatch(Tag tag, double& ret, const Plugin::ValueType& val);
326 template bool AssignParameterIfMatch(Tag tag, Plugin::AudioSampleFormat& ret, const Plugin::ValueType& val);
327 template bool AssignParameterIfMatch(Tag tag, Plugin::AudioChannelLayout& ret, const Plugin::ValueType& val);
328 
329 /**
330  * translate plugin error into pipeline error code
331  * @param pluginError
332  * @return
333  */
TranslatePluginStatus(Plugin::Status pluginError)334 OHOS::Media::ErrorCode TranslatePluginStatus(Plugin::Status pluginError)
335 {
336     const static std::map<Plugin::Status, ErrorCode> g_transTable = {
337         {Plugin::Status::END_OF_STREAM, ErrorCode::END_OF_STREAM},
338         {Plugin::Status::OK, ErrorCode::SUCCESS},
339         {Plugin::Status::NO_ERROR, ErrorCode::SUCCESS},
340         {Plugin::Status::ERROR_UNKNOWN, ErrorCode::ERROR_UNKNOWN},
341         {Plugin::Status::ERROR_PLUGIN_ALREADY_EXISTS, ErrorCode::ERROR_UNKNOWN},
342         {Plugin::Status::ERROR_INCOMPATIBLE_VERSION, ErrorCode::ERROR_UNKNOWN},
343         {Plugin::Status::ERROR_NO_MEMORY, ErrorCode::ERROR_NO_MEMORY},
344         {Plugin::Status::ERROR_WRONG_STATE, ErrorCode::ERROR_INVALID_OPERATION},
345         {Plugin::Status::ERROR_UNIMPLEMENTED, ErrorCode::ERROR_UNIMPLEMENTED},
346         {Plugin::Status::ERROR_INVALID_PARAMETER, ErrorCode::ERROR_INVALID_PARAMETER_VALUE},
347         {Plugin::Status::ERROR_INVALID_DATA, ErrorCode::ERROR_UNKNOWN},
348         {Plugin::Status::ERROR_MISMATCHED_TYPE, ErrorCode::ERROR_INVALID_PARAMETER_TYPE},
349         {Plugin::Status::ERROR_TIMED_OUT, ErrorCode::ERROR_TIMED_OUT},
350         {Plugin::Status::ERROR_UNSUPPORTED_FORMAT, ErrorCode::ERROR_UNSUPPORTED_FORMAT},
351         {Plugin::Status::ERROR_NOT_ENOUGH_DATA, ErrorCode::ERROR_UNKNOWN},
352         {Plugin::Status::ERROR_NOT_EXISTED, ErrorCode::ERROR_NOT_EXISTED},
353         {Plugin::Status::ERROR_AGAIN, ErrorCode::ERROR_AGAIN},
354         {Plugin::Status::ERROR_PERMISSION_DENIED, ErrorCode::ERROR_PERMISSION_DENIED},
355         {Plugin::Status::ERROR_DELAY_READY, ErrorCode::SUCCESS},
356     };
357     auto ite = g_transTable.find(pluginError);
358     if (ite == g_transTable.end()) {
359         return ErrorCode::ERROR_UNKNOWN;
360     }
361     return ite->second;
362 }
363 
TranslateIntoParameter(const int & key,OHOS::Media::Plugin::Tag & tag)364 bool TranslateIntoParameter(const int& key, OHOS::Media::Plugin::Tag& tag)
365 {
366     if (key < static_cast<int32_t>(OHOS::Media::Plugin::Tag::INVALID)) {
367         return false;
368     }
369     tag = static_cast<OHOS::Media::Plugin::Tag>(key);
370     return true;
371 }
372 
FindAvailablePlugins(const Plugin::Capability & upStreamCaps,Plugin::PluginType pluginType,Plugin::CodecMode preferredCodecMode)373 std::vector<std::pair<std::shared_ptr<Plugin::PluginInfo>, Plugin::Capability>> FindAvailablePlugins(
374     const Plugin::Capability& upStreamCaps, Plugin::PluginType pluginType, Plugin::CodecMode preferredCodecMode)
375 {
376     auto pluginNames = Plugin::PluginManager::Instance().ListPlugins(pluginType, preferredCodecMode);
377     std::vector<std::pair<std::shared_ptr<Plugin::PluginInfo>, Plugin::Capability>> infos;
378     for (const auto& name : pluginNames) {
379         auto tmpInfo = Plugin::PluginManager::Instance().GetPluginInfo(pluginType, name);
380         if (tmpInfo == nullptr) {
381             continue;
382         }
383         Capability cap;
384         if (ApplyCapabilitySet(upStreamCaps, tmpInfo->inCaps, cap)) {
385             infos.emplace_back(tmpInfo, cap);
386         }
387     }
388     return infos;
389 }
390 
FindAvailablePluginsByOutputMime(const std::string & outputMime,Plugin::PluginType pluginType)391 std::vector<std::shared_ptr<Plugin::PluginInfo>> FindAvailablePluginsByOutputMime(const std::string& outputMime,
392                                                                                   Plugin::PluginType pluginType)
393 {
394     auto pluginNames = Plugin::PluginManager::Instance().ListPlugins(pluginType);
395     std::vector<std::shared_ptr<Plugin::PluginInfo>> rets;
396     for (const auto& name : pluginNames) {
397         auto tmpInfo = Plugin::PluginManager::Instance().GetPluginInfo(pluginType, name);
398         if (tmpInfo == nullptr) {
399             MEDIA_LOG_E("tmpInfo is null");
400             return rets;
401         }
402         for (const auto& cap : tmpInfo->outCaps) {
403             if (cap.mime == outputMime) {
404                 rets.emplace_back(tmpInfo);
405                 break;
406             }
407         }
408     }
409     return rets;
410 }
GetBytesPerSample(Plugin::AudioSampleFormat fmt)411 uint8_t GetBytesPerSample(Plugin::AudioSampleFormat fmt)
412 {
413     uint8_t bytesPerSample = 0;
414     switch (fmt) {
415         case Plugin::AudioSampleFormat::S64:
416         case Plugin::AudioSampleFormat::S64P:
417         case Plugin::AudioSampleFormat::U64:
418         case Plugin::AudioSampleFormat::U64P:
419         case Plugin::AudioSampleFormat::F64:
420         case Plugin::AudioSampleFormat::F64P:
421             bytesPerSample = 8; // 8 bytes
422             break;
423         case Plugin::AudioSampleFormat::F32:
424         case Plugin::AudioSampleFormat::F32P:
425         case Plugin::AudioSampleFormat::S32:
426         case Plugin::AudioSampleFormat::S32P:
427         case Plugin::AudioSampleFormat::U32:
428         case Plugin::AudioSampleFormat::U32P:
429             bytesPerSample = 4; // 4 bytes
430             break;
431         case Plugin::AudioSampleFormat::S24:
432         case Plugin::AudioSampleFormat::S24P:
433         case Plugin::AudioSampleFormat::U24:
434         case Plugin::AudioSampleFormat::U24P:
435             bytesPerSample = 3; // 3 bytes
436             break;
437         case Plugin::AudioSampleFormat::S16:
438         case Plugin::AudioSampleFormat::S16P:
439         case Plugin::AudioSampleFormat::U16:
440         case Plugin::AudioSampleFormat::U16P:
441             bytesPerSample = 2; // 2 bytes
442             break;
443         case Plugin::AudioSampleFormat::S8:
444         case Plugin::AudioSampleFormat::S8P:
445         case Plugin::AudioSampleFormat::U8:
446         case Plugin::AudioSampleFormat::U8P:
447             bytesPerSample = 1; // 1 bytes
448             break;
449         default:
450             bytesPerSample = 0;
451             break;
452     }
453     return bytesPerSample;
454 }
455 
Capability2String(const Capability & capability)456 std::string Capability2String(const Capability& capability)
457 {
458     const static std::map<Capability::Key, CapStrnessFunc> capStrnessMap = {
459         {Capability::Key::MEDIA_BITRATE, CapKeyStringiness<int64_t>},
460         {Capability::Key::AUDIO_SAMPLE_RATE, CapKeyStringiness<uint32_t>},
461         {Capability::Key::AUDIO_CHANNELS, CapKeyStringiness<uint32_t>},
462         {Capability::Key::AUDIO_CHANNEL_LAYOUT, CapKeyStringiness<Plugin::AudioChannelLayout>},
463         {Capability::Key::AUDIO_SAMPLE_FORMAT, CapKeyStringiness<Plugin::AudioSampleFormat>},
464         {Capability::Key::AUDIO_MPEG_VERSION, CapKeyStringiness<uint32_t>},
465         {Capability::Key::AUDIO_MPEG_LAYER, CapKeyStringiness<uint32_t>},
466         {Capability::Key::AUDIO_AAC_PROFILE, CapKeyStringiness<Plugin::AudioAacProfile>},
467         {Capability::Key::AUDIO_AAC_LEVEL, CapKeyStringiness<uint32_t>},
468         {Capability::Key::AUDIO_AAC_STREAM_FORMAT, CapKeyStringiness<Plugin::AudioAacStreamFormat>},
469         {Capability::Key::VIDEO_PIXEL_FORMAT, CapKeyStringiness<Plugin::VideoPixelFormat>},
470         {Capability::Key::VIDEO_BIT_STREAM_FORMAT, CapKeyStringiness<Plugin::VideoBitStreamFormat>},
471     };
472     char buffer[MAX_BUF_LEN] = {0};
473     int pos = 0;
474     int32_t ret = 0;
475     RETURN_IF_SNPRI_FAILED(
476         snprintf_truncated_s(buffer, sizeof(buffer), "Capability{mime:%s, ", capability.mime.c_str()), ret, {});
477     pos += ret;
478     bool needEtc = false;
479     for (const auto& cap : capability.keys) {
480         if (pos >= MAX_BUF_LEN - 1) { // reserve for "}"
481             needEtc = true;
482             break;
483         }
484         if (capStrnessMap.count(cap.first) == 0 || !Plugin::HasTagInfo(static_cast<Tag>(cap.first))) {
485             MEDIA_LOG_W(PUBLIC_LOG_D32 " is not in map, may be new key which is not contained?", cap.first);
486             continue;
487         }
488         const auto& info = Plugin::g_tagInfoMap.at(static_cast<Tag>(cap.first));
489         RETURN_IF_SNPRI_FAILED(capStrnessMap.at(cap.first)(buffer + pos, MAX_BUF_LEN - pos, std::get<0>(info),
490             std::get<2>(info), cap.second), ret, buffer); // secondary parameter
491         pos += ret;
492         RETURN_IF_SNPRI_FAILED(snprintf_truncated_s(buffer + pos, MAX_BUF_LEN - pos, ", "), ret, buffer);
493         pos += ret;
494     }
495     if (needEtc) {
496         pos = MAX_BUF_LEN - 5; // 5 is length of " ...}"
497         snprintf_truncated_s(buffer + pos, MAX_BUF_LEN + 1 - pos, " ...}");
498     } else {
499         pos -= 2; // 2 is length of ", "
500         snprintf_truncated_s(buffer + pos, MAX_BUF_LEN + 1 - pos, "}");
501     }
502     return buffer;
503 }
504 
Meta2String(const Plugin::Meta & meta)505 std::string Meta2String(const Plugin::Meta& meta)
506 {
507     char buffer[MAX_BUF_LEN + 1] = {0}; // one more is for \0
508     int pos = 0;
509     int32_t ret = 0;
510     RETURN_IF_SNPRI_FAILED(snprintf_truncated_s(buffer + pos, MAX_BUF_LEN - pos, "Meta{"), ret, {});
511     pos += ret;
512     bool needEtc = false;
513     std::vector<Tag> keys;
514     meta.GetKeys(keys);
515     for (const auto& item: keys) {
516         if (pos >= MAX_BUF_LEN - 2) { // reserve for "}\0"
517             needEtc = true;
518             break;
519         }
520         if (!Plugin::HasTagInfo(static_cast<Tag>(item)) || g_metaStrnessMap.count(item) == 0) {
521             MEDIA_LOG_W("meta id " PUBLIC_LOG_D32 "is not is map, may be update the info map?", item);
522             continue;
523         }
524         Plugin::ValueType value;
525         auto isValueExist = meta.GetData(item, value);
526         const auto& tuple = Plugin::g_tagInfoMap.at(static_cast<Tag>(item));
527         if (isValueExist) {
528             RETURN_IF_SNPRI_FAILED(g_metaStrnessMap.at(item)(buffer + pos, MAX_BUF_LEN - pos,
529                 std::get<0>(tuple), std::get<2>(tuple), value), ret, buffer); // secondary parameter
530             pos += ret;
531             RETURN_IF_SNPRI_FAILED(snprintf_truncated_s(buffer + pos, MAX_BUF_LEN - pos, ", "), ret, buffer);
532             pos += ret;
533         }
534     }
535     if (needEtc) {
536         pos = MAX_BUF_LEN - 5; // 5 is length of " ...}\0"
537         snprintf_truncated_s(buffer + pos, MAX_BUF_LEN + 1 - pos, " ...}");
538     } else {
539         pos -= 2; // 2 is length of ", "
540         snprintf_truncated_s(buffer + pos, MAX_BUF_LEN + 1 - pos, "}");
541     }
542     return buffer;
543 }
544 #undef RETURN_IF_SNPRI_FAILED
545 } // namespace Pipeline
546 } // namespace Media
547 } // namespace OHOS
548