• 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 "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