• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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