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 "native_avformat.h"
17
18#include "common/log.h"
19#include "common/native_mfmagic.h"
20#include "common/status.h"
21#include "meta/meta_key.h"
22#include "securec.h"
23
24namespace {
25constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "NativeAVFormat" };
26}
27
28namespace {
29constexpr uint32_t MAX_STRING_LENGTH = 256;
30constexpr uint32_t MAX_DUMP_LENGTH = 1024;
31} // namespace
32
33using namespace OHOS::Media;
34
35struct OH_AVFormat *OH_AVFormat_Create(void)
36{
37    return new (std::nothrow) OH_AVFormat();
38}
39
40struct OH_AVFormat *OH_AVFormat_CreateAudioFormat(const char *mimeType, int32_t sampleRate, int32_t channelCount)
41{
42    FALSE_RETURN_V_MSG_E(mimeType != nullptr, nullptr, "mimeType is nullptr!");
43    OH_AVFormat *audioFormat = new (std::nothrow) OH_AVFormat();
44    FALSE_RETURN_V_MSG_E(audioFormat != nullptr, nullptr, "new format is nullptr!");
45    audioFormat->format_.PutStringValue(Tag::MIME_TYPE, mimeType);
46    audioFormat->format_.PutIntValue(Tag::AUDIO_SAMPLE_RATE, sampleRate);
47    audioFormat->format_.PutIntValue(Tag::AUDIO_CHANNEL_COUNT, channelCount);
48    return audioFormat;
49}
50
51struct OH_AVFormat *OH_AVFormat_CreateVideoFormat(const char *mimeType, int32_t width, int32_t height)
52{
53    FALSE_RETURN_V_MSG_E(mimeType != nullptr, nullptr, "mimeType is nullptr!");
54    OH_AVFormat *videoFormat = new (std::nothrow) OH_AVFormat();
55    FALSE_RETURN_V_MSG_E(videoFormat != nullptr, nullptr, "new format is nullptr!");
56    videoFormat->format_.PutStringValue(Tag::MIME_TYPE, mimeType);
57    videoFormat->format_.PutIntValue(Tag::VIDEO_WIDTH, width);
58    videoFormat->format_.PutIntValue(Tag::VIDEO_HEIGHT, height);
59    return videoFormat;
60}
61
62void OH_AVFormat_Destroy(struct OH_AVFormat *format)
63{
64    delete format;
65}
66
67bool OH_AVFormat_Copy(struct OH_AVFormat *to, struct OH_AVFormat *from)
68{
69    FALSE_RETURN_V_MSG_E(to != nullptr, false, "to format is nullptr!");
70    FALSE_RETURN_V_MSG_E(to->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
71    FALSE_RETURN_V_MSG_E(from != nullptr, false, "from format is nullptr!");
72    FALSE_RETURN_V_MSG_E(from->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
73
74    to->format_ = from->format_;
75    return true;
76}
77
78bool OH_AVFormat_SetIntValue(struct OH_AVFormat *format, const char *key, int32_t value)
79{
80    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
81    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
82    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
83
84    return format->format_.PutIntValue(key, value);
85}
86
87bool OH_AVFormat_SetLongValue(struct OH_AVFormat *format, const char *key, int64_t value)
88{
89    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
90    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
91    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
92
93    return format->format_.PutLongValue(key, value);
94}
95
96bool OH_AVFormat_SetFloatValue(struct OH_AVFormat *format, const char *key, float value)
97{
98    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
99    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
100    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
101
102    return format->format_.PutFloatValue(key, value);
103}
104
105bool OH_AVFormat_SetDoubleValue(struct OH_AVFormat *format, const char *key, double value)
106{
107    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
108    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
109    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
110
111    return format->format_.PutDoubleValue(key, value);
112}
113
114bool OH_AVFormat_SetStringValue(struct OH_AVFormat *format, const char *key, const char *value)
115{
116    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
117    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
118    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
119    FALSE_RETURN_V_MSG_E(value != nullptr, false, "value is nullptr!");
120
121    return format->format_.PutStringValue(key, value);
122}
123
124bool OH_AVFormat_SetBuffer(struct OH_AVFormat *format, const char *key, const uint8_t *addr, size_t size)
125{
126    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
127    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
128    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
129    FALSE_RETURN_V_MSG_E(addr != nullptr, false, "addr is nullptr!");
130    FALSE_RETURN_V_MSG_E(size != 0, false, "size is zero!");
131
132    return format->format_.PutBuffer(key, addr, size);
133}
134
135bool OH_AVFormat_GetIntValue(struct OH_AVFormat *format, const char *key, int32_t *out)
136{
137    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
138    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
139    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
140    FALSE_RETURN_V_MSG_E(out != nullptr, false, "out is nullptr!");
141
142    return format->format_.GetIntValue(key, *out);
143}
144
145bool OH_AVFormat_GetLongValue(struct OH_AVFormat *format, const char *key, int64_t *out)
146{
147    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
148    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
149    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
150    FALSE_RETURN_V_MSG_E(out != nullptr, false, "out is nullptr!");
151
152    return format->format_.GetLongValue(key, *out);
153}
154
155bool OH_AVFormat_GetFloatValue(struct OH_AVFormat *format, const char *key, float *out)
156{
157    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
158    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
159    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
160    FALSE_RETURN_V_MSG_E(out != nullptr, false, "out is nullptr!");
161
162    return format->format_.GetFloatValue(key, *out);
163}
164
165bool OH_AVFormat_GetDoubleValue(struct OH_AVFormat *format, const char *key, double *out)
166{
167    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
168    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
169    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
170    FALSE_RETURN_V_MSG_E(out != nullptr, false, "out is nullptr!");
171
172    return format->format_.GetDoubleValue(key, *out);
173}
174
175bool OH_AVFormat_GetStringValue(struct OH_AVFormat *format, const char *key, const char **out)
176{
177    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
178    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
179    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
180    FALSE_RETURN_V_MSG_E(out != nullptr, false, "out is nullptr!");
181
182    if (format->outString_ != nullptr) {
183        free(format->outString_);
184        format->outString_ = nullptr;
185    }
186
187    std::string str;
188    bool ret = format->format_.GetStringValue(key, str);
189    if (!ret) {
190        return false;
191    }
192    uint32_t bufLength = str.size() > MAX_STRING_LENGTH ? MAX_STRING_LENGTH : str.size();
193
194    format->outString_ = static_cast<char *>(malloc((bufLength + 1) * sizeof(char)));
195    FALSE_RETURN_V_MSG_E(format->outString_ != nullptr, false, "malloc out string nullptr!");
196
197    if (strcpy_s(format->outString_, bufLength + 1, str.c_str()) != EOK) {
198        MEDIA_LOG_E("Failed to strcpy_s");
199        free(format->outString_);
200        format->outString_ = nullptr;
201        return false;
202    }
203
204    *out = format->outString_;
205    return true;
206}
207
208bool OH_AVFormat_GetBuffer(struct OH_AVFormat *format, const char *key, uint8_t **addr, size_t *size)
209{
210    FALSE_RETURN_V_MSG_E(format != nullptr, false, "input format is nullptr!");
211    FALSE_RETURN_V_MSG_E(format->magic_ == MFMagic::MFMAGIC_FORMAT, false, "magic error!");
212    FALSE_RETURN_V_MSG_E(key != nullptr, false, "key is nullptr!");
213    FALSE_RETURN_V_MSG_E(addr != nullptr, false, "addr is nullptr!");
214    FALSE_RETURN_V_MSG_E(size != nullptr, false, "size is nullptr!");
215
216    return format->format_.GetBuffer(key, addr, *size);
217}
218
219const char *OH_AVFormat_DumpInfo(struct OH_AVFormat *format)
220{
221    FALSE_RETURN_V_MSG_E(format != nullptr, nullptr, "input format is nullptr!");
222    if (format->dumpInfo_ != nullptr) {
223        free(format->dumpInfo_);
224        format->dumpInfo_ = nullptr;
225    }
226    std::string info = format->format_.Stringify();
227    if (info.empty()) {
228        return nullptr;
229    }
230    uint32_t bufLength = info.size() > MAX_DUMP_LENGTH ? MAX_DUMP_LENGTH : info.size();
231    format->dumpInfo_ = static_cast<char *>(malloc((bufLength + 1) * sizeof(char)));
232    FALSE_RETURN_V_MSG_E(format->dumpInfo_ != nullptr, nullptr, "malloc dump info nullptr!");
233    if (strcpy_s(format->dumpInfo_, bufLength + 1, info.c_str()) != EOK) {
234        MEDIA_LOG_E("Failed to strcpy_s");
235        free(format->dumpInfo_);
236        format->dumpInfo_ = nullptr;
237    }
238    return format->dumpInfo_;
239}
240