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