1/*
2 * Copyright (c) 2023-2024 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 "histreamer_ability_parser.h"
17#include "dh_utils_tool.h"
18#include "distributed_hardware_log.h"
19
20
21namespace OHOS {
22namespace DistributedHardware {
23
24static const std::string NAME = "name";
25static const std::string INS = "ins";
26static const std::string OUTS = "outs";
27static const std::string MIME = "mime";
28static const std::string SAMPLE_RATE = "sample_rate";
29static const std::string AUDIO_SAMPLE_FORMAT = "sample_fmt";
30static const std::string AD_MPEG_VER = "ad_mpeg_ver";
31static const std::string AUDIO_AAC_PROFILE = "aac_profile";
32static const std::string AUDIO_AAC_STREAM_FORMAT = "aac_stm_fmt";
33static const std::string AUDIO_CHANNEL_LAYOUT = "channel_layout";
34
35static const std::string VIDEO_PIXEL_FMT = "pixel_fmt";
36static const std::string VIDEO_BIT_STREAM_FMT = "vd_bit_stream_fmt";
37
38void FromJson(const cJSON *jsonObject, AudioEncoderIn &audioEncoderIn)
39{
40    if (jsonObject == nullptr) {
41        DHLOGE("Json pointer is nullptr!");
42        return;
43    }
44    if (!IsString(jsonObject, MIME)) {
45        DHLOGE("AudioEncoderIn MIME is invalid!\n");
46        return;
47    }
48    audioEncoderIn.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
49    if (!IsArray(jsonObject, SAMPLE_RATE)) {
50        DHLOGE("AudioEncoderIn SAMPLE_RATE is invalid\n");
51        return;
52    }
53    cJSON *sampleRate = cJSON_GetObjectItem(jsonObject, SAMPLE_RATE.c_str());
54    if (sampleRate == NULL) {
55        DHLOGE("AudioEncoderIn SAMPLE_RATE is invalid\n");
56        return;
57    }
58    cJSON *sampleRateItem = nullptr;
59    cJSON_ArrayForEach(sampleRateItem, sampleRate) {
60        if (sampleRateItem && sampleRateItem->type == cJSON_Number) {
61            audioEncoderIn.sample_rate.push_back((uint32_t)sampleRateItem->valuedouble);
62        }
63    }
64}
65
66void FromJson(const cJSON *jsonObject, AudioEncoderOut &audioEncoderOut)
67{
68    if (jsonObject == nullptr) {
69        DHLOGE("Json pointer is nullptr!");
70        return;
71    }
72    if (!IsString(jsonObject, MIME)) {
73        DHLOGE("AudioEncoderOut MIME is invalid!");
74        return;
75    }
76    audioEncoderOut.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
77    if (!IsUInt32(jsonObject, AD_MPEG_VER)) {
78        DHLOGE("AudioEncoderOut AD_MPEG_VER is invalid!");
79        return;
80    }
81    audioEncoderOut.ad_mpeg_ver = (uint32_t)cJSON_GetObjectItem(jsonObject, AD_MPEG_VER.c_str())->valuedouble;
82
83    if (!IsUInt8(jsonObject, AUDIO_AAC_PROFILE)) {
84        DHLOGE("AudioEncoderOut AUDIO_AAC_PROFILE is invalid!");
85        return;
86    }
87    audioEncoderOut.aac_profile =
88        (AudioAacProfile)cJSON_GetObjectItem(jsonObject, AUDIO_AAC_PROFILE.c_str())->valuedouble;
89
90    if (!IsUInt8(jsonObject, AUDIO_AAC_STREAM_FORMAT)) {
91        DHLOGE("AudioEncoderOut AUDIO_AAC_STREAM_FORMAT is invalid!");
92        return;
93    }
94    audioEncoderOut.aac_stm_fmt =
95        (AudioAacStreamFormat)cJSON_GetObjectItem(jsonObject, AUDIO_AAC_STREAM_FORMAT.c_str())->valuedouble;
96}
97
98void FromJson(const cJSON *jsonObject, AudioEncoder &audioEncoder)
99{
100    if (jsonObject == nullptr) {
101        DHLOGE("Json pointer is nullptr!");
102        return;
103    }
104    if (!IsString(jsonObject, NAME)) {
105        DHLOGE("AudioEncoder NAME is invalid!");
106        return;
107    }
108    audioEncoder.name = cJSON_GetObjectItem(jsonObject, NAME.c_str())->valuestring;
109
110    if (!IsArray(jsonObject, INS)) {
111        DHLOGE("AudioEncoder INS is invalid!");
112        return;
113    }
114    cJSON *insJson = cJSON_GetObjectItem(jsonObject, INS.c_str());
115    cJSON *inJson = nullptr;
116    cJSON_ArrayForEach(inJson, insJson) {
117        AudioEncoderIn in;
118        FromJson(inJson, in);
119        audioEncoder.ins.push_back(in);
120    }
121
122    if (!IsArray(jsonObject, OUTS)) {
123        DHLOGE("AudioEncoder OUTS is invalid!");
124        return;
125    }
126    cJSON *outsJson = cJSON_GetObjectItem(jsonObject, OUTS.c_str());
127    cJSON *outJson = nullptr;
128    cJSON_ArrayForEach(outJson, outsJson) {
129        AudioEncoderOut out;
130        FromJson(outJson, out);
131        audioEncoder.outs.push_back(out);
132    }
133}
134
135void FromJson(const cJSON *jsonObject, AudioDecoderIn &audioDecoderIn)
136{
137    if (jsonObject == nullptr) {
138        DHLOGE("Json pointer is nullptr!");
139        return;
140    }
141    if (!IsString(jsonObject, MIME)) {
142        DHLOGE("AudioDecoderIn MIME is invalid!");
143        return;
144    }
145    audioDecoderIn.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
146
147    if (!IsArray(jsonObject, AUDIO_CHANNEL_LAYOUT)) {
148        DHLOGE("AudioDecoder AUDIO_CHANNEL_LAYOUT is invalid!");
149        return;
150    }
151    const cJSON *channelLayoutJson = cJSON_GetObjectItem(jsonObject, AUDIO_CHANNEL_LAYOUT.c_str());
152    const cJSON *layout = nullptr;
153    cJSON_ArrayForEach(layout, channelLayoutJson) {
154        if (layout && layout->type == cJSON_Number) {
155            audioDecoderIn.channel_layout.push_back((AudioChannelLayout)layout->valuedouble);
156        }
157    }
158}
159
160void FromJson(const cJSON *jsonObject, AudioDecoderOut &audioDecoderOut)
161{
162    if (jsonObject == nullptr) {
163        DHLOGE("Json pointer is nullptr!");
164        return;
165    }
166    if (!IsString(jsonObject, MIME)) {
167        DHLOGE("AudioDecoderOut MIME is invalid!");
168        return;
169    }
170    audioDecoderOut.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
171    if (!IsArray(jsonObject, AUDIO_SAMPLE_FORMAT)) {
172        DHLOGE("AudioDecoderOut AUDIO_SAMPLE_FORMAT is invalid!");
173        return;
174    }
175    cJSON *sampleFormatJson = cJSON_GetObjectItem(jsonObject, AUDIO_SAMPLE_FORMAT.c_str());
176    cJSON *format = nullptr;
177    cJSON_ArrayForEach(format, sampleFormatJson) {
178        if (format && format->type == cJSON_Number) {
179            audioDecoderOut.sample_fmt.push_back((AudioSampleFormat)format->valuedouble);
180        }
181    }
182}
183
184void FromJson(const cJSON *jsonObject, AudioDecoder &audioDecoder)
185{
186    if (jsonObject == nullptr) {
187        DHLOGE("Json pointer is nullptr!");
188        return;
189    }
190    if (!IsString(jsonObject, NAME)) {
191        DHLOGE("AudioDecoderOut MIME is invalid!");
192        return;
193    }
194    audioDecoder.name = cJSON_GetObjectItem(jsonObject, NAME.c_str())->valuestring;
195
196    if (!IsArray(jsonObject, INS)) {
197        DHLOGE("AudioDecoder OUTS is invalid!");
198        return;
199    }
200    const cJSON *insJson = cJSON_GetObjectItem(jsonObject, INS.c_str());
201    cJSON *inJson = nullptr;
202    cJSON_ArrayForEach(inJson, insJson) {
203        AudioDecoderIn in;
204        FromJson(inJson, in);
205        audioDecoder.ins.push_back(in);
206    }
207    if (!IsArray(jsonObject, OUTS)) {
208        DHLOGE("AudioDecoder OUTS is invalid!");
209        return;
210    }
211    cJSON *outsJson = cJSON_GetObjectItem(jsonObject, OUTS.c_str());
212    cJSON *outJson = nullptr;
213    cJSON_ArrayForEach(outJson, outsJson) {
214        AudioDecoderOut out;
215        FromJson(outJson, out);
216        audioDecoder.outs.push_back(out);
217    }
218}
219
220void FromJson(const cJSON *jsonObject, VideoEncoderIn &videoEncoderIn)
221{
222    if (jsonObject == nullptr) {
223        DHLOGE("Json pointer is nullptr!");
224        return;
225    }
226    if (!IsString(jsonObject, MIME)) {
227        DHLOGE("VideoEncoderIn MIME is invalid!");
228        return;
229    }
230    videoEncoderIn.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
231
232    if (!IsArray(jsonObject, VIDEO_PIXEL_FMT)) {
233        DHLOGE("VideoEncoderIn VIDEO_PIXEL_FMT is invalid!");
234        return;
235    }
236    cJSON *videoPixelFmt = cJSON_GetObjectItem(jsonObject, VIDEO_PIXEL_FMT.c_str());
237    cJSON *pixelFmt = nullptr;
238    cJSON_ArrayForEach(pixelFmt, videoPixelFmt) {
239        if (pixelFmt && pixelFmt->type == cJSON_Number) {
240            videoEncoderIn.pixel_fmt.push_back((VideoPixelFormat)pixelFmt->valuedouble);
241        }
242    }
243}
244
245void FromJson(const cJSON *jsonObject, VideoEncoderOut &videoEncoderOut)
246{
247    if (jsonObject == nullptr) {
248        DHLOGE("Json pointer is nullptr!");
249        return;
250    }
251    if (!IsString(jsonObject, MIME)) {
252        DHLOGE("VideoEncoderIn MIME is invalid!");
253        return;
254    }
255    videoEncoderOut.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
256}
257
258void FromJson(const cJSON *jsonObject, VideoEncoder &videoEncoder)
259{
260    if (jsonObject == nullptr) {
261        DHLOGE("Json pointer is nullptr!");
262        return;
263    }
264    if (!IsString(jsonObject, NAME)) {
265        DHLOGE("VideoEncoder NAME is invalid!");
266        return;
267    }
268    videoEncoder.name = cJSON_GetObjectItem(jsonObject, NAME.c_str())->valuestring;
269
270    if (!IsArray(jsonObject, INS)) {
271        DHLOGE("VideoEncoder INS is invalid!");
272        return;
273    }
274    cJSON *videoEncoderInsJson = cJSON_GetObjectItem(jsonObject, INS.c_str());
275    cJSON *inJson = nullptr;
276    cJSON_ArrayForEach(inJson, videoEncoderInsJson) {
277        VideoEncoderIn in;
278        FromJson(inJson, in);
279        videoEncoder.ins.push_back(in);
280    }
281
282    if (!IsArray(jsonObject, OUTS)) {
283        DHLOGE("VideoEncoder OUTS is invalid!");
284        return;
285    }
286    cJSON *videoEncoderOutsJson = cJSON_GetObjectItem(jsonObject, OUTS.c_str());
287    cJSON *outJson = nullptr;
288    cJSON_ArrayForEach(outJson, videoEncoderOutsJson) {
289        VideoEncoderOut out;
290        FromJson(outJson, out);
291        videoEncoder.outs.push_back(out);
292    }
293}
294
295void FromJson(const cJSON *jsonObject, VideoDecoderIn &videoDecoderIn)
296{
297    if (jsonObject == nullptr) {
298        DHLOGE("Json pointer is nullptr!");
299        return;
300    }
301    if (!IsString(jsonObject, MIME)) {
302        DHLOGE("VideoDecoderIn MIME is invalid!");
303        return;
304    }
305    videoDecoderIn.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
306
307    if (!IsArray(jsonObject, VIDEO_BIT_STREAM_FMT)) {
308        DHLOGE("VideoDecoderIn VIDEO_BIT_STREAM_FMT is invalid!");
309        return;
310    }
311    cJSON *videoBitStreamFmtJson = cJSON_GetObjectItem(jsonObject, VIDEO_BIT_STREAM_FMT.c_str());
312    cJSON *fmt = nullptr;
313    cJSON_ArrayForEach(fmt, videoBitStreamFmtJson) {
314        if (fmt && fmt->type == cJSON_Number) {
315            videoDecoderIn.vd_bit_stream_fmt.push_back((VideoBitStreamFormat)(fmt->valuedouble));
316        }
317    }
318}
319
320void FromJson(const cJSON *jsonObject, VideoDecoderOut &videoDecoderOut)
321{
322    if (jsonObject == nullptr) {
323        DHLOGE("Json pointer is nullptr!");
324        return;
325    }
326    if (!IsString(jsonObject, MIME)) {
327        DHLOGE("VideoDecoderOut MIME is invalid!");
328        return;
329    }
330    videoDecoderOut.mime = cJSON_GetObjectItem(jsonObject, MIME.c_str())->valuestring;
331
332    if (!IsArray(jsonObject, VIDEO_BIT_STREAM_FMT)) {
333        DHLOGE("videoDecoderOut VIDEO_PIXEL_FMT is invalid!");
334        return;
335    }
336    cJSON *videoPixelFmtJson = cJSON_GetObjectItem(jsonObject, VIDEO_PIXEL_FMT.c_str());
337    cJSON *fmt = nullptr;
338    cJSON_ArrayForEach(fmt, videoPixelFmtJson) {
339        if (fmt && fmt->type == cJSON_Number) {
340            videoDecoderOut.pixel_fmt.push_back((VideoPixelFormat)(fmt->valuedouble));
341        }
342    }
343}
344
345void FromJson(const cJSON *jsonObject, VideoDecoder &videoDecoder)
346{
347    if (jsonObject == nullptr) {
348        DHLOGE("Json pointer is nullptr!");
349        return;
350    }
351    if (!IsString(jsonObject, NAME)) {
352        DHLOGE("VideoDecoder NAME is invalid!");
353        return;
354    }
355    videoDecoder.name = cJSON_GetObjectItem(jsonObject, NAME.c_str())->valuestring;
356
357    if (!IsArray(jsonObject, INS)) {
358        DHLOGE("VideoDecoder INS is invalid!");
359        return;
360    }
361    cJSON *videoDecoderInsJson = cJSON_GetObjectItem(jsonObject, INS.c_str());
362    cJSON *inJson = nullptr;
363    cJSON_ArrayForEach(inJson, videoDecoderInsJson) {
364        VideoDecoderIn in;
365        FromJson(inJson, in);
366        videoDecoder.ins.push_back(in);
367    }
368
369    if (!IsArray(jsonObject, OUTS)) {
370        DHLOGE("VideoDecoder OUTS is invalid!");
371        return;
372    }
373    cJSON *videoDecoderOutsJson =  cJSON_GetObjectItem(jsonObject, OUTS.c_str());
374    cJSON *outJson = nullptr;
375    cJSON_ArrayForEach(outJson, videoDecoderOutsJson) {
376        VideoDecoderOut out;
377        FromJson(outJson, out);
378        videoDecoder.outs.push_back(out);
379    }
380}
381
382template <typename T>
383void FromJson(const std::string &key, const cJSON *jsonObject, std::vector<T> &objs)
384{
385    if (jsonObject == nullptr) {
386        DHLOGE("Json pointer is nullptr!");
387        return;
388    }
389    cJSON *json = cJSON_GetObjectItem(jsonObject, key.c_str());
390    if (json == NULL) {
391        DHLOGE("JSONObject key invalid, key: %{public}s", key.c_str());
392        return;
393    }
394    if (cJSON_IsArray(json)) {
395        cJSON *item;
396        cJSON_ArrayForEach(item, json) {
397            T obj;
398            FromJson(item, obj);
399            objs.push_back(obj);
400        }
401    } else {
402        T obj;
403        FromJson(json, obj);
404        objs.push_back(obj);
405    }
406}
407
408template
409void FromJson<AudioEncoder>(const std::string &key, const cJSON *jsonObject, std::vector<AudioEncoder> &objs);
410template
411void FromJson<AudioDecoder>(const std::string &key, const cJSON *jsonObject, std::vector<AudioDecoder> &objs);
412template
413void FromJson<VideoEncoder>(const std::string &key, const cJSON *jsonObject, std::vector<VideoEncoder> &objs);
414template
415void FromJson<VideoDecoder>(const std::string &key, const cJSON *jsonObject, std::vector<VideoDecoder> &objs);
416
417}
418}