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 <list>
17 #include <mutex>
18 #include <shared_mutex>
19 #include "avcodec_audio_encoder.h"
20 #include "avcodec_errors.h"
21 #include "avcodec_log.h"
22 #include "buffer/avsharedmemory.h"
23 #include "common/native_mfmagic.h"
24 #include "native_avcodec_audioencoder.h"
25 #include "native_avcodec_base.h"
26 #include "native_avmagic.h"
27
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "NativeAudioEncoder"};
30 }
31
32 using namespace OHOS::MediaAVCodec;
33 class NativeAudioEncoderCallback;
34
35 struct AudioEncoderObject : public OH_AVCodec {
AudioEncoderObjectAudioEncoderObject36 explicit AudioEncoderObject(const std::shared_ptr<AVCodecAudioEncoder> &encoder)
37 : OH_AVCodec(AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER), audioEncoder_(encoder)
38 {
39 }
40 ~AudioEncoderObject() = default;
41
42 const std::shared_ptr<AVCodecAudioEncoder> audioEncoder_;
43 std::list<OHOS::sptr<OH_AVMemory>> memoryObjList_;
44 std::shared_ptr<NativeAudioEncoderCallback> callback_ = nullptr;
45 std::atomic<bool> isFlushing_ = false;
46 std::atomic<bool> isFlushed_ = false;
47 std::atomic<bool> isStop_ = false;
48 std::atomic<bool> isEOS_ = false;
49 std::shared_mutex memoryObjListMutex_;
50 };
51
52 class NativeAudioEncoderCallback : public AVCodecCallback {
53 public:
NativeAudioEncoderCallback(OH_AVCodec * codec,struct OH_AVCodecAsyncCallback cb,void * userData)54 NativeAudioEncoderCallback(OH_AVCodec *codec, struct OH_AVCodecAsyncCallback cb, void *userData)
55 : codec_(codec), callback_(cb), userData_(userData)
56 {
57 }
58 virtual ~NativeAudioEncoderCallback() = default;
59
OnError(AVCodecErrorType errorType,int32_t errorCode)60 void OnError(AVCodecErrorType errorType, int32_t errorCode) override
61 {
62 std::unique_lock<std::shared_mutex> lock(mutex_);
63 (void)errorType;
64 if (codec_ != nullptr && callback_.onError != nullptr) {
65 int32_t extErr = AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(errorCode));
66 callback_.onError(codec_, extErr, userData_);
67 }
68 }
69
OnOutputFormatChanged(const Format & format)70 void OnOutputFormatChanged(const Format &format) override
71 {
72 std::unique_lock<std::shared_mutex> lock(mutex_);
73 if (codec_ != nullptr && callback_.onStreamChanged != nullptr) {
74 OHOS::sptr<OH_AVFormat> object = new (std::nothrow) OH_AVFormat(format);
75 // The object lifecycle is controlled by the current function stack
76 callback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
77 }
78 }
79
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)80 void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override
81 {
82 std::shared_lock<std::shared_mutex> lock(mutex_);
83 if (codec_ != nullptr && callback_.onNeedInputData != nullptr) {
84 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec_);
85 CHECK_AND_RETURN_LOG(audioEncObj->audioEncoder_ != nullptr, "audioEncoder_ is nullptr!");
86 if (audioEncObj->isFlushing_.load() || audioEncObj->isFlushed_.load() || audioEncObj->isStop_.load() ||
87 audioEncObj->isEOS_.load()) {
88 AVCODEC_LOGD("At flush, eos or stop, no buffer available");
89 return;
90 }
91
92 OH_AVMemory *data = GetInputData(codec_, index, buffer);
93 callback_.onNeedInputData(codec_, index, data, userData_);
94 }
95 }
96
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)97 void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
98 std::shared_ptr<AVSharedMemory> buffer) override
99 {
100 std::shared_lock<std::shared_mutex> lock(mutex_);
101 if (codec_ != nullptr && callback_.onNeedOutputData != nullptr) {
102 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec_);
103 CHECK_AND_RETURN_LOG(audioEncObj->audioEncoder_ != nullptr, "audioEncoder_ is nullptr!");
104 if (audioEncObj->isFlushing_.load() || audioEncObj->isFlushed_.load() || audioEncObj->isStop_.load()) {
105 AVCODEC_LOGD("At flush or stop, ignore");
106 return;
107 }
108 struct OH_AVCodecBufferAttr bufferAttr { info.presentationTimeUs, info.size, info.offset, flag };
109 bufferAttr.flags = flag;
110 // The bufferInfo lifecycle is controlled by the current function stack
111 OH_AVMemory *data = GetOutputData(codec_, index, buffer);
112 callback_.onNeedOutputData(codec_, index, data, &bufferAttr, userData_);
113 }
114 }
115
StopCallback()116 void StopCallback()
117 {
118 std::unique_lock<std::shared_mutex> lock(mutex_);
119 codec_ = nullptr;
120 }
121
122 private:
GetInputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)123 OH_AVMemory *GetInputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
124 {
125 CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "input codec is nullptr!");
126 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER, nullptr, "magic error!");
127
128 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
129 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, nullptr, "audioEncoder_ is nullptr!");
130 CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr, "get input buffer is nullptr!");
131
132 {
133 std::shared_lock<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
134 for (auto &memoryObj : audioEncObj->memoryObjList_) {
135 if (memoryObj->IsEqualMemory(memory)) {
136 return reinterpret_cast<OH_AVMemory *>(memoryObj.GetRefPtr());
137 }
138 }
139 }
140
141 OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
142 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new OH_AVMemory");
143
144 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
145 audioEncObj->memoryObjList_.push_back(object);
146 return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
147 }
148
GetOutputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)149 OH_AVMemory *GetOutputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
150 {
151 CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "input codec is nullptr!");
152 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER, nullptr, "magic error!");
153
154 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
155 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, nullptr, "audioEncoder_ is nullptr!");
156 CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr, "get output buffer is nullptr!");
157
158 {
159 std::shared_lock<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
160 for (auto &memoryObj : audioEncObj->memoryObjList_) {
161 if (memoryObj->IsEqualMemory(memory)) {
162 return reinterpret_cast<OH_AVMemory *>(memoryObj.GetRefPtr());
163 }
164 }
165 }
166
167 OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
168 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new OH_AVMemory");
169
170 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
171 audioEncObj->memoryObjList_.push_back(object);
172 return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
173 }
174
175 struct OH_AVCodec *codec_;
176 struct OH_AVCodecAsyncCallback callback_;
177 void *userData_;
178 std::shared_mutex mutex_;
179 };
180
181 namespace OHOS {
182 namespace MediaAVCodec {
183 #ifdef __cplusplus
184 extern "C" {
185 #endif
186
OH_AudioEncoder_CreateByMime(const char * mime)187 struct OH_AVCodec *OH_AudioEncoder_CreateByMime(const char *mime)
188 {
189 CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "input mime is nullptr!");
190
191 std::shared_ptr<AVCodecAudioEncoder> audioEncoder = AudioEncoderFactory::CreateByMime(mime);
192 CHECK_AND_RETURN_RET_LOG(audioEncoder != nullptr, nullptr, "failed to AudioEncoderFactory::CreateByMime");
193
194 struct AudioEncoderObject *object = new (std::nothrow) AudioEncoderObject(audioEncoder);
195 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new AudioEncoderObject");
196
197 return object;
198 }
199
OH_AudioEncoder_CreateByName(const char * name)200 struct OH_AVCodec *OH_AudioEncoder_CreateByName(const char *name)
201 {
202 CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "input name is nullptr!");
203
204 std::shared_ptr<AVCodecAudioEncoder> audioEncoder = AudioEncoderFactory::CreateByName(name);
205 CHECK_AND_RETURN_RET_LOG(audioEncoder != nullptr, nullptr, "failed to AudioEncoderFactory::CreateByMime");
206
207 struct AudioEncoderObject *object = new (std::nothrow) AudioEncoderObject(audioEncoder);
208 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new AudioEncoderObject");
209
210 return object;
211 }
212
OH_AudioEncoder_Destroy(struct OH_AVCodec * codec)213 OH_AVErrCode OH_AudioEncoder_Destroy(struct OH_AVCodec *codec)
214 {
215 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
216 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
217 AV_ERR_INVALID_VAL, "magic error!");
218
219 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
220
221 if (audioEncObj != nullptr && audioEncObj->audioEncoder_ != nullptr) {
222 if (audioEncObj->callback_ != nullptr) {
223 audioEncObj->callback_->StopCallback();
224 }
225 {
226 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
227 audioEncObj->memoryObjList_.clear();
228 }
229 int32_t ret = audioEncObj->audioEncoder_->Release();
230 if (ret != AVCS_ERR_OK) {
231 AVCODEC_LOGE("audioEncoder Release failed!");
232 delete codec;
233 return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
234 }
235 } else {
236 AVCODEC_LOGD("audioEncoder_ is nullptr!");
237 }
238
239 delete codec;
240 return AV_ERR_OK;
241 }
242
OH_AudioEncoder_Configure(struct OH_AVCodec * codec,struct OH_AVFormat * format)243 OH_AVErrCode OH_AudioEncoder_Configure(struct OH_AVCodec *codec, struct OH_AVFormat *format)
244 {
245 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
246 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
247 AV_ERR_INVALID_VAL, "magic error!");
248 CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
249 CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "magic error!");
250
251 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
252 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder is nullptr!");
253
254 int32_t ret = audioEncObj->audioEncoder_->Configure(format->format_);
255 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
256 "audioEncoder Configure failed!");
257
258 return AV_ERR_OK;
259 }
260
OH_AudioEncoder_Prepare(struct OH_AVCodec * codec)261 OH_AVErrCode OH_AudioEncoder_Prepare(struct OH_AVCodec *codec)
262 {
263 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
264 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
265 AV_ERR_INVALID_VAL, "magic error!");
266
267 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
268 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
269
270 int32_t ret = audioEncObj->audioEncoder_->Prepare();
271 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
272 "audioEncoder Prepare failed!");
273
274 return AV_ERR_OK;
275 }
276
OH_AudioEncoder_Start(struct OH_AVCodec * codec)277 OH_AVErrCode OH_AudioEncoder_Start(struct OH_AVCodec *codec)
278 {
279 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
280 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
281 AV_ERR_INVALID_VAL, "magic error!");
282
283 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
284 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
285 audioEncObj->isStop_.store(false);
286 audioEncObj->isEOS_.store(false);
287 audioEncObj->isFlushed_.store(false);
288 AVCODEC_LOGD("Set stop and eos status to false");
289 int32_t ret = audioEncObj->audioEncoder_->Start();
290 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
291 "audioEncoder Start failed!");
292
293 return AV_ERR_OK;
294 }
295
OH_AudioEncoder_Stop(struct OH_AVCodec * codec)296 OH_AVErrCode OH_AudioEncoder_Stop(struct OH_AVCodec *codec)
297 {
298 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
299 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
300 AV_ERR_INVALID_VAL, "magic error!");
301
302 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
303 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
304 audioEncObj->isStop_.store(true);
305 AVCODEC_LOGD("Set stop status to true");
306
307 int32_t ret = audioEncObj->audioEncoder_->Stop();
308 if (ret != AVCS_ERR_OK) {
309 audioEncObj->isStop_.store(false);
310 AVCODEC_LOGE("audioEncoder Stop failed! Set stop status to false");
311 return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
312 }
313 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
314 audioEncObj->memoryObjList_.clear();
315
316 return AV_ERR_OK;
317 }
318
OH_AudioEncoder_Flush(struct OH_AVCodec * codec)319 OH_AVErrCode OH_AudioEncoder_Flush(struct OH_AVCodec *codec)
320 {
321 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
322 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
323 AV_ERR_INVALID_VAL, "magic error!");
324
325 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
326 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
327
328 audioEncObj->isFlushing_.store(true);
329 AVCODEC_LOGD("Set flush status to true");
330
331 int32_t ret = audioEncObj->audioEncoder_->Flush();
332 if (ret != AVCS_ERR_OK) {
333 audioEncObj->isFlushing_.store(false);
334 audioEncObj->isFlushed_.store(false);
335 AVCODEC_LOGE("audioEncObj Flush failed! Set flush status to false");
336 return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
337 }
338 audioEncObj->isFlushed_.store(true);
339 audioEncObj->isFlushing_.store(false);
340 AVCODEC_LOGD("Set flush status to false");
341 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
342 audioEncObj->memoryObjList_.clear();
343 return AV_ERR_OK;
344 }
345
OH_AudioEncoder_Reset(struct OH_AVCodec * codec)346 OH_AVErrCode OH_AudioEncoder_Reset(struct OH_AVCodec *codec)
347 {
348 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
349 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
350 AV_ERR_INVALID_VAL, "magic error!");
351
352 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
353 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
354 audioEncObj->isStop_.store(true);
355 int32_t ret = audioEncObj->audioEncoder_->Reset();
356 if (ret != AVCS_ERR_OK) {
357 audioEncObj->isStop_.store(false);
358 AVCODEC_LOGE("audioEncoder Reset failed! Set stop status to false");
359 return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
360 }
361 std::lock_guard<std::shared_mutex> lock(audioEncObj->memoryObjListMutex_);
362 audioEncObj->memoryObjList_.clear();
363 return AV_ERR_OK;
364 }
365
OH_AudioEncoder_PushInputData(struct OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)366 OH_AVErrCode OH_AudioEncoder_PushInputData(struct OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
367 {
368 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
369 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
370 AV_ERR_INVALID_VAL, "magic error!");
371 CHECK_AND_RETURN_RET_LOG(attr.size >= 0, AV_ERR_INVALID_VAL, "Invalid buffer size!");
372
373 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
374 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
375
376 struct AVCodecBufferInfo bufferInfo;
377 bufferInfo.presentationTimeUs = attr.pts;
378 bufferInfo.size = attr.size;
379 bufferInfo.offset = attr.offset;
380 AVCodecBufferFlag bufferFlag = static_cast<AVCodecBufferFlag>(attr.flags);
381
382 int32_t ret = audioEncObj->audioEncoder_->QueueInputBuffer(index, bufferInfo, bufferFlag);
383 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
384 "audioEncoder QueueInputBuffer failed!");
385 if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
386 audioEncObj->isEOS_.store(true);
387 AVCODEC_LOGD("Set eos status to true");
388 }
389
390 return AV_ERR_OK;
391 }
392
OH_AudioEncoder_GetOutputDescription(struct OH_AVCodec * codec)393 OH_AVFormat *OH_AudioEncoder_GetOutputDescription(struct OH_AVCodec *codec)
394 {
395 CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "input codec is nullptr!");
396 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER, nullptr, "magic error!");
397
398 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
399 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, nullptr, "audioEncoder_ is nullptr!");
400
401 Format format;
402 int32_t ret = audioEncObj->audioEncoder_->GetOutputFormat(format);
403 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "audioEncoder GetOutputFormat failed!");
404
405 OH_AVFormat *avFormat = OH_AVFormat_Create();
406 avFormat->format_ = format;
407
408 return avFormat;
409 }
410
OH_AudioEncoder_FreeOutputData(struct OH_AVCodec * codec,uint32_t index)411 OH_AVErrCode OH_AudioEncoder_FreeOutputData(struct OH_AVCodec *codec, uint32_t index)
412 {
413 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
414 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
415 AV_ERR_INVALID_VAL, "magic error!");
416
417 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
418 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
419
420 int32_t ret = audioEncObj->audioEncoder_->ReleaseOutputBuffer(index);
421 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
422 "audioEncoder ReleaseOutputBuffer failed!");
423
424 return AV_ERR_OK;
425 }
426
OH_AudioEncoder_SetParameter(struct OH_AVCodec * codec,struct OH_AVFormat * format)427 OH_AVErrCode OH_AudioEncoder_SetParameter(struct OH_AVCodec *codec, struct OH_AVFormat *format)
428 {
429 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
430 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
431 AV_ERR_INVALID_VAL, "magic error!");
432 CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
433 CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "magic error!");
434
435 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
436 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
437
438 int32_t ret = audioEncObj->audioEncoder_->SetParameter(format->format_);
439 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
440 "audioEncoder SetParameter failed!");
441
442 return AV_ERR_OK;
443 }
444
OH_AudioEncoder_SetCallback(struct OH_AVCodec * codec,struct OH_AVCodecAsyncCallback callback,void * userData)445 OH_AVErrCode OH_AudioEncoder_SetCallback(struct OH_AVCodec *codec, struct OH_AVCodecAsyncCallback callback,
446 void *userData)
447 {
448 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "input codec is nullptr!");
449 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER,
450 AV_ERR_INVALID_VAL, "magic error!");
451 CHECK_AND_RETURN_RET_LOG(callback.onError != nullptr,
452 AV_ERR_INVALID_VAL, "Callback onError is nullptr");
453 CHECK_AND_RETURN_RET_LOG(callback.onNeedInputData != nullptr,
454 AV_ERR_INVALID_VAL, "Callback onNeedInputData is nullptr");
455 CHECK_AND_RETURN_RET_LOG(callback.onNeedOutputData != nullptr,
456 AV_ERR_INVALID_VAL, "Callback onNeedOutputData is nullptr");
457 CHECK_AND_RETURN_RET_LOG(callback.onStreamChanged != nullptr,
458 AV_ERR_INVALID_VAL, "Callback onStreamChanged is nullptr");
459
460 struct AudioEncoderObject *audioEncObj = reinterpret_cast<AudioEncoderObject *>(codec);
461 CHECK_AND_RETURN_RET_LOG(audioEncObj->audioEncoder_ != nullptr, AV_ERR_INVALID_VAL, "audioEncoder_ is nullptr!");
462
463 audioEncObj->callback_ = std::make_shared<NativeAudioEncoderCallback>(codec, callback, userData);
464
465 int32_t ret = audioEncObj->audioEncoder_->SetCallback(audioEncObj->callback_);
466 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
467 "audioEncoder SetCallback failed!");
468
469 return AV_ERR_OK;
470 }
471
OH_AudioEncoder_IsValid(OH_AVCodec * codec,bool * isValid)472 OH_AVErrCode OH_AudioEncoder_IsValid(OH_AVCodec *codec, bool *isValid)
473 {
474 CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Input codec is nullptr!");
475 CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER, AV_ERR_INVALID_VAL, "Magic error!");
476 CHECK_AND_RETURN_RET_LOG(isValid != nullptr, AV_ERR_INVALID_VAL, "Input isValid is nullptr!");
477 *isValid = true;
478 return AV_ERR_OK;
479 }
480
481 #ifdef __cplusplus
482 };
483 #endif
484 } // namespace MediaAVCodec
485 } // namespace OHOS