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