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